-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: persist proxy preferences (#254)
Co-authored-by: Uladzimir Dzmitračkoŭ <[email protected]>
- Loading branch information
1 parent
d45b1f2
commit a622a55
Showing
17 changed files
with
765 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { SettingsDialog } from '@/components/Settings/SettingsDialog' | ||
import { GearIcon } from '@radix-ui/react-icons' | ||
import { Tooltip, IconButton } from '@radix-ui/themes' | ||
import { useState } from 'react' | ||
|
||
export function SettingsButton() { | ||
const [open, setOpen] = useState(false) | ||
|
||
return ( | ||
<> | ||
<Tooltip content="Settings" side="right"> | ||
<IconButton | ||
area-label="Settings" | ||
color="gray" | ||
variant="ghost" | ||
onClick={() => setOpen(true)} | ||
> | ||
<GearIcon /> | ||
</IconButton> | ||
</Tooltip> | ||
|
||
<SettingsDialog open={open} onOpenChange={setOpen} /> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { FieldGroup } from '@/components/Form' | ||
import { ProxyStatus } from '@/types' | ||
import { stringAsNumber } from '@/utils/form' | ||
import { css } from '@emotion/react' | ||
import { Flex, Text, TextField, Checkbox } from '@radix-ui/themes' | ||
import { useEffect, useState } from 'react' | ||
import { Controller, useFormContext } from 'react-hook-form' | ||
import { UpstreamProxySettings } from './UpstreamProxySettings' | ||
import { SettingsSection } from './SettingsSection' | ||
import { ControlledRadioGroup } from '@/components/Form/ControllerRadioGroup' | ||
import { AppSettings } from '@/types/settings' | ||
|
||
const modeOptions = [ | ||
{ | ||
value: 'regular', | ||
label: 'Regular (requests are performed from this computer)', | ||
}, | ||
{ | ||
value: 'upstream', | ||
label: 'Upstream (requests are forwarded to an upstream server)', | ||
}, | ||
] | ||
|
||
export const ProxySettings = () => { | ||
const { | ||
formState: { errors }, | ||
control, | ||
register, | ||
watch, | ||
} = useFormContext<AppSettings>() | ||
const [proxyStatus, setProxyStatus] = useState<ProxyStatus>() | ||
|
||
const { proxy } = watch() | ||
|
||
useEffect(() => { | ||
async function fetchProxyStatus() { | ||
const status = await window.studio.proxy.getProxyStatus() | ||
setProxyStatus(status) | ||
} | ||
fetchProxyStatus() | ||
|
||
return window.studio.proxy.onProxyStatusChange((status) => | ||
setProxyStatus(status) | ||
) | ||
}, []) | ||
|
||
return ( | ||
<SettingsSection title="Proxy"> | ||
<FieldGroup | ||
name="proxy.port" | ||
label="Port number" | ||
errors={errors} | ||
hint="What port number k6 Studio proxy should listen to in this computer (between 1 and 65535)" | ||
hintType="text" | ||
> | ||
<TextField.Root | ||
placeholder="6000" | ||
type="number" | ||
min={1} | ||
{...register('proxy.port', { setValueAs: stringAsNumber })} | ||
/> | ||
</FieldGroup> | ||
|
||
<Flex gap="2" my="4"> | ||
<Controller | ||
control={control} | ||
name="proxy.automaticallyFindPort" | ||
render={({ field }) => ( | ||
<Text size="2" as="label"> | ||
<Checkbox | ||
{...register('proxy.automaticallyFindPort')} | ||
checked={field.value} | ||
onCheckedChange={field.onChange} | ||
/>{' '} | ||
Allow k6 Studio to find an available port if this port is in use | ||
</Text> | ||
)} | ||
/> | ||
</Flex> | ||
|
||
<FieldGroup | ||
label="Proxy mode" | ||
name="proxy.mode" | ||
errors={errors} | ||
hint="How k6 Studio proxy should handle requests" | ||
hintType="text" | ||
> | ||
<ControlledRadioGroup | ||
control={control} | ||
name="proxy.mode" | ||
options={modeOptions} | ||
/> | ||
</FieldGroup> | ||
|
||
{proxy && proxy.mode === 'upstream' && <UpstreamProxySettings />} | ||
|
||
<Flex gap="2" mt="5"> | ||
<Text size="2"> | ||
Proxy status: <ProxyStatusIndicator status={proxyStatus} /> | ||
</Text> | ||
</Flex> | ||
</SettingsSection> | ||
) | ||
} | ||
|
||
function ProxyStatusIndicator({ status }: { status?: ProxyStatus }) { | ||
const statusColorMap: Record<ProxyStatus, string> = { | ||
['online']: 'var(--green-9)', | ||
['offline']: 'var(--gray-9)', | ||
['restarting']: 'var(--blue-9)', | ||
} | ||
const backgroundColor = status ? statusColorMap[status] : '#fff' | ||
|
||
return ( | ||
<Text | ||
size="2" | ||
css={css` | ||
background-color: ${backgroundColor}; | ||
border-radius: 4px; | ||
color: #fff; | ||
padding: var(--space-1) var(--space-2); | ||
`} | ||
> | ||
{status} | ||
</Text> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { FieldGroup } from '@/components/Form' | ||
import { AppSettings } from '@/types/settings' | ||
import { Flex, Text, TextField, Checkbox, Button } from '@radix-ui/themes' | ||
import { Controller, useFormContext } from 'react-hook-form' | ||
import { SettingsSection } from './SettingsSection' | ||
|
||
export const RecorderSettings = () => { | ||
const { | ||
formState: { errors }, | ||
control, | ||
register, | ||
watch, | ||
setValue, | ||
clearErrors, | ||
} = useFormContext<AppSettings>() | ||
|
||
const { recorder } = watch() | ||
|
||
const handleSelectFile = async () => { | ||
const result = await window.studio.settings.selectBrowserExecutable() | ||
const { canceled, filePaths } = result | ||
if (canceled || !filePaths.length) return | ||
setValue('recorder.browserPath', filePaths[0], { shouldDirty: true }) | ||
clearErrors('recorder.browserPath') | ||
} | ||
|
||
return ( | ||
<SettingsSection title="Recorder"> | ||
<Flex gap="2" mb="4"> | ||
<Controller | ||
control={control} | ||
name="recorder.detectBrowserPath" | ||
render={({ field }) => ( | ||
<Text size="2" as="label"> | ||
<Checkbox | ||
{...register('recorder.detectBrowserPath')} | ||
checked={field.value} | ||
onCheckedChange={field.onChange} | ||
/>{' '} | ||
Automatically detect browser | ||
</Text> | ||
)} | ||
/> | ||
</Flex> | ||
|
||
{recorder && !recorder.detectBrowserPath && ( | ||
<Flex> | ||
<FieldGroup | ||
flexGrow="1" | ||
name="recorder.browserPath" | ||
label="Browser Path" | ||
errors={errors} | ||
hint="The location of the browser executable (k6 Studio currently supports Chrome)" | ||
hintType="text" | ||
> | ||
<TextField.Root type="text" {...register('recorder.browserPath')} /> | ||
</FieldGroup> | ||
|
||
<Button | ||
ml="2" | ||
onClick={handleSelectFile} | ||
style={{ | ||
display: 'flex', | ||
alignSelf: 'center', | ||
marginTop: errors.recorder ? 12 : 36, | ||
}} | ||
> | ||
Select executable | ||
</Button> | ||
</Flex> | ||
)} | ||
</SettingsSection> | ||
) | ||
} |
Oops, something went wrong.