Move request-related settings to workspace

This commit is contained in:
Gregory Schier
2024-01-15 11:52:36 -08:00
parent b01747299f
commit 34a8fc4e22
23 changed files with 207 additions and 148 deletions

View File

@@ -12,6 +12,7 @@ import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
import { responsesQueryKey } from '../hooks/useResponses';
import { settingsQueryKey } from '../hooks/useSettings';
import { useSyncWindowTitle } from '../hooks/useSyncWindowTitle';
import { useSyncAppearance } from '../hooks/useSyncAppearance';
import { workspacesQueryKey } from '../hooks/useWorkspaces';
import { NAMESPACE_NO_SYNC } from '../lib/keyValueStore';
import type { HttpRequest, HttpResponse, Model, Workspace } from '../lib/models';
@@ -27,6 +28,8 @@ export function GlobalHooks() {
useRecentEnvironments();
useRecentRequests();
useSyncAppearance();
useSyncWindowTitle();
const queryClient = useQueryClient();

View File

@@ -4,7 +4,9 @@ import { memo, useCallback, useMemo, useState } from 'react';
import { createGlobalState } from 'react-use';
import { useActiveRequest } from '../hooks/useActiveRequest';
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
import { useSettings } from '../hooks/useSettings';
import { useUpdateRequest } from '../hooks/useUpdateRequest';
import { useUpdateSettings } from '../hooks/useUpdateSettings';
import { tryFormatJson } from '../lib/formatters';
import type { HttpHeader, HttpRequest, HttpUrlParameter } from '../lib/models';
import {
@@ -20,10 +22,13 @@ import {
} from '../lib/models';
import { BasicAuth } from './BasicAuth';
import { BearerAuth } from './BearerAuth';
import { Checkbox } from './core/Checkbox';
import { CountBadge } from './core/CountBadge';
import { Editor } from './core/Editor';
import type { TabItem } from './core/Tabs/Tabs';
import { Input } from './core/Input';
import { VStack } from './core/Stacks';
import { TabContent, Tabs } from './core/Tabs/Tabs';
import type { TabItem } from './core/Tabs/Tabs';
import { EmptyStateText } from './EmptyStateText';
import { FormMultipartEditor } from './FormMultipartEditor';
import { FormUrlencodedEditor } from './FormUrlencodedEditor';

View File

@@ -7,7 +7,7 @@ import { VStack } from './core/Stacks';
export default function RouteError() {
const error = useRouteError();
console.log("Error", error);
console.log('Error', error);
const stringified = JSON.stringify(error);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const message = (error as any).message ?? stringified;

View File

@@ -1,75 +1,73 @@
import classNames from 'classnames';
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
import { useSettings } from '../hooks/useSettings';
import { useTheme } from '../hooks/useTheme';
import { useUpdateSettings } from '../hooks/useUpdateSettings';
import type { Appearance } from '../lib/theme/window';
import { useUpdateWorkspace } from '../hooks/useUpdateWorkspace';
import { Checkbox } from './core/Checkbox';
import { Input } from './core/Input';
import { VStack } from './core/Stacks';
import { HStack, VStack } from './core/Stacks';
export const SettingsDialog = () => {
const { appearance, setAppearance } = useTheme();
const workspace = useActiveWorkspace();
const updateWorkspace = useUpdateWorkspace(workspace?.id ?? null);
const settings = useSettings();
const updateSettings = useUpdateSettings();
if (settings == null) {
if (settings == null || workspace == null) {
return null;
}
console.log('SETTINGS', settings);
return (
<VStack space={2}>
<div className="w-full gap-2 grid grid-cols-[auto_1fr] gap-x-6 auto-rows-[2rem] items-center">
<VStack className="w-full" space={3}>
<Checkbox
className="col-span-full"
checked={settings.validateCertificates}
checked={workspace.settingValidateCertificates}
title="Validate TLS Certificates"
onChange={(validateCertificates) =>
updateSettings.mutateAsync({ ...settings, validateCertificates })
onChange={(settingValidateCertificates) =>
updateWorkspace.mutateAsync({ settingValidateCertificates })
}
/>
<Checkbox
className="col-span-full"
checked={settings.followRedirects}
checked={workspace.settingFollowRedirects}
title="Follow Redirects"
onChange={(followRedirects) =>
updateSettings.mutateAsync({ ...settings, followRedirects })
onChange={(settingFollowRedirects) =>
updateWorkspace.mutateAsync({ settingFollowRedirects })
}
/>
<div>Request Timeout (ms)</div>
<div>
<Input
size="sm"
name="requestTimeout"
label="Request Timeout (ms)"
containerClassName="col-span-2"
hideLabel
defaultValue={`${settings.requestTimeout}`}
validate={(value) => parseInt(value) >= 0}
onChange={(v) =>
updateSettings.mutateAsync({ ...settings, requestTimeout: parseInt(v) || 0 })
}
/>
</div>
<Input
size="xs"
name="requestTimeout"
label="Request Timeout (ms)"
labelPosition="left"
labelClassName="w-1/3"
containerClassName="col-span-2"
defaultValue={`${workspace.settingRequestTimeout}`}
validate={(value) => parseInt(value) >= 0}
onChange={(v) => updateWorkspace.mutateAsync({ settingRequestTimeout: parseInt(v) || 0 })}
/>
<div>Appearance</div>
<select
value={settings.appearance}
style={selectBackgroundStyles}
onChange={(e) => updateSettings.mutateAsync({ ...settings, appearance: e.target.value })}
className={classNames(
'border w-full px-2 outline-none bg-transparent',
'border-highlight focus:border-focus',
'h-sm',
)}
>
<option value="system">Match System</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>
<HStack alignItems="center" space={2}>
<div className="w-1/3">Appearance</div>
<select
value={settings.appearance}
style={selectBackgroundStyles}
onChange={(e) =>
updateSettings.mutateAsync({ ...settings, appearance: e.target.value })
}
className={classNames(
'font-mono text-xs border w-full px-2 outline-none bg-transparent',
'border-highlight focus:border-focus',
'h-xs',
)}
>
<option value="system">Match System</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</HStack>
</VStack>
{/*<Checkbox checked={appearance === 'dark'} title="Dark Mode" onChange={toggleAppearance} />*/}
</VStack>
);

View File

@@ -17,7 +17,7 @@ export function Checkbox({ checked, onChange, className, disabled, title, hideLa
as="label"
space={2}
alignItems="center"
className={classNames(className, disabled && 'opacity-disabled')}
className={classNames(className, 'text-gray-900 text-sm', disabled && 'opacity-disabled')}
>
<div className="relative flex">
<input

View File

@@ -74,7 +74,7 @@
}
.cm-scroller {
@apply font-mono text-[0.8rem] overflow-hidden;
@apply font-mono text-xs overflow-hidden;
}
.cm-line {

View File

@@ -26,6 +26,7 @@ export type InputProps = Omit<
type?: 'text' | 'password';
label: string;
hideLabel?: boolean;
labelPosition?: 'top' | 'left';
labelClassName?: string;
containerClassName?: string;
onChange?: (value: string) => void;
@@ -34,7 +35,7 @@ export type InputProps = Omit<
defaultValue?: string;
leftSlot?: ReactNode;
rightSlot?: ReactNode;
size?: 'sm' | 'md' | 'auto';
size?: 'xs' | 'sm' | 'md' | 'auto';
className?: string;
placeholder?: string;
validate?: (v: string) => boolean;
@@ -50,6 +51,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
hideLabel,
label,
labelClassName,
labelPosition = 'top',
leftSlot,
name,
onBlur,
@@ -115,12 +117,19 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
);
return (
<VStack ref={wrapperRef} className="w-full">
<div
ref={wrapperRef}
className={classNames(
'w-full',
labelPosition === 'left' && 'flex items-center gap-2',
labelPosition === 'top' && 'flex-row gap-0.5',
)}
>
<label
htmlFor={id}
className={classNames(
labelClassName,
'font-semibold text-xs uppercase text-gray-700',
'text-sm text-gray-900 whitespace-nowrap',
hideLabel && 'sr-only',
)}
>
@@ -136,6 +145,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
!isValid && '!border-invalid',
size === 'md' && 'h-md',
size === 'sm' && 'h-sm',
size === 'xs' && 'h-xs',
size === 'auto' && 'min-h-sm',
)}
>
@@ -177,7 +187,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
)}
{rightSlot}
</HStack>
</VStack>
</div>
);
});