Refactor/pre request routing (#5481)

* improve prop typings

* tidy up error a little
This commit is contained in:
Jack Kavanagh 2022-12-05 12:18:30 +01:00 committed by GitHub
parent a2a6b4bce8
commit cfc1ac09aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 59 additions and 62 deletions

View File

@ -11,8 +11,8 @@ describe('queryAllWorkspaceUrls', () => {
const w = await models.workspace.create({ const w = await models.workspace.create({
name: 'Workspace', name: 'Workspace',
}); });
await expect(queryAllWorkspaceUrls(w, models.request.type)).resolves.toHaveLength(0); await expect(queryAllWorkspaceUrls(w._id, models.request.type)).resolves.toHaveLength(0);
await expect(queryAllWorkspaceUrls(w, models.grpcRequest.type)).resolves.toHaveLength(0); await expect(queryAllWorkspaceUrls(w._id, models.grpcRequest.type)).resolves.toHaveLength(0);
}); });
it('should return urls and exclude that of the selected request', async () => { it('should return urls and exclude that of the selected request', async () => {
@ -78,17 +78,17 @@ describe('queryAllWorkspaceUrls', () => {
url: 'diff.url', url: 'diff.url',
}); });
// All items // All items
await expect(queryAllWorkspaceUrls(w, models.request.type)).resolves.toStrictEqual( await expect(queryAllWorkspaceUrls(w._id, models.request.type)).resolves.toStrictEqual(
expect.arrayContaining([r1.url, r2.url]), expect.arrayContaining([r1.url, r2.url]),
); );
await expect(queryAllWorkspaceUrls(w, models.grpcRequest.type)).resolves.toStrictEqual( await expect(queryAllWorkspaceUrls(w._id, models.grpcRequest.type)).resolves.toStrictEqual(
expect.arrayContaining([gr1.url, gr2.url]), expect.arrayContaining([gr1.url, gr2.url]),
); );
// Ignore url of the selected request id // Ignore url of the selected request id
await expect(queryAllWorkspaceUrls(w, models.request.type, r1._id)).resolves.toStrictEqual( await expect(queryAllWorkspaceUrls(w._id, models.request.type, r1._id)).resolves.toStrictEqual(
expect.arrayContaining([r2.url]), expect.arrayContaining([r2.url]),
); );
await expect(queryAllWorkspaceUrls(w, models.grpcRequest.type, gr1._id)).resolves.toStrictEqual( await expect(queryAllWorkspaceUrls(w._id, models.grpcRequest.type, gr1._id)).resolves.toStrictEqual(
expect.arrayContaining([gr2.url]), expect.arrayContaining([gr2.url]),
); );
}); });

View File

