connection form style

This commit is contained in:
Jan Prochazka
2021-02-13 19:05:37 +01:00
parent 521199ee1a
commit eab870c237
5 changed files with 121 additions and 52 deletions

View File

@@ -26,3 +26,27 @@ code {
.icon-invisible { .icon-invisible {
visibility: hidden; visibility: hidden;
} }
.largeFormMarker input[type='text'] {
width: 100%;
padding: 10px 10px;
font-size: 14px;
box-sizing: border-box;
border-radius: 4px;
}
.largeFormMarker input[type='password'] {
width: 100%;
padding: 10px 10px;
font-size: 14px;
box-sizing: border-box;
border-radius: 4px;
}
.largeFormMarker select {
width: 100%;
padding: 10px 10px;
font-size: 14px;
box-sizing: border-box;
border-radius: 4px;
}

View File

@@ -21,8 +21,29 @@ import { TabControl, TabPage } from '../widgets/TabControl';
import { usePlatformInfo } from '../utility/metadataLoaders'; import { usePlatformInfo } from '../utility/metadataLoaders';
import getElectron from '../utility/getElectron'; import getElectron from '../utility/getElectron';
import { FormFieldTemplateLarge } from '../utility/formStyle'; import { FormFieldTemplateLarge } from '../utility/formStyle';
import styled from 'styled-components';
// import FormikForm from '../utility/FormikForm'; // import FormikForm from '../utility/FormikForm';
const FlexContainer = styled.div`
display: flex;
`;
const TestResultContainer = styled.div`
margin-left: 10px;
align-self: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;
const ButtonsContainer = styled.div`
flex-shrink: 0;
`;
const AgentInfoWrap = styled.div`
margin-left: 20px;
`;
function DriverFields({ extensions }) { function DriverFields({ extensions }) {
const { values, setFieldValue } = useForm(); const { values, setFieldValue } = useForm();
const { authType, engine } = values; const { authType, engine } = values;
@@ -103,17 +124,6 @@ function SshTunnelFields() {
<FormTextField label="Login" name="sshLogin" disabled={!useSshTunnel} /> <FormTextField label="Login" name="sshLogin" disabled={!useSshTunnel} />
{sshMode == 'userPassword' && <FormPasswordField label="Password" name="sshPassword" disabled={!useSshTunnel} />} {sshMode == 'userPassword' && <FormPasswordField label="Password" name="sshPassword" disabled={!useSshTunnel} />}
{useSshTunnel &&
sshMode == 'agent' &&
(platformInfo.sshAuthSock ? (
<div>
<FontIcon icon="img ok" /> SSH Agent found
</div>
) : (
<div>
<FontIcon icon="img error" /> SSH Agent not found
</div>
))}
{sshMode == 'keyFile' && ( {sshMode == 'keyFile' && (
<FormElectronFileSelector label="Private key file" name="sshKeyfile" disabled={!useSshTunnel} /> <FormElectronFileSelector label="Private key file" name="sshKeyfile" disabled={!useSshTunnel} />
@@ -122,6 +132,20 @@ function SshTunnelFields() {
{sshMode == 'keyFile' && ( {sshMode == 'keyFile' && (
<FormPasswordField label="Key file passphrase" name="sshKeyfilePassword" disabled={!useSshTunnel} /> <FormPasswordField label="Key file passphrase" name="sshKeyfilePassword" disabled={!useSshTunnel} />
)} )}
{useSshTunnel && sshMode == 'agent' && (
<AgentInfoWrap>
{platformInfo.sshAuthSock ? (
<div>
<FontIcon icon="img ok" /> SSH Agent found
</div>
) : (
<div>
<FontIcon icon="img error" /> SSH Agent not found
</div>
)}
</AgentInfoWrap>
)}
</> </>
); );
} }
@@ -175,6 +199,26 @@ export default function ConnectionModal({ modalState, connection = undefined })
</FormSelectField> </FormSelectField>
<DriverFields extensions={extensions} /> <DriverFields extensions={extensions} />
<FormTextField label="Display name" name="displayName" /> <FormTextField label="Display name" name="displayName" />
</TabPage>
<TabPage label="SSH Tunnel" key="sshTunnel">
<SshTunnelFields />
</TabPage>
</TabControl>
</ModalContent>
<ModalFooter>
<FlexContainer>
<ButtonsContainer>
{isTesting ? (
<FormButton value="Cancel" onClick={handleCancel} />
) : (
<FormButton value="Test" onClick={handleTest} />
)}
<FormSubmit value="Save" onClick={handleSubmit} />
</ButtonsContainer>
<TestResultContainer>
{!isTesting && sqlConnectResult && sqlConnectResult.msgtype == 'connected' && ( {!isTesting && sqlConnectResult && sqlConnectResult.msgtype == 'connected' && (
<div> <div>
Connected: <FontIcon icon="img ok" /> {sqlConnectResult.version} Connected: <FontIcon icon="img ok" /> {sqlConnectResult.version}
@@ -185,22 +229,13 @@ export default function ConnectionModal({ modalState, connection = undefined })
Connect failed: <FontIcon icon="img error" /> {sqlConnectResult.error} Connect failed: <FontIcon icon="img error" /> {sqlConnectResult.error}
</div> </div>
)} )}
{isTesting && <LoadingInfo message="Testing connection" />} {isTesting && (
</TabPage> <div>
<TabPage label="SSH Tunnel" key="sshTunnel"> <FontIcon icon="icon loading" /> Testing connection
<SshTunnelFields /> </div>
</TabPage> )}
</TabControl> </TestResultContainer>
</ModalContent> </FlexContainer>
<ModalFooter>
{isTesting ? (
<FormButton value="Cancel" onClick={handleCancel} />
) : (
<FormButton value="Test" onClick={handleTest} />
)}
<FormSubmit value="Save" onClick={handleSubmit} />
</ModalFooter> </ModalFooter>
</FormProvider> </FormProvider>
</ModalBase> </ModalBase>

View File

@@ -50,6 +50,10 @@ export default function ThemeHelmet() {
border: 1px solid ${theme.border}; border: 1px solid ${theme.border};
} }
select[disabled] {
background-color: ${theme.input_background2};
}
textarea { textarea {
background-color: ${theme.input_background}; background-color: ${theme.input_background};
color: ${theme.input_font1}; color: ${theme.input_font1};

View File

@@ -14,10 +14,10 @@ export const FormLabel = styled.div`
export const FormValue = styled.div``; export const FormValue = styled.div``;
export function FormFieldTemplateDefault({ label, children, type }) { export function FormFieldTemplateDefault({ label, children, onLabelClick, type }) {
return ( return (
<FormRow> <FormRow>
<FormLabel>{label}</FormLabel> <FormLabel onClick={onLabelClick}>{label}</FormLabel>
<FormValue>{children}</FormValue> <FormValue>{children}</FormValue>
</FormRow> </FormRow>
); );
@@ -36,49 +36,51 @@ export const FormValueTiny = styled.div`
margin-top: 3px; margin-top: 3px;
`; `;
export function FormFieldTemplateTiny({ label, children, type }) { export function FormFieldTemplateTiny({ label, children, onLabelClick, type }) {
const theme = useTheme(); const theme = useTheme();
if (type == 'checkbox') { if (type == 'checkbox') {
return ( return (
<FormRowTiny> <FormRowTiny>
{children} {label} {children} <span onClick={onLabelClick}>{label}</span>
</FormRowTiny> </FormRowTiny>
); );
} }
return ( return (
<FormRowTiny> <FormRowTiny>
<FormLabelTiny theme={theme}>{label}</FormLabelTiny> <FormLabelTiny theme={theme} onClick={onLabelClick}>
{label}
</FormLabelTiny>
<FormValueTiny>{children}</FormValueTiny> <FormValueTiny>{children}</FormValueTiny>
</FormRowTiny> </FormRowTiny>
); );
} }
export const FormRowLarge = styled.div` export const FormRowLarge = styled.div`
margin: 5px; margin: 20px;
`; `;
export const FormLabelLarge = styled.div` export const FormLabelLarge = styled.div`
margin-bottom: 3px;
color: ${props => props.theme.manager_font3}; color: ${props => props.theme.manager_font3};
`; `;
export const FormValueLarge = styled.div` export const FormValueLarge = styled.div``;
margin-left: 15px;
margin-top: 3px;
`;
export function FormFieldTemplateLarge({ label, children, type }) { export function FormFieldTemplateLarge({ label, onLabelClick, children, type }) {
const theme = useTheme(); const theme = useTheme();
if (type == 'checkbox') { if (type == 'checkbox') {
return ( return (
<FormRowTiny> <FormRowLarge>
{children} {label} {children} <span onClick={onLabelClick}>{label}</span>
</FormRowTiny> </FormRowLarge>
); );
} }
return ( return (
<FormRowTiny> <FormRowLarge className="largeFormMarker">
<FormLabelTiny theme={theme}>{label}</FormLabelTiny> <FormLabelLarge theme={theme} onClick={onLabelClick}>
<FormValueTiny>{children}</FormValueTiny> {label}
</FormRowTiny> </FormLabelLarge>
<FormValueLarge>{children}</FormValueLarge>
</FormRowLarge>
); );
} }

View File

@@ -65,7 +65,7 @@ export function FormPasswordFieldRaw({ name, focused = false, ...other }) {
const isCrypted = value && value.startsWith('crypt:'); const isCrypted = value && value.startsWith('crypt:');
return ( return (
<> <FlexContainer>
<TextField <TextField
{...other} {...other}
value={isCrypted ? '' : value} value={isCrypted ? '' : value}
@@ -74,9 +74,12 @@ export function FormPasswordFieldRaw({ name, focused = false, ...other }) {
placeholder={isCrypted ? '(Password is encrypted)' : undefined} placeholder={isCrypted ? '(Password is encrypted)' : undefined}
type={isCrypted || showPassword ? 'text' : 'password'} type={isCrypted || showPassword ? 'text' : 'password'}
/> />
{!isCrypted && (
{!isCrypted && <FontIcon icon="icon eye" onClick={() => setShowPassword(x => !x)} />} <InlineButton onClick={() => setShowPassword(x => !x)}>
</> <FontIcon icon="icon eye" />
</InlineButton>
)}
</FlexContainer>
); );
} }
@@ -110,9 +113,10 @@ export function FormCheckboxFieldRaw({ name = undefined, defaultValue = undefine
} }
export function FormCheckboxField({ label, ...other }) { export function FormCheckboxField({ label, ...other }) {
const { values, setFieldValue } = useForm();
const FieldTemplate = useFormFieldTemplate(); const FieldTemplate = useFormFieldTemplate();
return ( return (
<FieldTemplate label={label} type="checkbox"> <FieldTemplate label={label} type="checkbox" onLabelClick={() => setFieldValue(other.name, !values[other.name])}>
<FormCheckboxFieldRaw {...other} /> <FormCheckboxFieldRaw {...other} />
</FieldTemplate> </FieldTemplate>
); );
@@ -329,7 +333,7 @@ export function FormArchiveFolderSelect({ name, additionalFolders = [], ...other
); );
} }
export function FormElectronFileSelectorRaw({ name }) { export function FormElectronFileSelectorRaw({ name, ...other }) {
const { values, setFieldValue } = useForm(); const { values, setFieldValue } = useForm();
const handleBrowse = () => { const handleBrowse = () => {
const electron = getElectron(); const electron = getElectron();
@@ -343,7 +347,7 @@ export function FormElectronFileSelectorRaw({ name }) {
}; };
return ( return (
<FlexContainer> <FlexContainer>
<TextField value={values[name]} onClick={handleBrowse} readOnly /> <TextField value={values[name]} onClick={handleBrowse} {...other} readOnly />
<InlineButton onClick={handleBrowse}>Browse</InlineButton> <InlineButton onClick={handleBrowse}>Browse</InlineButton>
</FlexContainer> </FlexContainer>
); );