Skip to content

feat: p.o.c showing how to make the toolbar extendable #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 80 additions & 2 deletions src/components/Editor.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
/* global WPGRAPHQL_IDE_DATA */
import { GraphiQL } from 'graphiql';
import {
ToolbarButton,
PrettifyIcon,
usePrettifyEditors,
useCopyQuery,
useMergeQuery,
MergeIcon,
CopyIcon,
useEditorContext
} from '@graphiql/react';

// Assuming wp.hooks is globally available through WordPress's script enqueueing mechanism.
const { applyFilters } = wp.hooks;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use @wordpress/hooks here so that this can eventually be ran outside of WordPress and also signal to @wordpress/scripts to add this dependency to *.asset.php.


import 'graphiql/graphiql.min.css';

Expand All @@ -18,13 +31,78 @@ const fetcher = async ( graphQLParams ) => {
return response.json();
};

const CustomButton = () => <button>custom</button>
const PrettifyButton = ( { onClick } ) => {
const prettify = usePrettifyEditors();
return (
<ToolbarButton onClick={prettify} label="Prettify query (Shift-Ctrl-P)">
<PrettifyIcon className="graphiql-toolbar-icon" aria-hidden="true" />
</ToolbarButton>
)
}

const CopyQueryButton = ({ onCopyQuery }) => {
const copy = useCopyQuery({ onCopyQuery });
return (
<ToolbarButton onClick={copy} label="Copy query (Shift-Ctrl-C)">
<CopyIcon className="graphiql-toolbar-icon" aria-hidden="true" />
</ToolbarButton>
)
}

const MergeFragmentsButton = () => {
const merge = useMergeQuery();
return (
<ToolbarButton
onClick={merge}
label="Merge fragments into query (Shift-Ctrl-M)"
>
<MergeIcon className="graphiql-toolbar-icon" aria-hidden="true" />
</ToolbarButton>
)
}

/**
* This button would provide a sharable link to users that they can use to share the current
* query and the user that visits the link would see the same query in the editor.
*
* The way I see this working is that the query would be hashed (similar to current WPGraphQL IDE) but instead of persisting the state in the URL as the query changes,
* it would be hashed when the "share" button is clicked and then appended to the current URL or a generic admin URL that could then be shared.
*
* i.e. site.com/wp-admin/admin.php?page=wpgraphql-ide&query=HASHED_QUERY
*
* Then GraphiQL would open with the query un-hashed and already set as the current query in the editor.
*
* This button, or similar buttons to it could/should be able to be "filtered" into GraphiQL by 3rd parties.
*/
const ShareDocumentButton = () => {
const { queryEditor } = useEditorContext();

// get the document from the queryEditor
const document = queryEditor?.operations ?? '';

// @todo: Implement the logic to generate a sharable link.
return (
<button onClick={ () => {
alert( 'clicking this would hash the current query and append it to the current URL or a generic admin URL that could then be shared.' );
}}>Share Link</button>
)
}

/**
* Filter the Buttons to allow 3rd parties to add their own buttons to the GraphiQL Toolbar.
*/
const toolbarButtons = applyFilters( 'wpgraphqlide_toolbar_buttons', {
copy: CopyQueryButton,
prettify: PrettifyButton,
merge: MergeFragmentsButton,
custom: ShareDocumentButton,
});

export function Editor( { setDrawerOpen } ) {
return (
<GraphiQL fetcher={ fetcher }>
<GraphiQL.Toolbar>
<CustomButton />
{Object.entries(toolbarButtons).map(([key, Button]) => <Button key={key} />)}
</GraphiQL.Toolbar>
<GraphiQL.Logo>
<button
Expand Down