mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-09 18:53:38 +02:00
Fix GraphQL schema getting nuked on codemirror language refresh
This commit is contained in:
@@ -12,9 +12,10 @@ import { settingsAtom } from '@yaakapp-internal/models';
|
|||||||
import type { EditorLanguage, TemplateFunction } from '@yaakapp-internal/plugins';
|
import type { EditorLanguage, TemplateFunction } from '@yaakapp-internal/plugins';
|
||||||
import { parseTemplate } from '@yaakapp-internal/templates';
|
import { parseTemplate } from '@yaakapp-internal/templates';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import type { GraphQLSchema } from 'graphql';
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
import { md5 } from 'js-md5';
|
import { md5 } from 'js-md5';
|
||||||
import type { MutableRefObject, ReactNode } from 'react';
|
import type { ReactNode, RefObject } from 'react';
|
||||||
import {
|
import {
|
||||||
Children,
|
Children,
|
||||||
cloneElement,
|
cloneElement,
|
||||||
@@ -77,6 +78,7 @@ export interface EditorProps {
|
|||||||
hideGutter?: boolean;
|
hideGutter?: boolean;
|
||||||
id?: string;
|
id?: string;
|
||||||
language?: EditorLanguage | 'pairs' | 'url';
|
language?: EditorLanguage | 'pairs' | 'url';
|
||||||
|
graphQLSchema?: GraphQLSchema | null;
|
||||||
onBlur?: () => void;
|
onBlur?: () => void;
|
||||||
onChange?: (value: string) => void;
|
onChange?: (value: string) => void;
|
||||||
onFocus?: () => void;
|
onFocus?: () => void;
|
||||||
@@ -115,6 +117,7 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
|
|||||||
format,
|
format,
|
||||||
heightMode,
|
heightMode,
|
||||||
hideGutter,
|
hideGutter,
|
||||||
|
graphQLSchema,
|
||||||
language,
|
language,
|
||||||
onBlur,
|
onBlur,
|
||||||
onChange,
|
onChange,
|
||||||
@@ -374,6 +377,7 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
|
|||||||
onClickVariable,
|
onClickVariable,
|
||||||
onClickMissingVariable,
|
onClickMissingVariable,
|
||||||
onClickPathParameter,
|
onClickPathParameter,
|
||||||
|
graphQLSchema: graphQLSchema ?? null,
|
||||||
});
|
});
|
||||||
view.dispatch({ effects: languageCompartment.reconfigure(ext) });
|
view.dispatch({ effects: languageCompartment.reconfigure(ext) });
|
||||||
}, [
|
}, [
|
||||||
@@ -386,6 +390,7 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
|
|||||||
onClickPathParameter,
|
onClickPathParameter,
|
||||||
completionOptions,
|
completionOptions,
|
||||||
useTemplating,
|
useTemplating,
|
||||||
|
graphQLSchema,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Initialize the editor when ref mounts
|
// Initialize the editor when ref mounts
|
||||||
@@ -408,6 +413,7 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
|
|||||||
onClickVariable,
|
onClickVariable,
|
||||||
onClickMissingVariable,
|
onClickMissingVariable,
|
||||||
onClickPathParameter,
|
onClickPathParameter,
|
||||||
|
graphQLSchema: graphQLSchema ?? null,
|
||||||
});
|
});
|
||||||
const extensions = [
|
const extensions = [
|
||||||
languageCompartment.of(langExt),
|
languageCompartment.of(langExt),
|
||||||
@@ -595,12 +601,12 @@ function getExtensions({
|
|||||||
}: Pick<EditorProps, 'singleLine' | 'readOnly' | 'hideGutter'> & {
|
}: Pick<EditorProps, 'singleLine' | 'readOnly' | 'hideGutter'> & {
|
||||||
stateKey: EditorProps['stateKey'];
|
stateKey: EditorProps['stateKey'];
|
||||||
container: HTMLDivElement | null;
|
container: HTMLDivElement | null;
|
||||||
onChange: MutableRefObject<EditorProps['onChange']>;
|
onChange: RefObject<EditorProps['onChange']>;
|
||||||
onPaste: MutableRefObject<EditorProps['onPaste']>;
|
onPaste: RefObject<EditorProps['onPaste']>;
|
||||||
onPasteOverwrite: MutableRefObject<EditorProps['onPasteOverwrite']>;
|
onPasteOverwrite: RefObject<EditorProps['onPasteOverwrite']>;
|
||||||
onFocus: MutableRefObject<EditorProps['onFocus']>;
|
onFocus: RefObject<EditorProps['onFocus']>;
|
||||||
onBlur: MutableRefObject<EditorProps['onBlur']>;
|
onBlur: RefObject<EditorProps['onBlur']>;
|
||||||
onKeyDown: MutableRefObject<EditorProps['onKeyDown']>;
|
onKeyDown: RefObject<EditorProps['onKeyDown']>;
|
||||||
}) {
|
}) {
|
||||||
// TODO: Ensure tooltips render inside the dialog if we are in one.
|
// TODO: Ensure tooltips render inside the dialog if we are in one.
|
||||||
const parent =
|
const parent =
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import {
|
|||||||
import { tags as t } from '@lezer/highlight';
|
import { tags as t } from '@lezer/highlight';
|
||||||
import type { EnvironmentVariable } from '@yaakapp-internal/models';
|
import type { EnvironmentVariable } from '@yaakapp-internal/models';
|
||||||
import { graphql } from 'cm6-graphql';
|
import { graphql } from 'cm6-graphql';
|
||||||
|
import type { GraphQLSchema } from 'graphql';
|
||||||
import { activeRequestIdAtom } from '../../../hooks/useActiveRequestId';
|
import { activeRequestIdAtom } from '../../../hooks/useActiveRequestId';
|
||||||
import { jotaiStore } from '../../../lib/jotai';
|
import { jotaiStore } from '../../../lib/jotai';
|
||||||
import { renderMarkdown } from '../../../lib/markdown';
|
import { renderMarkdown } from '../../../lib/markdown';
|
||||||
@@ -106,6 +107,7 @@ export function getLanguageExtension({
|
|||||||
onClickMissingVariable,
|
onClickMissingVariable,
|
||||||
onClickPathParameter,
|
onClickPathParameter,
|
||||||
completionOptions,
|
completionOptions,
|
||||||
|
graphQLSchema,
|
||||||
}: {
|
}: {
|
||||||
useTemplating: boolean;
|
useTemplating: boolean;
|
||||||
environmentVariables: EnvironmentVariable[];
|
environmentVariables: EnvironmentVariable[];
|
||||||
@@ -113,6 +115,7 @@ export function getLanguageExtension({
|
|||||||
onClickMissingVariable: (name: string, tagValue: string, startPos: number) => void;
|
onClickMissingVariable: (name: string, tagValue: string, startPos: number) => void;
|
||||||
onClickPathParameter: (name: string) => void;
|
onClickPathParameter: (name: string) => void;
|
||||||
completionOptions: TwigCompletionOption[];
|
completionOptions: TwigCompletionOption[];
|
||||||
|
graphQLSchema: GraphQLSchema | null;
|
||||||
} & Pick<EditorProps, 'language' | 'autocomplete'>) {
|
} & Pick<EditorProps, 'language' | 'autocomplete'>) {
|
||||||
const extraExtensions: Extension[] = [];
|
const extraExtensions: Extension[] = [];
|
||||||
|
|
||||||
@@ -128,7 +131,7 @@ export function getLanguageExtension({
|
|||||||
// GraphQL is a special exception
|
// GraphQL is a special exception
|
||||||
if (language === 'graphql') {
|
if (language === 'graphql') {
|
||||||
return [
|
return [
|
||||||
graphql(undefined, {
|
graphql(graphQLSchema ?? undefined, {
|
||||||
async onCompletionInfoRender(gqlCompletionItem): Promise<Node | null> {
|
async onCompletionInfoRender(gqlCompletionItem): Promise<Node | null> {
|
||||||
if (!gqlCompletionItem.documentation) return null;
|
if (!gqlCompletionItem.documentation) return null;
|
||||||
const innerHTML = await renderMarkdown(gqlCompletionItem.documentation);
|
const innerHTML = await renderMarkdown(gqlCompletionItem.documentation);
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import type { EditorView } from '@codemirror/view';
|
import type { EditorView } from '@codemirror/view';
|
||||||
import type { HttpRequest } from '@yaakapp-internal/models';
|
import type { HttpRequest } from '@yaakapp-internal/models';
|
||||||
import { updateSchema } from 'cm6-graphql';
|
|
||||||
|
|
||||||
import { formatSdl } from 'format-graphql';
|
import { formatSdl } from 'format-graphql';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import { useEffect, useMemo, useRef } from 'react';
|
import { useMemo, useRef } from 'react';
|
||||||
import { useLocalStorage } from 'react-use';
|
import { useLocalStorage } from 'react-use';
|
||||||
import { useIntrospectGraphQL } from '../../hooks/useIntrospectGraphQL';
|
import { useIntrospectGraphQL } from '../../hooks/useIntrospectGraphQL';
|
||||||
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
|
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
|
||||||
@@ -63,12 +62,6 @@ export function GraphQLEditor({ request, onChange, baseRequest, ...extraEditorPr
|
|||||||
onChange(newBody);
|
onChange(newBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Refetch the schema when the URL changes
|
|
||||||
useEffect(() => {
|
|
||||||
if (editorViewRef.current == null) return;
|
|
||||||
updateSchema(editorViewRef.current, schema ?? undefined);
|
|
||||||
}, [schema]);
|
|
||||||
|
|
||||||
const actions = useMemo<EditorProps['actions']>(
|
const actions = useMemo<EditorProps['actions']>(
|
||||||
() => [
|
() => [
|
||||||
<div key="actions" className="flex flex-row !opacity-100 !shadow">
|
<div key="actions" className="flex flex-row !opacity-100 !shadow">
|
||||||
@@ -201,6 +194,7 @@ export function GraphQLEditor({ request, onChange, baseRequest, ...extraEditorPr
|
|||||||
<Editor
|
<Editor
|
||||||
language="graphql"
|
language="graphql"
|
||||||
heightMode="auto"
|
heightMode="auto"
|
||||||
|
graphQLSchema={schema}
|
||||||
format={formatSdl}
|
format={formatSdl}
|
||||||
defaultValue={currentBody.query}
|
defaultValue={currentBody.query}
|
||||||
onChange={handleChangeQuery}
|
onChange={handleChangeQuery}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ export function useFilterResponse({
|
|||||||
filter,
|
filter,
|
||||||
})) as FilterResponse;
|
})) as FilterResponse;
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
console.log("Failed to filter response:", result.error);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user