diff --git a/webview/src/ConfigEditor/proxyFields.tsx b/webview/src/ConfigEditor/proxyFields.tsx
index 60f36b6..abfba19 100644
--- a/webview/src/ConfigEditor/proxyFields.tsx
+++ b/webview/src/ConfigEditor/proxyFields.tsx
@@ -1,17 +1,16 @@
import * as React from 'react';
+import { FieldConfig } from '../FieldTypes/config';
import { FieldDropdown } from '../FieldTypes/dropdown';
import { FieldNumber } from '../FieldTypes/number';
import { FieldString } from '../FieldTypes/string';
-import { connect } from '../redux';
import { FileSystemConfig } from '../types/fileSystemConfig';
import type { FieldFactory, FSCChanged, FSCChangedMultiple } from './fields';
-function proxy(config: FileSystemConfig, onChange: FSCChanged<'proxy'>): React.ReactElement {
+function hostAndPort(config: FileSystemConfig, onChange: FSCChanged<'proxy'>): React.ReactElement {
const onChangeHost = (host: string) => onChange('proxy', { ...config.proxy!, host });
const onChangePort = (port: number) => onChange('proxy', { ...config.proxy!, port });
console.log('Current config:', config);
return
- {new Date().toString()}
): React.R
;
}
-interface HopFieldProps {
- config: FileSystemConfig;
- configs: [name: string, label: string][];
- onChange: FSCChanged<'hop'>;
-}
-const HopField = connect(({ config, configs, onChange }: HopFieldProps) => {
- const callback = (newValue?: [string, string]) => onChange('hop', newValue?.[0]);
+function hop(config: FileSystemConfig, onChange: FSCChanged<'hop'>): React.ReactElement {
+ const callback = (newValue?: FileSystemConfig) => onChange('hop', newValue?.name);
const description = 'Use another configuration as proxy, using a SSH tunnel through the targeted config to the actual remote system';
- const displayName = (item: [string, string]) => item[1];
- const value = config.hop ? [config.hop, configs.find(c => c[0] === config.hop)?.[1] || config.hop] as const : undefined;
- return ;
-})>(state => {
- const pairs = new Map();
- for (const { name, label } of state.data.configs) {
- pairs.set(name, label || name);
- }
- return { configs: Array.from(pairs) };
-});
+ return ;
+}
-const ProxyTypeToString = {
- http: 'HTTP',
- socks4: 'SOCKS 4',
- socks5: 'SOCKS 5',
-} as const;
-const ProxyStringToType = {
- 'HTTP': 'http',
- 'SOCKS 4': 'socks4',
- 'SOCKS 5': 'socks5',
- 'SSH Hop': 'hop',
-} as const;
-type ProxyStrings = keyof typeof ProxyStringToType;
+enum ProxyType { http, socks4, socks5, hop }
+const ProxyTypeNames: Record = {
+ [ProxyType.http]: 'HTTP',
+ [ProxyType.socks4]: 'SOCKS 4',
+ [ProxyType.socks5]: 'SOCKS 5',
+ [ProxyType.hop]: 'SSH Hop',
+};
-function merged(config: FileSystemConfig, onChange: FSCChanged, onChangeMultiple: FSCChangedMultiple): React.ReactElement | null {
- function callback(newValue?: ProxyStrings) {
- // Fields starting with _ don't get saved to file
- // We use it here so we know when to display the hop stuff
+function Merged(props: { config: FileSystemConfig, onChange: FSCChanged, onChangeMultiple: FSCChangedMultiple }): React.ReactElement | null {
+ const { config, onChange, onChangeMultiple } = props;
+ const [showHop, setShowHop] = React.useState(!!config.hop);
+ function callback(newValue?: ProxyType) {
if (!newValue) {
+ setShowHop(false);
return onChangeMultiple({
- ['_hop' as any]: undefined,
hop: undefined,
proxy: undefined,
});
}
- const newType = ProxyStringToType[newValue];
- if (newType === 'hop') {
- return onChangeMultiple({
- ['_hop' as any]: true,
- proxy: undefined,
- });
+ if (newValue === ProxyType.hop) {
+ setShowHop(true);
+ return onChangeMultiple({ proxy: undefined });
}
+ setShowHop(false);
return onChangeMultiple({
- ['_hop' as any]: undefined,
hop: undefined,
proxy: {
host: '',
port: 22,
...config.proxy,
- type: newType,
+ type: ProxyType[newValue] as any,
}
});
}
const description = 'The type of proxy to use when connecting to the remote system';
- const values: ProxyStrings[] = ['SSH Hop', 'SOCKS 4', 'SOCKS 5', 'HTTP'];
- const showHop = config.hop || (config as any)._hop;
- const type = config.proxy && config.proxy.type;
- const value = showHop ? 'SSH Hop' : (type && ProxyTypeToString[type]);
+ const values: ProxyType[] = [ProxyType.hop, ProxyType.socks4, ProxyType.socks5, ProxyType.http];
+ const type = config.proxy?.type;
+ const value = (config.hop || showHop) ? ProxyType.hop : (type && ProxyType[type]);
return
-
- {showHop && }
- {config.proxy && proxy(config, onChange)}
+ ProxyTypeNames[i!]} onChange={callback} optional />
+ {(config.hop || showHop) && hop(config, onChange)}
+ {config.proxy && hostAndPort(config, onChange)}
;
}
-export const PROXY_FIELD: FieldFactory = merged;
\ No newline at end of file
+export const PROXY_FIELD: FieldFactory = (config, onChange, onChangeMultiple) =>
+ ;
diff --git a/webview/src/FieldTypes/base.tsx b/webview/src/FieldTypes/base.tsx
index 129ea1a..d4ffe21 100644
--- a/webview/src/FieldTypes/base.tsx
+++ b/webview/src/FieldTypes/base.tsx
@@ -2,7 +2,7 @@ import * as React from 'react';
import { FieldGroup } from './group';
import './index.css';
-interface Props {
+export interface Props {
label: string;
description?: string;
value: T;
diff --git a/webview/src/FieldTypes/config.tsx b/webview/src/FieldTypes/config.tsx
new file mode 100644
index 0000000..e413e1c
--- /dev/null
+++ b/webview/src/FieldTypes/config.tsx
@@ -0,0 +1,30 @@
+import { connect } from '../redux';
+import { FileSystemConfig, formatConfigLocation } from '../types/fileSystemConfig';
+import type { Props as FieldBaseProps } from './base';
+import { FieldDropdown, Props as FieldDropdownProps } from './dropdown';
+
+type Props = Omit, 'value'> & FieldDropdownProps & {
+ /**
+ * Defaults to `'full'`. Determines how `values` and the default `displayName`.
+ * In which way to display configs in the dropdown and how to handle duplicate:
+ * - `full`: Display `