@ -1,13 +1,16 @@
import { database as db } from '../../common/database'; import { database as db } from '../../common/database';
import * as models from '../../models';
import { invariant } from '../../utils/invariant';
import { GrpcRequest, type as GrpcRequestType } from '../grpc-request'; import { GrpcRequest, type as GrpcRequestType } from '../grpc-request';
import { Request, type as RequestType } from '../request'; import { Request, type as RequestType } from '../request';
import { Workspace } from '../workspace';
export const queryAllWorkspaceUrls = async ( export const queryAllWorkspaceUrls = async (
workspace: Workspace | null, workspaceId: string,
reqType: typeof RequestType | typeof GrpcRequestType, reqType: typeof RequestType | typeof GrpcRequestType,
reqId = 'n/a', reqId = 'n/a',
): Promise<string[]> => { ): Promise<string[]> => {
const workspace = await models.workspace.getById(workspaceId);
invariant(workspace, `Workspace ${workspaceId} not found`);
const docs = await db.withDescendants(workspace, reqType) as (Request | GrpcRequest)[]; const docs = await db.withDescendants(workspace, reqType) as (Request | GrpcRequest)[];
const urls = docs const urls = docs
.filter( .filter(

View File

@ -23,7 +23,7 @@ interface Props {
className?: string; className?: string;
fallbackValue?: string; fallbackValue?: string;
onEditStart?: () => void; onEditStart?: () => void;
onSubmit: (value?: string) => void; onSubmit: (value: string) => void;
preventBlank?: boolean; preventBlank?: boolean;
renderReadView?: (value: string | undefined, props: any) => ReactElement<HighlightProps>; renderReadView?: (value: string | undefined, props: any) => ReactElement<HighlightProps>;
singleClick?: boolean; singleClick?: boolean;
@ -63,7 +63,7 @@ export const Editable: FC<Props> = ({
const handleEditEnd = useCallback(() => { const handleEditEnd = useCallback(() => {
if (shouldSave(value, inputRef.current?.value.trim(), preventBlank)) { if (shouldSave(value, inputRef.current?.value.trim(), preventBlank)) {
// Don't run onSubmit for values that haven't been changed // Don't run onSubmit for values that haven't been changed
onSubmit(inputRef.current?.value.trim()); onSubmit(inputRef.current?.value.trim() || '');
} }
// This timeout prevents the UI from showing the old value after submit. // This timeout prevents the UI from showing the old value after submit.

View File

@ -3,7 +3,6 @@ import { useSelector } from 'react-redux';
import * as models from '../../../models'; import * as models from '../../../models';
import type { Environment } from '../../../models/environment'; import type { Environment } from '../../../models/environment';
import type { Workspace } from '../../../models/workspace';
import { selectActiveWorkspaceMeta, selectEnvironments, selectHotKeyRegistry } from '../../redux/selectors'; import { selectActiveWorkspaceMeta, selectEnvironments, selectHotKeyRegistry } from '../../redux/selectors';
import { type DropdownHandle, Dropdown } from '../base/dropdown/dropdown'; import { type DropdownHandle, Dropdown } from '../base/dropdown/dropdown';
import { DropdownButton } from '../base/dropdown/dropdown-button'; import { DropdownButton } from '../base/dropdown/dropdown-button';
@ -17,12 +16,12 @@ import { Tooltip } from '../tooltip';
interface Props { interface Props {
activeEnvironment?: Environment | null; activeEnvironment?: Environment | null;
workspace: Workspace; workspaceId: string;
} }
export const EnvironmentsDropdown: FC<Props> = ({ export const EnvironmentsDropdown: FC<Props> = ({
activeEnvironment, activeEnvironment,
workspace, workspaceId,
}) => { }) => {
const environments = useSelector(selectEnvironments); const environments = useSelector(selectEnvironments);
const hotKeyRegistry = useSelector(selectHotKeyRegistry); const hotKeyRegistry = useSelector(selectHotKeyRegistry);
@ -38,7 +37,7 @@ export const EnvironmentsDropdown: FC<Props> = ({
}); });
// NOTE: Base environment might not exist if the users hasn't managed environments yet. // NOTE: Base environment might not exist if the users hasn't managed environments yet.
const baseEnvironment = environments.find(environment => environment.parentId === workspace._id); const baseEnvironment = environments.find(environment => environment.parentId === workspaceId);
const subEnvironments = environments const subEnvironments = environments
.filter(environment => environment.parentId === (baseEnvironment && baseEnvironment._id)) .filter(environment => environment.parentId === (baseEnvironment && baseEnvironment._id))
.sort((e1, e2) => e1.metaSortKey - e2.metaSortKey); .sort((e1, e2) => e1.metaSortKey - e2.metaSortKey);

View File

@ -22,7 +22,6 @@ import {
newBodyFormUrlEncoded, newBodyFormUrlEncoded,
newBodyRaw, newBodyRaw,
} from '../../../../models/request'; } from '../../../../models/request';
import type { Settings } from '../../../../models/settings';
import type { Workspace } from '../../../../models/workspace'; import type { Workspace } from '../../../../models/workspace';
import { NunjucksEnabledProvider } from '../../../context/nunjucks/nunjucks-enabled-context'; import { NunjucksEnabledProvider } from '../../../context/nunjucks/nunjucks-enabled-context';
import { AskModal } from '../../modals/ask-modal'; import { AskModal } from '../../modals/ask-modal';
@ -38,35 +37,28 @@ import { UrlEncodedEditor } from './url-encoded-editor';
interface Props { interface Props {
request: Request; request: Request;
workspace: Workspace; workspace: Workspace;
settings: Settings;
environmentId: string; environmentId: string;
} }
export const BodyEditor: FC<Props> = ({ export const BodyEditor: FC<Props> = ({
request, request,
workspace, workspace,
settings,
environmentId, environmentId,
}) => { }) => {
const handleRawChange = useCallback((rawValue: string) => { const handleRawChange = useCallback((rawValue: string) => {
const oldContentType = request.body.mimeType || ''; models.request.update(request, { body: newBodyRaw(rawValue, request.body.mimeType || '') });
const body = newBodyRaw(rawValue, oldContentType);
models.request.update(request, { body });
}, [request]); }, [request]);
const handleGraphQLChange = useCallback((content: string) => { const handleGraphQLChange = useCallback((content: string) => {
const body = newBodyRaw(content, CONTENT_TYPE_GRAPHQL); models.request.update(request, { body: newBodyRaw(content, CONTENT_TYPE_GRAPHQL) });
models.request.update(request, { body });
}, [request]); }, [request]);
const handleFormUrlEncodedChange = useCallback((parameters: RequestBodyParameter[]) => { const handleFormUrlEncodedChange = useCallback((parameters: RequestBodyParameter[]) => {
const body = newBodyFormUrlEncoded(parameters); models.request.update(request, { body: newBodyFormUrlEncoded(parameters) });
models.request.update(request, { body });
}, [request]); }, [request]);
const handleFormChange = useCallback((parameters: RequestBodyParameter[]) => { const handleFormChange = useCallback((parameters: RequestBodyParameter[]) => {
const body = newBodyForm(parameters); models.request.update(request, { body: newBodyForm(parameters) });
models.request.update(request, { body });
}, [request]); }, [request]);
const handleFileChange = async (path: string) => { const handleFileChange = async (path: string) => {
@ -118,7 +110,7 @@ export const BodyEditor: FC<Props> = ({
} else if (mimeType === CONTENT_TYPE_FILE) { } else if (mimeType === CONTENT_TYPE_FILE) {
return <FileEditor key={uniqueKey} onChange={handleFileChange} path={fileName || ''} />; return <FileEditor key={uniqueKey} onChange={handleFileChange} path={fileName || ''} />;
} else if (mimeType === CONTENT_TYPE_GRAPHQL) { } else if (mimeType === CONTENT_TYPE_GRAPHQL) {
return <GraphQLEditor key={uniqueKey} uniquenessKey={uniqueKey} request={request} settings={settings} workspaceId={workspace._id} environmentId={environmentId} onChange={handleGraphQLChange} />; return <GraphQLEditor key={uniqueKey} uniquenessKey={uniqueKey} request={request} workspaceId={workspace._id} environmentId={environmentId} onChange={handleGraphQLChange} />;
} else if (!isBodyEmpty) { } else if (!isBodyEmpty) {
const contentType = getContentTypeFromHeaders(request.headers) || mimeType; const contentType = getContentTypeFromHeaders(request.headers) || mimeType;
return <RawEditor uniquenessKey={uniqueKey} contentType={contentType || 'text/plain'} content={request.body.text || ''} onChange={handleRawChange} />; return <RawEditor uniquenessKey={uniqueKey} contentType={contentType || 'text/plain'} content={request.body.text || ''} onChange={handleRawChange} />;

View File

@ -3,7 +3,12 @@ import React, { FC } from 'react';
import { KeyValueEditor } from '../../key-value-editor/key-value-editor'; import { KeyValueEditor } from '../../key-value-editor/key-value-editor';
interface Props { interface Props {
onChange: Function; onChange: (c: {
name: string;
value: string;
description?: string;
disabled?: boolean;
}[]) => void;
parameters: any[]; parameters: any[];
} }

View File

@ -10,6 +10,7 @@ import { Maybe } from 'graphql-language-service';
import prettier from 'prettier'; import prettier from 'prettier';
import React, { FC, useEffect, useRef, useState } from 'react'; import React, { FC, useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { useSelector } from 'react-redux';
import { jarFromCookies } from '../../../../common/cookies'; import { jarFromCookies } from '../../../../common/cookies';
import { markdownToHTML } from '../../../../common/markdown-to-html'; import { markdownToHTML } from '../../../../common/markdown-to-html';
@ -18,11 +19,11 @@ import { getRenderContext, render, RENDER_PURPOSE_SEND } from '../../../../commo
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 type { Settings } from '../../../../models/settings';
import { axiosRequest } from '../../../../network/axios-request'; import { axiosRequest } from '../../../../network/axios-request';
import { jsonPrettify } from '../../../../utils/prettify/json'; import { jsonPrettify } from '../../../../utils/prettify/json';
import { setDefaultProtocol } from '../../../../utils/url/protocol'; import { setDefaultProtocol } from '../../../../utils/url/protocol';
import { buildQueryStringFromParams, joinUrlAndQueryString } from '../../../../utils/url/querystring'; import { buildQueryStringFromParams, joinUrlAndQueryString } from '../../../../utils/url/querystring';
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';
import { DropdownDivider } from '../../base/dropdown/dropdown-divider'; import { DropdownDivider } from '../../base/dropdown/dropdown-divider';
@ -151,7 +152,6 @@ interface GraphQLBody {
interface Props { interface Props {
onChange: (value: string) => void; onChange: (value: string) => void;
request: Request; request: Request;
settings: Settings;
environmentId: string; environmentId: string;
className?: string; className?: string;
uniquenessKey?: string; uniquenessKey?: string;
@ -172,7 +172,6 @@ interface State {
export const GraphQLEditor: FC<Props> = ({ export const GraphQLEditor: FC<Props> = ({
request, request,
environmentId, environmentId,
settings,
onChange, onChange,
className, className,
uniquenessKey, uniquenessKey,
@ -252,12 +251,13 @@ export const GraphQLEditor: FC<Props> = ({
}; };
}, [environmentId, request._id, request.url, workspaceId]); }, [environmentId, request._id, request.url, workspaceId]);
const { editorIndentWithTabs, editorIndentSize } = useSelector(selectSettings);
const beautifyRequestBody = () => { const beautifyRequestBody = () => {
const { body } = state; const { body } = state;
const prettyQuery = prettier.format(body.query, { const prettyQuery = prettier.format(body.query, {
parser: 'graphql', parser: 'graphql',
useTabs: settings.editorIndentWithTabs, useTabs: editorIndentWithTabs,
tabWidth: settings.editorIndentSize, tabWidth: editorIndentSize,
}); });
const prettyVariables = body.variables && JSON.parse(jsonPrettify(JSON.stringify(body.variables))); const prettyVariables = body.variables && JSON.parse(jsonPrettify(JSON.stringify(body.variables)));
changeQuery(prettyQuery); changeQuery(prettyQuery);

View File

@ -3,7 +3,12 @@ import React, { FC } from 'react';
import { KeyValueEditor } from '../../key-value-editor/key-value-editor'; import { KeyValueEditor } from '../../key-value-editor/key-value-editor';
interface Props { interface Props {
onChange: Function; onChange: (c: {
name: string;
value: string;
description?: string;
disabled?: boolean;
}[]) => void;
parameters: any[]; parameters: any[];
} }

View File

@ -33,7 +33,12 @@ interface Props {
isDisabled?: boolean; isDisabled?: boolean;
isWebSocketRequest?: boolean; isWebSocketRequest?: boolean;
namePlaceholder?: string; namePlaceholder?: string;
onChange: Function; onChange: (c: {
name: string;
value: string;
description?: string;
disabled?: boolean;
}[]) => void;
pairs: Pair[]; pairs: Pair[];
valuePlaceholder?: string; valuePlaceholder?: string;
} }

View File

@ -1,9 +1,7 @@
import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react'; import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import * as session from '../../../account/session'; import * as session from '../../../account/session';
import { getAppVersion, getProductName } from '../../../common/constants'; import { getAppVersion, getProductName } from '../../../common/constants';
import { selectSettings } from '../../redux/selectors';
import { type ModalHandle, Modal, ModalProps } from '../base/modal'; import { type ModalHandle, Modal, ModalProps } from '../base/modal';
import { ModalBody } from '../base/modal-body'; import { ModalBody } from '../base/modal-body';
import { ModalHeader } from '../base/modal-header'; import { ModalHeader } from '../base/modal-header';
@ -26,7 +24,6 @@ export const TAB_INDEX_SHORTCUTS = 'keyboard';
export const TAB_INDEX_THEMES = 'themes'; export const TAB_INDEX_THEMES = 'themes';
export const TAB_INDEX_PLUGINS = 'plugins'; export const TAB_INDEX_PLUGINS = 'plugins';
export const SettingsModal = forwardRef<SettingsModalHandle, ModalProps>((props, ref) => { export const SettingsModal = forwardRef<SettingsModalHandle, ModalProps>((props, ref) => {
const settings = useSelector(selectSettings);
const [defaultTabKey, setDefaultTabKey] = useState('general'); const [defaultTabKey, setDefaultTabKey] = useState('general');
const modalRef = useRef<ModalHandle>(null); const modalRef = useRef<ModalHandle>(null);
const email = session.isLoggedIn() ? session.getFullName() : null; const email = session.isLoggedIn() ? session.getFullName() : null;
@ -79,7 +76,7 @@ export const SettingsModal = forwardRef<SettingsModalHandle, ModalProps>((props,
</TabItem> </TabItem>
<TabItem key="plugins" title="Plugins"> <TabItem key="plugins" title="Plugins">
<PanelContainer className="pad"> <PanelContainer className="pad">
<Plugins settings={settings} /> <Plugins />
</PanelContainer> </PanelContainer>
</TabItem> </TabItem>
</Tabs> </Tabs>

View File

@ -138,10 +138,7 @@ export const GrpcRequestPane: FunctionComponent<Props> = ({
defaultValue={activeRequest.url} defaultValue={activeRequest.url}
placeholder="grpcb.in:9000" placeholder="grpcb.in:9000"
onChange={url => models.grpcRequest.update(activeRequest, { url })} onChange={url => models.grpcRequest.update(activeRequest, { url })}
getAutocompleteConstants={async () => { getAutocompleteConstants={() => queryAllWorkspaceUrls(workspaceId, models.grpcRequest.type, activeRequest._id)}
const workspace = await models.workspace.getById(workspaceId);
return queryAllWorkspaceUrls(workspace, models.grpcRequest.type, activeRequest._id);
}}
/> />
</StyledUrlEditor> </StyledUrlEditor>
<StyledDropdown> <StyledDropdown>

View File

@ -88,10 +88,6 @@ export const RequestPane: FC<Props> = ({
handleEditDescription(true); handleEditDescription(true);
}, [handleEditDescription]); }, [handleEditDescription]);
const autocompleteUrls = useCallback(() => {
return queryAllWorkspaceUrls(workspace, models.request.type, request?._id);
}, [workspace, request]);
const handleUpdateSettingsUseBulkHeaderEditor = useCallback(() => { const handleUpdateSettingsUseBulkHeaderEditor = useCallback(() => {
models.settings.update(settings, { useBulkHeaderEditor:!settings.useBulkHeaderEditor }); models.settings.update(settings, { useBulkHeaderEditor:!settings.useBulkHeaderEditor });
}, [settings]); }, [settings]);
@ -178,7 +174,7 @@ export const RequestPane: FC<Props> = ({
ref={requestUrlBarRef} ref={requestUrlBarRef}
uniquenessKey={uniqueKey} uniquenessKey={uniqueKey}
onUrlChange={updateRequestUrl} onUrlChange={updateRequestUrl}
handleAutocompleteUrls={autocompleteUrls} handleAutocompleteUrls={() => queryAllWorkspaceUrls(workspace._id, models.request.type, request?._id)}
nunjucksPowerUserMode={settings.nunjucksPowerUserMode} nunjucksPowerUserMode={settings.nunjucksPowerUserMode}
request={request} request={request}
setLoading={setLoading} setLoading={setLoading}
@ -192,7 +188,6 @@ export const RequestPane: FC<Props> = ({
request={request} request={request}
workspace={workspace} workspace={workspace}
environmentId={environmentId} environmentId={environmentId}
settings={settings}
/> />
</TabItem> </TabItem>
<TabItem key="auth" title={<AuthDropdown />}> <TabItem key="auth" title={<AuthDropdown />}>

View File

@ -1,5 +1,6 @@
import * as path from 'path'; import * as path from 'path';
import React, { FC, useEffect, useState } from 'react'; import React, { FC, useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { import {
NPM_PACKAGE_BASE, NPM_PACKAGE_BASE,
@ -8,21 +9,17 @@ import {
import { docsPlugins } from '../../../common/documentation'; import { docsPlugins } from '../../../common/documentation';
import { clickLink, getDataDirectory } from '../../../common/electron-helpers'; import { clickLink, getDataDirectory } from '../../../common/electron-helpers';
import * as models from '../../../models'; import * as models from '../../../models';
import type { Settings } from '../../../models/settings';
import { createPlugin } from '../../../plugins/create'; import { createPlugin } from '../../../plugins/create';
import type { Plugin } from '../../../plugins/index'; import type { Plugin } from '../../../plugins/index';
import { getPlugins } from '../../../plugins/index'; import { getPlugins } from '../../../plugins/index';
import { reload } from '../../../templating/index'; import { reload } from '../../../templating/index';
import { selectSettings } from '../../redux/selectors';
import { CopyButton } from '../base/copy-button'; import { CopyButton } from '../base/copy-button';
import { Link } from '../base/link'; import { Link } from '../base/link';
import { HelpTooltip } from '../help-tooltip'; import { HelpTooltip } from '../help-tooltip';
import { showAlert, showPrompt } from '../modals'; import { showAlert, showPrompt } from '../modals';
import { Button } from '../themed-button'; import { Button } from '../themed-button';
interface Props {
settings: Settings;
}
interface State { interface State {
plugins: Plugin[]; plugins: Plugin[];
npmPluginValue: string; npmPluginValue: string;
@ -31,7 +28,7 @@ interface State {
isInstallingFromNpm: boolean; isInstallingFromNpm: boolean;
isRefreshingPlugins: boolean; isRefreshingPlugins: boolean;
} }
export const Plugins: FC<Props> = ({ settings }) => { export const Plugins: FC = () => {
const [state, setState] = useState<State>({ const [state, setState] = useState<State>({
plugins: [], plugins: [],
npmPluginValue: '', npmPluginValue: '',
@ -48,6 +45,7 @@ export const Plugins: FC<Props> = ({ settings }) => {
isRefreshingPlugins, isRefreshingPlugins,
npmPluginValue, npmPluginValue,
} = state; } = state;
const settings = useSelector(selectSettings);
useEffect(() => { useEffect(() => {
refreshPlugins(); refreshPlugins();

View File

@ -192,7 +192,7 @@ export const SidebarLayout: FC<Props> = ({
renderPaneTwo, renderPaneTwo,
renderPageSidebar, renderPageSidebar,
}) => { }) => {
const settings = useSelector(selectSettings); const { forceVerticalLayout } = useSelector(selectSettings);
const activeWorkspaceMeta = useSelector(selectActiveWorkspaceMeta); const activeWorkspaceMeta = useSelector(selectActiveWorkspaceMeta);
const reduxPaneHeight = useSelector(selectPaneHeight); const reduxPaneHeight = useSelector(selectPaneHeight);
const reduxPaneWidth = useSelector(selectPaneWidth); const reduxPaneWidth = useSelector(selectPaneWidth);
@ -359,7 +359,7 @@ export const SidebarLayout: FC<Props> = ({
<LayoutGrid <LayoutGrid
key="wrapper" key="wrapper"
id="wrapper" id="wrapper"
orientation={settings.forceVerticalLayout ? 'vertical' : 'horizontal'} orientation={forceVerticalLayout ? 'vertical' : 'horizontal'}
style={{ style={{
gridTemplateColumns: gridColumns, gridTemplateColumns: gridColumns,
gridTemplateRows: gridRows, gridTemplateRows: gridRows,

View File

@ -173,7 +173,7 @@ export const Debug: FC = () => {
<div className="sidebar__menu"> <div className="sidebar__menu">
<EnvironmentsDropdown <EnvironmentsDropdown
activeEnvironment={activeEnvironment} activeEnvironment={activeEnvironment}
workspace={activeWorkspace} workspaceId={activeWorkspace._id}
/> />
<button className="btn btn--super-compact" onClick={showCookiesModal}> <button className="btn btn--super-compact" onClick={showCookiesModal}>
<div className="sidebar__menu__thing"> <div className="sidebar__menu__thing">

View File

@ -44,8 +44,8 @@ export const ErrorRoute: FC = () => {
return ( return (
<Container> <Container>
<h1>Application Error</h1> <h1 style={{ color: 'var(--color-font)' }}>Application Error</h1>
<p> <p style={{ color: 'var(--color-font)' }}>
Failed to render. Please send the following error to{' '} Failed to render. Please send the following error to{' '}
<Mailto <Mailto
email="support@insomnia.rest" email="support@insomnia.rest"
@ -54,8 +54,9 @@ export const ErrorRoute: FC = () => {
/> />
. .
</p> </p>
<h2>Message:</h2> <span style={{ color: 'var(--color-font)' }}>Message:
<pre>{errorMessage}</pre> <code style={{ wordBreak: 'break-word', margin: 'var(--padding-sm)' }}>{errorMessage}</code>
</span>
<Button onClick={() => navigate(`/organization/${DEFAULT_ORGANIZATION_ID}/project/${DEFAULT_PROJECT_ID}`)}> <Button onClick={() => navigate(`/organization/${DEFAULT_ORGANIZATION_ID}/project/${DEFAULT_PROJECT_ID}`)}>
Try to reload the app{' '} Try to reload the app{' '}
<span>{navigation.state === 'loading' ? <Spinner /> : null}</span> <span>{navigation.state === 'loading' ? <Spinner /> : null}</span>