Verified Commit 661ea7d2 authored by Marco Kellershoff's avatar Marco Kellershoff 🤸
Browse files

Initial commit

parents
tags
TAGS
<!DOCTYPE html>
<html manifest="manifest.appcache">
<head>
<title>GraphQL Explorer - Connections</title>
<style>
html,body {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
font-family: monospace;
}
#app {
margin: 20px auto;
width: 776px;
max-width: 99%;
}
#connections li span.text {
padding-right: 10px;
cursor: pointer;
}
#connections li span.delete {
margin: 0;
border: 1px solid #000;
border-radius: 3px;
padding: 5px;
cursor: pointer;
font-size: 12px;
}
</style>
</head>
<body>
<div id="app">
<h2>New Connection</h2>
<div id="newconnection">
<input
id="apihost"
type="text"
placeholder="https://localhost/graphql" />
<button id="saveconnection">Save Connection</button>
<button id="connect">Quick Connect</button>
</div>
<h2>Saved Connections</h2>
<ul id="connections"></ul>
</div>
<script src="./connections.js"></script>
</body>
</html>
(function(window, document) {
"use strict";
const apihost = document.querySelector("#apihost");
const connectBtn = document.querySelector("#connect");
const saveBtn = document.querySelector("#saveconnection");
const connections = document.querySelector("#connections");
const setStore = (newStore) => {
window.localStorage.setItem("GRAPHQL_API_HOSTS", JSON.stringify(newStore));
}
const getStore = () => {
let store = window.localStorage.getItem("GRAPHQL_API_HOSTS");
if (!store) {
store = [];
} else {
store = JSON.parse(store);
}
return store;
};
const addToStore = (item) => {
const store = getStore();
store.push(item);
setStore(store);
refreshConnections();
return store;
};
const deleteFromStoreAtIndex = function(index) {
const i = parseInt(index, 10);
const store = getStore();
store.splice(i, 1);
setStore(store);
refreshConnections();
};
const deleteFunc = function(i) {
deleteFromStoreAtIndex(i);
};
const connectFunc = function(h) {
window.localStorage.setItem("GRAPHQL_API_HOST", h);
window.location.href = "explore.html";
};
const refreshConnections = function() {
const store = getStore();
connections.innerHTML = "";
store.forEach((item, i) => {
const li = document.createElement("li");
const text = document.createElement("span");
text.className = "text";
const deleteBtn = document.createElement("span");
deleteBtn.className = "delete";
text.innerHTML = item.text;
deleteBtn.innerHTML = "X";
text.addEventListener("click", function(){
connectFunc(this.parentNode.getAttribute("data-apihost"));
});
deleteBtn.addEventListener("click", function(){
deleteFunc(this.parentNode.getAttribute("data-index"));
});
li.setAttribute("data-apihost", item.value);
li.setAttribute("data-index", i);
li.appendChild(text);
li.appendChild(deleteBtn);
connections.appendChild(li);
});
};
saveBtn.addEventListener("click", function(evt) {
evt.preventDefault();
addToStore({text: apihost.value, value: apihost.value});
});
connectBtn.addEventListener("click", (evt) => {
evt.preventDefault();
connectFunc(apihost.value);
});
refreshConnections();
})(window, document)
<!DOCTYPE html>
<html manifest="manifest.appcache">
<head>
<title>GraphQL Explorer - Explore</title>
<style>
body {
height: 100%;
margin: 0;
width: 100%;
overflow: hidden;
}
#graphiql {
height: 100vh;
}
</style>
<script src="//cdn.jsdelivr.net/es6-promise/4.0.5/es6-promise.auto.min.js"></script>
<script src="//cdn.jsdelivr.net/fetch/0.9.0/fetch.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.4.2/react.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script>
<link rel="stylesheet" href="./graphiql.css" />
<script src="./graphiql.js"></script>
</head>
<body>
<div id="graphiql">Loading...</div>
<script src="./explore.js"></script>
</body>
</html>
// Parse the search string to get url parameters.
var search = window.location.search;
var parameters = {};
search.substr(1).split('&').forEach(function (entry) {
var eq = entry.indexOf('=');
if (eq >= 0) {
parameters[decodeURIComponent(entry.slice(0, eq))] =
decodeURIComponent(entry.slice(eq + 1));
}
});
// if variables was provided, try to format it.
if (parameters.variables) {
try {
parameters.variables =
JSON.stringify(JSON.parse(parameters.variables), null, 2);
} catch (e) {
// Do nothing, we want to display the invalid JSON as a string, rather
// than present an error.
}
}
// When the query and variables string is edited, update the URL bar so
// that it can be easily shared
function onEditQuery(newQuery) {
parameters.query = newQuery;
updateURL();
}
function onEditVariables(newVariables) {
parameters.variables = newVariables;
updateURL();
}
function onEditOperationName(newOperationName) {
parameters.operationName = newOperationName;
updateURL();
}
function updateURL() {
var newSearch = '?' + Object.keys(parameters).filter(function (key) {
return Boolean(parameters[key]);
}).map(function (key) {
return encodeURIComponent(key) + '=' +
encodeURIComponent(parameters[key]);
}).join('&');
history.replaceState(null, null, newSearch);
}
function graphQLFetcher(graphQLParams) {
return fetch(window.localStorage.getItem("GRAPHQL_API_HOST"), {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(graphQLParams),
credentials: true,
}).then(function (response) {
return response.text();
}).then(function (responseBody) {
try {
return JSON.parse(responseBody);
} catch (error) {
return responseBody;
}
});
}
ReactDOM.render(
React.createElement(GraphiQL, {
fetcher: graphQLFetcher,
query: parameters.query,
variables: parameters.variables,
operationName: parameters.operationName,
onEditQuery: onEditQuery,
onEditVariables: onEditVariables,
onEditOperationName: onEditOperationName
}),
document.getElementById('graphiql')
);
.graphiql-container,
.graphiql-container button,
.graphiql-container input {
color: #141823;
font-family:
system,
-apple-system,
'San Francisco',
'.SFNSDisplay-Regular',
'Segoe UI',
Segoe,
'Segoe WP',
'Helvetica Neue',
helvetica,
'Lucida Grande',
arial,
sans-serif;
font-size: 14px;
}
.graphiql-container {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
height: 100%;
margin: 0;
overflow: hidden;
width: 100%;
}
.graphiql-container .editorWrap {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
overflow-x: hidden;
}
.graphiql-container .title {
font-size: 18px;
}
.graphiql-container .title em {
font-family: georgia;
font-size: 19px;
}
.graphiql-container .topBarWrap {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
}
.graphiql-container .topBar {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
background: -webkit-gradient(linear, left top, left bottom, from(#f7f7f7), to(#e2e2e2));
background: linear-gradient(#f7f7f7, #e2e2e2);
border-bottom: 1px solid #d0d0d0;
cursor: default;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
height: 34px;
overflow-y: visible;
padding: 7px 14px 6px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.graphiql-container .toolbar {
overflow-x: visible;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.graphiql-container .docExplorerShow,
.graphiql-container .historyShow {
background: -webkit-gradient(linear, left top, left bottom, from(#f7f7f7), to(#e2e2e2));
background: linear-gradient(#f7f7f7, #e2e2e2);
border-radius: 0;
border-bottom: 1px solid #d0d0d0;
border-right: none;
border-top: none;
color: #3B5998;
cursor: pointer;
font-size: 14px;
margin: 0;
outline: 0;
padding: 2px 20px 0 18px;
}
.graphiql-container .docExplorerShow {
border-left: 1px solid rgba(0, 0, 0, 0.2);
}
.graphiql-container .historyShow {
border-right: 1px solid rgba(0, 0, 0, 0.2);
border-left: 0;
}
.graphiql-container .docExplorerShow:before {
border-left: 2px solid #3B5998;
border-top: 2px solid #3B5998;
content: '';
display: inline-block;
height: 9px;
margin: 0 3px -1px 0;
position: relative;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
width: 9px;
}
.graphiql-container .editorBar {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
.graphiql-container .queryWrap {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
.graphiql-container .resultWrap {
border-left: solid 1px #e0e0e0;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
position: relative;
}
.graphiql-container .docExplorerWrap,
.graphiql-container .historyPaneWrap {
background: white;
-webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.15);
box-shadow: 0 0 8px rgba(0, 0, 0, 0.15);
position: relative;
z-index: 3;
}
.graphiql-container .historyPaneWrap {
min-width: 230px;
z-index: 5;
}
.graphiql-container .docExplorerResizer {
cursor: col-resize;
height: 100%;
left: -5px;
position: absolute;
top: 0;
width: 10px;
z-index: 10;
}
.graphiql-container .docExplorerHide {
cursor: pointer;
font-size: 18px;
margin: -7px -8px -6px 0;
padding: 18px 16px 15px 12px;
}
.graphiql-container div .query-editor {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
position: relative;
}
.graphiql-container .variable-editor {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
height: 29px;
position: relative;
}
.graphiql-container .variable-editor-title {
background: #eeeeee;
border-bottom: 1px solid #d6d6d6;
border-top: 1px solid #e0e0e0;
color: #777;
font-variant: small-caps;
font-weight: bold;
letter-spacing: 1px;
line-height: 14px;
padding: 6px 0 8px 43px;
text-transform: lowercase;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.graphiql-container .codemirrorWrap {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
height: 100%;
position: relative;
}
.graphiql-container .result-window {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
height: 100%;
position: relative;
}
.graphiql-container .footer {
background: #f6f7f8;
border-left: 1px solid #e0e0e0;
border-top: 1px solid #e0e0e0;
margin-left: 12px;
position: relative;
}
.graphiql-container .footer:before {
background: #eeeeee;
bottom: 0;
content: " ";
left: -13px;
position: absolute;
top: -1px;
width: 12px;
}
/* No `.graphiql-container` here so themes can overwrite */
.result-window .CodeMirror {
background: #f6f7f8;
}
.graphiql-container .result-window .CodeMirror-gutters {
background-color: #eeeeee;
border-color: #e0e0e0;
cursor: col-resize;
}
.graphiql-container .result-window .CodeMirror-foldgutter,
.graphiql-container .result-window .CodeMirror-foldgutter-open:after,
.graphiql-container .result-window .CodeMirror-foldgutter-folded:after {
padding-left: 3px;
}
.graphiql-container .toolbar-button {
background: #fdfdfd;
background: -webkit-gradient(linear, left top, left bottom, from(#f9f9f9), to(#ececec));
background: linear-gradient(#f9f9f9, #ececec);
border-radius: 3px;
-webkit-box-shadow:
inset 0 0 0 1px rgba(0,0,0,0.20),
0 1px 0 rgba(255,255,255, 0.7),
inset 0 1px #fff;
box-shadow:
inset 0 0 0 1px rgba(0,0,0,0.20),
0 1px 0 rgba(255,255,255, 0.7),
inset 0 1px #fff;
color: #555;
cursor: pointer;
display: inline-block;
margin: 0 5px;
padding: 3px 11px 5px;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 150px;
}
.graphiql-container .toolbar-button:active {
background: -webkit-gradient(linear, left top, left bottom, from(#ececec), to(#d5d5d5));
background: linear-gradient(#ececec, #d5d5d5);
-webkit-box-shadow:
0 1px 0 rgba(255, 255, 255, 0.7),
inset 0 0 0 1px rgba(0,0,0,0.10),
inset 0 1px 1px 1px rgba(0, 0, 0, 0.12),
inset 0 0 5px rgba(0, 0, 0, 0.1);
box-shadow:
0 1px 0 rgba(255, 255, 255, 0.7),
inset 0 0 0 1px rgba(0,0,0,0.10),
inset 0 1px 1px 1px rgba(0, 0, 0, 0.12),
inset 0 0 5px rgba(0, 0, 0, 0.1);
}
.graphiql-container .toolbar-button.error {
background: -webkit-gradient(linear, left top, left bottom, from(#fdf3f3), to(#e6d6d7));
background: linear-gradient(#fdf3f3, #e6d6d7);
color: #b00;
}
.graphiql-container .toolbar-button-group {
margin: 0 5px;
white-space: nowrap;
}
.graphiql-container .toolbar-button-group > * {
margin: 0;
}
.graphiql-container .toolbar-button-group > *:not(:last-child) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.graphiql-container .toolbar-button-group > *:not(:first-child) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
margin-left: -1px;
}
.graphiql-container .execute-button-wrap {
height: 34px;
margin: 0 14px 0 28px;
position: relative;
}
.graphiql-container .execute-button {
background: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#d2d3d6));
background: linear-gradient(#fdfdfd, #d2d3d6);
border-radius: 17px;
border: 1px solid rgba(0,0,0,0.25);
-webkit-box-shadow: 0 1px 0 #fff;
box-shadow: 0 1px 0 #fff;
cursor: pointer;
fill: #444;
height: 34px;
margin: 0;
padding: 0;
width: 34px;
}
.graphiql-container .execute-button svg {
pointer-events: none;