Fix delete model

This commit is contained in:
soupette 2019-04-02 18:45:47 +02:00
parent 67099a676a
commit f99850ea8d
4 changed files with 64 additions and 31 deletions

View File

@ -41,7 +41,7 @@ class TableListRow extends React.Component {
if (isTemporary) {
deleteTemporaryModel();
} else {
onDelete(name);
onDelete(name, this.context);
}
this.setState({ showWarning: false });
@ -54,9 +54,7 @@ class TableListRow extends React.Component {
} = this.props;
push({
pathname: `/plugins/${pluginId}/models/${name}${
source ? `&source=${source}` : ''
}`,
pathname: `/plugins/${pluginId}/models/${name}${source ? `&source=${source}` : ''}`,
search: `modalType=model&settingType=base&actionType=edit&modelName=${name}`,
});
};
@ -71,19 +69,13 @@ class TableListRow extends React.Component {
);
};
toggleModalWarning = () =>
this.setState({ showWarning: !this.state.showWarning });
toggleModalWarning = () => this.setState({ showWarning: !this.state.showWarning });
handleShowModalWarning = () => {
if (
this.props.canOpenModalAddContentType ||
this.props.rowItem.isTemporary === true
) {
if (this.props.canOpenModalAddContentType || this.props.rowItem.isTemporary === true) {
this.setState({ showWarning: !this.state.showWarning });
} else {
strapi.notification.info(
`${pluginId}.notification.info.contentType.creating.notSaved`,
);
strapi.notification.info(`${pluginId}.notification.info.contentType.creating.notSaved`);
}
};
@ -92,9 +84,7 @@ class TableListRow extends React.Component {
const pluginSource = this.props.rowItem.source ? (
<FormattedMessage id={`${pluginId}.from`}>
{message => (
<span
style={{ fontStyle: 'italic', color: '#787E8F', fontWeight: '500' }}
>
<span style={{ fontStyle: 'italic', color: '#787E8F', fontWeight: '500' }}>
({message}: {this.props.rowItem.source})
</span>
)}
@ -134,16 +124,15 @@ class TableListRow extends React.Component {
<div className={`col-md-5 text-center ${styles.descriptionContainer}`}>
<div>{description}</div>
</div>
<div className="col-md-2 text-center">{this.props.rowItem.fields}</div>
<div className="col-md-1">
<div className='col-md-2 text-center'>{this.props.rowItem.fields}</div>
<div className='col-md-1'>
<IcoContainer icons={icons} />
</div>
<PopUpWarning
isOpen={this.state.showWarning}
toggleModal={this.toggleModalWarning}
content={{
message:
'content-type-builder.popUpWarning.bodyMessage.contentType.delete',
message: 'content-type-builder.popUpWarning.bodyMessage.contentType.delete',
}}
popUpWarningType={'danger'}
onConfirm={this.handleDelete}
@ -153,6 +142,11 @@ class TableListRow extends React.Component {
}
}
TableListRow.contextTypes = {
plugins: PropTypes.object,
updatePlugin: PropTypes.func,
};
TableListRow.propTypes = {
canOpenModalAddContentType: PropTypes.bool.isRequired,
deleteTemporaryModel: PropTypes.func.isRequired,

View File

@ -88,10 +88,11 @@ export function createTempContentType() {
};
}
export function deleteModel(modelName) {
export function deleteModel(modelName, context) {
return {
type: DELETE_MODEL,
modelName,
context,
};
}
@ -123,7 +124,13 @@ export function getData() {
export function getDataSucceeded({ allModels, models }, connections) {
const initialData = allModels.reduce((acc, current) => {
acc[current.name] = pick(current, ['name', 'collectionName', 'connection', 'description', 'mainField']);
acc[current.name] = pick(current, [
'name',
'collectionName',
'connection',
'description',
'mainField',
]);
const attributes = OrderedMap(buildModelAttributes(current.attributes));
set(acc, [current.name, 'attributes'], attributes);
@ -139,7 +146,8 @@ export function getDataSucceeded({ allModels, models }, connections) {
}
export function onChangeExistingContentTypeMainInfos({ target }) {
const value = target.name === 'name' ? camelCase(target.value.trim()).toLowerCase() : target.value;
const value =
target.name === 'name' ? camelCase(target.value.trim()).toLowerCase() : target.value;
return {
type: ON_CHANGE_EXISTING_CONTENT_TYPE_MAIN_INFOS,
@ -149,7 +157,8 @@ export function onChangeExistingContentTypeMainInfos({ target }) {
}
export function onChangeNewContentTypeMainInfos({ target }) {
const value = target.name === 'name' ? camelCase(target.value.trim()).toLowerCase() : target.value;
const value =
target.name === 'name' ? camelCase(target.value.trim()).toLowerCase() : target.value;
return {
type: ON_CHANGE_NEW_CONTENT_TYPE_MAIN_INFOS,
@ -252,7 +261,13 @@ export function setTemporaryAttribute(attributeName, isModelTemporary, modelName
};
}
export function setTemporaryAttributeRelation(target, isModelTemporary, source, attributeName, isEditing) {
export function setTemporaryAttributeRelation(
target,
isModelTemporary,
source,
attributeName,
isEditing,
) {
return {
type: SET_TEMPORARY_ATTRIBUTE_RELATION,
attributeName,

View File

@ -26,7 +26,7 @@ export function* getData() {
}
}
export function* deleteModel({ modelName }) {
export function* deleteModel({ context: { plugins, updatePlugin }, modelName }) {
try {
const requestURL = `/${pluginId}/models/${modelName}`;
const response = yield call(request, requestURL, { method: 'DELETE' }, true);
@ -34,6 +34,12 @@ export function* deleteModel({ modelName }) {
if (response.ok === true) {
strapi.notification.success(`${pluginId}.notification.success.contentTypeDeleted`);
yield put(deleteModelSucceeded(modelName));
const appPlugins = plugins.toJS ? plugins.toJS() : plugins;
const appMenu = get(appPlugins, ['content-manager', 'leftMenuSections'], []);
const updatedMenu = appMenu[0].links.filter(el => el.destination !== modelName);
appMenu[0].links = sortBy(updatedMenu, 'label');
updatePlugin('content-manager', 'leftMenuSections', appMenu);
}
} catch (err) {
strapi.notification.error('notification.error');
@ -67,7 +73,9 @@ export function* submitCT({
const appPlugins = plugins.toJS ? plugins.toJS() : plugins;
const appMenu = get(appPlugins, ['content-manager', 'leftMenuSections'], []);
const oldContentTypeNameIndex = appMenu[0].links.findIndex(el => el.destination === oldContentTypeName);
const oldContentTypeNameIndex = appMenu[0].links.findIndex(
el => el.destination === oldContentTypeName,
);
const updatedLink = { destination: name.toLowerCase(), label: capitalize(pluralize(name)) };
appMenu[0].links.splice(oldContentTypeNameIndex, 1, updatedLink);
appMenu[0].links = sortBy(appMenu[0].links, 'label');

View File

@ -7,12 +7,23 @@ import { all, fork, takeLatest, put } from 'redux-saga/effects';
import defaultSaga, { deleteModel, getData, submitCT, submitTempCT } from '../saga';
import { deleteModelSucceeded, getDataSucceeded } from '../actions';
import { DELETE_MODEL, GET_DATA, SUBMIT_CONTENT_TYPE, SUBMIT_TEMP_CONTENT_TYPE } from '../constants';
import {
DELETE_MODEL,
GET_DATA,
SUBMIT_CONTENT_TYPE,
SUBMIT_TEMP_CONTENT_TYPE,
} from '../constants';
const response = [
{
models: [
{ icon: 'fa-cube', name: 'permission', description: '', fields: 6, source: 'users-permissions' },
{
icon: 'fa-cube',
name: 'permission',
description: '',
fields: 6,
source: 'users-permissions',
},
],
allModels: [
{
@ -41,7 +52,10 @@ describe('CTB <App /> DeleteModel saga', () => {
let deleteModelGenerator;
beforeEach(() => {
deleteModelGenerator = deleteModel({ modelName: 'test' });
deleteModelGenerator = deleteModel({
context: { plugins: {}, updatePlugin: jest.fn() },
modelName: 'test',
});
const callDescriptor = deleteModelGenerator.next({ ok: true }).value;
expect(callDescriptor).toMatchSnapshot();
@ -56,7 +70,9 @@ describe('CTB <App /> DeleteModel saga', () => {
it('should dispatch the deleteModelSucceeded action if it requests the data successfully', () => {
const putDescriptor = deleteModelGenerator.next({ ok: true }).value;
expect(putDescriptor).toEqual(put(deleteModelSucceeded('test')));
expect(putDescriptor).toEqual(
put(deleteModelSucceeded('test', { plugins: {}, updatePlugin: jest.fn() })),
);
expect(strapi.notification.success).toHaveBeenCalled();
});