Add graphiql-explorer to canvas' graphiql instance
The graphiql-explorer makes it easy to explore the schema and build queries simply by checking the boxes next to fields from the schema test plan: - /graphiql still works as expected, but includes the explorer panel - canvas features that leverage graphql still work as expected (since the version of the graphql js client was updated) Change-Id: Ief625c6fb59e4e32e23a177f3b566aae271ab108 Reviewed-on: https://gerrit.instructure.com/181586 Tested-by: Jenkins Reviewed-by: Carl Kibler <ckibler@instructure.com> QA-Review: Carl Kibler <ckibler@instructure.com> Product-Review: Ed Schiebel <eschiebel@instructure.com>
This commit is contained in:
parent
df1e123392
commit
0f6321312c
|
@ -18,18 +18,6 @@
|
|||
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import GraphiQL from 'graphiql'
|
||||
import axios from 'axios'
|
||||
import 'graphiql/graphiql.css'
|
||||
import GraphiQLApp from '../graphiql/GraphiQLApp'
|
||||
|
||||
function fetcher (params) {
|
||||
return axios.post(
|
||||
'/api/graphql',
|
||||
JSON.stringify(params),
|
||||
{
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
}
|
||||
).then(({data}) => data)
|
||||
}
|
||||
|
||||
ReactDOM.render(<GraphiQL fetcher={fetcher} />, document.getElementById('graphiql'))
|
||||
ReactDOM.render(<GraphiQLApp/>, document.getElementById('graphiql'))
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2018 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import GraphiQLExplorer from 'graphiql-explorer';
|
||||
|
||||
// makeDefaultArg and getDefulatScalarArgValue
|
||||
// are used to fill in the default argument for
|
||||
// fields that require one. To see a more complete
|
||||
// implementation, should we decide to do something
|
||||
// more deluxe, see
|
||||
// https://github.com/OneGraph/graphiql-explorer-example/blob/master/src/CustomArgs.js
|
||||
|
||||
export function makeDefaultArg(_parentField, _arg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getDefaultScalarArgValue(parentField, arg, argType) {
|
||||
// so there's a good chance we get something, or nothing,
|
||||
// but probably not an error
|
||||
if (argType.name === 'ID') {
|
||||
return {kind: 'StringValue', value: '1'}
|
||||
}
|
||||
return GraphiQLExplorer.defaultValue(argType);
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright (C) 2018 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
import GraphiQL from 'graphiql'
|
||||
import GraphiQLExplorer from 'graphiql-explorer'
|
||||
import {getIntrospectionQuery, buildClientSchema} from 'graphql';
|
||||
import axios from 'axios'
|
||||
import 'graphiql/graphiql.css'
|
||||
import {makeDefaultArg, getDefaultScalarArgValue} from './CustomArgs';
|
||||
import StorageAPI from 'graphiql/dist/utility/StorageAPI'
|
||||
|
||||
function fetcher (params) {
|
||||
return axios.post(
|
||||
'/api/graphql',
|
||||
JSON.stringify(params),
|
||||
{
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
}
|
||||
).then(({data}) => data)
|
||||
}
|
||||
|
||||
const DEFAULT_QUERY = `{
|
||||
allCourses {
|
||||
_id,
|
||||
name
|
||||
}
|
||||
}`
|
||||
|
||||
export default class GraphiQLApp extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this._graphql = null
|
||||
this._storage = new StorageAPI()
|
||||
|
||||
// "true" or missing => open. explicit "false" => closed
|
||||
const explorerPaneOpen = this._storage.get('explorerPaneOpen') !== 'false'
|
||||
|
||||
this.state = {
|
||||
schema: null,
|
||||
query: DEFAULT_QUERY,
|
||||
explorerIsOpen: explorerPaneOpen
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
return fetcher({
|
||||
query: getIntrospectionQuery(),
|
||||
}).then(result => {
|
||||
this.setState({
|
||||
schema: buildClientSchema(result.data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_handleEditQuery = (query) => {
|
||||
this.setState({query})
|
||||
}
|
||||
|
||||
_handleToggleExplorer = () => {
|
||||
this.setState((state, _props) => {
|
||||
const isOpen = !state.explorerIsOpen
|
||||
this._storage.set('explorerPaneOpen', isOpen.toString())
|
||||
return {explorerIsOpen: isOpen}
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const {query, schema, explorerIsOpen} = this.state
|
||||
|
||||
return (
|
||||
<div className="graphiql-container">
|
||||
<GraphiQLExplorer
|
||||
schema={schema}
|
||||
query={query}
|
||||
onEdit={this._handleEditQuery}
|
||||
explorerIsOpen={explorerIsOpen}
|
||||
onToggleExplorer={this._handleToggleExplorer}
|
||||
getDefaultScalarArgValue={getDefaultScalarArgValue}
|
||||
makeDefaultArg={makeDefaultArg}
|
||||
/>
|
||||
<GraphiQL
|
||||
ref={ref => {this._graphiql = ref}}
|
||||
fetcher={fetcher}
|
||||
schema={schema}
|
||||
query={query}
|
||||
onEditQuery={this._handleEditQuery}
|
||||
>
|
||||
<GraphiQL.Toolbar>
|
||||
<GraphiQL.Button
|
||||
onClick={() => this._graphiql.handlePrettifyQuery()}
|
||||
label="Prettify"
|
||||
title="Prettify Query (Shift-Ctrl-P)"
|
||||
/>
|
||||
<GraphiQL.Button
|
||||
onClick={() => this._graphiql.handleToggleHistory()}
|
||||
label="History"
|
||||
title="Show History"
|
||||
/>
|
||||
<GraphiQL.Button
|
||||
onClick={this._handleToggleExplorer}
|
||||
label="Explorer"
|
||||
title="Toggle Explorer"
|
||||
/>
|
||||
</GraphiQL.Toolbar>
|
||||
</GraphiQL>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -63,7 +63,8 @@
|
|||
"formdata-polyfill": "^3.0.9",
|
||||
"fullcalendar": "https://github.com/instructure/fullcalendar.git#1108dd1c991a029ec6fd7de3337737ec5295ba97",
|
||||
"graphiql": "^0.11.2",
|
||||
"graphql": "^0.13.2",
|
||||
"graphiql-explorer": "^0.3.6",
|
||||
"graphql": "^14",
|
||||
"graphql-tag": "^2.8.0",
|
||||
"i18n-js": "^3",
|
||||
"ic-ajax": "~2.0.1",
|
||||
|
|
17
yarn.lock
17
yarn.lock
|
@ -8914,6 +8914,11 @@ graceful-fs@~2.0.3:
|
|||
dependencies:
|
||||
raphael "^2.1.4"
|
||||
|
||||
graphiql-explorer@^0.3.6:
|
||||
version "0.3.6"
|
||||
resolved "https://registry.yarnpkg.com/graphiql-explorer/-/graphiql-explorer-0.3.6.tgz#4696815ba81e63d6bdaf9962427038db44cec0d7"
|
||||
integrity sha512-jTPtwxPaZUjZ6zlFIfbdpLTnPj80/FUFBC9Ij19DUIZ3OfL4E+27dMF5UdYLP+7vpqZixCcT4bP611XZlvYIxg==
|
||||
|
||||
graphiql@^0.11.2:
|
||||
version "0.11.11"
|
||||
resolved "https://registry.yarnpkg.com/graphiql/-/graphiql-0.11.11.tgz#eeaf9a38927dbe8c6ecbf81e700735e16ec50e71"
|
||||
|
@ -9005,12 +9010,12 @@ graphql-tag@^2.8.0:
|
|||
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae"
|
||||
integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w==
|
||||
|
||||
graphql@^0.13.2:
|
||||
version "0.13.2"
|
||||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270"
|
||||
integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog==
|
||||
graphql@^14:
|
||||
version "14.1.1"
|
||||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.1.1.tgz#d5d77df4b19ef41538d7215d1e7a28834619fac0"
|
||||
integrity sha512-C5zDzLqvfPAgTtP8AUPIt9keDabrdRAqSWjj2OPRKrKxI9Fb65I36s1uCs1UUBFnSWTdO7hyHi7z1ZbwKMKF6Q==
|
||||
dependencies:
|
||||
iterall "^1.2.1"
|
||||
iterall "^1.2.2"
|
||||
|
||||
growl@1.10.5:
|
||||
version "1.10.5"
|
||||
|
@ -10922,7 +10927,7 @@ istanbul@^0.4.0:
|
|||
which "^1.1.1"
|
||||
wordwrap "^1.0.0"
|
||||
|
||||
iterall@^1.2.1:
|
||||
iterall@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7"
|
||||
integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==
|
||||
|
|
Loading…
Reference in New Issue