Edit content type in all views

This commit is contained in:
cyril lopez 2017-08-29 15:11:06 +02:00
parent 2d98f42b24
commit 3d03119897
7 changed files with 63 additions and 6 deletions

View File

@ -12,8 +12,13 @@ import { createStructuredSelector } from 'reselect';
import { map } from 'lodash'; import { map } from 'lodash';
import { pluginId } from 'app'; import { pluginId } from 'app';
import { define } from 'i18n'; import { define } from 'i18n';
import { makeSelectShouldRefetchContentType } from 'containers/Form/selectors';
import { storeData } from '../../utils/storeData'; import { storeData } from '../../utils/storeData';
import messages from '../../translations/en.json'; import messages from '../../translations/en.json';
import styles from './styles.scss'; import styles from './styles.scss';
import { modelsFetch } from './actions'; import { modelsFetch } from './actions';
@ -28,6 +33,12 @@ class App extends React.Component {
this.props.modelsFetch(); this.props.modelsFetch();
} }
componentWillReceiveProps(nextProps) {
if (nextProps.shouldRefetchContentType !== this.props.shouldRefetchContentType) {
this.props.modelsFetch();
}
}
componentWillUnmount() { componentWillUnmount() {
// Empty the app localStorage // Empty the app localStorage
@ -58,6 +69,7 @@ App.propTypes = {
children: React.PropTypes.node, children: React.PropTypes.node,
exposedComponents: React.PropTypes.object.isRequired, exposedComponents: React.PropTypes.object.isRequired,
modelsFetch: React.PropTypes.func, modelsFetch: React.PropTypes.func,
shouldRefetchContentType: React.PropTypes.bool,
}; };
export function mapDispatchToProps(dispatch) { export function mapDispatchToProps(dispatch) {
@ -69,7 +81,9 @@ export function mapDispatchToProps(dispatch) {
) )
} }
const mapStateToProps = createStructuredSelector({}); const mapStateToProps = createStructuredSelector({
shouldRefetchContentType: makeSelectShouldRefetchContentType(),
});
// Wrap the component to inject dispatch and state into it // Wrap the component to inject dispatch and state into it
export default connect(mapStateToProps, mapDispatchToProps)(App); export default connect(mapStateToProps, mapDispatchToProps)(App);

View File

@ -37,7 +37,7 @@ function appReducer(state = initialState, action) {
const modelsSize = size(state.get('models').toJS()) const modelsSize = size(state.get('models').toJS())
return state return state
.updateIn(['menu', '0', 'items'], (list) => list.splice(action.position, action.nbElementToRemove, action.newLink)) .updateIn(['menu', '0', 'items'], (list) => list.splice(action.position, action.nbElementToRemove, action.newLink))
.update('models', array => array.splice(action.nbElementToRemove === 0 ? modelsSize : modelsSize -1 , 1, action.newModel)); .update('models', array => array.splice(action.nbElementToRemove === 0 ? modelsSize : modelsSize - 1 , 1, action.newModel));
} }
default: default:
return state; return state;

View File

