From 3a0e681eef99cd3ed4df3ce8ea50c073d3e8586c Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Thu, 7 Mar 2024 15:12:34 -0700 Subject: [PATCH 1/4] - initial work on explorer plugin --- package-lock.json | 33 +++++++++++++++++-- package.json | 3 ++ plugins/query-composer/README.md | 7 ++++ .../components/QueryComposer.js | 7 ++++ plugins/query-composer/index.js | 19 +++++++++++ plugins/query-composer/query-composer.php | 33 +++++++++++++++++++ src/components/Editor.jsx | 1 + webpack.config.js | 1 + wpgraphql-ide.php | 3 +- 9 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 plugins/query-composer/README.md create mode 100644 plugins/query-composer/components/QueryComposer.js create mode 100644 plugins/query-composer/index.js create mode 100644 plugins/query-composer/query-composer.php diff --git a/package-lock.json b/package-lock.json index aeaf1e0..9db4e74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,9 @@ "packages": { "": { "dependencies": { + "@graphiql/plugin-explorer": "^1.0.3", + "@graphiql/react": "^0.20.3", + "@graphiql/toolkit": "^0.9.1", "@wordpress/components": "^27.0.0", "@wordpress/data": "^9.22.0", "@wordpress/element": "^5.23.0", @@ -2343,9 +2346,34 @@ "version": "0.2.1", "license": "MIT" }, + "node_modules/@graphiql/plugin-explorer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@graphiql/plugin-explorer/-/plugin-explorer-1.0.3.tgz", + "integrity": "sha512-dKgdNXut/CaxfU8lcFDi1Jb/5f7NnCHa62E7xlNUNYRzieZ7+Bka0rvspgxzXPYevviigzmrtPGtHd5SeaZ57g==", + "dependencies": { + "graphiql-explorer": "^0.9.0" + }, + "peerDependencies": { + "@graphiql/react": "^0.20.3", + "graphql": "^15.5.0 || ^16.0.0", + "react": "^16.8.0 || ^17 || ^18", + "react-dom": "^16.8.0 || ^17 || ^18" + } + }, + "node_modules/@graphiql/plugin-explorer/node_modules/graphiql-explorer": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/graphiql-explorer/-/graphiql-explorer-0.9.0.tgz", + "integrity": "sha512-fZC/wsuatqiQDO2otchxriFO0LaWIo/ovF/CQJ1yOudmY0P7pzDiP+l9CEHUiWbizk3e99x6DQG4XG1VxA+d6A==", + "peerDependencies": { + "graphql": "^0.6.0 || ^0.7.0 || ^0.8.0-b || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0", + "react": "^15.6.0 || ^16.0.0", + "react-dom": "^15.6.0 || ^16.0.0" + } + }, "node_modules/@graphiql/react": { "version": "0.20.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.20.3.tgz", + "integrity": "sha512-LHEiWQPABflTyRJZBZB50WSlrWER4RtlWg9XV1+D4yZQ3+6GbLM7X1zYf4D/TQ6AJB/vLZQHEnbhS0LuKcNqfA==", "dependencies": { "@graphiql/toolkit": "^0.9.1", "@headlessui/react": "^1.7.15", @@ -2378,7 +2406,8 @@ }, "node_modules/@graphiql/toolkit": { "version": "0.9.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.9.1.tgz", + "integrity": "sha512-LVt9pdk0830so50ZnU2Znb2rclcoWznG8r8asqAENzV0U1FM1kuY0sdPpc/rBc9MmmNgnB6A+WZzDhq6dbhTHA==", "dependencies": { "@n1ru4l/push-pull-async-iterable-iterator": "^3.1.0", "meros": "^1.1.4" diff --git a/package.json b/package.json index 96580fd..d6335f7 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,9 @@ "sort-package-json": "^2.7.0" }, "dependencies": { + "@graphiql/plugin-explorer": "^1.0.3", + "@graphiql/react": "^0.20.3", + "@graphiql/toolkit": "^0.9.1", "@wordpress/components": "^27.0.0", "@wordpress/data": "^9.22.0", "@wordpress/element": "^5.23.0", diff --git a/plugins/query-composer/README.md b/plugins/query-composer/README.md new file mode 100644 index 0000000..ade32c8 --- /dev/null +++ b/plugins/query-composer/README.md @@ -0,0 +1,7 @@ +# Query Composer + +The Query Composer is a tool that allows users to view fields in the GraphQL Schema +and compose queries by clicking on the fields they want to query for. + +Additionally, fields that accept input (i.e. connections, mutations, etc) provide UIs to enter the input. + diff --git a/plugins/query-composer/components/QueryComposer.js b/plugins/query-composer/components/QueryComposer.js new file mode 100644 index 0000000..b1f9ef3 --- /dev/null +++ b/plugins/query-composer/components/QueryComposer.js @@ -0,0 +1,7 @@ +export const QueryComposer = () => { + return ( + <> +

Query Composer...

+ + ) +} diff --git a/plugins/query-composer/index.js b/plugins/query-composer/index.js new file mode 100644 index 0000000..cd430a9 --- /dev/null +++ b/plugins/query-composer/index.js @@ -0,0 +1,19 @@ +import { registerPlugin } from 'wpgraphql-ide'; +import { explorerPlugin } from "@graphiql/plugin-explorer"; +import { Icon, pencil } from '@wordpress/icons'; +import { QueryComposer } from './components/QueryComposer' + + +registerPlugin( 'queryComposer', { + title: 'Query Composer', + icon: () => ( + + ), + content: () => +} ); + diff --git a/plugins/query-composer/query-composer.php b/plugins/query-composer/query-composer.php new file mode 100644 index 0000000..0fbb2d3 --- /dev/null +++ b/plugins/query-composer/query-composer.php @@ -0,0 +1,33 @@ + '#', ] ); - } + } } add_action( 'admin_bar_menu', __NAMESPACE__ . '\\register_wpadminbar_menus', 999 ); From 83e51623f9144054ebe957ae778bcb5dc957a889 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 8 Mar 2024 12:09:39 -0700 Subject: [PATCH 2/4] - showing the explorerPlugin() not working as a 3rd party extension --- plugins/query-composer/index.js | 34 +++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/plugins/query-composer/index.js b/plugins/query-composer/index.js index cd430a9..dae9562 100644 --- a/plugins/query-composer/index.js +++ b/plugins/query-composer/index.js @@ -1,19 +1,29 @@ import { registerPlugin } from 'wpgraphql-ide'; +import { addAction } from '@wordpress/hooks'; import { explorerPlugin } from "@graphiql/plugin-explorer"; + import { Icon, pencil } from '@wordpress/icons'; import { QueryComposer } from './components/QueryComposer' -registerPlugin( 'queryComposer', { - title: 'Query Composer', - icon: () => ( - - ), - content: () => -} ); +// registerPlugin( 'queryComposer', { +// title: 'Query Composer', +// icon: () => ( +// +// ), +// content: () => +// } ); + +addAction( 'wpgraphqlide_rendered', 'wpgraphql-ide-query-composer',() => { + console.log({ + wpgraphqlide_rendered: true + }) + registerPlugin( 'queryComposer', explorerPlugin() ); +}); + From f738b405ced484b69572afa7d370247797260ee8 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 8 Mar 2024 15:43:43 -0700 Subject: [PATCH 3/4] - another attempt at plugging in via 3rd party --- plugins/query-composer/index.js | 26 +++++++++++++++++++------- src/components/Editor.jsx | 6 +++++- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/plugins/query-composer/index.js b/plugins/query-composer/index.js index dae9562..5320fe0 100644 --- a/plugins/query-composer/index.js +++ b/plugins/query-composer/index.js @@ -1,5 +1,5 @@ import { registerPlugin } from 'wpgraphql-ide'; -import { addAction } from '@wordpress/hooks'; +import {addAction, addFilter} from '@wordpress/hooks'; import { explorerPlugin } from "@graphiql/plugin-explorer"; import { Icon, pencil } from '@wordpress/icons'; @@ -19,11 +19,23 @@ import { QueryComposer } from './components/QueryComposer' // content: () => // } ); -addAction( 'wpgraphqlide_rendered', 'wpgraphql-ide-query-composer',() => { - console.log({ - wpgraphqlide_rendered: true - }) - registerPlugin( 'queryComposer', explorerPlugin() ); -}); +// addAction( 'wpgraphqlide_rendered', 'wpgraphql-ide-query-composer',() => { +// console.log({ +// wpgraphqlide_rendered: true +// }) +// registerPlugin( 'queryComposer', explorerPlugin() ); +// }); + + + +addFilter( 'wpgraphqlide_plugins', 'wpgraphql-ide-query-composer', (plugins) => { + const explorer = explorerPlugin(); + console.log( { pluginsBefore: plugins }) + if ( ! plugins.includes( explorer ) ) { + plugins.push(explorer) + console.log({pluginsAfter: plugins}) + } + return plugins; +}) diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index fba198e..480f93b 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -3,6 +3,8 @@ import React from 'react'; import { GraphiQL } from 'graphiql'; import { useDispatch, useSelect } from '@wordpress/data'; import { applyFilters } from '@wordpress/hooks'; +import { useEffect } from '@wordpress/element' + import { explorerPlugin } from "@graphiql/plugin-explorer"; import { PrettifyButton } from './toolbarButtons/PrettifyButton'; @@ -51,12 +53,14 @@ export function Editor() { const { setDrawerOpen, setQuery } = useDispatch( 'wpgraphql-ide' ); + const activePlugins = applyFilters( 'wpgraphqlide_plugins', [] ); + return ( setQuery( query ) } - plugins={ plugins.length > 0 ? plugins : null } + plugins={ activePlugins } > { Object.entries( toolbarButtons ).map( ( [ key, Button ] ) => ( From 8e197a82d9324416426241bad6f652805725a0f8 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Mon, 11 Mar 2024 08:52:54 -0600 Subject: [PATCH 4/4] - attempt at configuring webpack externals so that the query composer plugin importing from GraphiQL uses the same --- plugins/query-composer/index.js | 50 +++++++++++--------- src/components/Editor.jsx | 7 +-- src/index.js | 81 +++++++++++++++++++++++++++++++++ src/store/index.js | 22 +++++++-- webpack.config.js | 38 ++++++++++++++-- 5 files changed, 164 insertions(+), 34 deletions(-) diff --git a/plugins/query-composer/index.js b/plugins/query-composer/index.js index 5320fe0..a3e71de 100644 --- a/plugins/query-composer/index.js +++ b/plugins/query-composer/index.js @@ -5,19 +5,22 @@ import { explorerPlugin } from "@graphiql/plugin-explorer"; import { Icon, pencil } from '@wordpress/icons'; import { QueryComposer } from './components/QueryComposer' - -// registerPlugin( 'queryComposer', { -// title: 'Query Composer', -// icon: () => ( -// -// ), -// content: () => -// } ); +// const queryComposerFake = () => { +// return { +// title: 'Query Composer Fake', +// icon: () => ( +// +// ), +// content: () => +// }; +// } +// +// registerPlugin( 'queryComposerFake', queryComposerFake ); // addAction( 'wpgraphqlide_rendered', 'wpgraphql-ide-query-composer',() => { // console.log({ @@ -26,16 +29,19 @@ import { QueryComposer } from './components/QueryComposer' // registerPlugin( 'queryComposer', explorerPlugin() ); // }); +const explorer = explorerPlugin(); +registerPlugin( 'queryComposer', explorer ); + -addFilter( 'wpgraphqlide_plugins', 'wpgraphql-ide-query-composer', (plugins) => { - const explorer = explorerPlugin(); - console.log( { pluginsBefore: plugins }) - if ( ! plugins.includes( explorer ) ) { - plugins.push(explorer) - console.log({pluginsAfter: plugins}) - } - return plugins; -}) +// addFilter( 'wpgraphqlide_plugins', 'wpgraphql-ide-query-composer', (plugins) => { +// const explorer = explorerPlugin(); +// console.log( { pluginsBefore: plugins }) +// if ( ! plugins.includes( explorer ) ) { +// plugins.push(explorer) +// console.log({pluginsAfter: plugins}) +// } +// return plugins; +// }) diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index 480f93b..71d5452 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -5,7 +5,7 @@ import { useDispatch, useSelect } from '@wordpress/data'; import { applyFilters } from '@wordpress/hooks'; import { useEffect } from '@wordpress/element' -import { explorerPlugin } from "@graphiql/plugin-explorer"; +// import { explorerPlugin } from "@graphiql/plugin-explorer"; import { PrettifyButton } from './toolbarButtons/PrettifyButton'; import { CopyQueryButton } from './toolbarButtons/CopyQueryButton'; @@ -46,14 +46,15 @@ export function Editor() { return { query: wpgraphqlIde.getQuery(), shouldRenderStandalone: wpgraphqlIde.shouldRenderStandalone(), - plugins: wpgraphqlIde.getPluginsArray(), + plugins: wpgraphqlIde.getRegisteredPlugins(), }; } ); const { setDrawerOpen, setQuery } = useDispatch( 'wpgraphql-ide' ); - const activePlugins = applyFilters( 'wpgraphqlide_plugins', [] ); + let activePlugins = plugins.length > 0 ? plugins : null; + activePlugins = applyFilters( 'wpgraphqlide_plugins', activePlugins ); return ( { isInitialStateLoaded: true, }; case 'REGISTER_PLUGIN': + // push the plugin into the registeredPlugins array return { ...state, - registeredPlugins: { + registeredPlugins: [ ...state.registeredPlugins, - [ action.name ]: action.config, - }, - }; + ...[ action.config ], + ], + } + + // return { + // ...state, + // registeredPlugins: { + // ...state.registeredPlugins, + // [ action.name ]: action.config, + // }, + // }; } return state; }; @@ -87,6 +96,9 @@ const selectors = { isInitialStateLoaded: ( state ) => { return state.isInitialStateLoaded; }, + getRegisteredPlugins: ( state ) => { + return state.registeredPlugins; + }, getPluginsArray: ( state ) => { const registeredPlugins = state.registeredPlugins; const pluginsArray = []; diff --git a/webpack.config.js b/webpack.config.js index 32d63d6..cf7c6a7 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,6 +1,24 @@ const defaults = require( '@wordpress/scripts/config/webpack.config' ); const path = require( 'path' ); +const defaultExternals = { + react: 'React', + 'react-dom': 'ReactDOM', + 'wpgraphql-ide': 'WPGraphQLIDE', +} + +// Define a mapping of entries to their respective externals +const entryExternals = { + index: { + ...defaultExternals + }, + queryComposer: { + ...defaultExternals, + GraphiQL: 'GraphiQL', + }, + // Define externals for other entries as needed +}; + module.exports = { ...defaults, entry: { @@ -9,9 +27,21 @@ module.exports = { help: path.resolve( process.cwd(), 'plugins/help', 'index.js' ), queryComposer: path.resolve( process.cwd(), 'plugins/query-composer', 'index.js' ), }, - externals: { - react: 'React', - 'react-dom': 'ReactDOM', - 'wpgraphql-ide': 'WPGraphQLIDE', + externals: (context, request, callback) => { + // Determine the current entry from context or other means + const currentEntry = determineCurrentEntry(context); + // Apply the externals based on the current entry + if (entryExternals[currentEntry] && entryExternals[currentEntry][request]) { + return callback(null, entryExternals[currentEntry][request]); + } + // Fallback to default behavior if no externals are defined for the current entry + callback(); }, }; + +function determineCurrentEntry(context) { + // Implement logic to determine the current entry based on context + // This might involve checking the context path to infer which entry is being processed + // Placeholder implementation: + return 'index'; // Replace with actual logic to determine the entry +}