Add and use ResourceCreationForm
authorFrank Bessou <frank.bessou@logilab.fr>
Wed, 10 May 2017 10:56:10 +0200
changeset 186 e44bcf04b4fd
parent 185 cfff71efc852
child 187 94c1c16ec8a0
Add and use ResourceCreationForm This component will be rendered for all routes which end with @@new. The newly created Resource component select this view.
src/components/Entity.js
src/components/Resource.js
src/index.js
--- a/src/components/Entity.js	Fri May 05 11:48:39 2017 +0200
+++ b/src/components/Entity.js	Wed May 10 10:56:10 2017 +0200
@@ -392,42 +392,6 @@
     router: PropTypes.object,
 };
 
-export class EntityCreationForm extends EntityForm {
-
-    constructor(props, context) {
-        super(props, context);
-        this.etype = props.match.params.etype;
-    }
-
-    componentDidMount() {
-        const {etype} = this.props.match.params;
-        HypermediaClient.getSchema(appendPath(`/${etype}`, '/schema?role=creation'))
-            .then(schema => this.setState({schema: schema}));
-    }
-
-    onSubmit({formData}) {
-        HypermediaClient.createResource(`/${this.etype}/`, formData)
-            .then(data => {
-                if (data.hasOwnProperty('errors')) {
-                    // XXX better update formData to `.addError` inline...
-                    this.setState({_errors: data.errors});
-                    return;
-                }
-                const path = `/${this.etype}`;
-                this.context.router.history.push(path);
-            });
-    }
-
-}
-
-EntityCreationForm.propTypes = {
-    match: PropTypes.shape({
-        params: PropTypes.shape({
-            etype: PropTypes.string,
-        }),
-    }),
-};
-
 export class AddRelated extends EntityForm {
 
     constructor(props, context) {
--- a/src/components/Resource.js	Fri May 05 11:48:39 2017 +0200
+++ b/src/components/Resource.js	Wed May 10 10:56:10 2017 +0200
@@ -2,6 +2,10 @@
 import hypermediaClient from '../services/hypermedia';
 import {PropTypes} from 'prop-types';
 
+import {appendPath} from '../utils';
+import {EntityForm} from './Entity';
+import {PropTypesResourceModel} from '../model';
+
 export class ResourceContainer extends React.Component {
     constructor(props) {
         super(props);
@@ -47,3 +51,63 @@
     url: PropTypes.string.isRequired,
     component: PropTypes.func.isRequired,
 };
+
+export class ResourceCreationForm extends React.Component {
+    constructor(props) {
+        super(props);
+        this.onSubmit = this.onSubmit.bind(this);
+        this.state = {};
+    }
+
+    componentDidMount() {
+        hypermediaClient.getSchema(appendPath(this.props.resource.url, '/schema?role=creation'))
+            .then(schema => this.setState({schema: schema}));
+    }
+
+    onSubmit({formData}) {
+        const path = this.props.resource.url;
+        hypermediaClient.createResource(path, formData)
+            .then(data => {
+                if (data.hasOwnProperty('errors')) {
+                    // XXX better update formData to `.addError` inline...
+                    this.setState({errors: data.errors});
+                    return;
+                }
+                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,
+};
+ResourceCreationForm.contextTypes = {
+    router: PropTypes.object,
+};
+
+export function Resource(props) {
+    function selectView() {
+        if (props.match.params.action === 'new') {
+            return ResourceCreationForm;
+        }
+    }
+    return <ResourceContainer url={props.match.params.apiUrl} component={selectView()} />;
+}
+Resource.propTypes = {
+    match: PropTypes.shape({
+        params: PropTypes.shape({
+            apiUrl: PropTypes.string.isRequired,
+            action: PropTypes.string,
+        }),
+    }),
+};
--- a/src/index.js	Fri May 05 11:48:39 2017 +0200
+++ b/src/index.js	Wed May 10 10:56:10 2017 +0200
@@ -5,7 +5,8 @@
 import {App, NotFound} from './components/App';
 import {Root} from './components/Root';
 import Entities from './components/Entities';
-import {Entity, EntityCreationForm, AddRelated} from './components/Entity';
+import {Entity, AddRelated} from './components/Entity';
+import {Resource} from './components/Resource';
 
 import "script-loader!jsonary/super-bundle/jsonary-super-bundle.js";
 
@@ -16,8 +17,8 @@
         <App>
             <Switch>
                 <Route exact path='/' component={Root} />
+                <Route exact path=":apiUrl(.*)@@:action(new)" component={Resource} />
                 <Route path="/:etype/:eid/relationships/:rtype" component={AddRelated} />
-                <Route path="/:etype/@@new" component={EntityCreationForm} />
                 <Route path="/:etype/:eid@@:view" component={Entity} />
                 <Route path="/:etype/:eid" component={Entity} />
                 <Route path="/:etype" component={Entities} />