From 43eea792a60ed3cabbcf89fb6de86e8e602c565d Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Mon, 29 Apr 2024 15:11:16 -0400 Subject: [PATCH 01/45] Refactor application store architecture --- .changeset/few-coins-design.md | 5 ++ package-lock.json | 3 + src/App.jsx | 6 +- src/components/Editor.jsx | 6 +- src/components/EditorDrawer.jsx | 4 +- src/index.js | 13 ++- src/store/app-store.js | 109 +++++++++++++++++++++++ src/store/editor-toolbar-store.js | 40 +++++++++ src/store/index.js | 138 +++++++----------------------- 9 files changed, 202 insertions(+), 122 deletions(-) create mode 100644 .changeset/few-coins-design.md create mode 100644 src/store/app-store.js create mode 100644 src/store/editor-toolbar-store.js diff --git a/.changeset/few-coins-design.md b/.changeset/few-coins-design.md new file mode 100644 index 0000000..591a724 --- /dev/null +++ b/.changeset/few-coins-design.md @@ -0,0 +1,5 @@ +--- +"wpgraphql-ide": major +--- + +Refactored stores, including renaming 'wpgraphql-ide' to 'wpgraphql-ide/app', and adding additional stores such as 'wpgraphql-ide/editor-toolbar diff --git a/package-lock.json b/package-lock.json index f6181de..4fc69e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,12 @@ { "name": "wpgraphql-ide", + "version": "1.1.8", "lockfileVersion": 3, "requires": true, "packages": { "": { + "name": "wpgraphql-ide", + "version": "1.1.8", "dependencies": { "@changesets/cli": "^2.27.1", "@graphiql/plugin-explorer": "^1.0.3", diff --git a/src/App.jsx b/src/App.jsx index 4a751be..7025491 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -19,7 +19,7 @@ const setInitialState = () => { setQuery, setShouldRenderStandalone, setInitialStateLoaded, - } = useDispatch( 'wpgraphql-ide' ); + } = useDispatch( 'wpgraphql-ide/app' ); if ( isDedicatedIdePage ) { setShouldRenderStandalone( true ); @@ -108,11 +108,11 @@ export function App() { export function RenderApp() { const isInitialStateLoaded = useSelect( ( select ) => { - return select( 'wpgraphql-ide' ).isInitialStateLoaded(); + return select( 'wpgraphql-ide/app' ).isInitialStateLoaded(); } ); const shouldRenderStandalone = useSelect( ( select ) => { - return select( 'wpgraphql-ide' ).shouldRenderStandalone(); + return select( 'wpgraphql-ide/app' ).shouldRenderStandalone(); } ); if ( ! isInitialStateLoaded ) { diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index 872dee9..ce04246 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -32,12 +32,12 @@ import '../../styles/explorer.css'; export function Editor() { const query = useSelect( ( select ) => - select( 'wpgraphql-ide' ).getQuery() + select( 'wpgraphql-ide/app' ).getQuery() ); const shouldRenderStandalone = useSelect( ( select ) => - select( 'wpgraphql-ide' ).shouldRenderStandalone() + select( 'wpgraphql-ide/app' ).shouldRenderStandalone() ); - const { setDrawerOpen } = useDispatch( 'wpgraphql-ide' ); + const { setDrawerOpen } = useDispatch( 'wpgraphql-ide/app' ); const [ isAuthenticated, setIsAuthenticated ] = useState( () => { const storedState = localStorage.getItem( 'graphiql:isAuthenticated' ); diff --git a/src/components/EditorDrawer.jsx b/src/components/EditorDrawer.jsx index 029affb..9931763 100644 --- a/src/components/EditorDrawer.jsx +++ b/src/components/EditorDrawer.jsx @@ -6,10 +6,10 @@ export function EditorDrawer( { children } ) { const buttonLabel = '🚀'; const isDrawerOpen = useSelect( ( select ) => { - return select( 'wpgraphql-ide' ).isDrawerOpen(); + return select( 'wpgraphql-ide/app' ).isDrawerOpen(); } ); - const { setDrawerOpen } = useDispatch( 'wpgraphql-ide' ); + const { setDrawerOpen } = useDispatch( 'wpgraphql-ide/app' ); return (
diff --git a/src/index.js b/src/index.js index ddea706..57d03a4 100644 --- a/src/index.js +++ b/src/index.js @@ -1,24 +1,23 @@ // WordPress dependencies for hooks, data handling, and component rendering. import { createHooks } from '@wordpress/hooks'; -import { register } from '@wordpress/data'; import { createRoot } from '@wordpress/element'; +import { registerStores, registerEditorToolbarButton } from './store'; import * as GraphQL from "graphql/index.js"; // Local imports including the store configuration and the main App component. -import { store } from './store'; import { App } from './App'; -// Register the store with wp.data to make it available throughout the plugin. -register( store ); - // Create a central event hook system for the WPGraphQL IDE. export const hooks = createHooks(); +// Register all application stores. +registerStores(); + // Expose a global variable for the IDE, facilitating extension through external scripts. window.WPGraphQLIDE = { hooks, - store, - GraphQL + GraphQL, + registerEditorToolbarButton }; /** diff --git a/src/store/app-store.js b/src/store/app-store.js new file mode 100644 index 0000000..6fd06fd --- /dev/null +++ b/src/store/app-store.js @@ -0,0 +1,109 @@ +import { createReduxStore } from '@wordpress/data'; + +const initialState = { + isDrawerOpen: false, + shouldRenderStandalone: false, + isInitialStateLoaded: false, + registeredPlugins: {}, + query: null, +}; + +const reducer = ( state = initialState, action ) => { + switch ( action.type ) { + case 'SET_RENDER_STANDALONE': + return { + ...state, + shouldRenderStandalone: action.shouldRenderStandalone, + }; + case 'SET_QUERY': + return { + ...state, + query: action.query, + }; + case 'SET_DRAWER_OPEN': + return { + ...state, + isDrawerOpen: action.isDrawerOpen, + }; + case 'SET_INITIAL_STATE_LOADED': + return { + ...state, + isInitialStateLoaded: true, + }; + case 'REGISTER_PLUGIN': + return { + ...state, + registeredPlugins: { + ...state.registeredPlugins, + [ action.name ]: action.config, + }, + }; + } + return state; +}; +const actions = { + setQuery: ( query ) => { + return { + type: 'SET_QUERY', + query, + }; + }, + setDrawerOpen: ( isDrawerOpen ) => { + return { + type: 'SET_DRAWER_OPEN', + isDrawerOpen, + }; + }, + setShouldRenderStandalone: ( shouldRenderStandalone ) => { + return { + type: 'SET_RENDER_STANDALONE', + shouldRenderStandalone, + }; + }, + setInitialStateLoaded: () => { + return { + type: 'SET_INITIAL_STATE_LOADED', + }; + }, + registerPlugin: ( name, config ) => { + return { + type: 'REGISTER_PLUGIN', + name, + config, + }; + }, +}; + +const selectors = { + getQuery: ( state ) => { + return state.query; + }, + isDrawerOpen: ( state ) => { + return state.isDrawerOpen; + }, + shouldRenderStandalone: ( state ) => { + return state.shouldRenderStandalone; + }, + isInitialStateLoaded: ( state ) => { + return state.isInitialStateLoaded; + }, + getPluginsArray: ( state ) => { + const registeredPlugins = state.registeredPlugins; + const pluginsArray = []; + Object.entries( registeredPlugins ).map( ( [ key, config ] ) => { + const plugin = () => { + return config; + }; + pluginsArray.push( plugin() ); + } ); + return pluginsArray; + }, +}; + +const store = createReduxStore( 'wpgraphql-ide/app', { + reducer, + selectors, + actions, +} ); + +export default store; \ No newline at end of file diff --git a/src/store/editor-toolbar-store.js b/src/store/editor-toolbar-store.js new file mode 100644 index 0000000..2ed9a27 --- /dev/null +++ b/src/store/editor-toolbar-store.js @@ -0,0 +1,40 @@ +import { createReduxStore } from '@wordpress/data'; + +const initialState = { + buttons: [] +}; + +const reducer = ( state = initialState, action ) => { + switch ( action.type ) { + case 'REGISTER_BUTTON': + return { + ...state, + buttons: state.buttons.push(action.name), + }; + } + return state; +}; + +const actions = { + registerButton: ( name, config ) => { + return { + type: 'REGISTER_BUTTON', + name, + config, + }; + } +}; + +const selectors = { + buttons: ( state ) => { + return state.buttons; + } +}; + +const store = createReduxStore( 'wpgraphql-ide/editor-toolbar', { + reducer, + selectors, + actions, +} ); + +export default store; \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index f032718..14dfd0c 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,107 +1,31 @@ -import { createReduxStore } from '@wordpress/data'; - -const initialState = { - isDrawerOpen: false, - shouldRenderStandalone: false, - isInitialStateLoaded: false, - registeredPlugins: {}, - query: null, -}; - -const reducer = ( state = initialState, action ) => { - switch ( action.type ) { - case 'SET_RENDER_STANDALONE': - return { - ...state, - shouldRenderStandalone: action.shouldRenderStandalone, - }; - case 'SET_QUERY': - return { - ...state, - query: action.query, - }; - case 'SET_DRAWER_OPEN': - return { - ...state, - isDrawerOpen: action.isDrawerOpen, - }; - case 'SET_INITIAL_STATE_LOADED': - return { - ...state, - isInitialStateLoaded: true, - }; - case 'REGISTER_PLUGIN': - return { - ...state, - registeredPlugins: { - ...state.registeredPlugins, - [ action.name ]: action.config, - }, - }; - } - return state; -}; -const actions = { - setQuery: ( query ) => { - return { - type: 'SET_QUERY', - query, - }; - }, - setDrawerOpen: ( isDrawerOpen ) => { - return { - type: 'SET_DRAWER_OPEN', - isDrawerOpen, - }; - }, - setShouldRenderStandalone: ( shouldRenderStandalone ) => { - return { - type: 'SET_RENDER_STANDALONE', - shouldRenderStandalone, - }; - }, - setInitialStateLoaded: () => { - return { - type: 'SET_INITIAL_STATE_LOADED', - }; - }, - registerPlugin: ( name, config ) => { - return { - type: 'REGISTER_PLUGIN', - name, - config, - }; - }, -}; - -const selectors = { - getQuery: ( state ) => { - return state.query; - }, - isDrawerOpen: ( state ) => { - return state.isDrawerOpen; - }, - shouldRenderStandalone: ( state ) => { - return state.shouldRenderStandalone; - }, - isInitialStateLoaded: ( state ) => { - return state.isInitialStateLoaded; - }, - getPluginsArray: ( state ) => { - const registeredPlugins = state.registeredPlugins; - const pluginsArray = []; - Object.entries( registeredPlugins ).map( ( [ key, config ] ) => { - const plugin = () => { - return config; - }; - pluginsArray.push( plugin() ); - } ); - return pluginsArray; - }, -}; - -export const store = createReduxStore( 'wpgraphql-ide', { - reducer, - selectors, - actions, -} ); +import { register, dispatch } from '@wordpress/data'; + +import appStore from './app-store'; +import editorToolbarStore from './editor-toolbar-store'; + +export function registerStores() { + register( appStore ); + register( editorToolbarStore ); +} + + + + + + + + + + + + + + + + + +// TEST FUNCTION +export function registerEditorToolbarButton( name, config ) { + console.log({ name, config }); + dispatch( editorToolbarStore ).registerButton( name, config ); +} \ No newline at end of file From 23e1b0ed2eaced054be2b9866c78ebe466245a5e Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Tue, 30 Apr 2024 12:10:47 -0400 Subject: [PATCH 02/45] Use name as key --- src/store/editor-toolbar-store.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/store/editor-toolbar-store.js b/src/store/editor-toolbar-store.js index 2ed9a27..6b2e739 100644 --- a/src/store/editor-toolbar-store.js +++ b/src/store/editor-toolbar-store.js @@ -1,7 +1,7 @@ import { createReduxStore } from '@wordpress/data'; const initialState = { - buttons: [] + buttons: {} }; const reducer = ( state = initialState, action ) => { @@ -9,7 +9,10 @@ const reducer = ( state = initialState, action ) => { case 'REGISTER_BUTTON': return { ...state, - buttons: state.buttons.push(action.name), + buttons: { + ...state.buttons, + [action.name]: action.config + }, }; } return state; From 8c50257d93e8a52cbeb0e59a36c41018d1ae7581 Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Tue, 30 Apr 2024 12:19:57 -0400 Subject: [PATCH 03/45] Handle attempted registration of duplicate names --- src/store/editor-toolbar-store.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/store/editor-toolbar-store.js b/src/store/editor-toolbar-store.js index 6b2e739..c0aeb4b 100644 --- a/src/store/editor-toolbar-store.js +++ b/src/store/editor-toolbar-store.js @@ -7,6 +7,18 @@ const initialState = { const reducer = ( state = initialState, action ) => { switch ( action.type ) { case 'REGISTER_BUTTON': + + // Validate buttons + if (action.name in state.buttons) { + console.warn({ + message: `The "${action.name}" button already exists. Name must be unique.`, + existingButton: state.buttons[action.name], + duplicateButton: action.config + }); + + return state; + } + return { ...state, buttons: { From 04dfda49b01fb48483dbefc72ad45d83d8aeae9c Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Wed, 8 May 2024 18:42:25 -0400 Subject: [PATCH 04/45] save --- src/App.jsx | 2 ++ src/components/help/HelpPanel.jsx | 3 +- src/index.js | 18 ++++------- src/store/app-store.js | 2 +- src/store/editor-toolbar-store.js | 43 +++++++++++++------------ src/store/index.js | 53 +++++++++++++++++-------------- src/wordpress-hooks.js | 9 ++++++ 7 files changed, 72 insertions(+), 58 deletions(-) create mode 100644 src/wordpress-hooks.js diff --git a/src/App.jsx b/src/App.jsx index 5880f81..a54d009 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -138,3 +138,5 @@ export function RenderApp() {
); } + +export default App; diff --git a/src/components/help/HelpPanel.jsx b/src/components/help/HelpPanel.jsx index 1fa14a0..15bafbd 100644 --- a/src/components/help/HelpPanel.jsx +++ b/src/components/help/HelpPanel.jsx @@ -76,8 +76,7 @@ export const helpCards = [ description: 'Join the WPGraphQL Community in Discord where you can ask questions, show off projects and help other WPGraphQL users. Join us today!', linkText: 'Join us in Discord', - linkUrl: - 'https://discord.gg/AGVBqqyaUY', + linkUrl: 'https://discord.gg/AGVBqqyaUY', }, ]; diff --git a/src/index.js b/src/index.js index f7dfacb..a431d8a 100644 --- a/src/index.js +++ b/src/index.js @@ -5,32 +5,25 @@ */ // External dependencies -import { createHooks } from '@wordpress/hooks'; import { createRoot } from '@wordpress/element'; import { registerStores, registerEditorToolbarButton } from './store'; -import * as GraphQL from "graphql/index.js"; +import * as GraphQL from 'graphql/index.js'; -// Local imports including the store configuration and the main App component. -import { App } from './App'; +// Local imports including the hook configuration and the main App component. +import hooks from './wordpress-hooks'; +import App from './App'; // Register all application stores. registerStores(); -/** - * Initializes a hooks system to extend the functionality of the WPGraphQL IDE through - * external scripts and internal plugin hooks. - */ -export const hooks = createHooks(); - /** * Exposes a global `WPGraphQLIDE` variable that includes hooks, store, and GraphQL references, * making them accessible for extensions and external scripts. */ window.WPGraphQLIDE = { hooks, - store, GraphQL, - registerEditorToolbarButton + registerEditorToolbarButton, }; /** @@ -40,6 +33,7 @@ window.WPGraphQLIDE = { const appMountPoint = document.getElementById( 'wpgraphql-ide-root' ); if ( appMountPoint ) { createRoot( appMountPoint ).render( ); + window.dispatchEvent( new Event( 'WPGraphQLIDEReady' ) ); } else { console.error( 'WPGraphQL IDE mount point not found. Please ensure an element with ID "wpgraphql-ide-root" exists.' diff --git a/src/store/app-store.js b/src/store/app-store.js index 6fd06fd..aeed891 100644 --- a/src/store/app-store.js +++ b/src/store/app-store.js @@ -106,4 +106,4 @@ const store = createReduxStore( 'wpgraphql-ide/app', { actions, } ); -export default store; \ No newline at end of file +export default store; diff --git a/src/store/editor-toolbar-store.js b/src/store/editor-toolbar-store.js index c0aeb4b..9a7a6b6 100644 --- a/src/store/editor-toolbar-store.js +++ b/src/store/editor-toolbar-store.js @@ -1,49 +1,52 @@ import { createReduxStore } from '@wordpress/data'; const initialState = { - buttons: {} + buttons: {}, }; const reducer = ( state = initialState, action ) => { switch ( action.type ) { case 'REGISTER_BUTTON': + // Validate buttons + if ( action.name in state.buttons ) { + console.warn( { + message: `The "${ action.name }" button already exists. Name must be unique.`, + existingButton: state.buttons[ action.name ], + duplicateButton: action.config, + } ); - // Validate buttons - if (action.name in state.buttons) { - console.warn({ - message: `The "${action.name}" button already exists. Name must be unique.`, - existingButton: state.buttons[action.name], - duplicateButton: action.config - }); - - return state; - } + return state; + } return { ...state, buttons: { - ...state.buttons, - [action.name]: action.config - }, + ...state.buttons, + [ action.name ]: action.config, + }, }; + default: + return state; } - return state; }; const actions = { registerButton: ( name, config ) => { return { type: 'REGISTER_BUTTON', - name, - config, + name, + config, }; - } + }, }; const selectors = { buttons: ( state ) => { return state.buttons; - } + }, + getButtonByName: ( state, name ) => { + return state.buttons[ name ]; + }, }; const store = createReduxStore( 'wpgraphql-ide/editor-toolbar', { @@ -52,4 +55,4 @@ const store = createReduxStore( 'wpgraphql-ide/editor-toolbar', { actions, } ); -export default store; \ No newline at end of file +export default store; diff --git a/src/store/index.js b/src/store/index.js index 14dfd0c..1c72890 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,31 +1,38 @@ -import { register, dispatch } from '@wordpress/data'; +import { register, dispatch, select } from '@wordpress/data'; +import hooks from '../wordpress-hooks'; import appStore from './app-store'; import editorToolbarStore from './editor-toolbar-store'; export function registerStores() { - register( appStore ); - register( editorToolbarStore ); + register( appStore ); + register( editorToolbarStore ); } - - - - - - - - - - - - - - - - -// TEST FUNCTION export function registerEditorToolbarButton( name, config ) { - console.log({ name, config }); - dispatch( editorToolbarStore ).registerButton( name, config ); -} \ No newline at end of file + const existingButton = select( + 'wpgraphql-ide/editor-toolbar' + ).getButtonByName( name ); + if ( existingButton ) { + console.warn( `Button with name ${ name } already exists.` ); + hooks.doAction( + 'registerToolbarButtonFailed', + name, + config, + 'Button name must be unique.' + ); + return; + } + + try { + dispatch( 'wpgraphql-ide/editor-toolbar' ).registerButton( + name, + config + ); + console.log( `Button registered: ${ name }` ); + hooks.doAction( 'afterRegisterToolbarButton', name, config ); + } catch ( error ) { + console.error( `Failed to register button: ${ name }`, error ); + hooks.doAction( 'registerToolbarButtonError', name, config, error ); + } +} diff --git a/src/wordpress-hooks.js b/src/wordpress-hooks.js new file mode 100644 index 0000000..fb474a5 --- /dev/null +++ b/src/wordpress-hooks.js @@ -0,0 +1,9 @@ +import { createHooks } from '@wordpress/hooks'; + +/** + * Initializes a hooks system to extend the functionality of the WPGraphQL IDE through + * external scripts and internal plugin hooks. + */ +const hooks = createHooks(); + +export default hooks; From a2a30bcf08d458e726373f6c1b9fd71dbd62899e Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Thu, 9 May 2024 13:16:37 -0400 Subject: [PATCH 05/45] save --- package-lock.json | 4 +-- src/components/DynamicToolbarButtons.jsx | 33 ++++++++++++++++++++++++ src/components/Editor.jsx | 26 +++---------------- src/store/editor-toolbar-store.js | 27 +++++++------------ src/store/index.js | 2 +- 5 files changed, 50 insertions(+), 42 deletions(-) create mode 100644 src/components/DynamicToolbarButtons.jsx diff --git a/package-lock.json b/package-lock.json index 4fc69e5..8c8d94e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wpgraphql-ide", - "version": "1.1.8", + "version": "1.1.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "wpgraphql-ide", - "version": "1.1.8", + "version": "1.1.9", "dependencies": { "@changesets/cli": "^2.27.1", "@graphiql/plugin-explorer": "^1.0.3", diff --git a/src/components/DynamicToolbarButtons.jsx b/src/components/DynamicToolbarButtons.jsx new file mode 100644 index 0000000..6e23d49 --- /dev/null +++ b/src/components/DynamicToolbarButtons.jsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useSelect } from '@wordpress/data'; + +export const DynamicToolbarButtons = ( { + isAuthenticated, + toggleAuthentication, +} ) => { + const buttons = useSelect( ( select ) => + select( 'wpgraphql-ide/editor-toolbar' ).buttons() + ); + + return ( + <> + { Object.entries( buttons ).map( ( [ key, ButtonComponent ] ) => { + if ( + typeof ButtonComponent !== 'function' && + typeof ButtonComponent !== 'object' + ) { + console.error( `Invalid component for key: ${ key }` ); + return null; + } + + return ( + + ); + } ) } + + ); +}; diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index 8a368c2..c246d90 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -3,27 +3,12 @@ import { GraphiQL } from 'graphiql'; import { useDispatch, useSelect } from '@wordpress/data'; import { parse, visit } from 'graphql'; import { explorerPlugin } from '@graphiql/plugin-explorer'; -import { helpPlugin } from './help'; -import { PrettifyButton } from './toolbarButtons/PrettifyButton'; -import { CopyQueryButton } from './toolbarButtons/CopyQueryButton'; -import { MergeFragmentsButton } from './toolbarButtons/MergeFragmentsButton'; -import { ShareDocumentButton } from './toolbarButtons/ShareDocumentButton'; -import { ToggleAuthButton } from './toolbarButtons/ToggleAuthButton'; +import { helpPlugin } from './help'; +import { DynamicToolbarButtons } from './DynamicToolbarButtons'; import 'graphiql/graphiql.min.css'; -/** - * Editor component encapsulating the GraphiQL IDE. - * Manages authentication state and integrates custom toolbar buttons. - */ -const toolbarButtons = { - copy: CopyQueryButton, - prettify: PrettifyButton, - merge: MergeFragmentsButton, - share: ShareDocumentButton, -}; - const explorer = explorerPlugin(); const help = helpPlugin(); @@ -131,15 +116,12 @@ export function Editor() { plugins={ [ explorer, help ] } > - - - - - + { ! shouldRenderStandalone && ( + ); +}; + +export default ToggleAuthenticationButton; diff --git a/plugins/third-party-plugin/src/index.js b/plugins/third-party-plugin/src/index.js new file mode 100644 index 0000000..11176cd --- /dev/null +++ b/plugins/third-party-plugin/src/index.js @@ -0,0 +1,16 @@ +import React from 'react'; +import { register } from '@wordpress/data'; + +import { store } from './store'; +import ToggleAuthenticationButton from './components/ToggleAuthenticationButton'; + +window.addEventListener( 'WPGraphQLIDEReady', () => { + register( store ); + + const { registerEditorToolbarButton } = window.WPGraphQLIDE; + + registerEditorToolbarButton( 'toggle-auth-button', { + title: 'Toggle Authentication', + component: ToggleAuthenticationButton, + } ); +} ); diff --git a/plugins/third-party-plugin/src/store.js b/plugins/third-party-plugin/src/store.js new file mode 100644 index 0000000..4f71d45 --- /dev/null +++ b/plugins/third-party-plugin/src/store.js @@ -0,0 +1,36 @@ +import { createReduxStore } from '@wordpress/data'; + +const initialState = { + isAuthenticated: true, +}; + +const reducer = ( state = initialState, action ) => { + switch ( action.type ) { + case 'TOGGLE_AUTHENTICATION': + return { + ...state, + isAuthenticated: ! state.isAuthenticated, + }; + } + return state; +}; + +const actions = { + toggleAuthentication: () => { + return { + type: 'TOGGLE_AUTHENTICATION', + }; + }, +}; + +const selectors = { + isAuthenticated: ( state ) => { + return state.isAuthenticated; + }, +}; + +export const store = createReduxStore( 'third-party-plugin', { + reducer, + selectors, + actions, +} ); diff --git a/plugins/third-party-plugin/third-party-plugin.php b/plugins/third-party-plugin/third-party-plugin.php new file mode 100644 index 0000000..fe3fe46 --- /dev/null +++ b/plugins/third-party-plugin/third-party-plugin.php @@ -0,0 +1,31 @@ +5wrj2QC|iIh7ceY1>&UA%$yYc%)FG;3cbYQ;?xqof{cRA z8}(0U1Za5aYU-W}_R!JtT5~19-&5D)theV`?{hx7Vc{FLHg{#e(pWKlshDW`v*(Sj zSA~Tq`@q; z0IrW8c!~l!3V66WLpVNgmVW;dd}#|Cl1bZg=SD=@7{A*KG=Z6sfk6yNmtx1;?;b-htvM$~fmr(8~;wbNOD5|DEEr^m$o%yNNNvx>! z*O5bs%WQTwB<-r0Bfc}~Gyi$B!c)tRuQ@!c>Ey&%RW>cdBdrm9ri^^1k8>KN@uZIQX)gEs4G{=bTxQl>Y1+b$58BN)rF` zmN(c3cr!AIFyoFqps>Nh65D8kOiqpoc%i00xF7jSXl Date: Thu, 9 May 2024 15:06:51 -0400 Subject: [PATCH 07/45] save --- .../components/ToggleAuthenticationButton.jsx | 6 ++-- plugins/third-party-plugin/src/index.js | 5 --- plugins/third-party-plugin/src/store.js | 36 ------------------- .../third-party-plugin/third-party-plugin.php | 1 - src/components/DynamicToolbarButtons.jsx | 11 ++---- src/components/Editor.jsx | 33 +++++++++++------ src/store/app-store.js | 14 ++++++++ wpgraphql-ide.php | 5 ++- 8 files changed, 45 insertions(+), 66 deletions(-) delete mode 100644 plugins/third-party-plugin/src/store.js diff --git a/plugins/third-party-plugin/src/components/ToggleAuthenticationButton.jsx b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton.jsx index 3909f89..6b771ef 100644 --- a/plugins/third-party-plugin/src/components/ToggleAuthenticationButton.jsx +++ b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton.jsx @@ -3,14 +3,14 @@ import { useDispatch, useSelect } from '@wordpress/data'; const ToggleAuthenticationButton = () => { const isAuthenticated = useSelect( ( select ) => - select( 'whatever-store-maintains-auth-state' ).isAuthenticated() + select( 'wpgraphql-ide/app' ).isAuthenticated() ); const { toggleAuthentication } = useDispatch( - 'whatever-store-maintains-auth-state' + 'wpgraphql-ide/app' ); return ( - - ); -}; - -export default ToggleAuthenticationButton; diff --git a/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/README.md b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/README.md new file mode 100644 index 0000000..02622ef --- /dev/null +++ b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/README.md @@ -0,0 +1 @@ +# ToggleAuthenticationButton diff --git a/src/components/toolbarButtons/ToggleAuthButton.jsx b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/ToggleAuthenticationButton.jsx similarity index 75% rename from src/components/toolbarButtons/ToggleAuthButton.jsx rename to plugins/third-party-plugin/src/components/ToggleAuthenticationButton/ToggleAuthenticationButton.jsx index 18eb7ef..45fcd6a 100644 --- a/src/components/toolbarButtons/ToggleAuthButton.jsx +++ b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/ToggleAuthenticationButton.jsx @@ -1,8 +1,8 @@ import React from 'react'; import clsx from 'clsx'; -import { ToolbarButton } from '@graphiql/react'; +import { useDispatch, useSelect } from '@wordpress/data'; -import styles from '../../../styles/ToggleAuthButton.module.css'; +import styles from './ToggleAuthenticationButton.module.css'; /** * Component to toggle the authentication state within the GraphiQL IDE. @@ -11,10 +11,9 @@ import styles from '../../../styles/ToggleAuthButton.module.css'; * @param {boolean} props.isAuthenticated Indicates if the current state is authenticated. * @param {Function} props.toggleAuthentication Function to toggle the authentication state. */ -export const ToggleAuthButton = ( { - isAuthenticated, - toggleAuthentication, -} ) => { +export const ToggleAuthenticationButton = ( { ToolbarButton } ) => { + const isAuthenticated = useSelect( ( select ) =>select( 'wpgraphql-ide/app' ).isAuthenticated()); + const { toggleAuthentication } = useDispatch( 'wpgraphql-ide/app' ); const avatarUrl = window.WPGRAPHQL_IDE_DATA?.context?.avatarUrl; const title = isAuthenticated ? 'Switch to execute as a public user' diff --git a/styles/ToggleAuthButton.module.css b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/ToggleAuthenticationButton.module.css similarity index 99% rename from styles/ToggleAuthButton.module.css rename to plugins/third-party-plugin/src/components/ToggleAuthenticationButton/ToggleAuthenticationButton.module.css index 0cfcf58..9cf1776 100644 --- a/styles/ToggleAuthButton.module.css +++ b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/ToggleAuthenticationButton.module.css @@ -6,7 +6,7 @@ background-size: cover; position: relative; } - + .authAvatarPublic { filter: grayscale(100%) !important; diff --git a/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/index.js b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/index.js new file mode 100644 index 0000000..10ba7f9 --- /dev/null +++ b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/index.js @@ -0,0 +1 @@ +export { ToggleAuthenticationButton as default } from './ToggleAuthenticationButton'; diff --git a/plugins/third-party-plugin/src/index.js b/plugins/third-party-plugin/src/index.js index 4e54254..f9dd844 100644 --- a/plugins/third-party-plugin/src/index.js +++ b/plugins/third-party-plugin/src/index.js @@ -1,4 +1,8 @@ import ToggleAuthenticationButton from './components/ToggleAuthenticationButton'; +import PrettifyButton from './components/PrettifyButton'; +import ShareDocumentButton from './components/ShareDocumentButton'; +import MergeFragmentsButton from './components/MergeFragmentsButton'; +import CopyQueryButton from './components/CopyQueryButton'; window.addEventListener( 'WPGraphQLIDEReady', () => { @@ -8,4 +12,25 @@ window.addEventListener( 'WPGraphQLIDEReady', () => { title: 'Toggle Authentication', component: ToggleAuthenticationButton, } ); + + registerEditorToolbarButton( 'prettify-button', { + title: 'Prettify query (Shift-Ctrl-P)', + component: PrettifyButton + } ); + + // registerEditorToolbarButton( 'share-document-button', { + // title: 'Prettify query (Shift-Ctrl-P)', + // component: ShareDocumentButton + // } ); + + // registerEditorToolbarButton( 'merge-fragments-button', { + // title: 'Merge fragments into query (Shift-Ctrl-M)', + // component: MergeFragmentsButton + // } ); + + // registerEditorToolbarButton( 'merge-fragments-button', { + // title: 'Copy query (Shift-Ctrl-C)', + // component: CopyQueryButton + // } ); + } ); diff --git a/plugins/third-party-plugin/third-party-plugin.php b/plugins/third-party-plugin/third-party-plugin.php index 6cbd241..fa10334 100644 --- a/plugins/third-party-plugin/third-party-plugin.php +++ b/plugins/third-party-plugin/third-party-plugin.php @@ -26,5 +26,13 @@ $asset_file['version'], true ); + + wp_enqueue_style( + 'third-party-plugin', + plugins_url( 'build/index.css', __FILE__ ), + [], + $asset_file['version'], + ); + }); diff --git a/src/components/DynamicToolbarButtons.jsx b/src/components/DynamicToolbarButtons.jsx index 66af09b..5176471 100644 --- a/src/components/DynamicToolbarButtons.jsx +++ b/src/components/DynamicToolbarButtons.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { useSelect } from '@wordpress/data'; +import { ToolbarButton } from '@graphiql/react' export const DynamicToolbarButtons = () => { const buttons = useSelect( ( select ) => @@ -17,7 +18,14 @@ export const DynamicToolbarButtons = () => { return null; } - return ; + return ( + <> + + + ) } ) } ); diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index 03f66ed..a366b6c 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -18,6 +18,9 @@ export function Editor() { const query = useSelect( ( select ) => select( 'wpgraphql-ide/app' ).getQuery() ); + + const { setQuery } = useDispatch( 'wpgraphql-ide/app' ); + const shouldRenderStandalone = useSelect( ( select ) => select( 'wpgraphql-ide/app' ).shouldRenderStandalone() ); @@ -59,6 +62,31 @@ export function Editor() { ); }, [ isAuthenticated ] ); + // const handleEditQuery = (editedQuery) => { + // let update = false; + + // if (editedQuery === query) { + // return; + // } + + // if (null === editedQuery || "" === editedQuery) { + // update = true; + // } else { + // try { + // parse(editedQuery); + // update = true; + // } catch (error) { + // return; + // } + // } + + // // If the query is valid and should be updated + // if (update) { + // // Update the state with the new query + // setQuery(editedQuery); + // } + // }; + const fetcher = useCallback( async ( graphQLParams ) => { let isIntrospectionQuery = false; @@ -121,6 +149,7 @@ export function Editor() { { if ( schema !== newSchema ) { diff --git a/src/components/toolbarButtons/PrettifyButton.jsx b/src/components/toolbarButtons/PrettifyButton.jsx deleted file mode 100644 index 8721639..0000000 --- a/src/components/toolbarButtons/PrettifyButton.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import { - ToolbarButton, - PrettifyIcon, - usePrettifyEditors, -} from '@graphiql/react'; - -export const PrettifyButton = ( { onClick } ) => { - const prettify = usePrettifyEditors(); - return ( - - - ); -}; diff --git a/src/store/app-store.js b/src/store/app-store.js index 926678d..27234b2 100644 --- a/src/store/app-store.js +++ b/src/store/app-store.js @@ -1,4 +1,5 @@ import { createReduxStore } from '@wordpress/data'; +import { parse } from 'graphql'; const initialState = { isDrawerOpen: false, @@ -9,6 +10,37 @@ const initialState = { isAuthenticated: true, }; +const setQuery = (state, action) => { + const editedQuery = action.query; + const query = state.query; + + let update = false; + + if (editedQuery === query) { + return { ...state }; + } + + if (null === editedQuery || "" === editedQuery) { + update = true; + } else { + try { + parse(editedQuery); + update = true; + } catch (error) { + return { ...state }; + } + } + + if (!update) { + return { ...state }; + } + + return { + ...state, + query: action.query, + }; +} + const reducer = ( state = initialState, action ) => { switch ( action.type ) { case 'SET_RENDER_STANDALONE': @@ -17,10 +49,7 @@ const reducer = ( state = initialState, action ) => { shouldRenderStandalone: action.shouldRenderStandalone, }; case 'SET_QUERY': - return { - ...state, - query: action.query, - }; + return setQuery( state, action ); case 'SET_DRAWER_OPEN': return { ...state, @@ -49,11 +78,18 @@ const reducer = ( state = initialState, action ) => { }; const actions = { setQuery: ( query ) => { + return { type: 'SET_QUERY', query, }; }, + prettifyQuery: (query) => { + return { + type: 'PRETTIFY_QUERY', + query, + } + }, setDrawerOpen: ( isDrawerOpen ) => { return { type: 'SET_DRAWER_OPEN', diff --git a/plugins/third-party-plugin/src/components/DynamicAvatar.jsx b/src/store/app/index.js similarity index 100% rename from plugins/third-party-plugin/src/components/DynamicAvatar.jsx rename to src/store/app/index.js diff --git a/src/store/document-editor/index.js b/src/store/document-editor/index.js new file mode 100644 index 0000000..e69de29 From 00fb3444991b438093e9f9b337b36551d760226f Mon Sep 17 00:00:00 2001 From: Joe Fusco Date: Fri, 10 May 2024 15:05:53 -0400 Subject: [PATCH 10/45] save --- src/components/DynamicToolbarButtons.jsx | 4 +-- src/components/Editor.jsx | 8 +++--- src/store/app-store.js | 32 ++++++++++++++---------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/components/DynamicToolbarButtons.jsx b/src/components/DynamicToolbarButtons.jsx index 5176471..69aa6cd 100644 --- a/src/components/DynamicToolbarButtons.jsx +++ b/src/components/DynamicToolbarButtons.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { useSelect } from '@wordpress/data'; -import { ToolbarButton } from '@graphiql/react' +import { ToolbarButton } from '@graphiql/react'; export const DynamicToolbarButtons = () => { const buttons = useSelect( ( select ) => @@ -25,7 +25,7 @@ export const DynamicToolbarButtons = () => { ToolbarButton={ ToolbarButton } /> - ) + ); } ) } ); diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index a366b6c..5091082 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -18,7 +18,7 @@ export function Editor() { const query = useSelect( ( select ) => select( 'wpgraphql-ide/app' ).getQuery() ); - + const { setQuery } = useDispatch( 'wpgraphql-ide/app' ); const shouldRenderStandalone = useSelect( ( select ) => @@ -64,11 +64,11 @@ export function Editor() { // const handleEditQuery = (editedQuery) => { // let update = false; - + // if (editedQuery === query) { // return; // } - + // if (null === editedQuery || "" === editedQuery) { // update = true; // } else { @@ -79,7 +79,7 @@ export function Editor() { // return; // } // } - + // // If the query is valid and should be updated // if (update) { // // Update the state with the new query diff --git a/src/store/app-store.js b/src/store/app-store.js index 27234b2..6f88d65 100644 --- a/src/store/app-store.js +++ b/src/store/app-store.js @@ -1,5 +1,5 @@ import { createReduxStore } from '@wordpress/data'; -import { parse } from 'graphql'; +import { parse, print } from 'graphql'; const initialState = { isDrawerOpen: false, @@ -10,28 +10,28 @@ const initialState = { isAuthenticated: true, }; -const setQuery = (state, action) => { +const setQuery = ( state, action ) => { const editedQuery = action.query; - const query = state.query; + const query = state.query; let update = false; - if (editedQuery === query) { + if ( editedQuery === query ) { return { ...state }; } - - if (null === editedQuery || "" === editedQuery) { + + if ( null === editedQuery || '' === editedQuery ) { update = true; } else { try { - parse(editedQuery); + parse( editedQuery ); update = true; - } catch (error) { + } catch ( error ) { return { ...state }; } } - if (!update) { + if ( ! update ) { return { ...state }; } @@ -39,7 +39,12 @@ const setQuery = (state, action) => { ...state, query: action.query, }; -} +}; + +const prettifyQuery = ( state, action ) => { + action.query = parse( query ); + return setQuery( state, action ); +}; const reducer = ( state = initialState, action ) => { switch ( action.type ) { @@ -50,6 +55,8 @@ const reducer = ( state = initialState, action ) => { }; case 'SET_QUERY': return setQuery( state, action ); + case 'PRETTIFY_QUERY': + return prettifyQuery( state, action ); case 'SET_DRAWER_OPEN': return { ...state, @@ -78,17 +85,16 @@ const reducer = ( state = initialState, action ) => { }; const actions = { setQuery: ( query ) => { - return { type: 'SET_QUERY', query, }; }, - prettifyQuery: (query) => { + prettifyQuery: ( query ) => { return { type: 'PRETTIFY_QUERY', query, - } + }; }, setDrawerOpen: ( isDrawerOpen ) => { return { From 7aba26fed76a98472b7ae5deb291f7b828567bc3 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 10 May 2024 14:14:50 -0600 Subject: [PATCH 11/45] - update third-party-plugin.php to not fatal if dependencies have not been built yet --- plugins/third-party-plugin/third-party-plugin.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/third-party-plugin/third-party-plugin.php b/plugins/third-party-plugin/third-party-plugin.php index fa10334..108a901 100644 --- a/plugins/third-party-plugin/third-party-plugin.php +++ b/plugins/third-party-plugin/third-party-plugin.php @@ -19,6 +19,10 @@ add_action( 'wpgraphqlide_enqueue_script', function() { $asset_file = include THIRD_PARTY_PLUGIN_PLUGIN_DIR_PATH . 'build/index.asset.php'; + if ( empty( $asset_file['dependencies'] ) ) { + return; + } + wp_enqueue_script( 'third-party-plugin', plugins_url( 'build/index.js', __FILE__ ), From ba43a124612a774a662e68561a12d678d3dfb6e9 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 10 May 2024 14:16:08 -0600 Subject: [PATCH 12/45] - update .gitignore - remove .zip from versioning --- plugins/third-party-plugin/.gitignore | 6 +++--- plugins/third-party-plugin/third-party-plugin.zip | Bin 660 -> 0 bytes 2 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 plugins/third-party-plugin/third-party-plugin.zip diff --git a/plugins/third-party-plugin/.gitignore b/plugins/third-party-plugin/.gitignore index e1a8683..b31e062 100644 --- a/plugins/third-party-plugin/.gitignore +++ b/plugins/third-party-plugin/.gitignore @@ -58,10 +58,10 @@ artifacts # build/release artifacts build/ -wpgraphql-ide/ -wpgraphql-ide.zip +third-party-plugin/ +third-party-plugin.php /test-results/ /playwright-report/ /blob-report/ /playwright/.cache/ -/@wpgraphql/ \ No newline at end of file +/@wpgraphql/ diff --git a/plugins/third-party-plugin/third-party-plugin.zip b/plugins/third-party-plugin/third-party-plugin.zip deleted file mode 100644 index f4a1fa5774023ba27f757147fa9fd4264c50f886..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 660 zcmWIWW@Zs#VBp|j$jh4>5wrj2QC|iIh7ceY1>&UA%$yYc%)FG;3cbYQ;?xqof{cRA z8}(0U1Za5aYU-W}_R!JtT5~19-&5D)theV`?{hx7Vc{FLHg{#e(pWKlshDW`v*(Sj zSA~Tq`@q; z0IrW8c!~l!3V66WLpVNgmVW;dd}#|Cl1bZg=SD=@7{A*KG=Z6sfk6yNmtx1;?;b-htvM$~fmr(8~;wbNOD5|DEEr^m$o%yNNNvx>! z*O5bs%WQTwB<-r0Bfc}~Gyi$B!c)tRuQ@!c>Ey&%RW>cdBdrm9ri^^1k8>KN@uZIQX)gEs4G{=bTxQl>Y1+b$58BN)rF` zmN(c3cr!AIFyoFqps>Nh65D8kOiqpoc%i00xF7jSXl Date: Fri, 10 May 2024 14:16:29 -0600 Subject: [PATCH 13/45] - update app-store.js to support prettify action --- src/store/app-store.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/store/app-store.js b/src/store/app-store.js index 6f88d65..da4c07f 100644 --- a/src/store/app-store.js +++ b/src/store/app-store.js @@ -11,7 +11,7 @@ const initialState = { }; const setQuery = ( state, action ) => { - const editedQuery = action.query; + let editedQuery = action.query; const query = state.query; let update = false; @@ -41,11 +41,6 @@ const setQuery = ( state, action ) => { }; }; -const prettifyQuery = ( state, action ) => { - action.query = parse( query ); - return setQuery( state, action ); -}; - const reducer = ( state = initialState, action ) => { switch ( action.type ) { case 'SET_RENDER_STANDALONE': @@ -55,8 +50,6 @@ const reducer = ( state = initialState, action ) => { }; case 'SET_QUERY': return setQuery( state, action ); - case 'PRETTIFY_QUERY': - return prettifyQuery( state, action ); case 'SET_DRAWER_OPEN': return { ...state, @@ -91,9 +84,17 @@ const actions = { }; }, prettifyQuery: ( query ) => { + + let editedQuery = query; + try { + editedQuery = print( parse( editedQuery ) ); + } catch ( error ) { + console.warn( error ); + } + return { - type: 'PRETTIFY_QUERY', - query, + type: 'SET_QUERY', + query: editedQuery, }; }, setDrawerOpen: ( isDrawerOpen ) => { From 8bba62c4c8de7452b4150710066f5ae271c09584 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 10 May 2024 22:26:53 -0600 Subject: [PATCH 14/45] - remove store/app-store.js in favor of store/app-store/index.js - moved reducers, actions, selectors into their own files - update .css to be valid - update DynamicToolbarButton --- .../ShareDocumentButton.jsx | 21 +-- .../ToggleAuthenticationButton.module.css | 8 +- plugins/third-party-plugin/src/index.js | 118 +++++++++++-- src/components/DynamicToolbarButtons.jsx | 22 +-- src/components/Editor.jsx | 5 + src/index.js | 3 +- src/store/app-store.js | 166 ------------------ src/store/app/actions.js | 60 +++++++ src/store/app/index.js | 15 ++ src/store/app/reducer.js | 97 ++++++++++ src/store/app/selectors.js | 34 ++++ src/store/document-editor/actions.js | 0 src/store/document-editor/reducer.js | 0 src/store/document-editor/selectors.js | 0 src/store/editor-toolbar/actions.js | 9 + src/store/editor-toolbar/index.js | 34 ++++ .../reducer.js} | 23 +-- src/store/editor-toolbar/selectors.js | 5 + src/store/index.js | 41 +---- 19 files changed, 389 insertions(+), 272 deletions(-) delete mode 100644 src/store/app-store.js create mode 100644 src/store/app/actions.js create mode 100644 src/store/app/reducer.js create mode 100644 src/store/app/selectors.js create mode 100644 src/store/document-editor/actions.js create mode 100644 src/store/document-editor/reducer.js create mode 100644 src/store/document-editor/selectors.js create mode 100644 src/store/editor-toolbar/actions.js create mode 100644 src/store/editor-toolbar/index.js rename src/store/{editor-toolbar-store.js => editor-toolbar/reducer.js} (58%) create mode 100644 src/store/editor-toolbar/selectors.js diff --git a/plugins/third-party-plugin/src/components/ShareDocumentButton/ShareDocumentButton.jsx b/plugins/third-party-plugin/src/components/ShareDocumentButton/ShareDocumentButton.jsx index 586e552..70eb111 100644 --- a/plugins/third-party-plugin/src/components/ShareDocumentButton/ShareDocumentButton.jsx +++ b/plugins/third-party-plugin/src/components/ShareDocumentButton/ShareDocumentButton.jsx @@ -3,7 +3,6 @@ import React from 'react'; import { Icon, external } from '@wordpress/icons'; import { VisuallyHidden } from '@wordpress/components'; import { useEditorContext } from '@graphiql/react'; -import LZString from 'lz-string'; import { useCopyToClipboard } from '../../../../../src/hooks/useCopyToClipboard'; /** @@ -51,22 +50,4 @@ export const ShareDocumentButton = ({ ToolbarButton }) => { ); }; -/** - * Compresses and encodes a query parameter object for use in a shareable URL. - * - * @param {Object} obj The object containing query parameters to be compressed and encoded. - * @return {string} A compressed and encoded string representing the query parameters. - */ -export function getHashedQueryParams( obj ) { - if ( typeof obj !== 'object' || obj === null ) { - console.error( 'Input must be a non-null object' ); - return ''; - } - try { - const queryParamString = JSON.stringify( obj ); - return LZString.compressToEncodedURIComponent( queryParamString ); - } catch ( error ) { - console.error( 'Failed to compress query parameter object:', error ); - return ''; - } -} + diff --git a/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/ToggleAuthenticationButton.module.css b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/ToggleAuthenticationButton.module.css index 9cf1776..5ac4478 100644 --- a/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/ToggleAuthenticationButton.module.css +++ b/plugins/third-party-plugin/src/components/ToggleAuthenticationButton/ToggleAuthenticationButton.module.css @@ -9,10 +9,10 @@ .authAvatarPublic { filter: grayscale(100%) !important; +} - .authBadge { - animation: bounceOut 0.5s forwards; - } +.authAvatarPublic .authBadge { + animation: bounceOut 0.5s forwards; } .authBadge { @@ -55,4 +55,4 @@ transform: scale(0.2); opacity: 0; } -} \ No newline at end of file +} diff --git a/plugins/third-party-plugin/src/index.js b/plugins/third-party-plugin/src/index.js index f9dd844..bd9047d 100644 --- a/plugins/third-party-plugin/src/index.js +++ b/plugins/third-party-plugin/src/index.js @@ -1,27 +1,99 @@ -import ToggleAuthenticationButton from './components/ToggleAuthenticationButton'; -import PrettifyButton from './components/PrettifyButton'; -import ShareDocumentButton from './components/ShareDocumentButton'; +/* global WPGRAPHQL_IDE_DATA */ import MergeFragmentsButton from './components/MergeFragmentsButton'; import CopyQueryButton from './components/CopyQueryButton'; +import {select, dispatch, useSelect, useDispatch} from "@wordpress/data"; +import styles from "./components/ToggleAuthenticationButton/ToggleAuthenticationButton.module.css"; +import clsx from "clsx"; +import {PrettifyIcon} from "@graphiql/react"; +import React from 'react'; +import {useCopyToClipboard} from "../../../src/hooks/useCopyToClipboard"; +import LZString from "lz-string"; + window.addEventListener( 'WPGraphQLIDEReady', () => { const { registerEditorToolbarButton } = window.WPGraphQLIDE; - registerEditorToolbarButton( 'toggle-auth-button', { - title: 'Toggle Authentication', - component: ToggleAuthenticationButton, + /** + * Register the toggle authentication button. + * + * This button allows the user to switch between executing queries as the logged-in user + * or as a public user. + */ + registerEditorToolbarButton( 'toggle-auth', () => { + const isAuthenticated = select( 'wpgraphql-ide/app' ).isAuthenticated(); + const avatarUrl = window.WPGRAPHQL_IDE_DATA?.context?.avatarUrl; + return { + label: isAuthenticated + ? 'Switch to execute as a public user' + : 'Switch to execute as the logged-in user', + children: ( + + + + ), + className: clsx( + 'graphiql-un-styled', + 'graphiql-toolbar-button graphiql-auth-button', + { + [ styles.authAvatarPublic ]: ! isAuthenticated, + 'is-authenticated': isAuthenticated, + 'is-public': ! isAuthenticated, + } + ), + onClick: () => { + dispatch( 'wpgraphql-ide/app' ).toggleAuthentication(); + } + }; } ); - registerEditorToolbarButton( 'prettify-button', { - title: 'Prettify query (Shift-Ctrl-P)', - component: PrettifyButton + registerEditorToolbarButton( 'prettify', () => { + const query = useSelect( ( select ) => select( 'wpgraphql-ide/app' ).getQuery() ); + const { prettifyQuery } = useDispatch( 'wpgraphql-ide/app' ); + + return { + label: 'Prettify query (Shift-Ctrl-P)', + children: ( +