Skip to content

Commit

Permalink
DPLT-975 feat: support for code-exporter (#100)
Browse files Browse the repository at this point in the history
  • Loading branch information
roshaans authored Jun 14, 2023
1 parent 8a21123 commit 841e2ae
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 11 deletions.
8 changes: 4 additions & 4 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@graphiql/plugin-explorer": "^0.1.20",
"@graphiql/plugin-code-exporter": "^0.1.2",
"@monaco-editor/react": "^4.1.3",
"@near-lake/primitives": "0.1.0",
"@next/font": "13.1.6",
Expand All @@ -34,9 +35,8 @@
"typescript": "4.9.5",
"graphiql": "^2.4.1",
"react-bootstrap-icons": "^1.10.3",
"buffer": "^6.0.3"
},
"devDependencies": {
"raw-loader": "^4.0.2"
"buffer": "^6.0.3",
"raw-loader": "^4.0.2",
"regenerator-runtime": "^0.13.11"
}
}
2 changes: 1 addition & 1 deletion frontend/src/components/Editor/ResizableLayoutEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const ResizableEditor = ({

// Render logic based on fileName
const editorComponents = {
GraphiQL: () => <GraphqlPlayground accountId={accountId} />,
GraphiQL: () => <GraphqlPlayground />,
"indexingLogic.js": () =>
diffView ? (
<DiffEditorComponent
Expand Down
91 changes: 86 additions & 5 deletions frontend/src/components/Playground/graphiql.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useContext, useState } from "react";
import GraphiQL from "graphiql";
import { sessionStorage } from "near-social-bridge";
import "graphiql/graphiql.min.css";
import { IndexerDetailsContext } from '../../contexts/IndexerDetailsContext';

import { useExporterPlugin } from '@graphiql/plugin-code-exporter';
import { useExplorerPlugin } from '@graphiql/plugin-explorer';
import '@graphiql/plugin-explorer/dist/style.css';
import "graphiql/graphiql.min.css";
import '@graphiql/plugin-code-exporter/dist/style.css';
import '@graphiql/plugin-explorer/dist/style.css';

const HASURA_ENDPOINT =
process.env.NEXT_PUBLIC_HASURA_ENDPOINT ||
Expand All @@ -25,23 +25,104 @@ const graphQLFetcher = async (graphQLParams, accountId) => {
return await response.json();
};

export const GraphqlPlayground = () => {
const extractQueryName = query => {
const match = query.match(/^[^{(]+\s([^{\s(]+)/);
return match ? match[1] : null;
};

const extractTableName = query => {
const match = query.match(/query\s*\w*\s*{\s*([^({\s]+)/);
return match ? match[1].trim() : null;
};

const bosQuerySnippet = (accountId) => {
return {
name: `BOS Widget`,
language: `JavaScript`,
codeMirrorMode: `jsx`,
options: [],
generate: arg => {
const { operationDataList } = arg;
const { query } = operationDataList[0];
const queryName = extractQueryName(query)
const tableName = extractTableName(query)
const formattedQuery = query.replace(/\n/g, `\n` + ` `.repeat(2));
return `
const QUERYAPI_ENDPOINT = \`${HASURA_ENDPOINT}\`;
State.init({
data: []
});
const query = \`${formattedQuery}\`
function fetchGraphQL(operationsDoc, operationName, variables) {
return asyncFetch(
QUERYAPI_ENDPOINT,
{
method: "POST",
headers: { "x-hasura-role": \`${accountId?.replaceAll(".", "_")}\` },
body: JSON.stringify({
query: operationsDoc,
variables: variables,
operationName: operationName,
}),
}
);
}
fetchGraphQL(query, "${queryName}", {}).then((result) => {
if (result.status === 200) {
if (result.body.data) {
const data = result.body.data.${tableName};
State.update({ data })
console.log(data);
}
}
});
const renderData = (a) => {
return (
<div key={JSON.stringify(a)}>
{JSON.stringify(a)}
</div>
);
};
const renderedData = state.data.map(renderData);
return (
{renderedData}
);`;
}
}
};

export default () => {
const { indexerDetails } = useContext(IndexerDetailsContext);
const snippets = [bosQuerySnippet(indexerDetails.accountId)];
const [query, setQuery] = useState("");

const explorerPlugin = useExplorerPlugin({
query,
onEdit: setQuery,
});
const exporterPlugin = useExporterPlugin({
query,
snippets,
codeMirrorTheme: 'graphiql',
});

return (
<div style={{ width: "100%", height: "75vh" }}>
<GraphiQL
query={query}
onEditQuery={setQuery}
fetcher={(params) => graphQLFetcher(params, indexerDetails.accountId)}
query={query}
onEditQuery={setQuery}
plugins={[explorerPlugin]}
defaultQuery=""
storage={sessionStorage}
theme="dark"
plugins={[explorerPlugin, exporterPlugin]}
/>
</div>
);
Expand Down
15 changes: 14 additions & 1 deletion frontend/src/components/Playground/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
import { GraphqlPlayground } from "./graphiql";
import dynamic from 'next/dynamic';

const DynamicGraphiQLWithExporter = dynamic(
() => import('./graphiql.jsx'),
{ ssr: false } // This will load the component only on client side
);

function GraphqlPlayground({ }) {
return (
<div style={{display: "block", width:"100%"}}>
<DynamicGraphiQLWithExporter />
</div>
);
}

export default GraphqlPlayground;
1 change: 1 addition & 0 deletions frontend/src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
NearSocialBridgeProvider,
} from "near-social-bridge";
import { IndexerDetailsProvider } from '../contexts/IndexerDetailsContext';
import 'regenerator-runtime/runtime';
overrideLocalStorage();

export default function App({ Component, pageProps }: AppProps) {
Expand Down

0 comments on commit 841e2ae

Please sign in to comment.