{% extends "templates/development.njk" %}

{% block title %}GraphiQL{% endblock %}

{% block css %}
{# Include the base development pieces #}
{{ super() }}
<link href="//cdn.jsdelivr.net/npm/graphiql@0.11.11/graphiql.css" rel="stylesheet" />
<style type="text/css">
  html, body {
    height: 100%;
    margin: 0;
    overflow: hidden;
    width: 100%;
  }
  #graphiql {
    position: absolute;
    right: 0;
    left: 0;
    bottom: 0;
    top: 56px;
  }
  *, ::after, ::before {
    box-sizing: inherit;
  }
</style>
{% endblock %}

{% block js %}
<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>
<script src="//cdn.jsdelivr.net/npm/graphiql@0.11.11/graphiql.min.js"></script>
<script type="text/javascript">
  // 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);
  }

  // We don't use safe-serialize for location, because it's not client input.
  var fetchURL = '{{ BASE_URL }}{{ endpointURL }}';

  // Defines a GraphQL fetcher using the fetch API.
  function graphQLFetcher(graphQLParams) {
    var headers = {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    };

    try {
      let token = localStorage.getItem('token');
      if (token) {
        headers['Authorization'] = 'Bearer ' + token;
      }
    } catch (e) {
      console.error(e);
    }

    return fetch(fetchURL, {
      method: 'post',
      headers: headers,
      body: JSON.stringify(graphQLParams),
      credentials: 'include',
    }).then(function (response) {
      return response.text();
    }).then(function (responseBody) {
      try {
        return JSON.parse(responseBody);
      } catch (error) {
        return responseBody;
      }
    });
  }

  // Render <GraphiQL /> into the body.
  ReactDOM.render(
    React.createElement(GraphiQL, {
      fetcher: graphQLFetcher,
      query: parameters.query,
      variables: parameters.variables,
      operationName: parameters.operationName,
      onEditQuery: onEditQuery,
      onEditVariables: onEditVariables,
      onEditOperationName: onEditOperationName
    }),
    document.querySelector("#graphiql")
  );
</script>
{% endblock %}

{% block html %}
<main id="graphiql"></main>
{% endblock %}
