Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
skevy committed Aug 25, 2015
0 parents commit f909cb4
Show file tree
Hide file tree
Showing 20 changed files with 965 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"stage": 0
}
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules

# OSX
.DS_Store

# App packaged
release
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
GraphiQL.app
------------

A light, Electron-based wrapper around GraphiQL.

This is a WIP, and was made in about an hour. It will get better over time.
57 changes: 57 additions & 0 deletions app/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.clearfix { display: inline-block; }
/* start commented backslash hack \*/
* html .clearfix { height: 1%; }
.clearfix { display: block; }
/* close commented backslash hack */

body {
font-family: helvetica, arial, sans-serif;
}

#react-root {
width: 100%;
height: 100%;
}

.ReactModal__Overlay {
z-index: 10000000;
}

.wrapper {
width: 100%;
height: 100%;
}

.config-form {
padding: 20px;
}

.field {
display: flex;
height: 40px;
flex-direction: row;
align-items: center;
justify-content: center;
float: left;
margin-right: 30px;
}

.field label {
margin-right: 20px;
line-height: 35px;
}

.field input, .field select {
height: 25px;
padding: 5px;
font-weight: bold;
font-size: 20px;
}
13 changes: 13 additions & 0 deletions app/app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GraphiQL</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
<link rel="stylesheet" href="../dist/main.css" />
</head>
<body>
<div id="react-root"></div>
<script src="../dist/bundle.js"></script>
</body>
</html>
Binary file added app/app.icns
Binary file not shown.
104 changes: 104 additions & 0 deletions app/components/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import _ from 'lodash';
import React from 'react';
import fetch from 'isomorphic-fetch';
import GraphiQL from 'graphiql/dist/index';
import Modal from 'react-modal/lib/index';

Modal.setAppElement(document.getElementById('react-root'));
Modal.injectCSS();

import HTTPHeaderEditor from './HTTPHeaderEditor';


export default class App extends React.Component {
constructor() {
super();

const storage = window.localStorage;

this.state = {
headers: JSON.parse(storage.getItem('graphiqlHeaders') || '{}'),
endpoint: storage.getItem('graphiqlEndpoint') || 'http://localhost:9000/data',
method: storage.getItem('graphiqlMethod') || 'post',
headerEditOpen: false
}
}

updateLocalStorage() {
window.localStorage.setItem('graphiqlHeaders', JSON.stringify(this.state.headers));
window.localStorage.setItem('graphiqlEndpoint', this.state.endpoint);
window.localStorage.setItem('graphiqlMethod', this.state.method);
}

graphQLFetcher = (graphQLParams) => {
const defaultHeaders = {
'Content-Type': 'application/json'
};

return fetch(this.state.endpoint, {
method: this.state.method,
headers: Object.assign({}, defaultHeaders, this.state.headers),
body: JSON.stringify(graphQLParams)
}).then(response => response.json());
}

handleChange(field, e) {
this.setState({
[field]: e.target.value
}, () => {
this.updateLocalStorage();
});
}

openHeaderEdit = () => {
this.setState({
headerEditOpen: true
});
}

closeModal = () => {
this.setState({
headerEditOpen: false
});
}

getHeadersFromModal = (headers) => {
this.setState({
headers: headers
}, () => {
this.updateLocalStorage();
});
}

render() {
return (
<div className="wrapper">
<div className="config-form clearfix">
<div className="field">
<label htmlFor="endpoint">GraphQL Endpoint</label>
<input type="text" name="endpoint"
value={this.state.endpoint} onChange={this.handleChange.bind(this, 'endpoint')} />
</div>
<div className="field">
<label htmlFor="method">Method</label>
<select name="method" value={this.state.method} onChange={this.handleChange.bind(this, 'method')}>
<option value="get">GET</option>
<option value="post">POST</option>
</select>
</div>
<div className="field headers">
<a href="javascript:;" onClick={this.openHeaderEdit}>Edit HTTP Headers</a>
</div>
</div>
<GraphiQL key={this.state.endpoint} fetcher={this.graphQLFetcher} />

<Modal isOpen={this.state.headerEditOpen} onRequestClose={this.closeModal}>
<HTTPHeaderEditor
headers={_.map(this.state.headers, (value, key) => ({ key, value }))}
onCreateHeaders={this.getHeadersFromModal}
closeModal={this.closeModal} />
</Modal>
</div>
);
}
}
117 changes: 117 additions & 0 deletions app/components/HTTPHeaderEditor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import _ from 'lodash';
import React from 'react';
// import Radium from 'radium';

export default class HTTPHeaderEditor extends React.Component {
constructor(props) {
super(props);

this.state = {
headers: props.headers || [],
addingHeader: false
};
}

sendHeaderListUpdate() {
if (this.props.onCreateHeaders) {
this.props.onCreateHeaders(
_.zipObject(_.map(this.state.headers, (val) => [val.key, val.value]))
);
}
}

addHeader = () => {
this.setState({
addingHeader: true
});
}

completeAdd = () => {
this.setState({
headers: [
...this.state.headers,
{
key: React.findDOMNode(this.newKeyInput).value,
value: React.findDOMNode(this.newValInput).value
}
]
}, () => {
this.setState({
addingHeader: false
});
this.sendHeaderListUpdate();
});
}

cancelAdd = () => {
this.setState({
addingHeader: false
});
}

removeRow = (i, event) => {
const newHeaders = [...this.state.headers];
newHeaders.splice(i, 1);
this.setState({
headers: newHeaders
}, () => {
this.sendHeaderListUpdate();
});
}

render() {
let addHeader = null;

if (this.state.addingHeader) {
addHeader = (
<tr>
<td><input ref={(c) => {
this.newKeyInput = c;
}} type="text" placeholder="Header Key" /></td>
<td><input ref={(c) => {
this.newValInput = c;
}} type="text" placeholder="Header Value" /></td>
<td>
<button onClick={this.completeAdd}>&#x2713;</button>
<button onClick={this.cancelAdd}>&times;</button>
</td>
</tr>
)
}

return (
<div className="headerEditor">
<h2>Edit HTTP Headers</h2>
<div>
<a href="javascript:;" onClick={this.addHeader}>+ Add Header</a>
<table className="pure-table pure-table-striped" style={styles.table}>
<thead>
<th>Key</th>
<th>Value</th>
<th></th>
</thead>
<tbody>
{this.state.headers.map((header, i) => (
<tr key={i}>
<td>{header.key}</td>
<td>{header.value.length > 40 ? header.value.substr(0, 40) + '...' : header.value}</td>
<td>
<button onClick={this.removeRow.bind(this, i)}>&times;</button>
</td>
</tr>
))}
{addHeader}
</tbody>
</table>
</div>
</div>
);
}
}

const styles = {
table: {
marginTop: 10,
width: '100%'
}
}
12 changes: 12 additions & 0 deletions app/hot-dev-app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GraphiQL</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
</head>
<body>
<div id="react-root"></div>
<script src="http://localhost:2992/dist/bundle.js"></script>
</body>
</html>
8 changes: 8 additions & 0 deletions app/mainApp.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import './app.css';
import 'graphiql/graphiql.css';

import React from 'react';

import App from './components/App';

React.render(<App />, document.getElementById('react-root'))
2 changes: 2 additions & 0 deletions dist/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
Loading

0 comments on commit f909cb4

Please sign in to comment.