import React from 'react'; import GraphenePlayground from './GraphenePlayground'; import _ from 'lodash'; const DEFAULT_CACHE_KEY = 'default'; function filterObject(object, callback, context) { if (!object) { return null; } var result = {}; for (var name in object) { if (hasOwnProperty.call(object, name) && callback.call(context, object[name], name, object)) { result[name] = object[name]; } } return result; } class Playground extends React.Component { componentWillMount() { var sourceWasInjected = false; var queryParams = this.context.router.getCurrentQuery(); var { cacheKey, noCache, } = queryParams; noCache = (noCache !== undefined) && (noCache !== 'false'); if (noCache) { cacheKey = undefined; } else if (!cacheKey) { cacheKey = DEFAULT_CACHE_KEY; } this.schemaCacheKey = `rp-${cacheKey}-schema`; this.queryCacheKey = `rp-${cacheKey}-query`; this.cacheKey = cacheKey; var initialSchema; var initialQuery; var storedSchema = localStorage.getItem(this.schemaCacheKey); var storedQuery = localStorage.getItem(this.queryCacheKey); if (noCache) { // Use case #1 // We use the noCache param to force a playground to have certain contents. // eg. static example apps initialSchema = queryParams.schema || ''; initialQuery = queryParams.query || ''; sourceWasInjected = true; queryParams = {}; } else if (cacheKey === DEFAULT_CACHE_KEY) { // Use case #2 // The user loaded the playground without a custom cache key. // Allow code injection via the URL // OR load code from localStorage // OR prime the playground with some default 'hello world' code if (queryParams.schema != null) { initialSchema = queryParams.schema; sourceWasInjected = queryParams.schema !== storedSchema; } else if (storedSchema != null) { initialSchema = storedSchema; } else { initialSchema = require('!raw!./examples/hello.schema.py'); } if (queryParams.query != null) { initialQuery = queryParams.query; sourceWasInjected = queryParams.query !== storedQuery; } else if (storedQuery != null) { initialQuery = storedQuery; } else { initialQuery = require('!raw!./examples/hello.graphql'); } queryParams = filterObject({ schema: queryParams.schema, query: queryParams.query, }, v => v !== undefined); } else if (cacheKey) { // Use case #3 // Custom cache keys are useful in cases where you want to embed a playground // that features both custom boilerplate code AND saves the developer's // progress, without overwriting the default code cache. eg. a tutorial. if (storedSchema != null) { initialSchema = storedSchema; } else { initialSchema = queryParams[`schema_${cacheKey}`]; if (initialSchema != null) { sourceWasInjected = true; } } if (storedQuery != null) { initialQuery = storedQuery; } else { initialQuery = queryParams[`query_${cacheKey}`]; if (initialQuery != null) { sourceWasInjected = true; } } queryParams = {}; } this.changeParams(queryParams); this.state = {initialSchema, initialQuery, sourceWasInjected}; this.queryParams = queryParams; } shouldComponentUpdate() { return false; } changeParams(queryParams) { var router = this.context.router; var routeName = router.getCurrentPathname(); var params = router.getCurrentParams(); queryParams = _.mapValues(queryParams, encodeURIComponent); router.replaceWith(routeName, params, queryParams); } render() { return ( { localStorage.setItem(this.schemaCacheKey, source); if (this.cacheKey === DEFAULT_CACHE_KEY) { this.queryParams.schema = source; if (!this.queryParams.query) { this.queryParams.query = this.state.initialQuery; } this.changeParams(this.queryParams); } }} onEditQuery={(source) => { localStorage.setItem(this.queryCacheKey, source); if (this.cacheKey === DEFAULT_CACHE_KEY) { this.queryParams.query = source; if (!this.queryParams.schema) { this.queryParams.schema = this.state.initialSchema; } this.changeParams(this.queryParams); } }} />); } }; Playground.contextTypes = { router: React.PropTypes.func }; module.exports = Playground;