Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.

Commit 5879f46

Browse files
Merge pull request #9 from thefringeninja/self-doc
Add Support for Curies
2 parents f0accca + 82679ee commit 5879f46

23 files changed

+227
-56
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"react": "16.5.2",
2727
"react-dom": "16.5.2",
2828
"react-inspector": "2.3.0",
29+
"react-remarkable": "1.1.3",
2930
"react-schema-form": "0.5.0",
3031
"react-scripts": "2.0.5",
3132
"react-tap-event-plugin": "3.0.2",

src/SqlStreamStoreBrowser.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { SqlStreamStore } from './components/Icons';
1515
import { actions, store, rels, views } from './stream-store';
1616
import theme from './theme';
1717
import { createState, connect } from './reactive';
18+
import { mediaTypes } from './utils';
1819

1920
const getSelfAlias = links =>
2021
Object.keys(links)
@@ -36,16 +37,20 @@ const state$ = createState(
3637
obs.of({ links: {}, forms: {}, loading: false }),
3738
);
3839

39-
const onNavigate = (url, authorization) =>
40-
actions.get.request.next({ url, headers: { authorization } });
40+
const onNavigate = (link, authorization) =>
41+
actions.get.request.next({ link, headers: { authorization } });
4142

4243
const initialNavigation = ({ authorization }) =>
43-
onNavigate(window.location.href, authorization);
44+
onNavigate(
45+
{ href: window.location.href, type: mediaTypes.hal },
46+
authorization,
47+
);
4448

4549
const formActions = {
4650
[rels.append]: actions.post,
4751
[rels.metadata]: actions.post,
48-
[rels.delete]: actions.delete,
52+
[rels.deleteStream]: actions.delete,
53+
[rels.deleteMessage]: actions.delete,
4954
};
5055

