Fix ActionLink
authorFrank Bessou <frank.bessou@logilab.fr>
Fri, 31 Mar 2017 18:20:48 +0200
changeset 68 1c9f3d4ad751
parent 67 830a5ff5bdc2
child 69 29faede0bd68
Fix ActionLink
src/Api.js
src/components/BaseViews.js
src/components/Entity.js
src/model.js
test/index.js
--- a/src/Api.js	Mon Apr 03 14:54:12 2017 +0200
+++ b/src/Api.js	Fri Mar 31 18:20:48 2017 +0200
@@ -104,7 +104,9 @@
     }
 
     getEntity(etype, eid) {
-        const url = `/${etype}/${eid}`;
+        const route = `/${etype}/${eid}`;
+        const url = route;
+
         const schemaPromise = this.getSchema(etype, eid);
         const fetchPromise = this.jsonFetchResponse(url);
         const dataPromise = fetchPromise.then( response => response.json() );
@@ -114,7 +116,8 @@
                 ([schema, data, allowedActions]) => {
                     const wrappedData = wrapEntityData(data, schema);
                     return {
-                        url: url,
+                        url: route,
+                        route: route,
                         etype: etype,
                         eid: eid,
                         data: wrappedData,
--- a/src/components/BaseViews.js	Mon Apr 03 14:54:12 2017 +0200
+++ b/src/components/BaseViews.js	Fri Mar 31 18:20:48 2017 +0200
@@ -1,5 +1,6 @@
 import React from 'react';
 import {Link} from 'react-router';
+import {PropTypeAction, PropTypesEntityModel} from '../model';
 
 export function OneLineView({entity}) {
     return (
@@ -41,31 +42,27 @@
     ).isRequired,
 };
 
-export function ActionLink({link}) {
-    const {rel, href, title} = link;
-    let url = `${href}`;
-    switch (rel) {
+export function ActionLink({target, action}) {
+    let {route} = target;
+    switch (action) {
         case 'delete':
-            url += '/delete';
+            route += '/delete';
             break;
         case 'edit':
-            url += '/edit';
+            route += '/edit';
             break;
         case 'create':
-            url += '/new';
+            route += '/new';
             break;
         default:
             return null;
     }
-    return <Link to={url} title={rel}>{title}</Link>;
+    return <Link to={route} title={action} >{action}</Link>;
 }
 
 ActionLink.propTypes = {
-    link: React.PropTypes.shape({
-        href: React.PropTypes.string.isRequired,
-        rel: React.PropTypes.string.isRequired,
-        title: React.PropTypes.string.isRequired,
-    }).isRequired,
+    action: PropTypeAction.isRequired,
+    target: PropTypesEntityModel.isRequired,
 };
 
 export function DropDownButton(props) {
--- a/src/components/Entity.js	Mon Apr 03 14:54:12 2017 +0200
+++ b/src/components/Entity.js	Fri Mar 31 18:20:48 2017 +0200
@@ -241,13 +241,13 @@
     }
 
     renderActions() {
-        const hyperLinks = Array.from(this.props.entity.data.links());
-        if (isEmpty(hyperLinks)) {
+        const actions = this.props.entity.allowedActions;
+        if (isEmpty(actions)) {
             return null;
         }
         return (
             <DropDownButton title="actions" style="pull-right">
-                { hyperLinks.map(link => <ActionLink link={link} />) }
+                { actions.map(action => <ActionLink target={this.props.entity} action={action} key={action} />) }
             </DropDownButton>
         );
     }
--- a/src/model.js	Mon Apr 03 14:54:12 2017 +0200
+++ b/src/model.js	Fri Mar 31 18:20:48 2017 +0200
@@ -11,6 +11,7 @@
 
 export const PropTypesEntityModel = React.PropTypes.shape({
     url: React.PropTypes.string.isRequired,
+    route: React.PropTypes.string.isRequired,
     etype: React.PropTypes.string.isRequired,
     eid: React.PropTypes.string.isRequired,
     data: PropTypeJsonaryWrapper.isRequired,
--- a/test/index.js	Mon Apr 03 14:54:12 2017 +0200
+++ b/test/index.js	Fri Mar 31 18:20:48 2017 +0200
@@ -190,7 +190,11 @@
 });
 
 describe('<ActionLink />', () => {
+    let targetResource;
     beforeEach(() => {
+        targetResource = {
+            route: "/any/123",
+        },
         sinon.stub(defaultApi, 'buildUrl').callsFake(x => `http://testing.com${x}`);
     });
 
@@ -198,52 +202,33 @@
         defaultApi.buildUrl.restore();
     });
 
-    it('given a "create" hyperlink, it renders a link pointing to "new" view', () => {
-        const hlink = {
-            rel: 'create',
-            href: '/thing',
-            title: 'Creation',
-        };
-        const wrapper = shallow(<ActionLink link={hlink}/>);
+    it('given a "create" action, it renders a link pointing to "create" view', () => {
+        const wrapper = shallow(<ActionLink target={targetResource} action='create'/>);
+
         expect(wrapper.is('Link')).to.be.equal(true);
-        expect(wrapper.prop('to')).to.be.equal(
-                'http://testing.com/thing/new');
+        expect(wrapper.prop('to')).to.be.equal('/any/123/new');
         expect(wrapper.prop('title')).to.be.equal('create');
     });
 
-    it('given an "edit" hyperlink, it renders a link pointing to "edit" view', () => {
-        const hlink = {
-            rel: 'edit',
-            href: '/thing/123',
-            title: 'Edition',
-        };
-        const wrapper = shallow(<ActionLink link={hlink}/>);
+    it('given an "edit" action, it renders a link pointing to "edit" view', () => {
+        const wrapper = shallow(<ActionLink target={targetResource} action='edit'/>);
+
         expect(wrapper.is('Link')).to.be.equal(true);
-        expect(wrapper.prop('to')).to.be.equal(
-                'http://testing.com/thing/123/edit');
+        expect(wrapper.prop('to')).to.be.equal( '/any/123/edit');
         expect(wrapper.prop('title')).to.be.equal('edit');
     });
 
-    it('given a "delete" hyperlink, it renders a link pointing to "delete" view', () => {
-        const hlink = {
-            rel: 'delete',
-            href: '/thing/123',
-            title: 'Delete',
-        };
-        const wrapper = shallow(<ActionLink link={hlink}/>);
+    it('given a "delete" action, it renders a link pointing to "delete" view', () => {
+        const wrapper = shallow(<ActionLink target={targetResource} action='delete'/>);
+
         expect(wrapper.is('Link')).to.be.equal(true);
-        expect(wrapper.prop('to')).to.be.equal(
-                'http://testing.com/thing/123/delete');
+        expect(wrapper.prop('to')).to.be.equal( '/any/123/delete');
         expect(wrapper.prop('title')).to.be.equal('delete');
     });
 
-    it('given an unknown hyperlink, it renders nothing', () => {
-        const hlink = {
-            rel: 'blah',
-            href: '/thing/123',
-            title: 'does not matter',
-        };
-        const wrapper = shallow(<ActionLink link={hlink}/>);
+    it('given an unknown action, it renders nothing', () => {
+        const wrapper = shallow(<ActionLink target={targetResource} action='foo'/>);
+
         expect(wrapper.html()).to.be.equal(null);
     });