@ -116,7 +116,29 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
} else { } else {
this.setState({ showModal: false }); this.setState({ showModal: false });
} }
}
// Close modal when updating a content type && success updating
if (nextProps.shouldRefetchContentType !== this.props.shouldRefetchContentType) {
// Check if localStorage because the PluginLeftMenu is based on the localStorage
if (storeData.getMenu()) {
// Update localStorage
const oldMenu = storeData.getMenu();
const index = findIndex(oldMenu, ['name', replace(this.props.hash.split('::')[0], '#edit', '')]);
const modifiedContentType = {
name: this.props.modifiedDataEdit.name,
icon: 'fa-caret-square-o-right',
};
oldMenu.splice(index, 1, modifiedContentType);
const newMenu = oldMenu;
storeData.setMenu(newMenu);
}
// Close Modal
router.push(`${this.props.redirectRoute}/${this.props.modifiedDataEdit.name}`);
// Reset props
this.props.resetDidFetchModelProp();
} }
} }
@ -146,6 +168,8 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
// Store new menu in localStorage and update App leftMenu // Store new menu in localStorage and update App leftMenu
this.props.storeTemporaryMenu(newMenu, position, index !== -1 ? 1 : 0); this.props.storeTemporaryMenu(newMenu, position, index !== -1 ? 1 : 0);
this.props.resetDidFetchModelProp();
router.push(`${this.props.redirectRoute}/${data.name}`); router.push(`${this.props.redirectRoute}/${data.name}`);
} }
@ -258,7 +282,6 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
toggle = () => { toggle = () => {
this.props.toggle(); this.props.toggle();
// Set the didFetchModel props to false when the modal is closing so the store is emptied // Set the didFetchModel props to false when the modal is closing so the store is emptied
// Only for editing // Only for editing
if (this.state.showModal && includes(this.props.hash, 'edit')) { if (this.state.showModal && includes(this.props.hash, 'edit')) {
@ -349,6 +372,7 @@ Form.propTypes = {
selectOptionsFetchSucceeded: React.PropTypes.bool, selectOptionsFetchSucceeded: React.PropTypes.bool,
setAttributeForm: React.PropTypes.func, setAttributeForm: React.PropTypes.func,
setForm: React.PropTypes.func.isRequired, setForm: React.PropTypes.func.isRequired,
shouldRefetchContentType: React.PropTypes.bool,
storeTemporaryMenu: React.PropTypes.func, storeTemporaryMenu: React.PropTypes.func,
toggle: React.PropTypes.func.isRequired, toggle: React.PropTypes.func.isRequired,
}; };

View File

@ -9,6 +9,7 @@ import {
CHANGE_INPUT, CHANGE_INPUT,
CHANGE_INPUT_ATTRIBUTE, CHANGE_INPUT_ATTRIBUTE,
CONNECTIONS_FETCH_SUCCEEDED, CONNECTIONS_FETCH_SUCCEEDED,
CONTENT_TYPE_ACTION_SUCCEEDED,
CONTENT_TYPE_FETCH_SUCCEEDED, CONTENT_TYPE_FETCH_SUCCEEDED,
RESET_DID_FETCH_MODEL_PROP, RESET_DID_FETCH_MODEL_PROP,
SET_ATTRIBUTE_FORM, SET_ATTRIBUTE_FORM,
@ -28,6 +29,7 @@ const initialState = fromJS({
modifiedDataEdit: Map(), modifiedDataEdit: Map(),
isFormSet: false, isFormSet: false,
didFetchModel: false, didFetchModel: false,
shouldRefetchContentType: false,
}); });
function formReducer(state = initialState, action) { function formReducer(state = initialState, action) {
@ -41,6 +43,10 @@ function formReducer(state = initialState, action) {
return state return state
.set('selectOptions', List(action.connections)) .set('selectOptions', List(action.connections))
.set('selectOptionsFetchSucceeded', !state.get('selectOptionsFetchSucceeded')); .set('selectOptionsFetchSucceeded', !state.get('selectOptionsFetchSucceeded'));
case CONTENT_TYPE_ACTION_SUCCEEDED:
return state
.set('shouldRefetchContentType', !state.get('shouldRefetchContentType'))
.set('initialDataEdit', state.get('modifiedDataEdit'));
case CONTENT_TYPE_FETCH_SUCCEEDED: case CONTENT_TYPE_FETCH_SUCCEEDED:
return state return state
.set('didFetchModel', true) .set('didFetchModel', true)
@ -48,12 +54,13 @@ function formReducer(state = initialState, action) {
.set('modifiedDataEdit', action.data); .set('modifiedDataEdit', action.data);
case RESET_DID_FETCH_MODEL_PROP: case RESET_DID_FETCH_MODEL_PROP:
return state return state
.set('didFetchModel', false); .set('didFetchModel', false)
.set('isFormSet', false);
case SET_ATTRIBUTE_FORM: { case SET_ATTRIBUTE_FORM: {
if (state.get('isFormSet')) { if (state.get('isFormSet')) {
return state.set('form', Map(action.form)); return state.set('form', Map(action.form));
} }
return state return state
.set('isFormSet', true) .set('isFormSet', true)
.set('form', Map(action.form)) .set('form', Map(action.form))

View File

@ -34,6 +34,12 @@ export function* editContentType() {
const requestUrl = `/content-type-builder/models/${initialContentType.name}`; const requestUrl = `/content-type-builder/models/${initialContentType.name}`;
yield call(request, requestUrl, opts); yield call(request, requestUrl, opts);
yield new Promise(resolve => {
setTimeout(() => {
resolve();
}, 5000);
});
yield put(contentTypeActionSucceeded()); yield put(contentTypeActionSucceeded());
} catch(error) { } catch(error) {

View File

@ -39,6 +39,11 @@ const makeSelectDidFetchModel = () => createSelector(
(substate) => substate.get('didFetchModel'), (substate) => substate.get('didFetchModel'),
); );
const makeSelectShouldRefetchContentType = () => createSelector(
selectFormDomain(),
(substate) => substate.get('shouldRefetchContentType'),
);
export default selectForm; export default selectForm;
export { export {
selectFormDomain, selectFormDomain,
@ -46,4 +51,5 @@ export {
makeSelectInitialDataEdit, makeSelectInitialDataEdit,
makeSelectModifiedData, makeSelectModifiedData,
makeSelectModifiedDataEdit, makeSelectModifiedDataEdit,
makeSelectShouldRefetchContentType,
}; };

View File

@ -85,7 +85,7 @@ module.exports = {
if (!name) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.name.missing' }] }]); if (!name) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.name.missing' }] }]);
if (!_.includes(Service.getConnections(), connection)) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.connection.unknow' }] }]); if (!_.includes(Service.getConnections(), connection)) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.connection.unknow' }] }]);
if (strapi.models[name]) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.exist' }] }]); if (strapi.models[name] && name !== model) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.exist' }] }]);
if (!strapi.models[model]) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.unknow' }] }]); if (!strapi.models[model]) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.unknow' }] }]);
if (!_.isNaN(parseFloat(name[0]))) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.name' }] }]); if (!_.isNaN(parseFloat(name[0]))) return ctx.badRequest(null, [{ messages: [{ id: 'request.error.model.name' }] }]);