<!--
The request to this GraphQL server provided the header "Accept: text/html"
and as a result has been presented GraphiQL - an in-browser IDE for
exploring GraphQL.
If you wish to receive JSON, provide the header "Accept: application/json" or
add "&raw" to the end of the URL within a browser.
-->
{% load static %}
{% load helpers %}
<!DOCTYPE html>
<html>
<head>
  <!-- Nautobot template requirements -->
  <title>{% block title %}GraphiQL{% endblock %} - {{ settings.BRANDING_TITLE }}</title>
  <link rel="stylesheet"
        href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}"
        onerror="window.location='{% url 'media_failure' %}?filename=bootstrap-3.4.1-dist/css/bootstrap.min.css'">
  <link rel="stylesheet"
        href="{% static 'materialdesignicons-6.5.95/css/materialdesignicons.min.css' %}"
        onerror="window.location='{% url 'media_failure' %}?filename=materialdesignicons-6.5.95/css/materialdesignicons.min.css'">
  <link rel="stylesheet"
        href="{% static 'jquery-ui-1.13.1/jquery-ui.min.css' %}"
        onerror="window.location='{% url 'media_failure' %}?filename=jquery-ui-1.13.1/jquery-ui.min.css'">
  <link rel="stylesheet"
        href="{% static 'select2-4.0.13/select2.min.css' %}"
        onerror="window.location='{% url 'media_failure' %}?filename=select2-4.0.13/select2.min.css'">
  <link rel="stylesheet"
        href="{% static 'select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css' %}"
        onerror="window.location='{% url 'media_failure' %}?filename=select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css'">
  <link rel="stylesheet"
        href="{% static 'flatpickr-4.6.9/themes/light.min.css' %}"
        onerror="window.location='{% url 'media_failure' %}?filename=flatpickr-4.6.9/themes/light.min.css'">
  <link rel="stylesheet" id="dark-theme"
        href="{% versioned_static 'css/dark.css' %}"
        onerror="window.location='{% url 'media_failure' %}?filename=css/dark.css'" disabled="disabled" />
  <link rel="stylesheet"
        href="{% versioned_static 'css/base.css' %}"
        onerror="window.location='{% url 'media_failure' %}?filename=css/base.css'">
  <link rel="apple-touch-icon" sizes="180x180" href="{% custom_branding_or_static 'icon_180' 'img/nautobot_icon_180x180.png' %}">
  <link rel="icon" type="image/png" sizes="32x32" href="{% custom_branding_or_static 'icon_32' 'img/nautobot_icon_32x32.png' %}">
  <link rel="icon" type="image/png" sizes="16x16" href="{% custom_branding_or_static 'icon_16' 'img/nautobot_icon_16x16.png' %}">
  <link rel="icon" type="image/png" sizes="192x192" href="{% custom_branding_or_static 'icon_192' 'img/nautobot_icon_192x192.png' %}">
  <link rel="mask-icon" type="image/png" color="#0097ff" href="{% custom_branding_or_static 'icon_mask' 'img/nautobot_icon_monochrome.png' %}">
  <link rel="shortcut icon" href="{% custom_branding_or_static 'favicon' 'img/favicon.ico' %}">
  <meta name="msapplication-TileColor" content="#2d89ef">
  <meta name="theme-color" content="#ffffff">
  <meta charset="UTF-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
  <!-- GraphiQL template requirements -->
  <style>
    html, body, #editor {
      height: 100%;
      margin: 0;
      width: 100%;
    }
    .toolbar .dropdown-menu > li > a {
        clear: left;
        margin-right: 120px;  /* leave room for the "Save Changes" button if present */
    }
  </style>
  <!-- As Nautobot may be run without internet access, we source these files locally rather than from an online CDN -->
  <link rel="stylesheet"
        href="{% static 'graphiql-1.5.16/graphiql.min.css' %}"
        onerror="window.location='{% url 'media_failure' %}?filename=graphiql-1.5.16/graphiql.min.css'">
  <script src="{% static 'whatwg-fetch-3.6.2/fetch.umd.min.js' %}"
      onerror="window.location='{% url 'media_failure' %}?filename=whatwg-fetch-3.6.2/fetch.umd.min.js'"></script>
  <script src="{% static 'react-16.14.0/react.production.min.js' %}"
          onerror="window.location='{% url 'media_failure' %}?filename=react-16.14.0/react.production.min.js'"></script>
  <script src="{% static 'react-dom-16.14.0/react-dom.production.min.js' %}"
          onerror="window.location='{% url 'media_failure' %}?filename=react-dom-16.14.0/react-dom.production.min.js'"></script>
  <script src="{% static 'graphiql-1.5.16/graphiql.min.js' %}"
          onerror="window.location='{% url 'media_failure' %}?filename=graphiql-1.5.16/graphiql.min.js'"></script>
  <script src="{% static 'subscriptions-transport-ws-0.9.18/client.min.js' %}"
      onerror="window.location='{% url 'media_failure' %}?filename=subscriptions-transport-ws-0.9.18/client.min.js'"></script>
  <!-- Custom CSS to address some conflicts between the two -->
  <style>
    body {
      padding-top: 54px;
    }
    .graphiql-container .doc-explorer-title-bar {
        box-sizing: content-box;
    }
  </style>
