diff --git a/packages/strapi-plugin-content-manager/config/routes.json b/packages/strapi-plugin-content-manager/config/routes.json index 4e529095c1..cdda7b8a8c 100644 --- a/packages/strapi-plugin-content-manager/config/routes.json +++ b/packages/strapi-plugin-content-manager/config/routes.json @@ -39,6 +39,14 @@ "config": { "policies": [] } + }, + { + "method": "DELETE", + "path": "/explorer/:model/:id", + "handler": "ContentManager.delete", + "config": { + "policies": [] + } } ] } diff --git a/packages/strapi-plugin-content-manager/controllers/ContentManager.js b/packages/strapi-plugin-content-manager/controllers/ContentManager.js index d9f178d501..f339a0fd1d 100644 --- a/packages/strapi-plugin-content-manager/controllers/ContentManager.js +++ b/packages/strapi-plugin-content-manager/controllers/ContentManager.js @@ -45,7 +45,7 @@ module.exports = { const entries = await User .find({ - _id + id }); ctx.body = entries; @@ -53,8 +53,15 @@ module.exports = { update: async(ctx) => { const entryUpdated = await User - .update({_id: ctx.request.body._id}, ctx.request.body); + .update({_id: ctx.request.params.id}, ctx.request.body); - return ctx.body = entryUpdated; + ctx.body = entryUpdated; + }, + + delete: async(ctx) => { + const entryDeleted = await User + .remove({_id: ctx.request.params.id}); + + ctx.body = entryDeleted; } }; diff --git a/packages/strapi-plugin-content-manager/public/app/containers/Edit/actions.js b/packages/strapi-plugin-content-manager/public/app/containers/Edit/actions.js index 23056cffbc..e527a536ee 100644 --- a/packages/strapi-plugin-content-manager/public/app/containers/Edit/actions.js +++ b/packages/strapi-plugin-content-manager/public/app/containers/Edit/actions.js @@ -12,6 +12,9 @@ import { EDIT_RECORD, EDIT_RECORD_SUCCESS, EDIT_RECORD_ERROR, + DELETE_RECORD, + DELETE_RECORD_SUCCESS, + DELETE_RECORD_ERROR, } from './constants'; export function setCurrentModelName(currentModelName) { @@ -60,3 +63,21 @@ export function recordEditError() { type: EDIT_RECORD_ERROR, }; } + +export function deleteRecord() { + return { + type: DELETE_RECORD, + }; +} + +export function recordDeleted() { + return { + type: DELETE_RECORD_SUCCESS, + }; +} + +export function recordDeleteError() { + return { + type: DELETE_RECORD_ERROR, + }; +} diff --git a/packages/strapi-plugin-content-manager/public/app/containers/Edit/constants.js b/packages/strapi-plugin-content-manager/public/app/containers/Edit/constants.js index 63bfe9fb4c..68dd1ac849 100644 --- a/packages/strapi-plugin-content-manager/public/app/containers/Edit/constants.js +++ b/packages/strapi-plugin-content-manager/public/app/containers/Edit/constants.js @@ -13,4 +13,8 @@ export const SET_RECORD_ATTRIBUTE = 'app/Edit/SET_RECORD_ATTRIBUTE'; export const EDIT_RECORD = 'app/Edit/EDIT_RECORD'; export const EDIT_RECORD_SUCCESS = 'app/Edit/EDIT_RECORD_SUCCESS'; -export const EDIT_RECORD_ERROR = 'app/Edit/EDIT_RECORD_ERROR'; \ No newline at end of file +export const EDIT_RECORD_ERROR = 'app/Edit/EDIT_RECORD_ERROR'; + +export const DELETE_RECORD = 'app/Edit/DELETE_RECORD'; +export const DELETE_RECORD_SUCCESS = 'app/Edit/DELETE_RECORD_SUCCESS'; +export const DELETE_RECORD_ERROR = 'app/Edit/DELETE_RECORD_ERROR'; \ No newline at end of file diff --git a/packages/strapi-plugin-content-manager/public/app/containers/Edit/index.js b/packages/strapi-plugin-content-manager/public/app/containers/Edit/index.js index 24c1d92845..b0bde19f6b 100644 --- a/packages/strapi-plugin-content-manager/public/app/containers/Edit/index.js +++ b/packages/strapi-plugin-content-manager/public/app/containers/Edit/index.js @@ -16,6 +16,7 @@ import { loadRecord, setRecordAttribute, editRecord, + deleteRecord, } from './actions'; import { @@ -23,6 +24,7 @@ import { makeSelectLoading, makeSelectCurrentModelName, makeSelectEditing, + makeSelectDeleting, } from './selectors'; import { @@ -65,6 +67,8 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer- }, { label: 'Delete', class: 'btn-danger', + onClick: this.props.deleteRecord, + disabled: this.props.deleting, }]; return ( @@ -109,6 +113,7 @@ Edit.propTypes = { ]), editRecord: React.PropTypes.func, editing: React.PropTypes.bool, + deleting: React.PropTypes.bool, }; const mapStateToProps = createStructuredSelector({ @@ -117,6 +122,7 @@ const mapStateToProps = createStructuredSelector({ currentModelName: makeSelectCurrentModelName(), models: makeSelectModels(), editing: makeSelectEditing(), + deleting: makeSelectDeleting(), }); function mapDispatchToProps(dispatch) { @@ -125,6 +131,12 @@ function mapDispatchToProps(dispatch) { loadRecord: (id) => dispatch(loadRecord(id)), setRecordAttribute: (key, value) => dispatch(setRecordAttribute(key, value)), editRecord: () => dispatch(editRecord()), + deleteRecord: () => { + // TODO: improve confirmation UX. + if (confirm('Are you sure ?')) { + dispatch(deleteRecord()); + } + }, dispatch, }; } diff --git a/packages/strapi-plugin-content-manager/public/app/containers/Edit/reducer.js b/packages/strapi-plugin-content-manager/public/app/containers/Edit/reducer.js index 56692cc29d..553c3d2115 100644 --- a/packages/strapi-plugin-content-manager/public/app/containers/Edit/reducer.js +++ b/packages/strapi-plugin-content-manager/public/app/containers/Edit/reducer.js @@ -13,6 +13,9 @@ import { EDIT_RECORD, EDIT_RECORD_SUCCESS, EDIT_RECORD_ERROR, + DELETE_RECORD, + DELETE_RECORD_SUCCESS, + DELETE_RECORD_ERROR, } from './constants'; const initialState = fromJS({ @@ -20,6 +23,7 @@ const initialState = fromJS({ loading: false, record: null, editing: false, + deleting: false, }); function editReducer(state = initialState, action) { @@ -48,6 +52,15 @@ function editReducer(state = initialState, action) { case EDIT_RECORD_ERROR: return state .set('editing', false); + case DELETE_RECORD: + return state + .set('deleting', true); + case DELETE_RECORD_SUCCESS: + return state + .set('deleting', false); + case DELETE_RECORD_ERROR: + return state + .set('deleting', false); default: return state; } diff --git a/packages/strapi-plugin-content-manager/public/app/containers/Edit/sagas.js b/packages/strapi-plugin-content-manager/public/app/containers/Edit/sagas.js index b0b85b9abf..aeeeb4aa73 100644 --- a/packages/strapi-plugin-content-manager/public/app/containers/Edit/sagas.js +++ b/packages/strapi-plugin-content-manager/public/app/containers/Edit/sagas.js @@ -1,16 +1,20 @@ import { takeLatest } from 'redux-saga'; import { put, select, fork, call } from 'redux-saga/effects'; import request from 'utils/request'; +import { browserHistory } from 'react-router'; import { recordLoaded, recordEdited, recordEditError, + recordDeleted, + recordDeleteError, } from './actions'; import { LOAD_RECORD, EDIT_RECORD, + DELETE_RECORD, } from './constants'; import { @@ -57,9 +61,32 @@ export function* editRecord() { } } +export function* deleteRecord() { + const currentModelName = yield select(makeSelectCurrentModelName()); + const record = yield select(makeSelectRecord()); + const recordJSON = record.toJSON(); + + try { + const requestURL = `http://localhost:1337/content-manager/explorer/${currentModelName}/${recordJSON.id}`; + + // Call our request helper (see 'utils/request') + yield call(request, requestURL, { + method: 'DELETE', + }); + + yield put(recordDeleted()); + window.Strapi.notification.success('The entry has been successfully deleted.'); + // TODO: Redirect to the list page. + } catch (err) { + yield put(recordDeleteError()); + window.Strapi.notification.error('An error occurred during record deletion.'); + } +} + export function* defaultSaga() { yield fork(takeLatest, LOAD_RECORD, getRecord); yield fork(takeLatest, EDIT_RECORD, editRecord); + yield fork(takeLatest, DELETE_RECORD, deleteRecord); } // All sagas to be loaded diff --git a/packages/strapi-plugin-content-manager/public/app/containers/Edit/selectors.js b/packages/strapi-plugin-content-manager/public/app/containers/Edit/selectors.js index 94623e9d41..1fde6f4b33 100644 --- a/packages/strapi-plugin-content-manager/public/app/containers/Edit/selectors.js +++ b/packages/strapi-plugin-content-manager/public/app/containers/Edit/selectors.js @@ -36,10 +36,16 @@ const makeSelectEditing = () => createSelector( (substate) => substate.get('editing') ); +const makeSelectDeleting = () => createSelector( + selectEditDomain(), + (substate) => substate.get('deleting') +); + export default selectEditDomain; export { makeSelectRecord, makeSelectLoading, makeSelectCurrentModelName, makeSelectEditing, + makeSelectDeleting, };