use same prettify mechanic for both editors (#5616)

This commit is contained in:
Jack Kavanagh 2023-01-05 15:10:26 +01:00 committed by GitHub
parent ac0dd5e4b3
commit 21c78170b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 47 deletions

View File

@ -233,14 +233,6 @@ export function resolveHomePath(p: string) {
} }
} }
export function jsonParseOr(str: string, fallback: any): any {
try {
return JSON.parse(str);
} catch (err) {
return fallback;
}
}
export function escapeHTML(unsafeText: string) { export function escapeHTML(unsafeText: string) {
const div = document.createElement('div'); const div = document.createElement('div');
div.innerText = unsafeText; div.innerText = unsafeText;

View File

@ -16,12 +16,11 @@ import { useLocalStorage } from 'react-use';
import { CONTENT_TYPE_JSON } from '../../../../common/constants'; import { CONTENT_TYPE_JSON } from '../../../../common/constants';
import { database as db } from '../../../../common/database'; import { database as db } from '../../../../common/database';
import { markdownToHTML } from '../../../../common/markdown-to-html'; import { markdownToHTML } from '../../../../common/markdown-to-html';
import { jsonParseOr } from '../../../../common/misc';
import type { ResponsePatch } from '../../../../main/network/libcurl-promise'; import type { ResponsePatch } from '../../../../main/network/libcurl-promise';
import * as models from '../../../../models'; import * as models from '../../../../models';
import type { Request } from '../../../../models/request'; import type { Request } from '../../../../models/request';
import * as network from '../../../../network/network'; import * as network from '../../../../network/network';
import { jsonPrettify } from '../../../../utils/prettify/json'; import { invariant } from '../../../../utils/invariant';
import { selectSettings } from '../../../redux/selectors'; import { selectSettings } from '../../../redux/selectors';
import { Dropdown } from '../../base/dropdown/dropdown'; import { Dropdown } from '../../base/dropdown/dropdown';
import { DropdownButton } from '../../base/dropdown/dropdown-button'; import { DropdownButton } from '../../base/dropdown/dropdown-button';
@ -54,15 +53,9 @@ const fetchGraphQLSchemaForRequest = async ({
if (!url) { if (!url) {
return; return;
} }
const request = await models.request.getById(requestId); const request = await models.request.getById(requestId);
invariant(request, 'Request not found');
if (!request) {
return;
}
try { try {
const bodyJson = JSON.stringify({ const bodyJson = JSON.stringify({
query: getIntrospectionQuery(), query: getIntrospectionQuery(),
operationName: 'IntrospectionQuery', operationName: 'IntrospectionQuery',
@ -115,8 +108,8 @@ const fetchGraphQLSchemaForRequest = async ({
interface GraphQLBody { interface GraphQLBody {
query: string; query: string;
variables?: string; variables: string;
operationName?: string; operationName: string;
} }
interface Props { interface Props {
@ -146,28 +139,25 @@ export const GraphQLEditor: FC<Props> = ({
uniquenessKey, uniquenessKey,
workspaceId, workspaceId,
}) => { }) => {
let requestBody: GraphQLBody; let initial: GraphQLBody = {
query: '',
variables: '',
operationName: '',
};
let documentAST = null;
try { try {
requestBody = JSON.parse(request.body.text || ''); initial = JSON.parse(request.body.text || '');
} catch (err) { initial.query = initial.query || '';
requestBody = { query: '' }; initial.variables = JSON.stringify(initial.variables || '', null, 2);
} initial.operationName = initial.operationName || '';
if (typeof requestBody.variables === 'string') { documentAST = parse(initial.query);
requestBody.variables = jsonParseOr(requestBody.variables, '');
}
let documentAST;
try {
documentAST = parse(requestBody.query || '');
} catch (error) { } catch (error) {
documentAST = null; console.error('[graphql] Failed to parse body from database', error);
} }
const [state, setState] = useState<State>({ const [state, setState] = useState<State>({
body: { body: initial,
query: requestBody.query || '',
variables: requestBody.variables,
operationName: requestBody.operationName,
},
operations: documentAST?.definitions.filter(isOperationDefinition)?.map(def => def.name?.value || '') || [], operations: documentAST?.definitions.filter(isOperationDefinition)?.map(def => def.name?.value || '') || [],
hideSchemaFetchErrors: false, hideSchemaFetchErrors: false,
variablesSyntaxError: '', variablesSyntaxError: '',
@ -188,7 +178,8 @@ export const GraphQLEditor: FC<Props> = ({
} | undefined>(); } | undefined>();
const [schemaIsFetching, setSchemaIsFetching] = useState<boolean | null>(null); const [schemaIsFetching, setSchemaIsFetching] = useState<boolean | null>(null);
const [schemaLastFetchTime, setSchemaLastFetchTime] = useState<number>(0); const [schemaLastFetchTime, setSchemaLastFetchTime] = useState<number>(0);
const editorRef = useRef<CodeEditorHandle>(null); const queryEditorRef = useRef<CodeEditorHandle>(null);
const variablesEditorRef = useRef<CodeEditorHandle>(null);
useEffect(() => { useEffect(() => {
if (!automaticFetch) { if (!automaticFetch) {
@ -222,13 +213,12 @@ export const GraphQLEditor: FC<Props> = ({
useTabs: editorIndentWithTabs, useTabs: editorIndentWithTabs,
tabWidth: editorIndentSize, tabWidth: editorIndentSize,
}); });
const prettyVariables = body.variables && JSON.parse(jsonPrettify(JSON.stringify(body.variables)));
changeQuery(prettyQuery); changeQuery(prettyQuery);
queryEditorRef.current?.setValue(prettyQuery);
const prettyVariables = JSON.stringify(JSON.parse(body.variables || ''), null, 2);
changeVariables(prettyVariables); changeVariables(prettyVariables);
// Update editor contents variablesEditorRef.current?.setValue(prettyVariables);
if (editorRef.current) {
editorRef.current?.setValue(prettyQuery);
}
}; };
useDocBodyKeyboardShortcuts({ useDocBodyKeyboardShortcuts({
@ -240,14 +230,15 @@ export const GraphQLEditor: FC<Props> = ({
}; };
const changeVariables = (variablesInput: string) => { const changeVariables = (variablesInput: string) => {
try { try {
const variables = JSON.parse(variablesInput || 'null'); const variables = JSON.parse(variablesInput);
onChange(JSON.stringify({ ...state.body, variables })); onChange(JSON.stringify({ ...state.body, variables }));
setState(state => ({ setState(state => ({
...state, ...state,
body: { ...state.body, variables }, body: { ...state.body, variables: variablesInput },
variablesSyntaxError: '', variablesSyntaxError: '',
})); }));
} catch (err) { } catch (err) {
onChange(JSON.stringify({ ...state.body, variables: variablesInput }));
setState(state => ({ ...state, variablesSyntaxError: err.message })); setState(state => ({ ...state, variablesSyntaxError: err.message }));
} }
}; };
@ -463,11 +454,11 @@ export const GraphQLEditor: FC<Props> = ({
<div className="graphql-editor__query"> <div className="graphql-editor__query">
<CodeEditor <CodeEditor
ref={editorRef} ref={queryEditorRef}
dynamicHeight dynamicHeight
showPrettifyButton showPrettifyButton
uniquenessKey={uniquenessKey ? uniquenessKey + '::query' : undefined} uniquenessKey={uniquenessKey ? uniquenessKey + '::query' : undefined}
defaultValue={requestBody.query || ''} defaultValue={initial.query}
className={className} className={className}
onChange={changeQuery} onChange={changeQuery}
mode="graphql" mode="graphql"
@ -509,11 +500,12 @@ export const GraphQLEditor: FC<Props> = ({
</h2> </h2>
<div className="graphql-editor__variables"> <div className="graphql-editor__variables">
<CodeEditor <CodeEditor
ref={variablesEditorRef}
dynamicHeight dynamicHeight
enableNunjucks enableNunjucks
uniquenessKey={uniquenessKey ? uniquenessKey + '::variables' : undefined} uniquenessKey={uniquenessKey ? uniquenessKey + '::variables' : undefined}
showPrettifyButton={false} showPrettifyButton={false}
defaultValue={jsonPrettify(JSON.stringify(requestBody.variables))} defaultValue={initial.variables}
className={className} className={className}
getAutocompleteConstants={() => Object.keys(variableTypes)} getAutocompleteConstants={() => Object.keys(variableTypes)}
lintOptions={{ lintOptions={{