mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 04:22:01 -06:00
9856 add wrapper to graphiql
This commit is contained in:
parent
371a2a29ca
commit
f456731929
@ -1,6 +1,10 @@
|
||||
import json
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.views import redirect_to_login
|
||||
from django.http import HttpResponseNotFound, HttpResponseForbidden
|
||||
from django.http import HttpResponse
|
||||
from django.template import loader
|
||||
from django.urls import reverse
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from rest_framework.exceptions import AuthenticationFailed
|
||||
@ -42,3 +46,9 @@ class NetBoxGraphQLView(GraphQLView):
|
||||
return HttpResponseForbidden("No credentials provided.")
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def render_graphql_ide(self, request):
|
||||
template = loader.get_template("graphiql.html")
|
||||
context = {"SUBSCRIPTION_ENABLED": json.dumps(self.subscriptions_enabled)}
|
||||
|
||||
return HttpResponse(template.render(context, request))
|
||||
|
@ -474,6 +474,10 @@ STATICFILES_DIRS = (
|
||||
os.path.join(BASE_DIR, 'project-static', 'img'),
|
||||
os.path.join(BASE_DIR, 'project-static', 'js'),
|
||||
('docs', os.path.join(BASE_DIR, 'project-static', 'docs')), # Prefix with /docs
|
||||
# os.path.join(ROOT_DIR, 'node_modules', 'graphiql-explorer'),
|
||||
# os.path.join(ROOT_DIR, 'node_modules', 'react', 'cjs'),
|
||||
# os.path.join(ROOT_DIR, 'node_modules', 'react_dom', 'cjs'),
|
||||
# os.path.join(ROOT_DIR, 'node_modules', 'js-cookie', 'dist'),
|
||||
)
|
||||
|
||||
# Media
|
||||
|
@ -1,5 +1,8 @@
|
||||
const esbuild = require('esbuild');
|
||||
const { sassPlugin } = require('esbuild-sass-plugin');
|
||||
const util = require('util');
|
||||
const fs = require('fs');
|
||||
const copyFilePromise = util.promisify(fs.copyFile);
|
||||
|
||||
// Bundler options common to all bundle jobs.
|
||||
const options = {
|
||||
@ -14,24 +17,49 @@ const options = {
|
||||
// Get CLI arguments for optional overrides.
|
||||
const ARGS = process.argv.slice(2);
|
||||
|
||||
function copyFiles(files) {
|
||||
return Promise.all(files.map(f => {
|
||||
return copyFilePromise(f.source, f.dest);
|
||||
}));
|
||||
}
|
||||
|
||||
async function bundleGraphIQL() {
|
||||
try {
|
||||
const result = await esbuild.build({
|
||||
...options,
|
||||
entryPoints: {
|
||||
graphiql: 'netbox-graphiql/index.ts',
|
||||
},
|
||||
target: 'es2016',
|
||||
define: {
|
||||
global: 'window',
|
||||
},
|
||||
});
|
||||
if (result.errors.length === 0) {
|
||||
console.log(`✅ Bundled source file 'netbox-graphiql/index.ts' to 'graphiql.js'`);
|
||||
fileMap = [
|
||||
{
|
||||
source: './node_modules/react/umd/react.production.min.js',
|
||||
dest: './dist/react.production.min.js'
|
||||
},
|
||||
{
|
||||
source: './node_modules/react-dom/umd/react-dom.production.min.js',
|
||||
dest: './dist/react-dom.production.min.js'
|
||||
},
|
||||
{
|
||||
source: './node_modules/js-cookie/dist/js.cookie.min.js',
|
||||
dest: './dist/js.cookie.min.js'
|
||||
},
|
||||
{
|
||||
source: './node_modules/graphiql/graphiql.min.js',
|
||||
dest: './dist/graphiql.min.js'
|
||||
},
|
||||
{
|
||||
source: './node_modules/@graphiql/plugin-explorer/dist/index.umd.js',
|
||||
dest: './dist/index.umd.js'
|
||||
},
|
||||
{
|
||||
source: './node_modules/graphiql/graphiql.min.css',
|
||||
dest: './dist/graphiql.min.css'
|
||||
},
|
||||
{
|
||||
source: './node_modules/@graphiql/plugin-explorer/dist/style.css',
|
||||
dest: './dist/plugin-explorer-style.css'
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
]
|
||||
|
||||
copyFiles(fileMap).then(() => {
|
||||
console.log('✅ Copied graphiql files');
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,7 +105,6 @@ async function bundleStyles() {
|
||||
'netbox': 'styles/netbox.scss',
|
||||
rack_elevation: 'styles/svg/rack_elevation.scss',
|
||||
cable_trace: 'styles/svg/cable_trace.scss',
|
||||
graphiql: 'netbox-graphiql/graphiql.scss',
|
||||
};
|
||||
const pluginOptions = { outputStyle: 'compressed' };
|
||||
// Allow cache disabling.
|
||||
|
BIN
netbox/project-static/dist/graphiql.css
vendored
BIN
netbox/project-static/dist/graphiql.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/graphiql.min.css
vendored
Normal file
BIN
netbox/project-static/dist/graphiql.min.css
vendored
Normal file
Binary file not shown.
BIN
netbox/project-static/dist/graphiql.min.js
vendored
Normal file
BIN
netbox/project-static/dist/graphiql.min.js
vendored
Normal file
Binary file not shown.
BIN
netbox/project-static/dist/index.umd.js
vendored
Normal file
BIN
netbox/project-static/dist/index.umd.js
vendored
Normal file
Binary file not shown.
BIN
netbox/project-static/dist/js.cookie.min.js
vendored
Normal file
BIN
netbox/project-static/dist/js.cookie.min.js
vendored
Normal file
Binary file not shown.
BIN
netbox/project-static/dist/plugin-explorer-style.css
vendored
Normal file
BIN
netbox/project-static/dist/plugin-explorer-style.css
vendored
Normal file
Binary file not shown.
BIN
netbox/project-static/dist/react-dom.production.min.js
vendored
Normal file
BIN
netbox/project-static/dist/react-dom.production.min.js
vendored
Normal file
Binary file not shown.
BIN
netbox/project-static/dist/react.production.min.js
vendored
Normal file
BIN
netbox/project-static/dist/react.production.min.js
vendored
Normal file
Binary file not shown.
@ -1,3 +0,0 @@
|
||||
// Rather than use CDNs to include GraphiQL dependencies, import and bundle the dependencies so
|
||||
// they can be locally served.
|
||||
@import '../node_modules/graphiql/graphiql.css';
|
@ -1,17 +0,0 @@
|
||||
/**
|
||||
* Rather than use CDNs to include GraphiQL dependencies, import and bundle the dependencies so
|
||||
* they can be locally served.
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import 'graphql';
|
||||
import GraphiQL from 'graphiql';
|
||||
import SubscriptionsTransportWs from 'subscriptions-transport-ws';
|
||||
|
||||
window.React = React;
|
||||
window.ReactDOM = ReactDOM;
|
||||
// @ts-expect-error Assigning to window is required for graphene-django
|
||||
window.SubscriptionsTransportWs = SubscriptionsTransportWs;
|
||||
// @ts-expect-error Assigning to window is required for graphene-django
|
||||
window.GraphiQL = GraphiQL;
|
@ -1,16 +1,17 @@
|
||||
{
|
||||
"name": "netbox-graphiql",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"description": "NetBox GraphiQL Custom Front End",
|
||||
"main": "dist/graphiql.js",
|
||||
"license": "Apache-2.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"graphiql": "1.8.9",
|
||||
"graphql": ">= v14.5.0 <= 15.5.0",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"subscriptions-transport-ws": "0.9.18",
|
||||
"whatwg-fetch": "3.6.2"
|
||||
"graphiql": "3.0.9",
|
||||
"graphql": "16.8.1",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"js-cookie": "3.0.5",
|
||||
"@graphiql/plugin-explorer": "1.0.2"
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{% comment %}
|
||||
This template derives from the graphene-django project:
|
||||
https://github.com/graphql-python/graphene-django/blob/main/graphene_django/templates/graphene/graphiql.html
|
||||
This template derives from the strawberry-graphql project:
|
||||
https://github.com/strawberry-graphql/strawberry/blob/main/strawberry/static/graphiql.html
|
||||
{% endcomment %}
|
||||
<!--
|
||||
The request to this GraphQL server provided the header "Accept: text/html"
|
||||
@ -11,36 +11,130 @@ add "&raw" to the end of the URL within a browser.
|
||||
-->
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<title>GraphiQL | NetBox</title>
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml,
|
||||
<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22>
|
||||
<!-- Strawberry Emoji as a HTML Entity (hex) -->
|
||||
<text y=%22.9em%22 font-size=%2280%22>🍓</text>
|
||||
</svg>"
|
||||
/>
|
||||
<style>
|
||||
html, body, #editor {
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#graphiql {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.docExplorerHide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.doc-explorer-contents {
|
||||
overflow-y: hidden !important;
|
||||
}
|
||||
|
||||
.docExplorerWrap {
|
||||
width: unset !important;
|
||||
min-width: unset !important;
|
||||
}
|
||||
|
||||
.graphiql-explorer-actions select {
|
||||
margin-left: 4px;
|
||||
}
|
||||
</style>
|
||||
<link href="{% static 'graphiql.css'%}" rel="stylesheet" />
|
||||
<link rel="icon" type="image/png" href="{% static 'graphql.ico' %}" />
|
||||
<title>GraphiQL | NetBox</title>
|
||||
|
||||
<script src="{% static 'react.production.min.js' %}"></script>
|
||||
<script src="{% static 'react-dom.production.min.js' %}"></script>
|
||||
<script src="{% static 'js.cookie.min.js' %}"></script>
|
||||
|
||||
<link rel="stylesheet" href="{% static 'graphiql.min.css' %}"/>
|
||||
<link rel="stylesheet" href="{% static 'plugin-explorer-style.css' %}"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="editor"></div>
|
||||
{% csrf_token %}
|
||||
<script type="application/javascript">
|
||||
window.GRAPHENE_SETTINGS = {
|
||||
{% if subscription_path %}
|
||||
subscriptionPath: "{{subscription_path}}",
|
||||
{% endif %}
|
||||
graphiqlHeaderEditorEnabled: {{ graphiql_header_editor_enabled|yesno:"true,false" }},
|
||||
};
|
||||
<div id="graphiql" class="graphiql-container">Loading...</div>
|
||||
<script src="{% static 'graphiql.min.js' %}"></script>
|
||||
<script src="{% static 'index.umd.js' %}"></script>
|
||||
|
||||
<script>
|
||||
const EXAMPLE_QUERY = `# Welcome to GraphiQL 🍓
|
||||
#
|
||||
# GraphiQL is an in-browser tool for writing, validating, and
|
||||
# testing GraphQL queries.
|
||||
#
|
||||
# Type queries into this side of the screen, and you will see intelligent
|
||||
# typeaheads aware of the current GraphQL type schema and live syntax and
|
||||
# validation errors highlighted within the text.
|
||||
#
|
||||
# GraphQL queries typically start with a "{" character. Lines that starts
|
||||
# with a # are ignored.
|
||||
#
|
||||
# An example GraphQL query might look like:
|
||||
#
|
||||
# {
|
||||
# field(arg: "value") {
|
||||
# subField
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# Keyboard shortcuts:
|
||||
#
|
||||
# Run Query: Ctrl-Enter (or press the play button above)
|
||||
#
|
||||
# Auto Complete: Ctrl-Space (or just start typing)
|
||||
#
|
||||
`;
|
||||
|
||||
const fetchURL = window.location.href;
|
||||
|
||||
function httpUrlToWebSockeUrl(url) {
|
||||
const parsedURL = new URL(url);
|
||||
const protocol = parsedURL.protocol === "http:" ? "ws:" : "wss:";
|
||||
parsedURL.protocol = protocol;
|
||||
parsedURL.hash = "";
|
||||
return parsedURL.toString();
|
||||
}
|
||||
|
||||
const headers = {};
|
||||
const csrfToken = Cookies.get("csrftoken");
|
||||
|
||||
if (csrfToken) {
|
||||
headers["x-csrftoken"] = csrfToken;
|
||||
}
|
||||
|
||||
const subscriptionsEnabled = JSON.parse("{{ SUBSCRIPTION_ENABLED }}");
|
||||
const subscriptionUrl = subscriptionsEnabled
|
||||
? httpUrlToWebSockeUrl(fetchURL)
|
||||
: null;
|
||||
|
||||
const fetcher = GraphiQL.createFetcher({
|
||||
url: fetchURL,
|
||||
headers: headers,
|
||||
subscriptionUrl,
|
||||
});
|
||||
|
||||
const explorerPlugin = GraphiQLPluginExplorer.explorerPlugin();
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById("graphiql"));
|
||||
|
||||
root.render(
|
||||
React.createElement(GraphiQL, {
|
||||
fetcher: fetcher,
|
||||
defaultEditorToolsVisibility: true,
|
||||
plugins: [explorerPlugin],
|
||||
inputValueDeprecation: true,
|
||||
}),
|
||||
);
|
||||
</script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="{% static 'graphiql.js' %}"
|
||||
onerror="window.location='{% url 'media_failure' %}?filename=graphiql.js'">
|
||||
</script>
|
||||
<script src="{% static 'graphene_django/graphiql.js' %}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user