diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/actions.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/actions.js index 3477f04f96..25cdfd7d02 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/actions.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/actions.js @@ -14,6 +14,7 @@ import { INIT_MODEL_PROPS, ON_CANCEL, RESET_PROPS, + SET_FILE_RELATIONS, SET_FORM_ERRORS, SUBMIT, SUBMIT_SUCCESS, @@ -72,6 +73,13 @@ export function resetProps() { }; } +export function setFileRelations(fileRelations) { + return { + type: SET_FILE_RELATIONS, + fileRelations, + }; +} + export function setFormErrors(formErrors) { return { type: SET_FORM_ERRORS, diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/constants.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/constants.js index 93bb837c7b..2996f1035a 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/constants.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/constants.js @@ -10,6 +10,7 @@ export const GET_DATA_SUCCEEDED = 'ContentManager/EditPage/GET_DATA_SUCCEEDED'; export const INIT_MODEL_PROPS = 'ContentManager/EditPage/INIT_MODEL_PROPS'; export const ON_CANCEL = 'ContentManager/EditPage/ON_CANCEL'; export const RESET_PROPS = 'ContentManager/EditPage/RESET_PROPS'; +export const SET_FILE_RELATIONS = 'ContentManager/EditPage/SET_FILE_RELATIONS'; export const SET_FORM_ERRORS = 'ContentManager/EditPage/SET_FORM_ERRORS'; export const SUBMIT = 'ContentManager/EditPage/SUBMIT'; export const SUBMIT_SUCCESS = 'ContentManager/EditPage/SUBMIT_SUCCESS'; diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/index.js index 0f0b30bcea..aa628ca5ec 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/index.js @@ -41,6 +41,7 @@ import { initModelProps, onCancel, resetProps, + setFileRelations, setFormErrors, submit, } from './actions'; @@ -62,6 +63,14 @@ export class EditPage extends React.Component { const mainField = get(this.getModel(), 'info.mainField') || this.getModel().primaryKey; this.props.getData(this.props.match.params.id, this.getSource(), mainField); } + + // Get all relations made with the upload plugin + // TODO: check if collectionName or model === 'upload_file' + const fileRelations = Object.keys(get(this.getSchema(), 'relations', {})).filter(relation => ( + get(this.getSchema(), ['relations', relation, 'plugin']) === 'upload' + )); + // Update the reducer so we can use it to create the appropriate FormData in the saga + this.props.setFileRelations(fileRelations); } componentWillReceiveProps(nextProps) { @@ -256,6 +265,7 @@ EditPage.propTypes = { onCancel: PropTypes.func.isRequired, resetProps: PropTypes.func.isRequired, schema: PropTypes.object.isRequired, + setFileRelations: PropTypes.func.isRequired, setFormErrors: PropTypes.func.isRequired, submit: PropTypes.func.isRequired, }; @@ -268,6 +278,7 @@ function mapDispatchToProps(dispatch) { initModelProps, onCancel, resetProps, + setFileRelations, setFormErrors, submit, }, diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/reducer.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/reducer.js index c64ab8048a..d82fb04bf8 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/reducer.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/reducer.js @@ -11,12 +11,14 @@ import { INIT_MODEL_PROPS, ON_CANCEL, RESET_PROPS, + SET_FILE_RELATIONS, SET_FORM_ERRORS, SUBMIT_SUCCESS, } from './constants'; const initialState = fromJS({ didCheckErrors: true, + fileRelations: List([]), formErrors: List([]), formValidations: List([]), isCreating: false, @@ -52,6 +54,8 @@ function editPageReducer(state = initialState, action) { .update('record', () => state.get('initialRecord')); case RESET_PROPS: return initialState; + case SET_FILE_RELATIONS: + return state.set('fileRelations', List(action.fileRelations)); case SET_FORM_ERRORS: return state .update('didCheckErrors', (v) => v = !v) diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/saga.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/saga.js index d1c23cf9dd..43a9358fe5 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/saga.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/saga.js @@ -1,5 +1,5 @@ import { LOCATION_CHANGE } from 'react-router-redux'; -import { get, isArray } from 'lodash'; +import { get, isArray, isNumber, isString, map } from 'lodash'; import { call, cancel, @@ -18,6 +18,7 @@ import templateObject from 'utils/templateObject'; import { getDataSucceeded, setFormErrors, submitSuccess } from './actions'; import { GET_DATA,SUBMIT } from './constants'; import { + makeSelectFileRelations, makeSelectIsCreating, makeSelectModelName, makeSelectRecord, @@ -43,45 +44,52 @@ function* dataGet(action) { export function* submit() { const currentModelName = yield select(makeSelectModelName()); - const record = yield select(makeSelectRecord()); - const recordJSON = record.toJSON(); - const source = yield select(makeSelectSource()); + const fileRelations = yield select(makeSelectFileRelations()); const isCreating = yield select(makeSelectIsCreating()); + const record = yield select(makeSelectRecord()); + const source = yield select(makeSelectSource()); try { - // const recordCleaned = Object.keys(recordJSON).reduce((acc, current) => { - // acc.append(current, cleanData(recordJSON[current], 'value', 'id')); - // - // return acc; - // }, new FormData()); - const recordCleaned = Object.keys(recordJSON).reduce((acc, current) => { - acc[current] = cleanData(recordJSON[current], 'value', 'id'); + const recordCleaned = Object.keys(record).reduce((acc, current) => { + const cleanedData = cleanData(record[current], 'value', 'id'); + + if (isString(cleanData) || isNumber(cleanData)) { + acc.append(current, cleanedData); + } else if (fileRelations.includes(current)) { + // Don't stringify the file + map(record[current], (file) => acc.append(current, file)); + } else { + acc.append(current, JSON.stringify(cleanData(record[current], 'value', 'id'))); + } return acc; - }, {}); + }, new FormData()); - console.log(recordCleaned); - const id = isCreating ? '' : recordCleaned.id; + const id = isCreating ? '' : record.id; const params = { source }; + // Change the request helper default headers so we can pass a FormData + const headers = { + 'X-Forwarded-Host': 'strapi', + }; const requestUrl = `/content-manager/explorer/${currentModelName}/${id}`; // Call our request helper (see 'utils/request') + // Pass false and false as arguments so the request helper doesn't stringify + // the body and doesn't watch for the server to restart yield call(request, requestUrl, { method: isCreating ? 'POST' : 'PUT', - // headers: { - // 'X-Forwarded-Host': 'strapi', - // }, + headers, body: recordCleaned, params, - }); + }, false, false); strapi.notification.success('content-manager.success.record.save'); + // Redirect the user to the ListPage container yield put(submitSuccess()); - } catch(err) { - // NOTE: leave the error log + // NOTE: leave the error log console.log(err.response); if (isArray(err.response.payload.message)) { const errors = err.response.payload.message.reduce((acc, current) => { diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/selectors.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/selectors.js index 85bfb54767..f046579eaa 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/selectors.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/selectors.js @@ -25,6 +25,11 @@ const makeSelectEditPage = () => createSelector( * * Other specific selectors */ +const makeSelectFileRelations = () => createSelector( + selectEditPageDomain(), + (substate) => substate.get('fileRelations').toJS(), +); + const makeSelectIsCreating = () => createSelector( selectEditPageDomain(), (substate) => substate.get('isCreating'), @@ -37,7 +42,7 @@ const makeSelectModelName = () => createSelector( const makeSelectRecord = () => createSelector( selectEditPageDomain(), - (substate) => substate.get('record'), + (substate) => substate.get('record').toJS(), ); const makeSelectSource = () => createSelector( @@ -47,6 +52,7 @@ const makeSelectSource = () => createSelector( export default makeSelectEditPage; export { + makeSelectFileRelations, makeSelectIsCreating, makeSelectModelName, makeSelectRecord, diff --git a/packages/strapi-plugin-content-manager/controllers/ContentManager.js b/packages/strapi-plugin-content-manager/controllers/ContentManager.js index c236f9a56f..5744b9a16a 100755 --- a/packages/strapi-plugin-content-manager/controllers/ContentManager.js +++ b/packages/strapi-plugin-content-manager/controllers/ContentManager.js @@ -80,7 +80,7 @@ module.exports = { update: async ctx => { const { source } = ctx.request.query; - console.log('hhhh', ctx.request.body); + console.log('hhhh', ctx.request.body.files.pictures[0]); try { // Return the last one which is the current model. ctx.body = await strapi.plugins['content-manager'].services['contentmanager'].edit(ctx.params, ctx.request.body, source);