Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions enact-all-samples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@
"@enact/spotlight": "next",
"@enact/ui": "next",
"@enact/webos": "next",
"apollo-boost": "^0.1.8",
"graphql": "^0.13.2",
"graphql-tag": "^2.9.2",
"prop-types": "^15.6.0",
"react": "^16.3.2",
"react-apollo": "^2.1.5",
"react-dom": "^16.3.2",
"react-redux": "^5.0.3",
"react-router-dom": "^4.1.1",
Expand Down
2 changes: 2 additions & 0 deletions enact-all-samples/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import PatternActivityPanelsDeepLinking from '../../pattern-activity-panels-deep
import PatternActivityPanelsRedux from '../../pattern-activity-panels-redux/src/main';
import PatternDynamicPanel from '../../pattern-dynamic-panel/src/App';
import PatternExpandableList from '../../pattern-expandablelist-object/src/App';
import PatternGraphQL from '../../pattern-graphql/src/App';
import PatternListDetails from '../../pattern-list-details/src/App';
import PatternListDetailsRedux from '../../pattern-list-details-redux/src/main';
import PatternLocaleSwitching from '../../pattern-locale-switching/src/main';
Expand All @@ -28,6 +29,7 @@ export const routes = [
{path: '/PatternActivityPanelsRedux', component: PatternActivityPanelsRedux},
{path: '/PatternDynamicPanel', component: PatternDynamicPanel},
{path: '/PatternExpandableList', component: PatternExpandableList},
{path: '/PatternGraphQL', component: PatternGraphQL},
{path: '/PatternListDetails', component: PatternListDetails},
{path: '/PatternListDetailsRedux', component: PatternListDetailsRedux},
{path: '/PatternLocaleSwitching', component: PatternLocaleSwitching},
Expand Down
16 changes: 16 additions & 0 deletions pattern-graphql/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.

# dependencies
node_modules

# testing
coverage

# production
build
dist

# misc
.DS_Store
npm-debug.log
.env
107 changes: 107 additions & 0 deletions pattern-graphql/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
## Use Apollo with Enact and GitHub GraphqQL API

A sample application that demonstrates how to use GraphqQL with Enact components. It uses [Apollo Client](https://github.com/apollographql/apollo-client), (GraphqQL client.)

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.

#### Enact Components Used
- `moonstone/Panels/ActivityPanels`
- `moonstone/Panels/Panel`
- `moonstone/Panels/Header`
- `moonstone/Button`
- `moonstone/VirtualList`
- `moonstone/Item`
- `moonstone/Divider`
- `moonstone/Image`
- `moonstone/Input`
- `ui/Layout/Column`
- `ui/Layout/Cell`
- `ui/resolution/scale`

## Setup and use
1. Get a personal access token for the [GitHub API](https://github.com/settings/tokens/new).
- Assign a name to the token and select the "read:org" under "admin:org" scope.
2. Replace the dummy token in [src/config.json](src/config.json) with the token generated above.
3. Install npm modules.

```bash
npm install
```
4. Serve.

```bash
npm run serve
```

5. Open [localhost](http://localhost:8080/).
6. Search for a GitHub id, selecting which information you wish to retrieve.


### How Apollo is used.

In **App.js**, a new `ApolloClient` is created with GitHub URI and request setup:

[src/App/App.js]
```javascript
import ApolloClient from "apollo-boost";

const client = new ApolloClient({
uri: 'https://api.github.com/graphql',
request: operation => {
operation.setContext({
headers: {
authorization: `Bearer ${config.token}`
}
});
}
});
```

Next, the `client` prop is passed to the `ApolloProvider` component, which wraps the components that need the queried data:
[src/App/App.js](src/App/App.js)
```javascript
import { ApolloProvider } from "react-apollo";

<ApolloProvider client={client}>
...
</ApolloProvider>
```

Finally, a GraphQL query (`GET_USER`) is created using `gql` and is passed as the `query` prop to the `Query` component:

[src/views/Detail.js](src/views/Detail.js)
```javascript
import { Query } from "react-apollo";
import gql from "graphql-tag";

const GET_USER = gql`
query($login: String!) {
user(login: $login) {
name
avatarUrl
organizations(first: 10) {
nodes {
name
}
}
repositories(first: 10) {
nodes {
name
url
}
}
followers(first: 10) {
nodes {
name
}
}
}
}
`;

<Query query={GET_USER} variables={{login: userId}}>
{({loading, data}) => {
...
}}
</Query>
```
46 changes: 46 additions & 0 deletions pattern-graphql/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "pattern-graphql",
"version": "1.0.0",
"description": "An Enact Moonstone GraphQL application.",
"author": "Hailey HanGyeol Ryu",
"main": "src/index.js",
"scripts": {
"serve": "enact serve",
"pack": "enact pack",
"pack-p": "enact pack -p",
"watch": "enact pack --watch",
"clean": "enact clean",
"lint": "enact lint --strict .",
"license": "enact license",
"test": "enact test start --single-run",
"test-watch": "enact test start"
},
"license": "Apache-2.0",
"private": true,
"repository": "https://github.com/enactjs/samples",
"enact": {
"theme": "moonstone"
},
"eslintConfig": {
"extends": "enact/strict"
},
"eslintIgnore": [
"node_modules/*",
"build/*",
"dist/*"
],
"dependencies": {
"@enact/core": "next",
"@enact/i18n": "next",
"@enact/moonstone": "next",
"@enact/spotlight": "next",
"@enact/ui": "next",
"apollo-boost": "^0.1.8",
"graphql": "^0.13.2",
"graphql-tag": "^2.9.2",
"prop-types": "^15.6.0",
"react": "^16.4.0",
"react-apollo": "^2.1.5",
"react-dom": "^16.4.0"
}
}
3 changes: 3 additions & 0 deletions pattern-graphql/resources/ilibmanifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"files": []
}
80 changes: 80 additions & 0 deletions pattern-graphql/src/App/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {ActivityPanels} from '@enact/moonstone/Panels';
import ApolloClient from 'apollo-boost';
import {ApolloProvider} from 'react-apollo';
import MoonstoneDecorator from '@enact/moonstone/MoonstoneDecorator';
import Notification from '@enact/moonstone/Notification';
import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Detail from '../views/Detail';
import Search from '../views/Search';
import config from '../config.json';


const client = new ApolloClient({
uri: 'https://api.github.com/graphql',
request: operation => {
operation.setContext({
headers: {
authorization: `Bearer ${config.token}`
}
});
}
});

class AppBase extends Component {
static propTypes = {
index: PropTypes.number,
onSearch: PropTypes.func
};

static defaultProps = {
index: 0
};

constructor (props) {
super(props);

this.state = {
index: this.props.index,
fol: false,
org: false,
repo: true,
userId: ''
};
}

handleSelectBreadcrumb = ({index}) => {
this.setState({index});
};

onSearch = ({userId, repo, fol, org}) => {
this.setState({
index: 1,
userId,
repo,
fol,
org
});
};

render () {
const {index, userId, repo, org, fol} = this.state;

return (
<ApolloProvider client={client}>
{!config.token && <Notification open><p>Please set your github token in src/config.json.</p></Notification>}
<ActivityPanels {...this.props} index={index} onSelectBreadcrumb={this.handleSelectBreadcrumb}>
<Search
onSearch={this.onSearch}
/>
<Detail repo={repo} org={org} fol={fol} userId={userId} />
</ActivityPanels>
</ApolloProvider>
);
}
}

const App = MoonstoneDecorator(AppBase);

export default App;
3 changes: 3 additions & 0 deletions pattern-graphql/src/App/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"main": "App.js"
}
43 changes: 43 additions & 0 deletions pattern-graphql/src/components/List.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {Cell} from '@enact/ui/Layout';
import Divider from '@enact/moonstone/Divider';
import Item from '@enact/moonstone/Item';
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {scale} from '@enact/ui/resolution';
import VirtualList from '@enact/moonstone/VirtualList';

class List extends Component {
static propTypes = {
list: PropTypes.arrayOf(PropTypes.object).isRequired,
title: PropTypes.string,
userId: PropTypes.string
}

renderItem = ({index, ...rest}) => (
<Item
{...rest}
index={index}
>
{this.props.list[index].name}
</Item>
);

render () {
const {list, title} = this.props;

return [
<Cell key="header" shrink><Divider>{title}</Divider></Cell>,
<Cell
component={VirtualList}
key="list"
dataSize={list.length}
focusableScrollbar={null}
itemRenderer={this.renderItem}
itemSize={scale(60)}
size={list.length <= 4 ? (60 * list.length) : null}
spacing={0}
/>];
}
}

export default List;
3 changes: 3 additions & 0 deletions pattern-graphql/src/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"token":""
}
13 changes: 13 additions & 0 deletions pattern-graphql/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import {render} from 'react-dom';

import App from './App';

const appElement = (<App skin="light" />);

// In a browser environment, render instead of exporting
if (typeof window !== 'undefined') {
render(appElement, document.getElementById('root'));
}

export default appElement;
Loading