5156
const Hero = () => (

src/components/HyperMediaControls/Dialog.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111

1212
import RelIcon from '../RelIcon';
1313
import RelButton from './RelButton';
14+
import HelpButton from './HelpButton';
1415
const styles = theme => ({
1516
button: {
1617
margin: theme.spacing.unit,
@@ -19,6 +20,8 @@ const styles = theme => ({
1920

2021
const SlideUp = props => <Slide direction={'up'} {...props} />;
2122

23+
const isStandardRel = rel => rel.indexOf(':') === -1;
24+
2225
export default withStyles(styles)(
2326
class HyperMediaDialog extends PureComponent {
2427
state = {
@@ -46,7 +49,7 @@ export default withStyles(styles)(
4649
};
4750

4851
render() {
49-
const { label, rel, title, classes, children } = this.props;
52+
const { label, rel, title, classes, children, curies } = this.props;
5053
const { open } = this.state;
5154

5255
return (
@@ -69,6 +72,9 @@ export default withStyles(styles)(
6972
<DialogTitle>{title}</DialogTitle>
7073
<DialogContent>{children}</DialogContent>
7174
<DialogActions>
75+
{!isStandardRel(rel) && (
76+
<HelpButton rel={rel} curies={curies} />
77+
)}
7278
<Button onClick={this._onClose}>{'Cancel'}</Button>
7379
<Button
7480
variant={'contained'}

src/components/HyperMediaControls/FormButton.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ const getValue = value => {
2525
class FormButton extends PureComponent {
2626
state = {};
2727
_onSubmit = () => {
28-
const { rel, url, actions, authorization } = this.props;
28+
const { rel, link, actions, authorization } = this.props;
2929
const { model: body } = this.state;
3030

3131
if (actions[rel]) {
3232
actions[rel].request.next({
3333
body,
34-
url,
34+
link,
3535
headers: {
3636
authorization,
3737
},
@@ -51,13 +51,14 @@ class FormButton extends PureComponent {
5151
};
5252

5353
render() {
54-
const { schema, rel, title } = this.props;
54+
const { schema, rel, title, curies } = this.props;
5555
const { model } = this.state;
5656
return (
5757
<Dialog
5858
label={title}
5959
rel={rel}
6060
title={schema.title}
61+
curies={curies}
6162
onSubmit={this._onSubmit}
6263
>
6364
<SchemaForm
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import React, { PureComponent } from 'react';
2+
import { Button, Drawer, withStyles } from '@material-ui/core';
3+
import Remarkable from 'react-remarkable';
4+
import uriTemplate from 'uri-template';
5+
import { Help } from '../Icons';
6+
import { withAuthorization } from '../AuthorizationProvider';
7+
import { http } from '../../utils';
8+
import Typography from '@material-ui/core/es/Typography/Typography';
9+
10+
const getCurie = (rel, curies) => {
11+
const [prefix, rest] = rel.split(':', 2);
12+
13+
return !rest || rest.indexOf(':') !== -1
14+
? { href: rel }
15+
: curies
16+
.filter(({ name }) => name === prefix)
17+
.map(({ href, ...link }) => ({
18+
...link,
19+
href: uriTemplate
20+
.parse(decodeURI(href))
21+
.expand({ rel: rest }),
22+
}))[0] || { href: rel };
23+
};
24+
25+
const Documentation = withStyles(theme => ({
26+
drawerPaper: {
27+
width: '45%',
28+
padding: theme.spacing.unit * 2,
29+
},
30+
}))(({ open, children, onClose, classes }) => (
31+
<Drawer
32+
open={open}
33+
onClose={onClose}
34+
anchor={'right'}
35+
classes={{
36+
paper: classes.drawerPaper,
37+
}}
38+
>
39+
<Typography>
40+
<Remarkable
41+
options={{
42+
typographer: true,
43+
}}
44+
>
45+
{children}
46+
</Remarkable>
47+
</Typography>
48+
</Drawer>
49+
));
50+
51+
class HelpButton extends PureComponent {
52+
state = {
53+
open: false,
54+
href: null,
55+
type: null,
56+
disabled: true,
57+
documentation: null,
58+
};
59+
60+
static getDerivedStateFromProps = ({ rel, curies }, state) => ({
61+
...state,
62+
disabled: false,
63+
...getCurie(rel, curies),
64+
});
65+
66+
_handleOnClick = async () => {
67+
const { authorization } = this.props;
68+
const { href, type } = this.state;
69+
const { body: documentation } = await http.get({
70+
link: { href, type },
71+
headers: { authorization },
72+
});
73+
74+
this.setState({
75+
...this.state,
76+
open: true,
77+
documentation:
78+
typeof documentation === 'string'
79+
? documentation
80+
: JSON.stringify(documentation),
81+
});
82+
};
83+
84+
_handleOnClose = () => this.setState({ open: false });
85+
86+
render() {
87+
const { disabled } = this.props;
88+
const { documentation, open } = this.state;
89+
90+
return (
91+
<Button
92+
color={'secondary'}
93+
disabled={disabled}
94+
onClick={this._handleOnClick}
95+
>
96+
<Documentation onClose={this._handleOnClose} open={open}>
97+
{documentation}
98+
</Documentation>
99+
<Help />
100+
{'Help'}
101+
</Button>
102+
);
103+
}
104+
}
105+
106+
export default withAuthorization()(HelpButton);

src/components/HyperMediaControls/LinkButton.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const TemplatedLinkButton = withAuthorization()(
1717
});
1818

1919
render() {
20-
const { rel, link, authorization, onNavigate } = this.props;
20+
const { rel, link, authorization, onNavigate, curies } = this.props;
2121

2222
const template = uriTemplate.parse(decodeURI(link.href));
2323

@@ -26,8 +26,12 @@ const TemplatedLinkButton = withAuthorization()(
2626
label={link.title}
2727
rel={rel}
2828
title={link.title}
29+
curies={curies}
2930
onSubmit={() =>
30-
onNavigate(template.expand(this.state), authorization)
31+
onNavigate(
32+
{ ...link, href: template.expand(this.state) },
33+
authorization,
34+
)
3135
}
3236
>
3337
{template.expressions
@@ -52,7 +56,7 @@ const NonTemplatedLinkButton = withAuthorization()(
5256
rel={rel}
5357
title={link.title}
5458
color={'action'}
55-
onClick={preventDefault(() => onNavigate(link.href, authorization))}
59+
onClick={preventDefault(() => onNavigate(link, authorization))}
5660
/>
5761
),
5862
);

src/components/HyperMediaControls/index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import { rels } from '../../stream-store';
99
const isNotSelf = (rel, links) =>
1010
links[rels.self] && links[rel].href !== links[rels.self].href;
1111

12-
const state$ = createState(store.url$.map(url => ['url', () => url]));
12+
const state$ = createState(store.url$.map(href => ['href', () => href]));
1313

14-
const HyperMediaControls = ({ forms, url, actions, links, onNavigate }) => (
14+
const HyperMediaControls = ({ forms, href, actions, links, onNavigate }) => (
1515
<Card>
1616
<CardActions>
1717
<div>
@@ -22,10 +22,10 @@ const HyperMediaControls = ({ forms, url, actions, links, onNavigate }) => (
2222
<LinkButton
2323
key={rel}
2424
rel={rel}
25-
url={url}
2625
link={links[rel]}
2726
onNavigate={onNavigate}
2827
color={'active'}
28+
curies={[links[rels.curies]]}
2929
/>
3030
))}
3131
</div>
@@ -34,9 +34,10 @@ const HyperMediaControls = ({ forms, url, actions, links, onNavigate }) => (
3434
<FormButton
3535
key={rel}
3636
rel={rel}
37-
url={url}
37+
link={{ href }}
3838
actions={actions}
3939
schema={forms[rel]}
40+
curies={[links[rels.curies]]}
4041
/>
4142
))}
4243
</div>

src/components/Hyperlink.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ const styles = {
2222
};
2323
const Hyperlink = withAuthorization()(
2424
withStyles(styles)(
25-
({ classes, href, children, authorization, onNavigate }) => (
25+
({ classes, link, children, authorization, onNavigate }) => (
2626
<a
27-
href={href}
27+
href={link.href}
2828
className={classes.hyperlink}
29-
onClick={preventDefault(() => onNavigate(href, authorization))}
29+
onClick={preventDefault(() => onNavigate(link, authorization))}
3030
>
3131
{children}
3232
</a>

src/components/Icons/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ export { default as Refresh } from '@material-ui/icons/Refresh';
2020
export { default as SpaceBar } from '@material-ui/icons/SpaceBar';
2121
export { default as Search } from '@material-ui/icons/Search';
2222
export { default as List } from '@material-ui/icons/List';
23+
export { default as Help } from '@material-ui/icons/Help';

src/components/NavigationLinks.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const NavigationLinks = ({ onNavigate, links, authorization }) => (
2222
disabled={!links[rel]}
2323
key={rel}
2424
onClick={preventDefault(() =>
25-
onNavigate(links[rel].href, authorization),
25+
onNavigate(links[rel], authorization),
2626
)}
2727
link={links[rel]}
2828
rel={rel}

0 commit comments

Comments
 (0)