Always show GQL schema dropdown.

Fixes https://feedback.yaak.app/p/unable-to-disable-graphql-automatic-introspection
This commit is contained in:
Gregory Schier
2025-03-21 07:28:08 -07:00
parent 4c4eaba7d2
commit d86549f492
3 changed files with 57 additions and 38 deletions

View File

@@ -7,6 +7,7 @@ import { useEffect, useMemo, useRef, useState } from 'react';
import { useLocalStorage } from 'react-use';
import { useIntrospectGraphQL } from '../hooks/useIntrospectGraphQL';
import { showDialog } from '../lib/dialog';
import { Banner } from './core/Banner';
import { Button } from './core/Button';
import { Dropdown } from './core/Dropdown';
import type { EditorProps } from './core/Editor/Editor';
@@ -64,9 +65,50 @@ export function GraphQLEditor({ request, onChange, baseRequest, ...extraEditorPr
const actions = useMemo<EditorProps['actions']>(
() => [
<div key="introspection" className="!opacity-100">
{schema === undefined ? null /* Initializing */ : !error ? (
{schema === undefined ? null /* Initializing */ : (
<Dropdown
items={[
{
hidden: !error,
label: (
<Banner color="danger">
<p className="mb-1">Schema introspection failed</p>
<Button
size="xs"
color="danger"
variant="border"
onClick={() => {
showDialog({
title: 'Introspection Failed',
size: 'sm',
id: 'introspection-failed',
render: ({ hide }) => (
<>
<FormattedError>{error ?? 'unknown'}</FormattedError>
<div className="w-full my-4">
<Button
onClick={async () => {
hide();
await refetch();
}}
className="ml-auto"
color="primary"
size="sm"
>
Retry Request
</Button>
</div>
</>
),
});
}}
>
View Error
</Button>
</Banner>
),
type: 'content',
},
{
label: 'Refetch',
leftSlot: <Icon icon="refresh" />,
@@ -105,44 +147,12 @@ export function GraphQLEditor({ request, onChange, baseRequest, ...extraEditorPr
variant="border"
title="Refetch Schema"
isLoading={isLoading}
color={isLoading || schema ? 'default' : 'warning'}
color={error ? 'danger' : 'default'}
forDropdown
>
{isLoading ? 'Introspecting' : schema ? 'Schema' : 'No Schema'}
{error ? 'Introspection Failed' : schema ? 'Schema' : 'No Schema'}
</Button>
</Dropdown>
) : (
<Button
size="sm"
color="danger"
isLoading={isLoading}
onClick={() => {
showDialog({
title: 'Introspection Failed',
size: 'dynamic',
id: 'introspection-failed',
render: ({ hide }) => (
<>
<FormattedError>{error ?? 'unknown'}</FormattedError>
<div className="w-full my-4">
<Button
onClick={async () => {
hide();
await refetch();
}}
className="ml-auto"
color="primary"
size="sm"
>
Try Again
</Button>
</div>
</>
),
});
}}
>
Introspection Failed
</Button>
)}
</div>,
],

View File

@@ -558,7 +558,15 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle' | 'items'
}
if (item.type === 'content') {
return (
<div key={i} className={classNames('my-1.5 mx-2 max-w-xs')}>
// eslint-disable-next-line jsx-a11y/no-static-element-interactions,jsx-a11y/click-events-have-key-events
<div
key={i}
className={classNames('my-1 mx-2 max-w-xs')}
onClick={() => {
// Ensure the dropdown is closed when anything in the content is clicked
onClose();
}}
>
{item.label}
</div>
);

View File

@@ -51,7 +51,7 @@ export function useIntrospectGraphQL(
const bodyText = await getResponseBodyText(response);
if (response.status < 200 || response.status >= 300) {
return setError(`Request failed with status ${response.status}.\n\n${bodyText}`);
return setError(`Request failed with status ${response.status}.\nThe response body is:\n\n${bodyText}`);
}
if (bodyText === null) {
@@ -80,6 +80,7 @@ export function useIntrospectGraphQL(
}, [request.id, request.url, request.method, activeEnvironment?.id]);
const clear = useCallback(async () => {
setError('');
await setIntrospection(null);
}, [setIntrospection]);