Resource: merge ResourceCreationForm in ResourceEditionForm
authorPhilippe Pepiot <philippe.pepiot@logilab.fr>
Tue, 04 Jul 2017 12:08:35 +0200
changeset 248 3d18fb4a7444
parent 247 307dc63312aa
child 249 e641480b7e11
Resource: merge ResourceCreationForm in ResourceEditionForm Almost only HTTP method differ here.
src/components/Resource.js
src/components/Resource.spec.js
--- a/src/components/Resource.js	Tue Jul 04 11:58:08 2017 +0200
+++ b/src/components/Resource.js	Tue Jul 04 12:08:35 2017 +0200
@@ -72,51 +72,6 @@
     component: PropTypes.func.isRequired,
 };
 
-export class ResourceCreationForm extends React.Component {
-    constructor(props) {
-        super(props);
-        this.onSubmit = this.onSubmit.bind(this);
-        this.state = {};
-    }
-
-    componentDidMount() {
-        hypermediaClient.getSubmissionSchema(this.props.resource)
-            .then(schema => this.setState({schema: schema}));
-    }
-
-    onSubmit({formData}) {
-        const path = this.props.resource.url;
-        hypermediaClient.submitResource('POST', path, formData)
-            .then(data => {
-                if (data.hasOwnProperty('errors')) {
-                    // XXX better update formData to `.addError` inline...
-                    this.setState({errors: data.errors});
-                    return;
-                }
-                this.props.updateResource();
-                this.context.router.history.push(path);
-            });
-    }
-
-    render() {
-        if (!this.state.schema) {
-            return <div>Loading...</div>;
-        }
-        return <EntityForm
-            schema={this.state.schema}
-            onSubmit={this.onSubmit}
-            errors={this.state.errors}
-        />;
-    }
-}
-ResourceCreationForm.propTypes = {
-    resource: PropTypesResourceModel.isRequired,
-    updateResource: PropTypes.func,
-};
-ResourceCreationForm.contextTypes = {
-    router: PropTypes.object,
-};
-
 export class ResourceView extends React.Component {
     constructor(props) {
         super(props);
@@ -214,9 +169,12 @@
         return hypermediaClient.getSubmissionSchema(this.props.resource)
             .then(
                 (schema) => {
-                    const {data} = this.props.resource;
-                    const entity = mapToSchema(data.value(), schema);
-                    const formData = buildFormData(entity);
+                    let formData = null;
+                    if (this.props.method === 'PUT') {
+                        const {data} = this.props.resource;
+                        const entity = mapToSchema(data.value(), schema);
+                        formData = buildFormData(entity);
+                    }
                     this.setState({schema: schema, formData: formData});
                 }
             );
@@ -224,14 +182,18 @@
 
     onSubmit({formData}) {
         const url = this.props.resource.url;
-        hypermediaClient.submitResource('PUT', url, formData)
+        hypermediaClient.submitResource(this.props.method, url, formData)
             .then(data => {
                 if (data.hasOwnProperty('errors')) {
                     // XXX better update formData to `.addError` inline...
                     this.setState({errors: data.errors});
                     return;
                 }
-                this.props.updateResource(data);
+                if (this.props.method === 'PUT') {
+                    this.props.updateResource(data);
+                } else {
+                    this.props.updateResource();
+                }
                 this.context.router.history.push(url);
             });
     }
@@ -253,6 +215,7 @@
 ResourceEditionForm.propTypes = {
     resource: PropTypesResourceModel.isRequired,
     updateResource: PropTypes.func.isRequired,
+    method: PropTypes.oneOf(['POST', 'PUT']).isRequired,
 };
 ResourceEditionForm.contextTypes = {
     router: PropTypes.object.isRequired,
@@ -261,20 +224,24 @@
 export const PaginatedResourceView = withPagination(ResourceView);
 
 export function Resource(props) {
+    const childProps = {};
     function selectView() {
         switch (props.match.params.action) {
             case 'add':
-                return ResourceCreationForm;
+                childProps['method'] = 'POST';
+                return ResourceEditionForm;
             case 'delete':
                 return ResourceDeletionView;
             case 'edit':
+                childProps['method'] = 'PUT';
                 return ResourceEditionForm;
             case 'view':
             default:
                 return PaginatedResourceView;
         }
     }
-    return <ResourceContainer url={props.match.params.apiUrl} component={selectView()} />;
+    return <ResourceContainer childProps={childProps} url={props.match.params.apiUrl}
+        component={selectView()} />;
 }
 Resource.propTypes = {
     match: PropTypes.shape({
--- a/src/components/Resource.spec.js	Tue Jul 04 11:58:08 2017 +0200
+++ b/src/components/Resource.spec.js	Tue Jul 04 12:08:35 2017 +0200
@@ -5,7 +5,6 @@
 import {mapToSchema} from "../jsonaryutils";
 import {
     Resource,
-    ResourceCreationForm,
     ResourceEditionForm,
     ResourceView,
     PaginatedResourceView,
@@ -17,26 +16,28 @@
 } from '../views/Generics';
 
 describe('Resource', () => {
-    it('should select "ResourceCreationForm" when action is "add"', () => {
+    it('should select "ResourceEditionForm" with method POST when action is "add"', () => {
         const params = {
             apiUrl: '/book/',
             action: 'add',
         };
         const wrapper = shallow(<Resource match={{params: params}}/>);
-        const component = wrapper.props().component;
+        const props = wrapper.props();
 
-        expect(component).to.be.equal(ResourceCreationForm);
+        expect(props.component).to.be.equal(ResourceEditionForm);
+        expect(props.childProps.method).to.be.equal('POST');
     });
 
-    it('should select "ResourceEditionForm" when action is "edit"', () => {
+    it('should select "ResourceEditionForm" with method PUT when action is "edit"', () => {
         const params = {
             apiUrl: '/book/123',
             action: 'edit',
         };
         const wrapper = shallow(<Resource match={{params: params}}/>);
-        const component = wrapper.props().component;
+        const props = wrapper.props();
 
-        expect(component).to.be.equal(ResourceEditionForm);
+        expect(props.component).to.be.equal(ResourceEditionForm);
+        expect(props.childProps.method).to.be.equal('PUT');
     });
 
     it('should select "ResourceDeletionView" when action is "delete"', () => {