Skip to content

Commit 00e9205

Browse files
Hailey RyuHailey Ryu
authored andcommitted
Added graphql-example
1 parent 308cdb0 commit 00e9205

File tree

15 files changed

+467
-0
lines changed

15 files changed

+467
-0
lines changed

graphql-example/.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# See http://help.github.com/ignore-files/ for more about ignoring files.
2+
3+
# dependencies
4+
node_modules
5+
6+
# testing
7+
coverage
8+
9+
# production
10+
build
11+
dist
12+
13+
# misc
14+
.DS_Store
15+
npm-debug.log
16+
.env

graphql-example/README.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
## Use Apollo with Enact and Github GraphqQL API
2+
3+
A sample application that demonstrates how to use GraphqQL with Enact components. It uses [Apollo Client](https://github.com/apollographql/apollo-client), (GraphqQL client.)
4+
5+
Run `npm install` then `npm run serve` to have the app running on [http://localhost:8080](http://localhost:8080), where you can view it in your browser.
6+
7+
#### Enact Components Used
8+
- `moonstone/Panels/ActivityPanels`
9+
- `moonstone/Panels/Panel`
10+
- `moonstone/Panels/Header`
11+
- `moonstone/Button`
12+
- `moonstone/VirtualList`
13+
- `moonstone/Item`
14+
- `moonstone/Divider`
15+
- `moonstone/Image`
16+
- `moonstone/Input`
17+
- `ui/Layout/Column`
18+
- `ui/Layout/Cell`
19+
- `ui/resolution/scale`
20+
21+
## Setup and use
22+
1. Get Personal access token for github API from https://github.com/settings/tokens/new.
23+
- Select repo for scopes.
24+
2. Replace the dummy token in [src/config.json](src/config.json) with your token.
25+
3. Install node_modules
26+
```
27+
npm install
28+
```
29+
4. Serve
30+
```
31+
npm run serve
32+
```
33+
5. Open http://localhost:8080/.
34+
6. Search a github id with selections of repositories, followers, and/or organizations.
35+
36+
37+
### How Apollo is used.
38+
39+
You need to make a new ApolloClient with uri and request setup.
40+
[src/App/App.js]
41+
```javascript
42+
import ApolloClient from "apollo-boost";
43+
44+
const client = new ApolloClient({
45+
uri: 'https://api.github.com/graphql',
46+
request: operation => {
47+
operation.setContext({
48+
headers: {
49+
authorization: `Bearer ${config.token}`,
50+
},
51+
});
52+
},
53+
});
54+
```
55+
56+
Pass the client as a prop to the ApolloProvider component which wraps your components which will need the data from Query.
57+
[src/App/App.js](src/App/App.js)
58+
```javascript
59+
import { ApolloProvider } from "react-apollo";
60+
61+
<ApolloProvider client={client}>
62+
...
63+
</ApolloProvider>
64+
```
65+
66+
Write a query (GET_USER) using gql and pass it as query prop for the Query component.
67+
68+
[src/views/Detail.js](src/views/Detail.js)
69+
```javascript
70+
import { Query } from "react-apollo";
71+
import gql from "graphql-tag";
72+
73+
const GET_USER = gql`
74+
query($login: String!) {
75+
user(login: $login) {
76+
name
77+
avatarUrl
78+
organizations(first: 10) {
79+
nodes {
80+
name
81+
}
82+
}
83+
repositories(first: 10) {
84+
nodes {
85+
name
86+
url
87+
}
88+
}
89+
followers(first: 10) {
90+
nodes {
91+
name
92+
}
93+
}
94+
}
95+
}
96+
`;
97+
98+
<Query query={GET_USER} variables={{ login: formData.userId }}>
99+
{({loading, data}) => {
100+
...
101+
}}
102+
</Query>
103+
```

graphql-example/package.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"name": "newapp",
3+
"version": "1.0.0",
4+
"description": "A general template for an Enact Moonstone application.",
5+
"author": "Hailey HanGyeol Ryu",
6+
"main": "src/index.js",
7+
"scripts": {
8+
"serve": "enact serve",
9+
"pack": "enact pack",
10+
"pack-p": "enact pack -p",
11+
"watch": "enact pack --watch",
12+
"clean": "enact clean",
13+
"lint": "enact lint .",
14+
"license": "enact license",
15+
"test": "enact test start --single-run",
16+
"test-watch": "enact test start"
17+
},
18+
"license": "UNLICENSED",
19+
"private": true,
20+
"repository": "",
21+
"enact": {
22+
"theme": "moonstone"
23+
},
24+
"eslintConfig": {
25+
"extends": "enact/strict"
26+
},
27+
"eslintIgnore": [
28+
"node_modules/*",
29+
"build/*",
30+
"dist/*"
31+
],
32+
"dependencies": {
33+
"@enact/core": "^2.0.0-beta.7",
34+
"@enact/i18n": "^2.0.0-beta.7",
35+
"@enact/moonstone": "^2.0.0-beta.7",
36+
"@enact/spotlight": "^2.0.0-beta.7",
37+
"@enact/ui": "^2.0.0-beta.7",
38+
"apollo-boost": "^0.1.8",
39+
"graphql": "^0.13.2",
40+
"graphql-tag": "^2.9.2",
41+
"prop-types": "^15.6.0",
42+
"react": "^16.4.0",
43+
"react-apollo": "^2.1.5",
44+
"react-dom": "^16.4.0"
45+
}
46+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"files": []
3+
}

graphql-example/src/App/App.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import {ApolloProvider} from 'react-apollo';
2+
import ApolloClient from 'apollo-boost';
3+
4+
import React, {Component} from 'react';
5+
import PropTypes from 'prop-types';
6+
import {ActivityPanels} from '@enact/moonstone/Panels';
7+
import MoonstoneDecorator from '@enact/moonstone/MoonstoneDecorator';
8+
9+
import Detail from '../views/Detail';
10+
import Search from '../views/Search';
11+
import config from '../config.json';
12+
13+
const client = new ApolloClient({
14+
uri: 'https://api.github.com/graphql',
15+
request: operation => {
16+
operation.setContext({
17+
headers: {
18+
authorization: `Bearer ${config.token}`
19+
}
20+
});
21+
}
22+
});
23+
24+
class AppBase extends Component {
25+
static propTypes = {
26+
index: PropTypes.number,
27+
onListSelectionChange: PropTypes.func,
28+
onSearch: PropTypes.func,
29+
onUserIdChange: PropTypes.func
30+
};
31+
32+
static defaultProps = {
33+
index: 0
34+
};
35+
36+
37+
constructor (props) {
38+
super(props);
39+
this.userId = 'haileyr';
40+
this.lists = {
41+
repo: true,
42+
fol: true,
43+
org: true
44+
};
45+
46+
this.state = {
47+
userId: '',
48+
lists: {},
49+
index: this.props.index
50+
};
51+
}
52+
53+
handleSelectBreadcrumb = ({index}) => {
54+
this.lists = {
55+
repo: false,
56+
fol: false,
57+
org: false
58+
};
59+
this.setState({
60+
index,
61+
userId: '',
62+
lists: this.lists
63+
});
64+
};
65+
66+
onUserIdChange = (userId) => {
67+
this.userId = userId;
68+
};
69+
70+
onListSelectionChange = (target, value) => {
71+
this.lists[target] = value;
72+
};
73+
74+
onSearch = () => {
75+
this.setState({index: 1, userId: this.userId, lists: this.lists});
76+
};
77+
78+
render () {
79+
const {index, userId, lists} = this.state;
80+
81+
return (
82+
<ApolloProvider client={client}>
83+
<ActivityPanels {...this.props} onSelectBreadcrumb={this.handleSelectBreadcrumb} index={index}>
84+
<Search
85+
onUserIdChange={this.onUserIdChange}
86+
onListSelectionChange={this.onListSelectionChange}
87+
onSearch={this.onSearch}
88+
/>
89+
<Detail userId={userId} lists={lists} />
90+
</ActivityPanels>
91+
</ApolloProvider>);
92+
}
93+
}
94+
95+
const App = MoonstoneDecorator(AppBase);
96+
97+
export default App;
98+
export {App, AppBase};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"main": "App.js"
3+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import VirtualList from '@enact/moonstone/VirtualList';
2+
import Item from '@enact/moonstone/Item';
3+
import Divider from '@enact/moonstone/Divider';
4+
import {Cell} from '@enact/ui/Layout';
5+
import {scale} from '@enact/ui/resolution';
6+
import kind from '@enact/core/kind';
7+
import React from 'react';
8+
import PropTypes from 'prop-types';
9+
10+
// eslint-disable-next-line enact/display-name, enact/prop-types
11+
const renderItem = ({list}) => ({index, ...rest}) => {
12+
return (
13+
<Item
14+
{...rest}
15+
index={index}
16+
>
17+
{list[index].name}
18+
</Item>
19+
);
20+
};
21+
22+
const ListBase = kind({
23+
name: 'Detail',
24+
25+
propTypes: {
26+
list: PropTypes.object,
27+
userId: PropTypes.string
28+
},
29+
30+
computed: {
31+
itemRenderer: renderItem
32+
},
33+
34+
render: ({itemRenderer, list}) => {
35+
return [
36+
<Cell key="header" shrink><Divider>Repositories</Divider></Cell>,
37+
<Cell
38+
component={VirtualList} size={list.length <= 4 ? (60 * list.length) : null}
39+
key="list"
40+
dataSize={list.length}
41+
focusableScrollbar={null}
42+
itemRenderer={itemRenderer}
43+
itemSize={scale(60)}
44+
spacing={0}
45+
/>];
46+
}
47+
});
48+
49+
export default ListBase;
50+
export {ListBase as List, ListBase};

graphql-example/src/config.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"token":"a67285b115df55b4bc1b38"
3+
}

graphql-example/src/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import React from 'react';
2+
import {render} from 'react-dom';
3+
4+
import App from './App';
5+
6+
const appElement = (<App skin="light" />);
7+
8+
// In a browser environment, render instead of exporting
9+
if (typeof window !== 'undefined') {
10+
render(appElement, document.getElementById('root'));
11+
}
12+
13+
export default appElement;

0 commit comments

Comments
 (0)