GraphQL query editor transformer works!

This commit is contained in:
Gregory Schier
2023-03-14 19:08:18 -07:00
parent b9294ff994
commit 3247190a46
9 changed files with 51 additions and 21 deletions

Binary file not shown.

View File

@@ -81,13 +81,11 @@ function FormRow({
pair,
onChange,
onDelete,
onFocus,
isLast,
}: {
pair: PairWithId;
onChange: (pair: PairWithId) => void;
onDelete?: (pair: PairWithId) => void;
onFocus?: (pair: PairWithId) => void;
isLast?: boolean;
}) {
return (
@@ -99,7 +97,6 @@ function FormRow({
label="Name"
name="name"
onChange={(name) => onChange({ id: pair.id, header: { name } })}
onFocus={() => onFocus?.(pair)}
placeholder="name"
useEditor={{ useTemplating: true }}
/>
@@ -110,7 +107,6 @@ function FormRow({
label="Value"
name="value"
onChange={(value) => onChange({ id: pair.id, header: { value } })}
onFocus={() => onFocus?.(pair)}
placeholder="value"
useEditor={{ useTemplating: true }}
/>
@@ -118,7 +114,8 @@ function FormRow({
<IconButton
icon="trash"
onClick={() => onDelete(pair)}
className="invisible group-hover:visible"
tabIndex={-1}
className={classnames('opacity-0 group-hover:opacity-100')}
/>
)}
</div>

View File

@@ -1,10 +1,12 @@
import classnames from 'classnames';
import { act } from 'react-dom/test-utils';
import { useActiveRequest } from '../hooks/useActiveRequest';
import { useSendRequest } from '../hooks/useSendRequest';
import { useUpdateRequest } from '../hooks/useUpdateRequest';
import { Editor } from './core/Editor';
import { HeaderEditor } from './HeaderEditor';
import { TabContent, Tabs } from './core/Tabs/Tabs';
import { GraphQLEditor } from './editors/GraphQLEditor';
import { HeaderEditor } from './HeaderEditor';
import { UrlBar } from './UrlBar';
interface Props {
@@ -63,21 +65,20 @@ export function RequestPane({ fullHeight, className }: Props) {
{activeRequest.bodyType === 'json' ? (
<Editor
key={activeRequest.id}
useTemplating
className="!bg-gray-50"
heightMode={fullHeight ? 'full' : 'auto'}
useTemplating
defaultValue={activeRequest.body ?? ''}
contentType="application/json"
onChange={(body) => updateRequest.mutate({ body })}
/>
) : activeRequest.bodyType === 'graphql' ? (
<Editor
<GraphQLEditor
key={activeRequest.id}
className="!bg-gray-50"
heightMode={fullHeight ? 'full' : 'auto'}
useTemplating
defaultValue={activeRequest.body ?? ''}
contentType="application/graphql+json"
className="!bg-gray-50"
defaultValue={activeRequest?.body ?? ''}
heightMode={fullHeight ? 'full' : 'auto'}
onChange={(body) => updateRequest.mutate({ body })}
/>
) : (

View File

@@ -6,6 +6,7 @@ import { VStack } from './core/Stacks';
export default function RouteError() {
const error = useRouteError();
const stringified = JSON.stringify(error);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const message = (error as any).message ?? stringified;
return (
<div className="flex items-center justify-center h-full">

View File

@@ -31,7 +31,7 @@ export default function Workspace() {
: 'grid-cols-1 grid-rows-[minmax(0,auto)_minmax(0,100%)]',
)}
>
<RequestPane fullHeight={isH} className={classnames(!isH && 'pr-2 pb-0')} />
<RequestPane fullHeight={isH} className={classnames(!isH && 'pr-2')} />
<ResponsePane />
</div>
</div>

View File

@@ -33,7 +33,6 @@ import {
} from '@codemirror/view';
import { tags as t } from '@lezer/highlight';
import { graphqlLanguageSupport } from 'cm6-graphql';
import { debouncedAutocompletionDisplay } from './autocomplete';
import { twig } from './twig/extension';
import { url } from './url/extension';
@@ -78,7 +77,7 @@ export const myHighlightStyle = HighlightStyle.define([
// ]);
const syntaxExtensions: Record<string, LanguageSupport> = {
'application/graphql+json': graphqlLanguageSupport(),
'application/graphql': graphqlLanguageSupport(),
'application/json': json(),
'application/javascript': javascript(),
'text/html': html(),

View File

@@ -1,6 +1,6 @@
import * as T from '@radix-ui/react-tabs';
import classnames from 'classnames';
import type { ReactElement, ReactNode } from 'react';
import type { ReactNode } from 'react';
import { useState } from 'react';
import { Button } from '../Button';
import type { DropdownMenuRadioItem, DropdownMenuRadioProps } from '../Dropdown';
@@ -81,7 +81,7 @@ export function Tabs({ defaultValue, label, children, tabs, className, tabListCl
)}
>
{t.options.items.find((i) => i.value === t.options?.value)?.label ?? ''}
<Icon icon="triangleDown" className="-mr-1.5" />
<Icon icon="triangleDown" className="-mr-1.5 opacity-40" />
</Button>
</T.Trigger>
);

View File

@@ -0,0 +1,32 @@
import { useMemo } from 'react';
import type { EditorProps } from '../core/Editor';
import { Editor } from '../core/Editor';
type Props = Pick<
EditorProps,
'heightMode' | 'onChange' | 'defaultValue' | 'className' | 'useTemplating'
>;
export function GraphQLEditor({ defaultValue, onChange, ...props }: Props) {
const { query } = useMemo(() => {
try {
const { query } = JSON.parse(defaultValue ?? '{}');
return { query };
} catch (err) {
return { query: 'failed to parse' };
}
}, [defaultValue]);
const handleChange = (query: string) => {
onChange?.(JSON.stringify({ query }, null, 2));
};
return (
<Editor
defaultValue={query ?? ''}
onChange={handleChange}
contentType="application/graphql"
{...props}
/>
);
}

View File

@@ -11,11 +11,11 @@ const darkTheme: AppTheme = {
blackPoint: 0.2,
colors: {
gray: '#6b5b98',
red: '#ee3b3b',
red: '#ff417b',
orange: '#ff9411',
yellow: '#dcc73b',
green: '#44cb44',
blue: '#2e91ff',
yellow: '#e8d13f',
green: '#43e76f',
blue: '#219dff',
pink: '#f670f6',
violet: '#b176ff',
},