fix(graphql): load playground from CDN
This commit is contained in:
parent
d52bdd598c
commit
07173401de
3 changed files with 45 additions and 54 deletions
|
@ -1,49 +0,0 @@
|
||||||
import { useExplorerPlugin } from '@graphiql/plugin-explorer';
|
|
||||||
import { createGraphiQLFetcher } from '@graphiql/toolkit';
|
|
||||||
import { GraphiQL } from 'graphiql';
|
|
||||||
import { useState, createElement } from 'react';
|
|
||||||
import { createRoot } from 'react-dom/client';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import 'graphiql/graphiql.css';
|
|
||||||
import '@graphiql/plugin-explorer/dist/style.css';
|
|
||||||
|
|
||||||
declare const window: Window & typeof globalThis & { gon: unknown };
|
|
||||||
const Gon = z.object({
|
|
||||||
defaultQuery: z.string(),
|
|
||||||
defaultVariables: z.string()
|
|
||||||
});
|
|
||||||
const { defaultQuery, defaultVariables } = Gon.parse(window.gon);
|
|
||||||
|
|
||||||
const fetcher = createGraphiQLFetcher({
|
|
||||||
url: '/api/v2/graphql',
|
|
||||||
headers: { 'x-csrf-token': csrfToken() ?? '' }
|
|
||||||
});
|
|
||||||
|
|
||||||
function GraphiQLWithExplorer() {
|
|
||||||
const [query, setQuery] = useState(defaultQuery);
|
|
||||||
const explorerPlugin = useExplorerPlugin({
|
|
||||||
query,
|
|
||||||
onEdit: setQuery
|
|
||||||
});
|
|
||||||
return createElement(GraphiQL, {
|
|
||||||
fetcher,
|
|
||||||
query,
|
|
||||||
variables: defaultVariables,
|
|
||||||
onEditQuery: setQuery,
|
|
||||||
plugins: [explorerPlugin],
|
|
||||||
defaultEditorToolsVisibility: true,
|
|
||||||
isHeadersEditorEnabled: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const container = document.getElementById('graphiql');
|
|
||||||
if (container) {
|
|
||||||
const root = createRoot(container);
|
|
||||||
root.render(createElement(GraphiQLWithExplorer));
|
|
||||||
}
|
|
||||||
|
|
||||||
function csrfToken() {
|
|
||||||
const meta = document.querySelector<HTMLMetaElement>('meta[name=csrf-token]');
|
|
||||||
return meta?.content;
|
|
||||||
}
|
|
|
@ -13,6 +13,13 @@
|
||||||
= favicon_link_tag(image_url("#{FAVICON_32PX_SRC}"), type: "image/png", sizes: "32x32")
|
= favicon_link_tag(image_url("#{FAVICON_32PX_SRC}"), type: "image/png", sizes: "32x32")
|
||||||
= favicon_link_tag(image_url("#{FAVICON_96PX_SRC}"), type: "image/png", sizes: "96x96")
|
= favicon_link_tag(image_url("#{FAVICON_96PX_SRC}"), type: "image/png", sizes: "96x96")
|
||||||
|
|
||||||
|
%link{ rel: "stylesheet", href: "https://unpkg.com/graphiql/graphiql.min.css" }
|
||||||
|
%link{ rel: "stylesheet", href: "https://unpkg.com/@graphiql/plugin-explorer/dist/style.css" }
|
||||||
|
%script{ crossorigin: true, src: "https://unpkg.com/react@17/umd/react.development.js" }
|
||||||
|
%script{ crossorigin: true, src: "https://unpkg.com/react-dom@17/umd/react-dom.development.js" }
|
||||||
|
%script{ crossorigin: true, src: "https://unpkg.com/graphiql/graphiql.min.js" }
|
||||||
|
%script{ crossorigin: true, src: "https://unpkg.com/@graphiql/plugin-explorer/dist/graphiql-plugin-explorer.umd.js" }
|
||||||
|
|
||||||
= Gon::Base.render_data(camel_case: true, init: true, nonce: request.content_security_policy_nonce)
|
= Gon::Base.render_data(camel_case: true, init: true, nonce: request.content_security_policy_nonce)
|
||||||
|
|
||||||
:css
|
:css
|
||||||
|
@ -27,9 +34,42 @@
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
= vite_client_tag
|
|
||||||
= vite_typescript_tag 'playground'
|
|
||||||
|
|
||||||
%body
|
%body
|
||||||
#graphiql
|
#graphiql
|
||||||
Loading...
|
Loading...
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
function csrfToken() {
|
||||||
|
var meta = document.querySelector('meta[name=csrf-token]');
|
||||||
|
return meta && meta.content;
|
||||||
|
}
|
||||||
|
var defaultQuery = window.gon.defaultQuery;
|
||||||
|
var defaultVariables = window.gon.defaultVariables;
|
||||||
|
|
||||||
|
var fetcher = GraphiQL.createFetcher({
|
||||||
|
url: '/api/v2/graphql',
|
||||||
|
headers: { 'x-csrf-token': csrfToken() }
|
||||||
|
});
|
||||||
|
|
||||||
|
function GraphiQLWithExplorer() {
|
||||||
|
var [query, setQuery] = React.useState(defaultQuery);
|
||||||
|
var explorerPlugin = GraphiQLPluginExplorer.useExplorerPlugin({
|
||||||
|
query: query,
|
||||||
|
onEdit: setQuery,
|
||||||
|
});
|
||||||
|
return React.createElement(GraphiQL, {
|
||||||
|
fetcher: fetcher,
|
||||||
|
defaultEditorToolsVisibility: true,
|
||||||
|
plugins: [explorerPlugin],
|
||||||
|
query: query,
|
||||||
|
variables: defaultVariables,
|
||||||
|
onEditQuery: setQuery,
|
||||||
|
defaultEditorToolsVisibility: true,
|
||||||
|
isHeadersEditorEnabled: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
React.createElement(GraphiQLWithExplorer),
|
||||||
|
document.getElementById('graphiql'),
|
||||||
|
);
|
||||||
|
|
|
@ -12,13 +12,13 @@ Rails.application.config.content_security_policy do |policy|
|
||||||
|
|
||||||
# Javascript: allow us, SendInBlue and Matomo.
|
# Javascript: allow us, SendInBlue and Matomo.
|
||||||
# We need unsafe_inline because miniprofiler and us have some inline buttons :(
|
# We need unsafe_inline because miniprofiler and us have some inline buttons :(
|
||||||
scripts_whitelist = ["*.crisp.chat", "crisp.chat", "cdn.jsdelivr.net", "maxcdn.bootstrapcdn.com", "code.jquery.com"]
|
scripts_whitelist = ["*.crisp.chat", "crisp.chat", "cdn.jsdelivr.net", "maxcdn.bootstrapcdn.com", "code.jquery.com", "unpkg.com"]
|
||||||
scripts_whitelist << URI(MATOMO_IFRAME_URL).host if MATOMO_IFRAME_URL.present?
|
scripts_whitelist << URI(MATOMO_IFRAME_URL).host if MATOMO_IFRAME_URL.present?
|
||||||
policy.script_src(:self, :unsafe_eval, :unsafe_inline, :blob, *scripts_whitelist)
|
policy.script_src(:self, :unsafe_eval, :unsafe_inline, :blob, *scripts_whitelist)
|
||||||
|
|
||||||
# CSS: We have a lot of inline style, and some <style> tags.
|
# CSS: We have a lot of inline style, and some <style> tags.
|
||||||
# It's too complicated to be fixed right now (and it wouldn't add value: this is hardcoded in views, so not subject to injections)
|
# It's too complicated to be fixed right now (and it wouldn't add value: this is hardcoded in views, so not subject to injections)
|
||||||
policy.style_src(:self, :unsafe_inline, "*.crisp.chat", "crisp.chat", 'cdn.jsdelivr.net', 'maxcdn.bootstrapcdn.com')
|
policy.style_src(:self, :unsafe_inline, "*.crisp.chat", "crisp.chat", 'cdn.jsdelivr.net', 'maxcdn.bootstrapcdn.com', "unpkg.com")
|
||||||
|
|
||||||
connect_whitelist = ["wss://*.crisp.chat", "*.crisp.chat", "app.franceconnect.gouv.fr", "openmaptiles.geo.data.gouv.fr", "openmaptiles.github.io", "tiles.geo.api.gouv.fr", "wxs.ign.fr"]
|
connect_whitelist = ["wss://*.crisp.chat", "*.crisp.chat", "app.franceconnect.gouv.fr", "openmaptiles.geo.data.gouv.fr", "openmaptiles.github.io", "tiles.geo.api.gouv.fr", "wxs.ign.fr"]
|
||||||
connect_whitelist << ENV.fetch('APP_HOST')
|
connect_whitelist << ENV.fetch('APP_HOST')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue