diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/actions.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/actions.js
index 0ae4089cff..7730e81f3f 100644
--- a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/actions.js
+++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/actions.js
@@ -3,7 +3,7 @@
* App actions
*
*/
-import { pick, set, camelCase } from 'lodash';
+import { cloneDeep, pick, set, camelCase } from 'lodash';
import {
ADD_ATTRIBUTE_TO_EXISITING_CONTENT_TYPE,
ADD_ATTRIBUTE_TO_TEMP_CONTENT_TYPE,
@@ -25,6 +25,8 @@ import {
RESET_PROPS,
SAVE_EDITED_ATTRIBUTE,
SET_TEMPORARY_ATTRIBUTE,
+ SUBMIT_CONTENT_TYPE,
+ SUBMIT_CONTENT_TYPE_SUCCEEDED,
SUBMIT_TEMP_CONTENT_TYPE,
SUBMIT_TEMP_CONTENT_TYPE_SUCCEEDED,
UPDATE_TEMP_CONTENT_TYPE,
@@ -192,9 +194,34 @@ export function resetProps() {
};
}
-export function submitTempContentType() {
+export function submitContentType(oldContentTypeName, data, context, source) {
+ const attributes = formatModelAttributes(data.attributes);
+ const body = Object.assign(cloneDeep(data), { attributes });
+
+ return {
+ type: SUBMIT_CONTENT_TYPE,
+ oldContentTypeName,
+ body,
+ source,
+ context,
+ };
+}
+
+export function submitContentTypeSucceeded(oldContentTypeName) {
+ return {
+ type: SUBMIT_CONTENT_TYPE_SUCCEEDED,
+ oldContentTypeName,
+ };
+}
+
+export function submitTempContentType(data, context) {
+ const attributes = formatModelAttributes(data.attributes);
+ const body = Object.assign(cloneDeep(data), { attributes });
+
return {
type: SUBMIT_TEMP_CONTENT_TYPE,
+ body,
+ context,
};
}
@@ -220,3 +247,22 @@ export const buildModelAttributes = attributes => {
return formattedAttributes;
};
+
+export const formatModelAttributes = attributes =>
+ Object.keys(attributes).reduce((acc, current) => {
+ const attribute = Object.keys(attributes[current]).reduce(
+ (acc2, curr) => {
+ if (curr === 'plugin' && !!attributes[current][curr]) {
+ acc2.params.pluginValue = attributes[current][curr];
+ acc2.params.plugin = true;
+ } else {
+ acc2.params[curr] = attributes[current][curr];
+ }
+
+ return acc2;
+ },
+ { name: current, params: {} },
+ );
+
+ return acc.concat(attribute);
+ }, []);
diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/constants.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/constants.js
index 88fc142549..1d72202978 100644
--- a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/constants.js
+++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/constants.js
@@ -29,6 +29,8 @@ export const RESET_EDIT_TEMP_CONTENT_TYPE = 'ContentTypeBuilder/App/RESET_EDIT_T
export const RESET_PROPS = 'ContentTypeBuilder/App/RESET_PROPS';
export const SAVE_EDITED_ATTRIBUTE = 'ContentTypeBuilder/App/SAVE_EDITED_ATTRIBUTE';
export const SET_TEMPORARY_ATTRIBUTE = 'ContentTypeBuilder/App/SET_TEMPORARY_ATTRIBUTE';
+export const SUBMIT_CONTENT_TYPE = 'ContentTypeBuilder/App/SUBMIT_CONTENT_TYPE';
+export const SUBMIT_CONTENT_TYPE_SUCCEEDED = 'ContentTypeBuilder/App/SUBMIT_CONTENT_TYPE_SUCCEEDED';
export const SUBMIT_TEMP_CONTENT_TYPE = 'ContentTypeBuilder/App/SUBMIT_TEMP_CONTENT_TYPE';
export const SUBMIT_TEMP_CONTENT_TYPE_SUCCEEDED = 'ContentTypeBuilder/App/SUBMIT_TEMP_CONTENT_TYPE_SUCCEEDED';
export const UPDATE_TEMP_CONTENT_TYPE = 'ContentTypeBuilder/App/UPDATE_TEMP_CONTENT_TYPE';
diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/reducer.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/reducer.js
index aa9558f8c7..2ed1368f5c 100644
--- a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/reducer.js
+++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/reducer.js
@@ -25,8 +25,10 @@ import {
RESET_PROPS,
SAVE_EDITED_ATTRIBUTE,
SET_TEMPORARY_ATTRIBUTE,
+ // SUBMIT_CONTENT_TYPE_SUCCEEDED,
SUBMIT_TEMP_CONTENT_TYPE_SUCCEEDED,
UPDATE_TEMP_CONTENT_TYPE,
+ SUBMIT_CONTENT_TYPE_SUCCEEDED,
} from './constants';
export const initialState = fromJS({
@@ -127,7 +129,7 @@ function appReducer(state = initialState, action) {
.update('isLoading', () => false)
.update('modifiedData', () => fromJS(action.initialData))
.updateIn(['newContentType', 'connection'], () => action.connections[0])
- .update('models', () => List(action.models));
+ .update('models', () => List(action.models).sortBy(model => model.name));
case ON_CHANGE_EXISTING_CONTENT_TYPE_MAIN_INFOS:
return state.updateIn(['modifiedData', ...action.keys], () => action.value);
case ON_CHANGE_NEW_CONTENT_TYPE_MAIN_INFOS:
@@ -180,6 +182,33 @@ function appReducer(state = initialState, action) {
return attribute;
});
+ case SUBMIT_CONTENT_TYPE_SUCCEEDED: {
+ const newName = state.getIn(['modifiedData', action.oldContentTypeName, 'name']);
+ const newState = state
+ .updateIn(['modifiedData', newName], () => state.getIn(['modifiedData', action.oldContentTypeName]))
+ .updateIn(['initialData', newName], () => state.getIn(['modifiedData', action.oldContentTypeName]));
+
+ if (newName === action.oldContentTypeName) {
+ return newState;
+ }
+
+ return (
+ newState
+ // .updateIn(['modifiedData', newName], () => state.getIn(['modifiedData', action.oldContentTypeName]))
+ // .updateIn(['initialData', newName], () => state.getIn(['modifiedData', action.oldContentTypeName]))
+ .removeIn(['modifiedData', action.oldContentTypeName])
+ .removeIn(['initialData', action.oldContentTypeName])
+ .updateIn(
+ [
+ 'models',
+ state.get('models').findIndex(model => model.name === action.oldContentTypeName),
+ 'name',
+ ],
+ () => newName,
+ )
+ .update('models', models => models.sortBy(model => model.name))
+ );
+ }
case SUBMIT_TEMP_CONTENT_TYPE_SUCCEEDED:
return state
.updateIn(['initialData', state.getIn(['newContentType', 'name'])], () => state.get('newContentType'))
diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/saga.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/saga.js
index 80356d4f6c..ccd6ee796b 100644
--- a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/saga.js
+++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/saga.js
@@ -1,10 +1,16 @@
-import { get } from 'lodash';
+import pluralize from 'pluralize';
+import { capitalize, get, sortBy } from 'lodash';
import { all, fork, takeLatest, call, put } from 'redux-saga/effects';
import request from 'utils/request';
import pluginId from '../../pluginId';
-import { getDataSucceeded, deleteModelSucceeded, submitTempContentTypeSucceeded } from './actions';
-import { GET_DATA, DELETE_MODEL, SUBMIT_TEMP_CONTENT_TYPE } from './constants';
+import {
+ getDataSucceeded,
+ deleteModelSucceeded,
+ submitContentTypeSucceeded,
+ submitTempContentTypeSucceeded,
+} from './actions';
+import { GET_DATA, DELETE_MODEL, SUBMIT_CONTENT_TYPE, SUBMIT_TEMP_CONTENT_TYPE } from './constants';
export function* getData() {
try {
@@ -38,10 +44,70 @@ export function* deleteModel({ modelName }) {
// yield put(emitEvent('willSaveContentType'));
// emitEvent('didSaveContentType')
-export function* submitTempCT() {
+export function* submitCT({
+ oldContentTypeName,
+ body,
+ source,
+ context: { emitEvent, plugins, updatePlugin },
+}) {
try {
+ const requestURL = `/${pluginId}/models/${oldContentTypeName}`;
+ const { name } = body;
+
+ if (source) {
+ body.plugin = source;
+ }
+
+ yield put(emitEvent('willSaveContentType'));
+
+ const opts = { method: 'PUT', body };
+
+ yield call(request, requestURL, opts, true);
+ yield put(emitEvent('didSaveContentType'));
+ yield put(submitContentTypeSucceeded(oldContentTypeName));
+
+ if (name !== oldContentTypeName) {
+ yield put(emitEvent('didEditNameOfContentType'));
+
+ 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 updatedLink = { destination: name.toLowerCase(), label: capitalize(pluralize(name)) };
+ appMenu[0].links.splice(oldContentTypeNameIndex, 1, updatedLink);
+ appMenu[0].links = sortBy(appMenu[0].links, 'label');
+ updatePlugin('content-manager', 'leftMenuSections', appMenu);
+ }
+ } catch (error) {
+ const errorMessage = get(
+ error,
+ ['response', 'payload', 'message', '0', 'messages', '0', 'id'],
+ 'notification.error',
+ );
+ strapi.notification.error(errorMessage);
+ }
+}
+
+export function* submitTempCT({ body, context: { emitEvent, plugins, updatePlugin } }) {
+ try {
+ yield put(emitEvent('willSaveContentType'));
+
+ const requestURL = `/${pluginId}/models`;
+ const opts = { method: 'POST', body };
+
+ yield call(request, requestURL, opts, true);
+
+ yield put(emitEvent('didSaveContentType'));
yield put(submitTempContentTypeSucceeded());
- } catch (err) {
+
+ const { name } = body;
+ const appPlugins = plugins.toJS ? plugins.toJS() : plugins;
+ const appMenu = get(appPlugins, ['content-manager', 'leftMenuSections'], []);
+ const newLink = { destination: name.toLowerCase(), label: capitalize(pluralize(name)) };
+ appMenu[0].links.push(newLink);
+ appMenu[0].links = sortBy(appMenu[0].links, 'label');
+
+ updatePlugin('content-manager', 'leftMenuSections', appMenu);
+ } catch (error) {
const errorMessage = get(
error,
['response', 'payload', 'message', '0', 'messages', '0', 'id'],
@@ -56,6 +122,7 @@ export default function* defaultSaga() {
yield all([
fork(takeLatest, GET_DATA, getData),
fork(takeLatest, DELETE_MODEL, deleteModel),
+ fork(takeLatest, SUBMIT_CONTENT_TYPE, submitCT),
fork(takeLatest, SUBMIT_TEMP_CONTENT_TYPE, submitTempCT),
]);
}
diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/tests/actions.test.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/tests/actions.test.js
index f1dc1de1f3..8849997c20 100644
--- a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/tests/actions.test.js
+++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/tests/actions.test.js
@@ -12,7 +12,7 @@ import {
onChangeExistingContentTypeMainInfos,
onChangeNewContentTypeMainInfos,
onChangeAttribute,
- submitTempContentType,
+ // submitTempContentType,
submitTempContentTypeSucceeded,
saveEditedAttribute,
setTemporaryAttribute,
@@ -38,7 +38,7 @@ import {
ON_CHANGE_EXISTING_CONTENT_TYPE_MAIN_INFOS,
ON_CHANGE_NEW_CONTENT_TYPE_MAIN_INFOS,
ON_CHANGE_ATTRIBUTE,
- SUBMIT_TEMP_CONTENT_TYPE,
+ // SUBMIT_TEMP_CONTENT_TYPE,
SUBMIT_TEMP_CONTENT_TYPE_SUCCEEDED,
SAVE_EDITED_ATTRIBUTE,
SET_TEMPORARY_ATTRIBUTE,
@@ -429,15 +429,15 @@ describe('App actions', () => {
});
});
- describe('SubmitTempContentType', () => {
- it('has a type SUBMIT_TEMP_CONTENT_TYPE and returns the correct data', () => {
- const expected = {
- type: SUBMIT_TEMP_CONTENT_TYPE,
- };
+ // describe('SubmitTempContentType', () => {
+ // it('has a type SUBMIT_TEMP_CONTENT_TYPE and returns the correct data', () => {
+ // const expected = {
+ // type: SUBMIT_TEMP_CONTENT_TYPE,
+ // };
- expect(submitTempContentType()).toEqual(expected);
- });
- });
+ // expect(submitTempContentType()).toEqual(expected);
+ // });
+ // });
describe('SubmitTempContentTypeSucceeded', () => {
it('has a type SUBMIT_TEMP_CONTENT_TYPE_SUCCEEDED and returns the correct data', () => {
diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/tests/saga.test.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/tests/saga.test.js
index dfbccce1bc..de08701308 100644
--- a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/tests/saga.test.js
+++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/tests/saga.test.js
@@ -4,10 +4,10 @@
/* eslint-disable redux-saga/yield-effects */
import { all, fork, takeLatest, put } from 'redux-saga/effects';
-import defaultSaga, { deleteModel, getData, submitTempCT } from '../saga';
+import defaultSaga, { deleteModel, getData, submitCT, submitTempCT } from '../saga';
-import { deleteModelSucceeded, getDataSucceeded, submitTempContentTypeSucceeded } from '../actions';
-import { DELETE_MODEL, GET_DATA, SUBMIT_TEMP_CONTENT_TYPE } from '../constants';
+import { deleteModelSucceeded, getDataSucceeded } from '../actions';
+import { DELETE_MODEL, GET_DATA, SUBMIT_CONTENT_TYPE, SUBMIT_TEMP_CONTENT_TYPE } from '../constants';
const response = [
{
@@ -93,22 +93,29 @@ describe('CTB