</head>
<body>
  <!-- Nautobot page contents -->
  {% include 'inc/nav_menu.html' %}
  {% include 'modals/modal_theme.html' with name='theme'%}
  {% include 'inc/javascript.html' %}
  <!-- GraphiQL page contents -->
  <div id="editor"></div>
  {% include 'inc/footer.html' %}
  {% csrf_token %}
  <script type="application/javascript">
    window.GRAPHENE_SETTINGS = {
    {% if subscription_path %}
      subscriptionPath: "{{subscription_path}}",
    {% endif %}
      graphiqlHeaderEditorEnabled: {{ graphiql_header_editor_enabled|yesno:"true,false" }},
    };
  </script>
  <script src="{% static 'graphene_django/graphiql.js' %}"></script>
  <script>
  {% if perms.extras.view_graphqlquery %}
    document.addEventListener('DOMContentLoaded', function() {
      queries_tab = `
        <div class="btn-group" role="button">
          <button class="toolbar-button dropdown-toggle" aria-haspopup="true" aria-expanded="false" data-toggle="dropdown">
              <span>Queries </span>
              <span class="caret"></span>
          </button>
          <ul class="dropdown-menu" id="graphql-queries-menu">
            <li class="dropdown-header">Saved Queries</li>
              {% for query in saved_graphiql_queries %}
                <li>
                    {% if request.GET.id|slugify == query.id|slugify %}
                        <div class="buttons pull-right">
                            <a class="btn btn-xs btn-warning" onclick="save()"><i class="mdi mdi-content-save-edit"></i> Save Changes</a>
                        </div>
                        <a href="#" onclick="reload('{{ query.id }}', '{{ query.query|urlencode }}', '{{ query.variables|render_json|urlencode }}')">
                            <strong>{{ query.name }}</strong>
                        </a>
                    {% else %}
                        <a href="#" onclick="reload('{{ query.id }}', '{{ query.query|urlencode }}', '{{ query.variables|render_json|urlencode }}')">{{ query.name }}</a>
                    {% endif %}
                </li>
              {% endfor %}
              <li class="divider" role="separator"></li>
                <li>
                    <a onclick="populate_model()" data-toggle="modal" data-target="#GraphQLQueries_form" title="Query Form">Save Current Query As...</a>
                </li>
            </ul>
        </div>
      `
      $(".toolbar").append(queries_tab);
    }, false);
  {% endif %}

    function reload(id, query, variables) {
      if (variables == null){
          variables = '{}';
      }
      window.location.replace("#");
      window.location.hash = 'query=' + query + "&variables=" + variables;

      search = new URLSearchParams(location.search);
      search.set('id', id);
      location.search = search.toString();
    }

    function getHashParams() {
      // Retrieve fragments (# params) from URL
      // All fragments are converted into a JSON object
      // To modify the GraphiQL termial, hash fragments in the URL need to be set,
      // this then adds text to the query, vairable and output text boxes in the UI.
      var hashParams = {};
      var matches,
          re_match_plus = /\+/g,  // Regex for replacing addition symbol with a space
          re_match_query_param_and_value = /([^&;=]+)=?([^&;]*)/g,
          decode_and_replace_plus_with_space = function (s) { return decodeURIComponent(s.replace(re_match_plus, " ")); },
          query_text = window.location.hash.substring(1);

      while (matches = re_match_query_param_and_value.exec(query_text))
        hashParams[decode_and_replace_plus_with_space(matches[1])] = decode_and_replace_plus_with_space(matches[2]);

      return hashParams;
    }

    function save() {
      var url = new URL(window.location.href);
      var id = url.searchParams.get("id");
      var result_window = $(".result-window").find(".CodeMirror-code");
      if (!id) {
        var html = `
<pre class="CodeMirror-code">
  <span role="presentation" style="padding-right: 0.1px">
    <span class="cm-def">Unable to find query ID.</span>
  </span>
</pre>
        `;
        result_window.html(html);
        return
      };

      var graphql_data = JSON.stringify({"query": getHashParams().query});

      $.ajax({
        url: `{% url 'extras-api:graphqlquery-list' %}${id}/`,
        method: "PATCH",
        headers: {"X-CSRFTOKEN": "{{ csrf_token }}"},
        contentType: "application/json",
        dataType: "json",
        data: graphql_data,
        success: function(data) {
            data = JSON.stringify(data, undefined, 2).split("\n");
            var html = `<pre class="CodeMirror-code"><span role="presentation" style="padding-right: 0.1px"><span class="cm-property">Success:</span></span></pre>`;
            for(var i = 0;i < data.length;i++){
              html += `<pre class="CodeMirror-code"><span role="presentation" style="padding-right: 0.1px"><span class="cm-property">${data[i]}</span></span></pre>`;
            };
            result_window.html(html);
        },
        error: function(error) {
            error = JSON.stringify(error, undefined, 2).split("\n");
            var html = `<pre class="CodeMirror-code"><span role="presentation" style="padding-right: 0.1px"><span class="cm-def">Failure:</span></span></pre>`;
            for(var i = 0;i < error.length;i++){
              html += `<pre class="CodeMirror-code"><span role="presentation" style="padding-right: 0.1px"><span class="cm-def">${error[i]}</span></span></pre>`;
            };
            result_window.html(html);
        }
      });
    }

    function populate_model() {
      query = getHashParams().query;
      model_query = $("#id_query");
      model_query.val(query);
    }

  </script>
  {% modal_form_as_dialog form editing=editing form_name="GraphQLQueries" obj=obj obj_type="GraphQLQueries" %}
</body>
</html>
