mirror of
https://github.com/strapi/strapi.git
synced 2025-10-03 20:33:21 +00:00
Relations creation TU
This commit is contained in:
parent
fa094f1ede
commit
56af6dd558
@ -2,9 +2,23 @@ import styled from 'styled-components';
|
|||||||
|
|
||||||
const RelationsWrapper = styled.div`
|
const RelationsWrapper = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
.relation-base {
|
||||||
padding: 2.7rem 1.5rem 3.3rem 1.5rem;
|
display: flex;
|
||||||
justify-content: space-between;
|
padding: 2.7rem 1.5rem 3.3rem 1.5rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.relation-advanced {
|
||||||
|
.row {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
width: 100%;
|
||||||
|
margin: 1.3rem 1.5rem 2.1rem 1.5rem;
|
||||||
|
height: 1px;
|
||||||
|
background-color: rgba(14, 22, 34, 0.04);
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default RelationsWrapper;
|
export default RelationsWrapper;
|
||||||
|
@ -227,18 +227,17 @@ export function getDataSucceeded({ allModels, models }, connections, { data }) {
|
|||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const initialDataGroup = data.reduce((acc, current) => {
|
const initialDataGroup = data.reduce((acc, current) => {
|
||||||
const {
|
const { schema, uid } = current;
|
||||||
schema: { attributes, name },
|
const { attributes, name } = schema;
|
||||||
uid,
|
|
||||||
} = current;
|
|
||||||
|
|
||||||
const group = {
|
const group = {
|
||||||
...current,
|
...schema,
|
||||||
|
attributes: buildGroupAttributes(attributes),
|
||||||
|
uid,
|
||||||
name: name || uid,
|
name: name || uid,
|
||||||
isTemporary: false,
|
isTemporary: false,
|
||||||
};
|
};
|
||||||
set(group, ['schema', 'attributes'], buildGroupAttributes(attributes));
|
acc[uid] = group;
|
||||||
acc[current.uid] = group;
|
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
@ -251,13 +250,13 @@ export function getDataSucceeded({ allModels, models }, connections, { data }) {
|
|||||||
} = current;
|
} = current;
|
||||||
|
|
||||||
acc.push({
|
acc.push({
|
||||||
|
uid,
|
||||||
description: description || '',
|
description: description || '',
|
||||||
fields: Object.keys(attributes).length,
|
fields: Object.keys(attributes).length,
|
||||||
icon: 'fa-cube',
|
icon: 'fa-cube',
|
||||||
isTemporary: false,
|
isTemporary: false,
|
||||||
name: name || uid,
|
name: name || uid,
|
||||||
source,
|
source: source || null,
|
||||||
uid,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
@ -292,12 +291,9 @@ export function onChangeExistingGroupMainInfos({ target }) {
|
|||||||
? camelCase(target.value.trim()).toLowerCase()
|
? camelCase(target.value.trim()).toLowerCase()
|
||||||
: target.value;
|
: target.value;
|
||||||
|
|
||||||
const array = target.name.split('.');
|
|
||||||
array.splice(1, 0, 'schema');
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: ON_CHANGE_EXISTING_GROUP_MAIN_INFOS,
|
type: ON_CHANGE_EXISTING_GROUP_MAIN_INFOS,
|
||||||
keys: array,
|
keys: target.name.split('.'),
|
||||||
value,
|
value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -571,6 +567,7 @@ export function submitContentType(oldContentTypeName, data, context, source) {
|
|||||||
|
|
||||||
export function submitGroup(oldGroupName, data, context, source) {
|
export function submitGroup(oldGroupName, data, context, source) {
|
||||||
const attributes = formatGroupAttributes(data.attributes);
|
const attributes = formatGroupAttributes(data.attributes);
|
||||||
|
delete data['isTemporary'];
|
||||||
const body = Object.assign(cloneDeep(data), { attributes });
|
const body = Object.assign(cloneDeep(data), { attributes });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -612,8 +609,7 @@ export function submitTempContentTypeSucceeded() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function submitTempGroup(data, context) {
|
export function submitTempGroup(data, context) {
|
||||||
const attributes = formatGroupAttributes(data.schema.attributes);
|
const attributes = formatGroupAttributes(data.attributes);
|
||||||
delete data['schema'];
|
|
||||||
const body = Object.assign(cloneDeep(data), { attributes });
|
const body = Object.assign(cloneDeep(data), { attributes });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -700,9 +696,11 @@ export const buildGroupAttributes = attributes =>
|
|||||||
|
|
||||||
export const formatGroupAttributes = attributes => {
|
export const formatGroupAttributes = attributes => {
|
||||||
const formattedAttributes = attributes.reduce((acc, current) => {
|
const formattedAttributes = attributes.reduce((acc, current) => {
|
||||||
acc[current.name] = current;
|
const name = current['name'];
|
||||||
delete current['name'];
|
let newAttribute = { ...current };
|
||||||
|
delete newAttribute['name'];
|
||||||
|
|
||||||
|
acc[name] = newAttribute;
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
|
@ -83,7 +83,6 @@ export class App extends React.Component {
|
|||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
if (prevProps.shouldRefetchData !== this.props.shouldRefetchData) {
|
if (prevProps.shouldRefetchData !== this.props.shouldRefetchData) {
|
||||||
console.log('UPDATE !!');
|
|
||||||
this.props.getData();
|
this.props.getData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,22 +133,9 @@ export class App extends React.Component {
|
|||||||
return newGroup;
|
return newGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
return get(
|
return get(modifiedDataGroup, this.getFeatureNameFromSearch(), {}, {});
|
||||||
modifiedDataGroup,
|
|
||||||
[this.getFeatureNameFromSearch(), 'schema'],
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// getFeatureName = () => {
|
|
||||||
// const { modifiedDataGroup } = this.props;
|
|
||||||
// return get(
|
|
||||||
// modifiedDataGroup,
|
|
||||||
// [this.getFeatureNameFromSearch(), 'schema', 'name'],
|
|
||||||
// {}
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
|
|
||||||
getFeatureNameFromSearch = () =>
|
getFeatureNameFromSearch = () =>
|
||||||
getQueryParameters(this.getSearch(), `${this.getFeatureType()}Name`);
|
getQueryParameters(this.getSearch(), `${this.getFeatureType()}Name`);
|
||||||
|
|
||||||
@ -221,7 +207,6 @@ export class App extends React.Component {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
console.log('loading');
|
|
||||||
return <Loader />;
|
return <Loader />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,22 +123,18 @@ export const initialState = fromJS({
|
|||||||
initialDataGroup: {},
|
initialDataGroup: {},
|
||||||
modifiedDataGroup: {},
|
modifiedDataGroup: {},
|
||||||
newGroup: {
|
newGroup: {
|
||||||
|
attributes: [],
|
||||||
collectionName: '',
|
collectionName: '',
|
||||||
connection: '',
|
connection: '',
|
||||||
|
description: '',
|
||||||
name: '',
|
name: '',
|
||||||
schema: {
|
|
||||||
attributes: [],
|
|
||||||
description: '',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
newGroupClone: {
|
newGroupClone: {
|
||||||
|
attributes: [],
|
||||||
collectionName: '',
|
collectionName: '',
|
||||||
connection: '',
|
connection: '',
|
||||||
|
description: '',
|
||||||
name: '',
|
name: '',
|
||||||
schema: {
|
|
||||||
attributes: [],
|
|
||||||
description: '',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -196,7 +192,7 @@ function appReducer(state = initialState, action) {
|
|||||||
: ['modifiedDataGroup', groupName];
|
: ['modifiedDataGroup', groupName];
|
||||||
|
|
||||||
return state
|
return state
|
||||||
.updateIn([...basePath, 'schema', 'attributes'], arr =>
|
.updateIn([...basePath, 'attributes'], arr =>
|
||||||
arr.push(state.get('temporaryAttributeRelationGroup'))
|
arr.push(state.get('temporaryAttributeRelationGroup'))
|
||||||
)
|
)
|
||||||
.update('temporaryAttributeRelationGroup', () =>
|
.update('temporaryAttributeRelationGroup', () =>
|
||||||
@ -246,9 +242,8 @@ function appReducer(state = initialState, action) {
|
|||||||
.setIn(['type'], type);
|
.setIn(['type'], type);
|
||||||
|
|
||||||
return state
|
return state
|
||||||
.updateIn(
|
.updateIn(['modifiedDataGroup', action.groupName, 'attributes'], arr =>
|
||||||
['modifiedDataGroup', action.groupName, 'schema', 'attributes'],
|
arr.push(newAttribute)
|
||||||
arr => arr.push(newAttribute)
|
|
||||||
)
|
)
|
||||||
.update('temporaryAttributeGroup', () => Map({}));
|
.update('temporaryAttributeGroup', () => Map({}));
|
||||||
}
|
}
|
||||||
@ -294,9 +289,7 @@ function appReducer(state = initialState, action) {
|
|||||||
.setIn(['type'], type);
|
.setIn(['type'], type);
|
||||||
|
|
||||||
return state
|
return state
|
||||||
.updateIn(['newGroup', 'schema', 'attributes'], arr =>
|
.updateIn(['newGroup', 'attributes'], arr => arr.push(newAttribute))
|
||||||
arr.push(newAttribute)
|
|
||||||
)
|
|
||||||
.update('temporaryAttributeGroup', () => Map({}));
|
.update('temporaryAttributeGroup', () => Map({}));
|
||||||
}
|
}
|
||||||
case CANCEL_NEW_CONTENT_TYPE:
|
case CANCEL_NEW_CONTENT_TYPE:
|
||||||
@ -581,9 +574,7 @@ function appReducer(state = initialState, action) {
|
|||||||
case RESET_EDIT_TEMP_CONTENT_TYPE:
|
case RESET_EDIT_TEMP_CONTENT_TYPE:
|
||||||
return state.updateIn(['newContentType', 'attributes'], () => Map({}));
|
return state.updateIn(['newContentType', 'attributes'], () => Map({}));
|
||||||
case RESET_EDIT_TEMP_GROUP:
|
case RESET_EDIT_TEMP_GROUP:
|
||||||
return state.updateIn(['newGroup', 'schema', 'attributes'], () =>
|
return state.updateIn(['newGroup', 'attributes'], () => List([]));
|
||||||
List([])
|
|
||||||
);
|
|
||||||
case RESET_EXISTING_CONTENT_TYPE_MAIN_INFOS:
|
case RESET_EXISTING_CONTENT_TYPE_MAIN_INFOS:
|
||||||
return state.updateIn(['modifiedData', action.contentTypeName], () => {
|
return state.updateIn(['modifiedData', action.contentTypeName], () => {
|
||||||
const initialContentType = state
|
const initialContentType = state
|
||||||
@ -596,24 +587,16 @@ function appReducer(state = initialState, action) {
|
|||||||
return initialContentType;
|
return initialContentType;
|
||||||
});
|
});
|
||||||
case RESET_EXISTING_GROUP_MAIN_INFOS: {
|
case RESET_EXISTING_GROUP_MAIN_INFOS: {
|
||||||
return state.updateIn(
|
return state.updateIn(['modifiedDataGroup', action.groupName], () => {
|
||||||
['modifiedDataGroup', action.groupName, 'schema'],
|
const initialGroup = state
|
||||||
() => {
|
.getIn(['initialDataGroup', action.groupName])
|
||||||
const initialGroup = state
|
.set(
|
||||||
.getIn(['initialDataGroup', action.groupName, 'schema'])
|
'attributes',
|
||||||
.set(
|
state.getIn(['modifiedDataGroup', action.groupName, 'attributes'])
|
||||||
'attributes',
|
);
|
||||||
state.getIn([
|
|
||||||
'modifiedDataGroup',
|
|
||||||
action.groupName,
|
|
||||||
'schema',
|
|
||||||
'attributes',
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
return initialGroup;
|
return initialGroup;
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
case RESET_NEW_CONTENT_TYPE_MAIN_INFOS:
|
case RESET_NEW_CONTENT_TYPE_MAIN_INFOS:
|
||||||
return state.updateIn(['newContentType'], () => {
|
return state.updateIn(['newContentType'], () => {
|
||||||
@ -660,8 +643,8 @@ function appReducer(state = initialState, action) {
|
|||||||
|
|
||||||
case SAVE_EDITED_ATTRIBUTE_GROUP: {
|
case SAVE_EDITED_ATTRIBUTE_GROUP: {
|
||||||
const basePath = action.isGroupTemporary
|
const basePath = action.isGroupTemporary
|
||||||
? ['newGroup', 'schema']
|
? ['newGroup']
|
||||||
: ['modifiedDataGroup', action.groupName, 'schema'];
|
: ['modifiedDataGroup', action.groupName];
|
||||||
|
|
||||||
const temporaryAttribute = state.get('temporaryAttributeGroup');
|
const temporaryAttribute = state.get('temporaryAttributeGroup');
|
||||||
state.update('temporaryAttributeGroup', () => {});
|
state.update('temporaryAttributeGroup', () => {});
|
||||||
@ -791,8 +774,8 @@ function appReducer(state = initialState, action) {
|
|||||||
case SET_TEMPORARY_ATTRIBUTE_GROUP:
|
case SET_TEMPORARY_ATTRIBUTE_GROUP:
|
||||||
return state.update('temporaryAttributeGroup', () => {
|
return state.update('temporaryAttributeGroup', () => {
|
||||||
const basePath = action.isGroupTemporary
|
const basePath = action.isGroupTemporary
|
||||||
? ['newGroup', 'schema']
|
? ['newGroup']
|
||||||
: ['modifiedDataGroup', action.groupName, 'schema'];
|
: ['modifiedDataGroup', action.groupName];
|
||||||
|
|
||||||
const attribute = state
|
const attribute = state
|
||||||
.getIn([...basePath, 'attributes', action.attributeIndex])
|
.getIn([...basePath, 'attributes', action.attributeIndex])
|
||||||
@ -844,22 +827,12 @@ function appReducer(state = initialState, action) {
|
|||||||
return state
|
return state
|
||||||
.update('temporaryAttributeRelationGroup', () =>
|
.update('temporaryAttributeRelationGroup', () =>
|
||||||
state
|
state
|
||||||
.getIn([
|
.getIn([...basePath, 'attributes', action.attributeName])
|
||||||
...basePath,
|
|
||||||
'schema',
|
|
||||||
'attributes',
|
|
||||||
action.attributeName,
|
|
||||||
])
|
|
||||||
.set('name', action.attributeName)
|
.set('name', action.attributeName)
|
||||||
)
|
)
|
||||||
.update('initialTemporaryAttributeRelationGroup', () =>
|
.update('initialTemporaryAttributeRelationGroup', () =>
|
||||||
state
|
state
|
||||||
.getIn([
|
.getIn([...basePath, 'attributes', action.attributeName])
|
||||||
...basePath,
|
|
||||||
'schema',
|
|
||||||
'attributes',
|
|
||||||
action.attributeName,
|
|
||||||
])
|
|
||||||
.set('name', action.attributeName)
|
.set('name', action.attributeName)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -885,24 +858,6 @@ function appReducer(state = initialState, action) {
|
|||||||
return state
|
return state
|
||||||
.update('isLoading', () => true)
|
.update('isLoading', () => true)
|
||||||
.update('shouldRefetchData', v => !v);
|
.update('shouldRefetchData', v => !v);
|
||||||
// {
|
|
||||||
// let modifiedGroup = state
|
|
||||||
// .get('modifiedDataGroup')
|
|
||||||
// .find(
|
|
||||||
// (group, key) => !group.equals(state.getIn(['initialDataGroup', key]))
|
|
||||||
// );
|
|
||||||
|
|
||||||
// const uid = modifiedGroup.get('uid');
|
|
||||||
// const groupToUpdate = state.get('groups').findIndex(group => {
|
|
||||||
// return group.get('uid') === uid;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return state
|
|
||||||
// .updateIn(['initialDataGroup', uid], () => modifiedGroup)
|
|
||||||
// .updateIn(['groups', groupToUpdate, 'name'], () =>
|
|
||||||
// modifiedGroup.getIn(['schema', 'name'])
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
case SUBMIT_TEMP_CONTENT_TYPE_SUCCEEDED:
|
case SUBMIT_TEMP_CONTENT_TYPE_SUCCEEDED:
|
||||||
return state
|
return state
|
||||||
.update('isLoading', () => true)
|
.update('isLoading', () => true)
|
||||||
|
@ -501,9 +501,8 @@ describe('App actions', () => {
|
|||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
uid: 'ingredients',
|
uid: 'ingredients',
|
||||||
name: 'ingredients',
|
|
||||||
source: null,
|
|
||||||
schema: {
|
schema: {
|
||||||
|
name: 'ingredients',
|
||||||
connection: 'default',
|
connection: 'default',
|
||||||
collectionName: 'ingredients',
|
collectionName: 'ingredients',
|
||||||
description: 'Little description',
|
description: 'Little description',
|
||||||
@ -556,30 +555,27 @@ describe('App actions', () => {
|
|||||||
isTemporary: false,
|
isTemporary: false,
|
||||||
uid: 'ingredients',
|
uid: 'ingredients',
|
||||||
name: 'ingredients',
|
name: 'ingredients',
|
||||||
source: null,
|
connection: 'default',
|
||||||
schema: {
|
collectionName: 'ingredients',
|
||||||
connection: 'default',
|
description: 'Little description',
|
||||||
collectionName: 'ingredients',
|
attributes: [
|
||||||
description: 'Little description',
|
{
|
||||||
attributes: [
|
name: 'name',
|
||||||
{
|
type: 'string',
|
||||||
name: 'name',
|
required: true,
|
||||||
type: 'string',
|
},
|
||||||
required: true,
|
{
|
||||||
},
|
name: 'quantity',
|
||||||
{
|
type: 'float',
|
||||||
name: 'quantity',
|
required: true,
|
||||||
type: 'float',
|
},
|
||||||
required: true,
|
{
|
||||||
},
|
name: 'picture',
|
||||||
{
|
model: 'file',
|
||||||
name: 'picture',
|
via: 'related',
|
||||||
model: 'file',
|
plugin: 'upload',
|
||||||
via: 'related',
|
},
|
||||||
plugin: 'upload',
|
],
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const connections = ['default'];
|
const connections = ['default'];
|
||||||
@ -596,8 +592,8 @@ describe('App actions', () => {
|
|||||||
icon: 'fa-cube',
|
icon: 'fa-cube',
|
||||||
isTemporary: false,
|
isTemporary: false,
|
||||||
name: 'ingredients',
|
name: 'ingredients',
|
||||||
source: null,
|
|
||||||
uid: 'ingredients',
|
uid: 'ingredients',
|
||||||
|
source: null,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -147,25 +147,31 @@ describe('appReducer', () => {
|
|||||||
target: '',
|
target: '',
|
||||||
unique: false,
|
unique: false,
|
||||||
},
|
},
|
||||||
|
temporaryAttributeRelationGroup: {
|
||||||
|
name: '',
|
||||||
|
columnName: '',
|
||||||
|
dominant: false,
|
||||||
|
targetColumnName: '',
|
||||||
|
key: '-',
|
||||||
|
nature: 'oneWay',
|
||||||
|
plugin: '',
|
||||||
|
target: '',
|
||||||
|
unique: false,
|
||||||
|
},
|
||||||
shouldRefetchData: false,
|
shouldRefetchData: false,
|
||||||
|
|
||||||
newGroup: {
|
newGroup: {
|
||||||
collectionName: '',
|
collectionName: '',
|
||||||
connection: '',
|
connection: '',
|
||||||
name: '',
|
name: '',
|
||||||
schema: {
|
attributes: [],
|
||||||
attributes: [],
|
description: '',
|
||||||
description: '',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
newGroupClone: {
|
newGroupClone: {
|
||||||
collectionName: '',
|
collectionName: '',
|
||||||
connection: '',
|
connection: '',
|
||||||
name: '',
|
name: '',
|
||||||
schema: {
|
attributes: [],
|
||||||
attributes: [],
|
description: '',
|
||||||
description: '',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -749,24 +755,21 @@ describe('appReducer', () => {
|
|||||||
tests: {
|
tests: {
|
||||||
uid: 'tests',
|
uid: 'tests',
|
||||||
name: 'tests',
|
name: 'tests',
|
||||||
source: null,
|
connection: 'default',
|
||||||
schema: {
|
collectionName: 'tests',
|
||||||
connection: 'default',
|
description: '',
|
||||||
collectionName: 'tests',
|
attributes: [
|
||||||
description: '',
|
{
|
||||||
attributes: [
|
name: 'name',
|
||||||
{
|
type: 'string',
|
||||||
name: 'name',
|
required: true,
|
||||||
type: 'string',
|
},
|
||||||
required: true,
|
{
|
||||||
},
|
name: 'quantity',
|
||||||
{
|
type: 'float',
|
||||||
name: 'quantity',
|
required: true,
|
||||||
type: 'float',
|
},
|
||||||
required: true,
|
],
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
isTemporary: false,
|
isTemporary: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -776,7 +779,6 @@ describe('appReducer', () => {
|
|||||||
{
|
{
|
||||||
uid: 'tests',
|
uid: 'tests',
|
||||||
name: 'tests',
|
name: 'tests',
|
||||||
source: null,
|
|
||||||
schema: {
|
schema: {
|
||||||
connection: 'default',
|
connection: 'default',
|
||||||
collectionName: 'tests',
|
collectionName: 'tests',
|
||||||
@ -1046,24 +1048,31 @@ describe('appReducer', () => {
|
|||||||
target: '',
|
target: '',
|
||||||
unique: false,
|
unique: false,
|
||||||
},
|
},
|
||||||
|
temporaryAttributeRelationGroup: {
|
||||||
|
name: '',
|
||||||
|
columnName: '',
|
||||||
|
dominant: false,
|
||||||
|
targetColumnName: '',
|
||||||
|
key: '-',
|
||||||
|
nature: 'oneWay',
|
||||||
|
plugin: '',
|
||||||
|
target: '',
|
||||||
|
unique: false,
|
||||||
|
},
|
||||||
shouldRefetchData: false,
|
shouldRefetchData: false,
|
||||||
newGroup: {
|
newGroup: {
|
||||||
collectionName: '',
|
collectionName: '',
|
||||||
connection: '',
|
connection: '',
|
||||||
name: '',
|
name: '',
|
||||||
schema: {
|
attributes: [],
|
||||||
attributes: [],
|
description: '',
|
||||||
description: '',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
newGroupClone: {
|
newGroupClone: {
|
||||||
collectionName: '',
|
collectionName: '',
|
||||||
connection: '',
|
connection: '',
|
||||||
name: '',
|
name: '',
|
||||||
schema: {
|
attributes: [],
|
||||||
attributes: [],
|
description: '',
|
||||||
description: '',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
initialDataGroup: {},
|
initialDataGroup: {},
|
||||||
modifiedDataGroup: {},
|
modifiedDataGroup: {},
|
||||||
|
@ -104,9 +104,7 @@ export class GroupPage extends React.Component {
|
|||||||
return get(modifiedDataGroup, this.getFeatureName(), {});
|
return get(modifiedDataGroup, this.getFeatureName(), {});
|
||||||
};
|
};
|
||||||
|
|
||||||
getFeatureSchema = () => get(this.getFeature(), 'schema', {});
|
getFeatureAttributes = () => get(this.getFeature(), 'attributes', []);
|
||||||
|
|
||||||
getFeatureAttributes = () => get(this.getFeatureSchema(), 'attributes', []);
|
|
||||||
|
|
||||||
getFeatureAttributesNames = () => {
|
getFeatureAttributesNames = () => {
|
||||||
return this.getFeatureAttributes().map(attribute => {
|
return this.getFeatureAttributes().map(attribute => {
|
||||||
@ -139,25 +137,13 @@ export class GroupPage extends React.Component {
|
|||||||
return displayName;
|
return displayName;
|
||||||
};
|
};
|
||||||
|
|
||||||
getFeatureHeaderTitle = () => {
|
|
||||||
const { modifiedDataGroup, newGroup } = this.props;
|
|
||||||
const name = this.getFeatureName();
|
|
||||||
|
|
||||||
/* istanbul ignore if */
|
|
||||||
const displayName = this.isUpdatingTempFeature()
|
|
||||||
? get(newGroup, ['schema', 'name'], null)
|
|
||||||
: get(modifiedDataGroup, [name, 'schema', 'name'], null);
|
|
||||||
|
|
||||||
return displayName;
|
|
||||||
};
|
|
||||||
|
|
||||||
getFeatureHeaderDescription = () => {
|
getFeatureHeaderDescription = () => {
|
||||||
const { modifiedDataGroup, newGroup } = this.props;
|
const { modifiedDataGroup, newGroup } = this.props;
|
||||||
const name = this.getFeatureName();
|
const name = this.getFeatureName();
|
||||||
|
|
||||||
const description = this.isUpdatingTempFeature()
|
const description = this.isUpdatingTempFeature()
|
||||||
? get(newGroup, ['schema', 'description'], null)
|
? get(newGroup, 'description', null)
|
||||||
: get(modifiedDataGroup, [name, 'schema', 'description'], null);
|
: get(modifiedDataGroup, [name, 'description'], null);
|
||||||
|
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
@ -190,7 +176,7 @@ export class GroupPage extends React.Component {
|
|||||||
? submitTempGroup(newGroup, this.context)
|
? submitTempGroup(newGroup, this.context)
|
||||||
: submitGroup(
|
: submitGroup(
|
||||||
featureName,
|
featureName,
|
||||||
get(modifiedDataGroup, [featureName, 'schema']),
|
get(modifiedDataGroup, featureName),
|
||||||
Object.assign(this.context, {
|
Object.assign(this.context, {
|
||||||
history: this.props.history,
|
history: this.props.history,
|
||||||
}),
|
}),
|
||||||
@ -287,11 +273,10 @@ export class GroupPage extends React.Component {
|
|||||||
const { attrToDelete } = this.state;
|
const { attrToDelete } = this.state;
|
||||||
|
|
||||||
const keys = this.isUpdatingTempFeature()
|
const keys = this.isUpdatingTempFeature()
|
||||||
? ['newGroup', 'schema', 'attributes', attrToDelete]
|
? ['newGroup', 'attributes', attrToDelete]
|
||||||
: [
|
: [
|
||||||
'modifiedDataGroup',
|
'modifiedDataGroup',
|
||||||
this.getFeatureName(),
|
this.getFeatureName(),
|
||||||
'schema',
|
|
||||||
'attributes',
|
'attributes',
|
||||||
attrToDelete,
|
attrToDelete,
|
||||||
];
|
];
|
||||||
@ -444,7 +429,7 @@ export class GroupPage extends React.Component {
|
|||||||
<ViewContainer
|
<ViewContainer
|
||||||
{...this.props}
|
{...this.props}
|
||||||
featureType={this.featureType}
|
featureType={this.featureType}
|
||||||
headerTitle={this.getFeatureHeaderTitle()}
|
headerTitle={this.getFeatureDisplayName()}
|
||||||
headerDescription={this.getFeatureHeaderDescription()}
|
headerDescription={this.getFeatureHeaderDescription()}
|
||||||
pluginHeaderActions={this.getPluginHeaderActions()}
|
pluginHeaderActions={this.getPluginHeaderActions()}
|
||||||
onClickIcon={this.openEditFeatureModal}
|
onClickIcon={this.openEditFeatureModal}
|
||||||
|
@ -61,23 +61,21 @@ const props = {
|
|||||||
uid: 'tests',
|
uid: 'tests',
|
||||||
name: 'Tests',
|
name: 'Tests',
|
||||||
source: null,
|
source: null,
|
||||||
schema: {
|
connection: 'default',
|
||||||
connection: 'default',
|
collectionName: 'tests',
|
||||||
collectionName: 'tests',
|
description: 'tests description',
|
||||||
description: 'tests description',
|
attributes: [
|
||||||
attributes: [
|
{
|
||||||
{
|
name: 'name',
|
||||||
name: 'name',
|
type: 'string',
|
||||||
type: 'string',
|
required: true,
|
||||||
required: true,
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'quantity',
|
||||||
name: 'quantity',
|
type: 'float',
|
||||||
type: 'float',
|
required: true,
|
||||||
required: true,
|
},
|
||||||
},
|
],
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
location: {
|
location: {
|
||||||
@ -89,23 +87,21 @@ const props = {
|
|||||||
uid: 'tests',
|
uid: 'tests',
|
||||||
name: 'Tests',
|
name: 'Tests',
|
||||||
source: null,
|
source: null,
|
||||||
schema: {
|
connection: 'default',
|
||||||
connection: 'default',
|
collectionName: 'tests',
|
||||||
collectionName: 'tests',
|
description: 'tests description',
|
||||||
description: 'tests description',
|
attributes: [
|
||||||
attributes: [
|
{
|
||||||
{
|
name: 'name',
|
||||||
name: 'name',
|
type: 'string',
|
||||||
type: 'string',
|
required: true,
|
||||||
required: true,
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'quantity',
|
||||||
name: 'quantity',
|
type: 'float',
|
||||||
type: 'float',
|
required: true,
|
||||||
required: true,
|
},
|
||||||
},
|
],
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
@ -117,12 +113,13 @@ const props = {
|
|||||||
collectionName: '',
|
collectionName: '',
|
||||||
connection: '',
|
connection: '',
|
||||||
name: '',
|
name: '',
|
||||||
schema: {
|
attributes: [],
|
||||||
attributes: [],
|
description: '',
|
||||||
description: '',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
onChangeAttributeGroup: jest.fn(),
|
onChangeAttributeGroup: jest.fn(),
|
||||||
|
onChangeRelationGroup: jest.fn(),
|
||||||
|
onChangeRelationNatureGroup: jest.fn(),
|
||||||
|
onChangeRelationTargetGroup: jest.fn(),
|
||||||
resetEditTempGroup: jest.fn(),
|
resetEditTempGroup: jest.fn(),
|
||||||
saveEditedAttributeGroup: jest.fn(),
|
saveEditedAttributeGroup: jest.fn(),
|
||||||
setTemporaryAttributeGroup: jest.fn(),
|
setTemporaryAttributeGroup: jest.fn(),
|
||||||
@ -130,6 +127,17 @@ const props = {
|
|||||||
submitTempGroup: jest.fn(),
|
submitTempGroup: jest.fn(),
|
||||||
submitGroup: jest.fn(),
|
submitGroup: jest.fn(),
|
||||||
temporaryAttributeGroup: {},
|
temporaryAttributeGroup: {},
|
||||||
|
temporaryAttributeRelationGroup: {
|
||||||
|
name: '',
|
||||||
|
columnName: '',
|
||||||
|
dominant: false,
|
||||||
|
targetColumnName: '',
|
||||||
|
key: '-',
|
||||||
|
nature: 'oneWay',
|
||||||
|
plugin: '',
|
||||||
|
target: '',
|
||||||
|
unique: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('CTB <GroupPage />', () => {
|
describe('CTB <GroupPage />', () => {
|
||||||
@ -229,9 +237,9 @@ describe('CTB <GroupPage />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should call the openAttributesModal when clicking on the EmptyAttributesBlock', () => {
|
it('should call the openAttributesModal when clicking on the EmptyAttributesBlock', () => {
|
||||||
props.initialDataGroup.tests.schema.attributes = [];
|
props.initialDataGroup.tests.attributes = [];
|
||||||
props.modifiedDataGroup.tests.schema.attributes = [];
|
props.modifiedDataGroup.tests.attributes = [];
|
||||||
props.newGroup.schema.attributes = [];
|
props.newGroup.attributes = [];
|
||||||
|
|
||||||
const wrapper = shallow(<GroupPage {...props} />);
|
const wrapper = shallow(<GroupPage {...props} />);
|
||||||
const spyOnClick = jest.spyOn(wrapper.instance(), 'openAttributesModal');
|
const spyOnClick = jest.spyOn(wrapper.instance(), 'openAttributesModal');
|
||||||
@ -456,7 +464,7 @@ describe('CTB <GroupPage />, lifecycle', () => {
|
|||||||
props.groups.find(item => item.name == 'tests').isTemporary = true;
|
props.groups.find(item => item.name == 'tests').isTemporary = true;
|
||||||
props.newGroup.name = 'tests';
|
props.newGroup.name = 'tests';
|
||||||
|
|
||||||
props.newGroup.schema.attributes = [
|
props.newGroup.attributes = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -479,7 +487,7 @@ describe('CTB <GroupPage />, lifecycle', () => {
|
|||||||
it('should call submitGroup with modifiedDataGroup param when isTemporary is false', () => {
|
it('should call submitGroup with modifiedDataGroup param when isTemporary is false', () => {
|
||||||
props.groups.find(item => item.name == 'tests').isTemporary = false;
|
props.groups.find(item => item.name == 'tests').isTemporary = false;
|
||||||
|
|
||||||
props.initialDataGroup.tests.schema.attributes = [
|
props.initialDataGroup.tests.attributes = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -491,7 +499,7 @@ describe('CTB <GroupPage />, lifecycle', () => {
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
props.modifiedDataGroup.tests.schema.attributes = [
|
props.modifiedDataGroup.tests.attributes = [
|
||||||
{
|
{
|
||||||
name: 'firstname',
|
name: 'firstname',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -563,7 +571,7 @@ describe('CTB <GroupPage />, lifecycle', () => {
|
|||||||
showWarning: true,
|
showWarning: true,
|
||||||
});
|
});
|
||||||
handleDeleteAttribute();
|
handleDeleteAttribute();
|
||||||
const keys = ['modifiedDataGroup', 'tests', 'schema', 'attributes', 0];
|
const keys = ['modifiedDataGroup', 'tests', 'attributes', 0];
|
||||||
expect(props.deleteGroupAttribute).toHaveBeenCalledWith(keys);
|
expect(props.deleteGroupAttribute).toHaveBeenCalledWith(keys);
|
||||||
expect(context.emitEvent).toHaveBeenCalledWith('willDeleteFieldOfGroup');
|
expect(context.emitEvent).toHaveBeenCalledWith('willDeleteFieldOfGroup');
|
||||||
});
|
});
|
||||||
@ -582,7 +590,7 @@ describe('CTB <GroupPage />, lifecycle', () => {
|
|||||||
handleClickOnTrashIcon(0);
|
handleClickOnTrashIcon(0);
|
||||||
handleDeleteAttribute();
|
handleDeleteAttribute();
|
||||||
|
|
||||||
const keys = ['newGroup', 'schema', 'attributes', 0];
|
const keys = ['newGroup', 'attributes', 0];
|
||||||
expect(props.deleteGroupAttribute).toHaveBeenCalledWith(keys);
|
expect(props.deleteGroupAttribute).toHaveBeenCalledWith(keys);
|
||||||
expect(context.emitEvent).toHaveBeenCalledWith('willDeleteFieldOfGroup');
|
expect(context.emitEvent).toHaveBeenCalledWith('willDeleteFieldOfGroup');
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"customBootstrapClass": "col-md-12",
|
||||||
|
"label": {
|
||||||
|
"id": "content-type-builder.form.attribute.item.uniqueField"
|
||||||
|
},
|
||||||
|
"name": "unique",
|
||||||
|
"type": "checkbox",
|
||||||
|
"value": false,
|
||||||
|
"validations": {},
|
||||||
|
"inputDescription": {
|
||||||
|
"id": "content-type-builder.form.attribute.item.uniqueField.description"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addon": "name",
|
||||||
|
"label": {
|
||||||
|
"id": "content-type-builder.form.attribute.item.customColumnName"
|
||||||
|
},
|
||||||
|
"name": "columnName",
|
||||||
|
"type": "string",
|
||||||
|
"value": "",
|
||||||
|
"validations": {},
|
||||||
|
"inputDescription": {
|
||||||
|
"id": "content-type-builder.form.attribute.item.customColumnName.description"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addon": "key",
|
||||||
|
"label": "",
|
||||||
|
"name": "targetColumnName",
|
||||||
|
"type": "string",
|
||||||
|
"value": "",
|
||||||
|
"validations": {}
|
||||||
|
}
|
||||||
|
]
|
@ -9,6 +9,8 @@ import PropTypes from 'prop-types';
|
|||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { get, isEmpty } from 'lodash';
|
import { get, isEmpty } from 'lodash';
|
||||||
|
|
||||||
|
import { InputsIndex as Input } from 'strapi-helper-plugin';
|
||||||
|
|
||||||
import pluginId from '../../pluginId';
|
import pluginId from '../../pluginId';
|
||||||
|
|
||||||
import BodyModal from '../../components/BodyModal';
|
import BodyModal from '../../components/BodyModal';
|
||||||
@ -28,6 +30,8 @@ import WrapperModal from '../../components/WrapperModal';
|
|||||||
import Icon from '../../assets/icons/icon_type_ct.png';
|
import Icon from '../../assets/icons/icon_type_ct.png';
|
||||||
import IconGroup from '../../assets/icons/icon_type_groups.png';
|
import IconGroup from '../../assets/icons/icon_type_groups.png';
|
||||||
|
|
||||||
|
import formAdvanced from './advanced.json';
|
||||||
|
|
||||||
const NAVLINKS = [{ id: 'base', custom: 'relation' }, { id: 'advanced' }];
|
const NAVLINKS = [{ id: 'base', custom: 'relation' }, { id: 'advanced' }];
|
||||||
|
|
||||||
class RelationFormGroup extends React.Component {
|
class RelationFormGroup extends React.Component {
|
||||||
@ -110,6 +114,21 @@ class RelationFormGroup extends React.Component {
|
|||||||
onChangeRelationTarget(group, featureToEditName, actionType === 'edit');
|
onChangeRelationTarget(group, featureToEditName, actionType === 'edit');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleGoTo = to => {
|
||||||
|
const { emitEvent } = this.context;
|
||||||
|
const { actionType, attributeToEditName, push } = this.props;
|
||||||
|
const attributeName =
|
||||||
|
actionType === 'edit' ? `&attributeName=${attributeToEditName}` : '';
|
||||||
|
|
||||||
|
if (to === 'advanced') {
|
||||||
|
emitEvent('didSelectContentTypeFieldSettings');
|
||||||
|
}
|
||||||
|
|
||||||
|
push({
|
||||||
|
search: `modalType=attributeForm&attributeType=relation&settingType=${to}&actionType=${actionType}${attributeName}`,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
handleOnClosed = () => {
|
handleOnClosed = () => {
|
||||||
const { onCancel } = this.props;
|
const { onCancel } = this.props;
|
||||||
|
|
||||||
@ -146,21 +165,6 @@ class RelationFormGroup extends React.Component {
|
|||||||
push({ search: '' });
|
push({ search: '' });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleGoTo = to => {
|
|
||||||
const { emitEvent } = this.context;
|
|
||||||
const { actionType, attributeToEditName, push } = this.props;
|
|
||||||
const attributeName =
|
|
||||||
actionType === 'edit' ? `&attributeName=${attributeToEditName}` : '';
|
|
||||||
|
|
||||||
if (to === 'advanced') {
|
|
||||||
emitEvent('didSelectContentTypeFieldSettings');
|
|
||||||
}
|
|
||||||
|
|
||||||
push({
|
|
||||||
search: `modalType=attributeForm&attributeType=relation&settingType=${to}&actionType=${actionType}${attributeName}`,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleSubmit = e => {
|
handleSubmit = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@ -191,13 +195,39 @@ class RelationFormGroup extends React.Component {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
renderAdvancedSettings = () => {
|
||||||
|
const { didCheckErrors } = this.state;
|
||||||
|
const { modifiedData, onChange } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relation-advanced">
|
||||||
|
<div className="row">
|
||||||
|
{formAdvanced.map((input, i) => {
|
||||||
|
return (
|
||||||
|
<React.Fragment key={input.name}>
|
||||||
|
<Input
|
||||||
|
{...input}
|
||||||
|
addon={modifiedData[input.addon]}
|
||||||
|
didCheckErrors={didCheckErrors}
|
||||||
|
key={input.name}
|
||||||
|
onChange={onChange}
|
||||||
|
value={modifiedData[input.name]}
|
||||||
|
/>
|
||||||
|
{i === 0 && <hr />}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
submit = (shouldContinue = false) => {
|
submit = (shouldContinue = false) => {
|
||||||
const { actionType, onSubmit, onSubmitEdit } = this.props;
|
const { actionType, onSubmit, onSubmitEdit } = this.props;
|
||||||
|
|
||||||
if (actionType === 'edit') {
|
if (actionType === 'edit') {
|
||||||
onSubmitEdit(shouldContinue);
|
onSubmitEdit(shouldContinue);
|
||||||
} else {
|
} else {
|
||||||
console.log('SUUUBMIT');
|
|
||||||
onSubmit(shouldContinue);
|
onSubmit(shouldContinue);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -213,7 +243,7 @@ class RelationFormGroup extends React.Component {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
const { formErrors, didCheckErrors } = this.state;
|
const { formErrors, didCheckErrors } = this.state;
|
||||||
return (
|
return (
|
||||||
<RelationsWrapper>
|
<div className="relation-base">
|
||||||
<RelationBox
|
<RelationBox
|
||||||
autoFocus
|
autoFocus
|
||||||
didCheckErrors={didCheckErrors}
|
didCheckErrors={didCheckErrors}
|
||||||
@ -244,7 +274,7 @@ class RelationFormGroup extends React.Component {
|
|||||||
source={source}
|
source={source}
|
||||||
value={key}
|
value={key}
|
||||||
/>
|
/>
|
||||||
</RelationsWrapper>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -287,7 +317,9 @@ class RelationFormGroup extends React.Component {
|
|||||||
</section>
|
</section>
|
||||||
</HeaderModal>
|
</HeaderModal>
|
||||||
<form onSubmit={this.handleSubmitAndContinue}>
|
<form onSubmit={this.handleSubmitAndContinue}>
|
||||||
<BodyModal>{showForm && content}</BodyModal>
|
<BodyModal>
|
||||||
|
<RelationsWrapper>{showForm && content}</RelationsWrapper>
|
||||||
|
</BodyModal>
|
||||||
<FooterModal>
|
<FooterModal>
|
||||||
<section>
|
<section>
|
||||||
<ButtonModalPrimary
|
<ButtonModalPrimary
|
||||||
@ -321,30 +353,30 @@ RelationFormGroup.contextTypes = {
|
|||||||
RelationFormGroup.defaultProps = {
|
RelationFormGroup.defaultProps = {
|
||||||
actionType: 'create',
|
actionType: 'create',
|
||||||
activeTab: 'base',
|
activeTab: 'base',
|
||||||
|
alreadyTakenAttributes: [],
|
||||||
featureType: 'model',
|
featureType: 'model',
|
||||||
features: [],
|
features: [],
|
||||||
featuereToEditName: '',
|
featureToEditName: '',
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
isUpdatingTemporary: false,
|
isUpdatingTemporary: false,
|
||||||
onChange: () => {},
|
|
||||||
onChangeRelationTarget: () => {},
|
|
||||||
onSubmit: () => {},
|
|
||||||
source: null,
|
source: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
RelationFormGroup.propTypes = {
|
RelationFormGroup.propTypes = {
|
||||||
actionType: PropTypes.string,
|
actionType: PropTypes.string,
|
||||||
activeTab: PropTypes.string,
|
activeTab: PropTypes.string,
|
||||||
|
alreadyTakenAttributes: PropTypes.array,
|
||||||
features: PropTypes.array,
|
features: PropTypes.array,
|
||||||
featureType: PropTypes.string,
|
featureType: PropTypes.string,
|
||||||
featuereToEditName: PropTypes.string,
|
featureToEditName: PropTypes.string,
|
||||||
isOpen: PropTypes.bool,
|
isOpen: PropTypes.bool,
|
||||||
isUpdatingTemporary: PropTypes.bool,
|
isUpdatingTemporary: PropTypes.bool,
|
||||||
modifiedData: PropTypes.object.isRequired,
|
modifiedData: PropTypes.object.isRequired,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func.isRequired,
|
||||||
onChangeRelationTarget: PropTypes.func,
|
onChangeRelationTarget: PropTypes.func.isRequired,
|
||||||
onSubmit: PropTypes.func,
|
onSubmit: PropTypes.func.isRequired,
|
||||||
push: PropTypes.func.isRequired,
|
push: PropTypes.func.isRequired,
|
||||||
|
setTempAttribute: PropTypes.func.isRequired,
|
||||||
source: PropTypes.string,
|
source: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,366 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import mountWithIntl from 'testUtils/mountWithIntl';
|
||||||
|
import formatMessagesWithPluginId from 'testUtils/formatMessages';
|
||||||
|
|
||||||
|
import pluginId from '../../../pluginId';
|
||||||
|
import pluginTradsEn from '../../../translations/en.json';
|
||||||
|
import RelationFormGroup from '../index';
|
||||||
|
|
||||||
|
const messages = formatMessagesWithPluginId(pluginId, pluginTradsEn);
|
||||||
|
const renderComponent = (props = {}, context = {}) =>
|
||||||
|
mountWithIntl(<RelationFormGroup {...props} />, messages, context);
|
||||||
|
|
||||||
describe('<RelationFormGroup />', () => {
|
describe('<RelationFormGroup />', () => {
|
||||||
|
let props;
|
||||||
|
let wrapper;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
props = {
|
||||||
|
activeTab: 'base',
|
||||||
|
alreadyTakenAttributes: [],
|
||||||
|
attributeToEditName: '',
|
||||||
|
setTempAttribute: jest.fn(),
|
||||||
|
isOpen: true,
|
||||||
|
features: [],
|
||||||
|
featureToEditName: '',
|
||||||
|
modifiedData: {
|
||||||
|
key: '',
|
||||||
|
name: '',
|
||||||
|
source: '',
|
||||||
|
},
|
||||||
|
onCancel: jest.fn(),
|
||||||
|
onChange: jest.fn(),
|
||||||
|
onChangeRelationNature: jest.fn(),
|
||||||
|
onChangeRelationTarget: jest.fn(),
|
||||||
|
onSubmit: jest.fn(),
|
||||||
|
onSubmitEdit: jest.fn(),
|
||||||
|
setTempAttribute: jest.fn(),
|
||||||
|
push: jest.fn(),
|
||||||
|
source: null,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
|
||||||
it('should not crash', () => {
|
it('should not crash', () => {
|
||||||
expect(true).toBe(true);
|
wrapper = renderComponent(props);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the advanced tab if the active tab is advanced', () => {
|
||||||
|
props.activeTab = 'advanced';
|
||||||
|
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const compo = wrapper.find(RelationFormGroup);
|
||||||
|
const spyOnRenderAdvancedSettings = jest.spyOn(
|
||||||
|
compo.instance(),
|
||||||
|
'renderAdvancedSettings'
|
||||||
|
);
|
||||||
|
compo.instance().forceUpdate();
|
||||||
|
|
||||||
|
expect(spyOnRenderAdvancedSettings).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GetFormErrors', () => {
|
||||||
|
it('should return an object with the errors if the form is empty', () => {
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { getFormErrors } = wrapper.find(RelationFormGroup).instance();
|
||||||
|
|
||||||
|
expect(getFormErrors()).toEqual({
|
||||||
|
name: [{ id: 'content-type-builder.error.validation.required' }],
|
||||||
|
key: [{ id: 'content-type-builder.error.validation.required' }],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an object if a name is already taken', () => {
|
||||||
|
props.alreadyTakenAttributes = ['test'];
|
||||||
|
props.modifiedData.name = 'test';
|
||||||
|
props.modifiedData.key = 'strapi';
|
||||||
|
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { getFormErrors } = wrapper.find(RelationFormGroup).instance();
|
||||||
|
|
||||||
|
expect(getFormErrors()).toEqual({
|
||||||
|
name: [{ id: 'content-type-builder.error.attribute.key.taken' }],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an error if the key is equal to the name', () => {
|
||||||
|
props.alreadyTakenAttributes = [];
|
||||||
|
props.modifiedData.name = 'test';
|
||||||
|
props.modifiedData.key = 'test';
|
||||||
|
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { getFormErrors } = wrapper.find(RelationFormGroup).instance();
|
||||||
|
|
||||||
|
expect(getFormErrors()).toEqual({
|
||||||
|
key: [{ id: 'content-type-builder.error.attribute.key.taken' }],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not return an error when editing', () => {
|
||||||
|
props.alreadyTakenAttributes = ['test', 'strapi'];
|
||||||
|
props.modifiedData.name = 'test';
|
||||||
|
props.modifiedData.key = 'strapi';
|
||||||
|
props.actionType = 'edit';
|
||||||
|
props.attributeToEditName = 'test';
|
||||||
|
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { getFormErrors } = wrapper.find(RelationFormGroup).instance();
|
||||||
|
|
||||||
|
expect(getFormErrors()).toEqual({});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('<RelationFormGroup />, basic instances', () => {
|
||||||
|
describe('HandleChangeRelationTarget', () => {
|
||||||
|
it('should call the onChangeRelationTarget with the correct data (not editing)', () => {
|
||||||
|
props.featureToEditName = 'test';
|
||||||
|
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { handleChangeRelationTarget } = wrapper
|
||||||
|
.find(RelationFormGroup)
|
||||||
|
.instance();
|
||||||
|
|
||||||
|
handleChangeRelationTarget('strapi');
|
||||||
|
|
||||||
|
expect(props.onChangeRelationTarget).toHaveBeenLastCalledWith(
|
||||||
|
'strapi',
|
||||||
|
'test',
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the onChangeRelationTarget with the correct data (editing)', () => {
|
||||||
|
props.featureToEditName = 'test';
|
||||||
|
props.actionType = 'edit';
|
||||||
|
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { handleChangeRelationTarget } = wrapper
|
||||||
|
.find(RelationFormGroup)
|
||||||
|
.instance();
|
||||||
|
|
||||||
|
handleChangeRelationTarget('strapi');
|
||||||
|
|
||||||
|
expect(props.onChangeRelationTarget).toHaveBeenLastCalledWith(
|
||||||
|
'strapi',
|
||||||
|
'test',
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('HandleCancel', () => {
|
||||||
|
it('should clear the search', () => {
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { handleCancel } = wrapper.find(RelationFormGroup).instance();
|
||||||
|
|
||||||
|
handleCancel();
|
||||||
|
|
||||||
|
expect(props.push).toHaveBeenCalledWith({ search: '' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('HandleGoTo', () => {
|
||||||
|
it('should emit the event didSelectContentTypeFieldSettings if the user clicks on the advanced tab', () => {
|
||||||
|
const context = { emitEvent: jest.fn() };
|
||||||
|
|
||||||
|
wrapper = renderComponent(props, context);
|
||||||
|
const { handleGoTo } = wrapper.find(RelationFormGroup).instance();
|
||||||
|
|
||||||
|
handleGoTo('advanced');
|
||||||
|
|
||||||
|
expect(props.push).toHaveBeenCalledWith({
|
||||||
|
search:
|
||||||
|
'modalType=attributeForm&attributeType=relation&settingType=advanced&actionType=create',
|
||||||
|
});
|
||||||
|
expect(context.emitEvent).toHaveBeenCalledWith(
|
||||||
|
'didSelectContentTypeFieldSettings'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add the keep the attribute name if the action is edit', () => {
|
||||||
|
const context = { emitEvent: jest.fn() };
|
||||||
|
props.actionType = 'edit';
|
||||||
|
props.attributeToEditName = 'test';
|
||||||
|
wrapper = renderComponent(props, context);
|
||||||
|
const { handleGoTo } = wrapper.find(RelationFormGroup).instance();
|
||||||
|
|
||||||
|
handleGoTo('advanced');
|
||||||
|
|
||||||
|
expect(props.push).toHaveBeenCalledWith({
|
||||||
|
search:
|
||||||
|
'modalType=attributeForm&attributeType=relation&settingType=advanced&actionType=edit&attributeName=test',
|
||||||
|
});
|
||||||
|
expect(context.emitEvent).toHaveBeenCalledWith(
|
||||||
|
'didSelectContentTypeFieldSettings'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not emit the event if the tab is base', () => {
|
||||||
|
const context = { emitEvent: jest.fn() };
|
||||||
|
|
||||||
|
wrapper = renderComponent(props, context);
|
||||||
|
const { handleGoTo } = wrapper.find(RelationFormGroup).instance();
|
||||||
|
|
||||||
|
handleGoTo('base');
|
||||||
|
|
||||||
|
expect(props.push).toHaveBeenCalledWith({
|
||||||
|
search:
|
||||||
|
'modalType=attributeForm&attributeType=relation&settingType=base&actionType=create',
|
||||||
|
});
|
||||||
|
expect(context.emitEvent).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('HandleOnClosed', () => {
|
||||||
|
it('should update the state and call the onCancel prop', () => {
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const compo = wrapper.find(RelationFormGroup);
|
||||||
|
compo.setState({ showForm: true, formErrors: { name: [] } });
|
||||||
|
|
||||||
|
expect(compo.state('showForm')).toBeTruthy();
|
||||||
|
|
||||||
|
const { handleOnClosed } = compo.instance();
|
||||||
|
|
||||||
|
handleOnClosed();
|
||||||
|
|
||||||
|
expect(compo.state('formErrors')).toEqual({});
|
||||||
|
expect(compo.state('showForm')).toBeFalsy();
|
||||||
|
expect(props.onCancel).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('HandleOnOpened', () => {
|
||||||
|
it('should update the state and call the onCancel prop', () => {
|
||||||
|
props.features = [{ name: 'test', source: 'test' }];
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const compo = wrapper.find(RelationFormGroup);
|
||||||
|
|
||||||
|
expect(compo.state('showForm')).toBeFalsy();
|
||||||
|
|
||||||
|
const { handleOnOpened } = compo.instance();
|
||||||
|
|
||||||
|
handleOnOpened();
|
||||||
|
|
||||||
|
expect(compo.state('showForm')).toBeTruthy();
|
||||||
|
expect(props.setTempAttribute).toHaveBeenCalledWith(
|
||||||
|
'test',
|
||||||
|
false,
|
||||||
|
'test',
|
||||||
|
'',
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should update the state and call the onCancel prop', () => {
|
||||||
|
props.features = [{ name: 'test' }];
|
||||||
|
props.featureToEditName = 'strapi';
|
||||||
|
props.actionType = 'edit';
|
||||||
|
props.attributeToEditName = 'test';
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const compo = wrapper.find(RelationFormGroup);
|
||||||
|
|
||||||
|
expect(compo.state('showForm')).toBeFalsy();
|
||||||
|
|
||||||
|
const { handleOnOpened } = compo.instance();
|
||||||
|
|
||||||
|
handleOnOpened();
|
||||||
|
|
||||||
|
expect(compo.state('showForm')).toBeTruthy();
|
||||||
|
expect(props.setTempAttribute).toHaveBeenCalledWith(
|
||||||
|
'strapi',
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
'test',
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('HandleSubmit', () => {
|
||||||
|
it('should call the submit prop if there is no error', () => {
|
||||||
|
props.modifiedData = {
|
||||||
|
name: 'test',
|
||||||
|
nature: 'oneWay',
|
||||||
|
target: 'test',
|
||||||
|
key: '-',
|
||||||
|
};
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { handleSubmit } = wrapper.instance();
|
||||||
|
|
||||||
|
handleSubmit({ preventDefault: jest.fn() });
|
||||||
|
|
||||||
|
expect(props.onSubmit).toHaveBeenCalledWith(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not call the submit if the form is empty', () => {
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { handleSubmit } = wrapper.instance();
|
||||||
|
|
||||||
|
handleSubmit({ preventDefault: jest.fn() });
|
||||||
|
|
||||||
|
expect(props.onSubmit).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('HandleSubmitAndContinue', () => {
|
||||||
|
it('should call the submit prop if there is no error', () => {
|
||||||
|
props.modifiedData = {
|
||||||
|
name: 'test',
|
||||||
|
nature: 'oneWay',
|
||||||
|
target: 'test',
|
||||||
|
key: '-',
|
||||||
|
};
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { handleSubmitAndContinue } = wrapper.instance();
|
||||||
|
|
||||||
|
handleSubmitAndContinue({ preventDefault: jest.fn() });
|
||||||
|
|
||||||
|
expect(props.onSubmit).toHaveBeenCalledWith(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not call the submit if the form is empty', () => {
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { handleSubmitAndContinue } = wrapper.instance();
|
||||||
|
|
||||||
|
handleSubmitAndContinue({ preventDefault: jest.fn() });
|
||||||
|
|
||||||
|
expect(props.onSubmit).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('HandleToggle', () => {
|
||||||
|
it('should clear the search', () => {
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
const { handleToggle } = wrapper.instance();
|
||||||
|
|
||||||
|
handleToggle();
|
||||||
|
|
||||||
|
expect(props.push).toHaveBeenCalledWith({ search: '' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('Submit', () => {
|
||||||
|
it('should call the onSubmitEditProp if the actionType is edit', () => {
|
||||||
|
props.actionType = 'edit';
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
|
||||||
|
const { submit } = wrapper.instance();
|
||||||
|
|
||||||
|
submit();
|
||||||
|
|
||||||
|
expect(props.onSubmitEdit).toHaveBeenCalledWith(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the onSubmitEdit if the actionType is create', () => {
|
||||||
|
wrapper = renderComponent(props);
|
||||||
|
|
||||||
|
const { submit } = wrapper.instance();
|
||||||
|
|
||||||
|
submit(true);
|
||||||
|
|
||||||
|
expect(props.onSubmit).toHaveBeenCalledWith(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user