diff --git a/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/GraphiQLWrapper/GraphiQLWrapper.js b/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/GraphiQLWrapper/GraphiQLWrapper.js index ff35d90dfec..76ceeeacd29 100644 --- a/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/GraphiQLWrapper/GraphiQLWrapper.js +++ b/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/GraphiQLWrapper/GraphiQLWrapper.js @@ -198,7 +198,7 @@ class GraphiQLWrapper extends Component { ); return; } - dispatch(_push('/api/rest/create')); + dispatch(_push('/api/rest/create?from=graphiql')); }; const _toggleCacheDirective = () => { diff --git a/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/Rest/Form/RestEndpointForm.tsx b/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/Rest/Form/RestEndpointForm.tsx index 94bb2714b66..84c8d0da4e8 100644 --- a/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/Rest/Form/RestEndpointForm.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/Rest/Form/RestEndpointForm.tsx @@ -15,7 +15,8 @@ import globals from '../../../../../Globals'; import { FaArrowRight, FaMagic } from 'react-icons/fa'; import { IndicatorCard } from '../../../../../new-components/IndicatorCard'; import clsx from 'clsx'; -import { Link } from 'react-router'; +import { openInGraphiQL } from '../../../../../features/RestEndpoints/components/RestEndpointDetails/utils'; +import { Analytics } from '../../../../../features/Analytics'; const editorOptions = { minLines: 10, @@ -131,11 +132,19 @@ export const RestEndpointForm: React.FC = ({ description="Support GraphQL queries and mutations." editorOptions={editorOptions} /> -
- - {request ? 'Test it in ' : 'Import from '} GraphiQL{' '} - - +
+ + +
@@ -159,8 +168,8 @@ export const RestEndpointForm: React.FC = ({ customIcon={FaMagic} headline="No Parameterized variable specification needed" > - All parameterized variables in your GraphQL query will be - auto-specifed in the URL + All parameterized variables (e.g. {prependLabel}example/:id) in your + GraphQL query will be auto-specifed in the URL = ({ - + + + diff --git a/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/Rest/Form/index.tsx b/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/Rest/Form/index.tsx index f74453594d1..c880bf4dc17 100644 --- a/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/Rest/Form/index.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/components/Services/ApiExplorer/Rest/Form/index.tsx @@ -1,10 +1,12 @@ import React from 'react'; import { RouteComponentProps } from 'react-router'; import { connect, ConnectedProps } from 'react-redux'; +import queryString from 'query-string'; import { Analytics, REDACT_EVERYTHING, } from '../../../../../features/Analytics'; +import { parse, print } from 'graphql'; import { AllowedRESTMethods, RestEndpointEntry, @@ -84,8 +86,14 @@ const useRestEndpointFormStateForCreation: RestEndpointFormStateHook = ( formSubmitHandler: RestEndpointFormSubmitHandler; } => { const formState: RestEndpointFormState = {}; - formState.request = getLSItem(LS_KEYS.graphiqlQuery) ?? undefined; - + try { + const parsedQuery = queryString.parseUrl(window.location.href); + if (parsedQuery.query?.from === 'graphiql') { + formState.request = print(parse(getLSItem(LS_KEYS.graphiqlQuery) ?? '')); + } + } catch (e) { + // ignore + } return { formState, formSubmitHandler: createEndpoint }; }; diff --git a/frontend/libs/console/legacy-ce/src/lib/features/RestEndpoints/components/RestEndpointDetails/RequestHeaders.tsx b/frontend/libs/console/legacy-ce/src/lib/features/RestEndpoints/components/RestEndpointDetails/RequestHeaders.tsx index 3b062ddfae4..30d783432be 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/RestEndpoints/components/RestEndpointDetails/RequestHeaders.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/RestEndpoints/components/RestEndpointDetails/RequestHeaders.tsx @@ -12,6 +12,12 @@ type RequestHeadersProps = { export const RequestHeaders = (props: RequestHeadersProps) => { const { headers, setHeaders } = props; + + const showRemove = !!( + headers.length > 1 || + headers?.[0]?.name || + headers?.[0]?.value + ); return ( {
Headers List
header.selected)} @@ -49,72 +55,74 @@ export const RequestHeaders = (props: RequestHeadersProps) => { 'Name', 'Value', ]} - data={headers.map((header, i) => [ - - setHeaders( - headers.map(h => ({ - ...h, - selected: h.name === header.name ? !!checked : h.selected, - })) - ) - } - />, - - setHeaders( - headers.map(h => ({ - ...h, - name: h.name === header.name ? e.target.value : h.name, - })) - ) - } - />, - - setHeaders( - headers.map(h => ({ - ...h, - value: h.name === header.name ? e.target.value : h.value, - })) - ) - } - />, + data={headers.map((header, i) => + [ + + setHeaders( + headers.map(h => ({ + ...h, + selected: h.name === header.name ? !!checked : h.selected, + })) + ) + } + />, + + setHeaders( + headers.map(h => ({ + ...h, + name: h.name === header.name ? e.target.value : h.name, + })) + ) + } + />, + + setHeaders( + headers.map(h => ({ + ...h, + value: h.name === header.name ? e.target.value : h.value, + })) + ) + } + />, + showRemove && ( + - ), - ])} + if (newHeaders.length === 0) { + newHeaders.push({ + name: '', + value: '', + selected: true, + }); + } + setHeaders(newHeaders); + }} + > + Remove + + ), + ].filter(Boolean) + )} />
diff --git a/frontend/libs/console/legacy-ce/src/lib/features/RestEndpoints/components/RestEndpointDetails/RestEndpointDetails.tsx b/frontend/libs/console/legacy-ce/src/lib/features/RestEndpoints/components/RestEndpointDetails/RestEndpointDetails.tsx index e6efa0528a5..29b6ffef298 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/RestEndpoints/components/RestEndpointDetails/RestEndpointDetails.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/RestEndpoints/components/RestEndpointDetails/RestEndpointDetails.tsx @@ -1,5 +1,6 @@ import React, { useEffect } from 'react'; import { z } from 'zod'; +import AceEditor from 'react-ace'; import { CheckboxesField, CodeEditorField, @@ -10,13 +11,15 @@ import { import { Button } from '../../../../new-components/Button'; import { FaArrowRight, FaPlay } from 'react-icons/fa'; import { useRestEndpoint } from '../../hooks/useRestEndpoint'; -import { getSessionVarsFromLS } from '../../../../components/Common/ConfigureTransformation/utils'; import { parseQueryVariables } from '../../../../components/Services/ApiExplorer/Rest/utils'; import { useRestEndpointRequest } from '../../hooks/useRestEndpointRequest'; -import { IndicatorCard } from '../../../../new-components/IndicatorCard'; import { RequestHeaders } from './RequestHeaders'; import { Variables } from './Variables'; import { AllowedRESTMethods } from '../../../../metadata/types'; +import { openInGraphiQL } from './utils'; +import { LS_KEYS, getLSItem } from '../../../../utils'; +import { hasuraToast } from '../../../../new-components/Toasts'; +import { Analytics } from '../../../Analytics'; export type Variable = Exclude< ReturnType, @@ -66,10 +69,37 @@ const validationSchema = z.object({ request: z.string().min(1, { message: 'Please add a GraphQL query' }), }); +export const getInitialHeaders = (): Header[] => { + const headers = getLSItem(LS_KEYS.apiExplorerConsoleGraphQLHeaders); + + if (headers) { + return JSON.parse(headers).map( + (header: { key: string; value: string; isDisabled: boolean }) => { + const value = + header.key === 'x-hasura-admin-secret' + ? window.__env.adminSecret || getLSItem(LS_KEYS.consoleAdminSecret) + : header.value; + return { + name: header.key, + value, + selected: !header.isDisabled, + }; + } + ); + } + return [ + { + name: '', + value: '', + selected: true, + }, + ]; +}; + export const RestEndpointDetails = (props: RestEndpointDetailsProps) => { const endpoint = useRestEndpoint(props.name); - const initialHeaders = getSessionVarsFromLS(); + const initialHeaders = getInitialHeaders(); const [headers, setHeaders] = React.useState( initialHeaders.map(header => ({ @@ -80,11 +110,7 @@ export const RestEndpointDetails = (props: RestEndpointDetailsProps) => { const [variables, setVariables] = React.useState([]); - const { data, refetch, isFetching, error } = useRestEndpointRequest( - endpoint?.endpoint, - headers, - variables - ); + const { data, mutate, isLoading } = useRestEndpointRequest(); const { Form, @@ -129,10 +155,17 @@ export const RestEndpointDetails = (props: RestEndpointDetailsProps) => { label="GraphQL Request" /> -
- - Test it in GraphiQL - +
+