mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
Merge remote-tracking branch 'origin/devel' into devel
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer, useLocalStore } from 'mobx-react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { useMemo } from 'react';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { Loader } from '@cloudbeaver/core-blocks';
|
||||
@@ -53,12 +54,10 @@ export const ElementsTree: React.FC<Props> = observer(function ElementsTree({
|
||||
const nodeChildren = useChildren(root);
|
||||
const Placeholder = emptyPlaceholder;
|
||||
|
||||
const context = useLocalStore<ITreeContext, ITreeContext>(source => source, {
|
||||
control,
|
||||
onOpen,
|
||||
onSelect,
|
||||
isSelected,
|
||||
});
|
||||
const context = useMemo<ITreeContext>(
|
||||
() => ({ control, onOpen, onSelect, isSelected }),
|
||||
[control, onOpen, onSelect, isSelected]
|
||||
);
|
||||
|
||||
if (!nodeChildren.children || nodeChildren.children.length === 0) {
|
||||
if (nodeChildren.isLoading()) {
|
||||
|
||||
@@ -22,6 +22,8 @@ export * from './shared/NavigationTabs/TabNavigationContext';
|
||||
export * from './shared/ToolsPanel/LogViewTab/LogViewerMenuService';
|
||||
export * from './shared/ToolsPanel/LogViewTab/LogViewerService';
|
||||
export * from './shared/SessionExpireDialog/SessionExpiredDialogService';
|
||||
export * from './NavigationTree/ElementsTree';
|
||||
export * from './NavigationTree/TreeContext';
|
||||
export * from './NavigationTree/NavigationTreeService';
|
||||
export * from './NavigationTree/NavigationTreeContextMenuService';
|
||||
export * from './AppLocaleService';
|
||||
|
||||
@@ -120,7 +120,7 @@ export class NavNodeManagerService extends Bootstrap {
|
||||
this.connectionInfo.onItemAdd.subscribe(this.connectionUpdateHandler.bind(this));
|
||||
this.connectionInfo.onItemDelete.subscribe(this.connectionRemoveHandler.bind(this));
|
||||
this.connectionInfo.onConnectionCreate.subscribe(this.connectionCreateHandler.bind(this));
|
||||
this.sessionResource.onDataUpdate.subscribe(this.updateRootChildren.bind(this));
|
||||
this.sessionResource.onDataUpdate.subscribe(this.refreshRoot.bind(this));
|
||||
}
|
||||
|
||||
load(): void {}
|
||||
@@ -319,7 +319,13 @@ export class NavNodeManagerService extends Bootstrap {
|
||||
};
|
||||
};
|
||||
|
||||
private async updateRootChildren() {
|
||||
async updateRoot(): Promise<void> {
|
||||
if (await this.isNavTreeEnabled()) {
|
||||
await this.navTree.refresh(ROOT_NODE_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
async refreshRoot(): Promise<void> {
|
||||
this.navTree.delete(ROOT_NODE_PATH);
|
||||
if (await this.isNavTreeEnabled()) {
|
||||
await this.navTree.refresh(ROOT_NODE_PATH);
|
||||
|
||||
@@ -41,6 +41,7 @@ const checkboxStyles = composes(
|
||||
}
|
||||
checkbox-label {
|
||||
composes: theme-typography--body2 from global;
|
||||
cursor: pointer;
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer, useLocalStore } from 'mobx-react';
|
||||
import { useRef } from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { useMemo, useRef } from 'react';
|
||||
import styled, { use } from 'reshadow';
|
||||
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
@@ -50,7 +50,7 @@ export const TreeNode: React.FC<Props> = observer(function TreeNode({
|
||||
handlersRef.current.onOpen?.();
|
||||
};
|
||||
|
||||
const nodeContext = useLocalStore<ITreeNodeContext, ITreeNodeContext>(source => source, {
|
||||
const nodeContext = useMemo<ITreeNodeContext>(() => ({
|
||||
loading,
|
||||
selected,
|
||||
expanded,
|
||||
@@ -58,16 +58,7 @@ export const TreeNode: React.FC<Props> = observer(function TreeNode({
|
||||
expand: handleExpand,
|
||||
select: handleSelect,
|
||||
open: handleOpen,
|
||||
});
|
||||
// const nodeContext = useMemo<ITreeNodeContext>(() => ({
|
||||
// loading,
|
||||
// selected,
|
||||
// expanded,
|
||||
// leaf,
|
||||
// expand: handleExpand,
|
||||
// select: handleSelect,
|
||||
// open: handleOpen,
|
||||
// }), [loading, selected, expanded, leaf, handleExpand, handleSelect, handleOpen]);
|
||||
}), [loading, selected, expanded, leaf, handleExpand, handleSelect, handleOpen]);
|
||||
|
||||
return styled(useStyles(TREE_NODE_STYLES))(
|
||||
<node as="div" {...use({ expanded })} className={className}>
|
||||
|
||||
+7
-2
@@ -28,7 +28,6 @@ import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { EConnectionType } from '../EConnectionType';
|
||||
import { IConnectionFormModel } from '../IConnectionFormModel';
|
||||
import { formStyles } from './formStyles';
|
||||
import { OptionsController } from './OptionsController';
|
||||
import { ParametersForm } from './ParametersForm';
|
||||
|
||||
@@ -52,6 +51,12 @@ const styles = css`
|
||||
flex-direction: column;
|
||||
max-width: 630px;
|
||||
}
|
||||
connection-type {
|
||||
margin-left: 180px;
|
||||
}
|
||||
Radio {
|
||||
composes: theme-typography--body2 from global;
|
||||
}
|
||||
`;
|
||||
|
||||
export const Options = observer(function Options({
|
||||
@@ -66,7 +71,7 @@ export const Options = observer(function Options({
|
||||
const translate = useTranslate();
|
||||
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
|
||||
|
||||
return styled(useStyles(styles, formStyles))(
|
||||
return styled(useStyles(styles))(
|
||||
<SubmittingForm ref={focusedRef} onChange={controller.onFormChange} onSubmit={onSave}>
|
||||
<FormBox>
|
||||
<FormBoxElement>
|
||||
|
||||
+8
-4
@@ -7,21 +7,25 @@
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import styled, { use, css } from 'reshadow';
|
||||
import styled, { css, use } from 'reshadow';
|
||||
|
||||
import { FormGroup, InputField } from '@cloudbeaver/core-blocks';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { ConnectionInfo } from '@cloudbeaver/core-sdk';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { formStyles } from './formStyles';
|
||||
|
||||
interface ParametersFormProps {
|
||||
connection: ConnectionInfo;
|
||||
disabled?: boolean;
|
||||
embedded?: boolean;
|
||||
}
|
||||
|
||||
const parametersFormStyles = css`
|
||||
sub-label {
|
||||
composes: theme-typography--caption from global;
|
||||
line-height: 14px;
|
||||
}`;
|
||||
|
||||
export const ParametersForm = observer(function ParametersForm({
|
||||
connection,
|
||||
embedded,
|
||||
@@ -29,7 +33,7 @@ export const ParametersForm = observer(function ParametersForm({
|
||||
}: ParametersFormProps) {
|
||||
const translate = useTranslate();
|
||||
|
||||
return styled(useStyles(formStyles))(
|
||||
return styled(useStyles(parametersFormStyles))(
|
||||
<>
|
||||
{!embedded && (
|
||||
<layout-grid-inner as="div">
|
||||
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { css } from 'reshadow';
|
||||
|
||||
export const formStyles = css`
|
||||
connection-form {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
flex-direction: row;
|
||||
}
|
||||
layout-grid {
|
||||
flex: 1;
|
||||
}
|
||||
connection-type {
|
||||
margin-left: 180px;
|
||||
}
|
||||
Radio {
|
||||
composes: theme-typography--body1 from global;
|
||||
}
|
||||
sub-label {
|
||||
composes: theme-typography--caption from global;
|
||||
line-height: 14px;
|
||||
}
|
||||
`;
|
||||
@@ -17,10 +17,17 @@ import { GQLErrorCatcher } from '@cloudbeaver/core-sdk';
|
||||
import { ConnectionInfoResource } from '../ConnectionInfoResource';
|
||||
import { DBDriverResource } from '../DBDriverResource';
|
||||
|
||||
interface IDBAuthConfig {
|
||||
credentials: any;
|
||||
saveCredentials: boolean;
|
||||
}
|
||||
@injectable()
|
||||
export class DBAuthDialogController implements IInitializableController, IDestructibleController {
|
||||
@observable isAuthenticating = false;
|
||||
@observable credentials = {};
|
||||
@observable config: IDBAuthConfig = {
|
||||
credentials: {},
|
||||
saveCredentials: false,
|
||||
};
|
||||
|
||||
readonly error = new GQLErrorCatcher();
|
||||
|
||||
@@ -53,7 +60,7 @@ export class DBAuthDialogController implements IInitializableController, IDestru
|
||||
|
||||
this.isAuthenticating = true;
|
||||
try {
|
||||
await this.connectionInfoResource.init(this.connectionId, this.credentials);
|
||||
await this.connectionInfoResource.init(this.connectionId, this.config.credentials);
|
||||
this.close();
|
||||
} catch (exception) {
|
||||
if (!this.error.catch(exception) || this.isDistructed) {
|
||||
|
||||
@@ -10,10 +10,11 @@ import { observer } from 'mobx-react';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import {
|
||||
SubmittingForm, ErrorMessage, Loader, useFocus, ObjectPropertyInfoForm
|
||||
SubmittingForm, ErrorMessage, Loader, useFocus, ObjectPropertyInfoForm, FieldCheckbox, FormBox, FormBoxElement, FormGroup
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import { useController } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogWrapper, DialogComponentProps } from '@cloudbeaver/core-dialogs';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { composes, useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { useConnectionInfo } from '../useConnectionInfo';
|
||||
@@ -46,6 +47,10 @@ const styles = composes(
|
||||
ObjectPropertyInfoForm {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: inline-flex;
|
||||
}
|
||||
FormBox {
|
||||
align-items: center;
|
||||
}
|
||||
ErrorMessage {
|
||||
position: sticky;
|
||||
@@ -64,6 +69,7 @@ export const DatabaseAuthDialog = observer(function DatabaseAuthDialog({
|
||||
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
|
||||
const { driver } = useDBDriver(connection.connectionInfo?.driverId || '');
|
||||
const controller = useController(DBAuthDialogController, payload, rejectDialog);
|
||||
const translate = useTranslate();
|
||||
|
||||
return styled(useStyles(styles))(
|
||||
<CommonDialogWrapper
|
||||
@@ -82,12 +88,26 @@ export const DatabaseAuthDialog = observer(function DatabaseAuthDialog({
|
||||
? <Loader />
|
||||
: (
|
||||
<SubmittingForm ref={focusedRef} onSubmit={controller.login}>
|
||||
<ObjectPropertyInfoForm
|
||||
autofillToken={`section-${connection.connectionInfo?.id || ''} section-auth`}
|
||||
properties={connection.connectionInfo?.authProperties}
|
||||
credentials={controller.credentials}
|
||||
disabled={controller.isAuthenticating}
|
||||
/>
|
||||
<FormBox>
|
||||
<FormBoxElement>
|
||||
<ObjectPropertyInfoForm
|
||||
autofillToken={`section-${connection.connectionInfo?.id || ''} section-auth`}
|
||||
properties={connection.connectionInfo?.authProperties}
|
||||
credentials={controller.config.credentials}
|
||||
disabled={controller.isAuthenticating}
|
||||
/>
|
||||
<FormGroup>
|
||||
<FieldCheckbox
|
||||
name="saveCredentials"
|
||||
value={connection.connectionInfo?.id || 'DBAuthSaveCredentials'}
|
||||
checkboxLabel={translate('connections_connection_edit_save_credentials')}
|
||||
disabled={controller.isAuthenticating}
|
||||
state={controller.config}
|
||||
mod='surface'
|
||||
/>
|
||||
</FormGroup>
|
||||
</FormBoxElement>
|
||||
</FormBox>
|
||||
</SubmittingForm>
|
||||
)}
|
||||
{controller.error.responseMessage && (
|
||||
|
||||
+3
@@ -34,6 +34,7 @@ export const ServerConfigurationConfigurationForm: React.FC<Props> = observer(fu
|
||||
mod={['primary']}
|
||||
disabled={!serverConfig.authenticationEnabled}
|
||||
long
|
||||
autoHide
|
||||
>
|
||||
{translate('administration_configuration_wizard_configuration_anonymous_access')}
|
||||
</Switch>
|
||||
@@ -45,6 +46,7 @@ export const ServerConfigurationConfigurationForm: React.FC<Props> = observer(fu
|
||||
description={translate('administration_configuration_wizard_configuration_authentication_description')}
|
||||
mod={['primary']}
|
||||
long
|
||||
autoHide
|
||||
>
|
||||
{translate('administration_configuration_wizard_configuration_authentication')}
|
||||
</Switch>
|
||||
@@ -56,6 +58,7 @@ export const ServerConfigurationConfigurationForm: React.FC<Props> = observer(fu
|
||||
description={translate('administration_configuration_wizard_configuration_custom_connections_description')}
|
||||
mod={['primary']}
|
||||
long
|
||||
autoHide
|
||||
>
|
||||
{translate('administration_configuration_wizard_configuration_custom_connections')}
|
||||
</Switch>
|
||||
|
||||
+26
-11
@@ -10,7 +10,7 @@ import { observer } from 'mobx-react';
|
||||
import styled, { use, css } from 'reshadow';
|
||||
|
||||
import { AdministrationTools, ADMINISTRATION_TOOLS_STYLES } from '@cloudbeaver/core-administration';
|
||||
import { FormBox, FormBoxElement, IconButton, SubmittingForm, useFocus } from '@cloudbeaver/core-blocks';
|
||||
import { FormBox, FormBoxElement, IconButton, Loader, SubmittingForm, useFocus } from '@cloudbeaver/core-blocks';
|
||||
import { useController, useService } from '@cloudbeaver/core-di';
|
||||
import { useFormValidator } from '@cloudbeaver/core-executor';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
@@ -44,6 +44,8 @@ const styles = composes(
|
||||
|
||||
layout-grid-cell {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: solid 1px;
|
||||
}
|
||||
|
||||
@@ -62,6 +64,10 @@ const styles = composes(
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
FormBox {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 2;
|
||||
}
|
||||
@@ -70,12 +76,13 @@ const styles = composes(
|
||||
|
||||
export const ServerConfigurationPage = observer(function ServerConfigurationPage() {
|
||||
const translate = useTranslate();
|
||||
const style = useStyles(styles, ADMINISTRATION_TOOLS_STYLES);
|
||||
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
|
||||
const service = useService(ServerConfigurationService);
|
||||
const controller = useController(ServerConfigurationPageController);
|
||||
useFormValidator(service.validationTask, focusedRef);
|
||||
|
||||
return styled(useStyles(styles, ADMINISTRATION_TOOLS_STYLES))(
|
||||
return styled(style)(
|
||||
<layout-grid as="div">
|
||||
<layout-grid-inner as="div">
|
||||
<layout-grid-cell as='div' {...use({ span: 12 })}>
|
||||
@@ -91,15 +98,23 @@ export const ServerConfigurationPage = observer(function ServerConfigurationPage
|
||||
</AdministrationTools>
|
||||
)}
|
||||
<SubmittingForm ref={focusedRef} name='server_config' onSubmit={controller.save} onChange={controller.change}>
|
||||
<FormBox>
|
||||
<FormBoxElement>
|
||||
<ServerConfigurationInfoForm serverConfig={controller.state.serverConfig} />
|
||||
{!controller.editing && <ServerConfigurationAdminForm serverConfig={controller.state.serverConfig} />}
|
||||
</FormBoxElement>
|
||||
<FormBoxElement>
|
||||
<ServerConfigurationConfigurationForm serverConfig={controller.state.serverConfig} />
|
||||
</FormBoxElement>
|
||||
</FormBox>
|
||||
{service.loading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<>
|
||||
<FormBox>
|
||||
<FormBoxElement>
|
||||
<ServerConfigurationInfoForm serverConfig={controller.state.serverConfig} />
|
||||
{!controller.editing && (
|
||||
<ServerConfigurationAdminForm serverConfig={controller.state.serverConfig} />
|
||||
)}
|
||||
</FormBoxElement>
|
||||
<FormBoxElement>
|
||||
<ServerConfigurationConfigurationForm serverConfig={controller.state.serverConfig} />
|
||||
</FormBoxElement>
|
||||
</FormBox>
|
||||
</>
|
||||
)}
|
||||
</SubmittingForm>
|
||||
</layout-grid-cell>
|
||||
</layout-grid-inner>
|
||||
|
||||
+16
-7
@@ -26,6 +26,7 @@ export interface IValidationStatusContext {
|
||||
@injectable()
|
||||
export class ServerConfigurationService {
|
||||
@observable state: IServerConfigurationPageState;
|
||||
@observable loading: boolean;
|
||||
readonly validationTask: IExecutor<boolean>;
|
||||
|
||||
constructor(
|
||||
@@ -35,19 +36,27 @@ export class ServerConfigurationService {
|
||||
private readonly notificationService: NotificationService,
|
||||
private readonly usersResource: UsersResource
|
||||
) {
|
||||
this.loading = true;
|
||||
this.state = this.getConfig();
|
||||
this.validationTask = new Executor();
|
||||
}
|
||||
|
||||
async loadConfig(): Promise<void> {
|
||||
const config = await this.serverConfigResource.load(null);
|
||||
this.loading = true;
|
||||
try {
|
||||
const config = await this.serverConfigResource.load(null);
|
||||
|
||||
this.state = this.administrationScreenService
|
||||
.getItemState(
|
||||
'server-configuration',
|
||||
() => this.getConfig(config),
|
||||
!config?.configurationMode
|
||||
);
|
||||
this.state = this.administrationScreenService
|
||||
.getItemState(
|
||||
'server-configuration',
|
||||
() => this.getConfig(config),
|
||||
!config?.configurationMode
|
||||
);
|
||||
} catch (exception) {
|
||||
this.notificationService.logException(exception, 'Can\'t load server configuration');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
isDone(): boolean {
|
||||
|
||||
+90
-60
@@ -7,17 +7,16 @@
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import styled from 'reshadow';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import {
|
||||
Radio, InputField, useFocus, ObjectPropertyInfoForm, InputGroup
|
||||
Radio, InputField, useFocus, ObjectPropertyInfoForm, InputGroup, FieldCheckbox, SubmittingForm, FormBox, FormBoxElement, FormGroup, RadioGroup
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import { DBDriver } from '@cloudbeaver/core-connections';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { ConnectionType } from '../ConnectionFormDialogController';
|
||||
import { formStyles } from './formStyles';
|
||||
import { IFormController } from './IFormController';
|
||||
import { ParametersForm } from './ParametersForm';
|
||||
|
||||
@@ -26,68 +25,99 @@ interface ConnectionFormProps {
|
||||
controller: IFormController;
|
||||
}
|
||||
|
||||
const connectionFormStyles = css`
|
||||
SubmittingForm {
|
||||
flex: 1;
|
||||
}
|
||||
FormBoxElement {
|
||||
flex: 1;
|
||||
}
|
||||
FormBox {
|
||||
padding: 4px 24px 18px;
|
||||
}
|
||||
connection-type {
|
||||
padding: 12px;
|
||||
margin-left: 160px;
|
||||
}
|
||||
Radio {
|
||||
composes: theme-typography--body2 from global;
|
||||
font-weight: 500;
|
||||
padding: 0 12px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const ConnectionForm = observer(function ConnectionForm({
|
||||
driver,
|
||||
controller,
|
||||
}: ConnectionFormProps) {
|
||||
const translate = useTranslate();
|
||||
const [focusedRef] = useFocus<HTMLDivElement>({ focusFirstChild: true });
|
||||
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
|
||||
|
||||
return styled(useStyles(formStyles))(
|
||||
<connection-form as='div'>
|
||||
<connection-type ref={focusedRef} as="div">
|
||||
<Radio
|
||||
name="type"
|
||||
id="custom"
|
||||
value="custom"
|
||||
checked={controller.connectionType === ConnectionType.Attributes}
|
||||
disabled={controller.isConnecting}
|
||||
mod={['primary']}
|
||||
onClick={() => controller.onChangeType(ConnectionType.Attributes)}
|
||||
>
|
||||
{translate('customConnection_connectionType_custom')}
|
||||
</Radio>
|
||||
<Radio
|
||||
name="type"
|
||||
id="url"
|
||||
value="url"
|
||||
checked={controller.connectionType === ConnectionType.URL}
|
||||
disabled={controller.isConnecting}
|
||||
mod={['primary']}
|
||||
onClick={() => controller.onChangeType(ConnectionType.URL)}
|
||||
>
|
||||
{translate('customConnection_connectionType_url')}
|
||||
</Radio>
|
||||
</connection-type>
|
||||
{controller.connectionType === ConnectionType.Attributes ? (
|
||||
<ParametersForm controller={controller} embedded={driver?.embedded} />
|
||||
) : (
|
||||
<group as="div">
|
||||
<InputField
|
||||
type="text"
|
||||
name="url"
|
||||
value={controller.config.url}
|
||||
disabled={controller.isConnecting}
|
||||
mod='surface'
|
||||
onChange={value => controller.onChange('url', value)}
|
||||
>
|
||||
{translate('customConnection_url_JDBC')}
|
||||
</InputField>
|
||||
</group>
|
||||
)}
|
||||
{controller.authModel && (
|
||||
<>
|
||||
<group as="div">
|
||||
<InputGroup>{translate('connections_connection_edit_authentication')}</InputGroup>
|
||||
</group>
|
||||
<ObjectPropertyInfoForm
|
||||
autofillToken='new-password'
|
||||
properties={controller.authModel.properties}
|
||||
credentials={controller.config.credentials}
|
||||
disabled={controller.isConnecting}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</connection-form>
|
||||
return styled(useStyles(connectionFormStyles))(
|
||||
<SubmittingForm ref={focusedRef}>
|
||||
<FormBox>
|
||||
<FormBoxElement>
|
||||
<FormGroup>
|
||||
<connection-type as="div">
|
||||
<RadioGroup name='type' value={controller.connectionType} onChange={controller.onChangeType}>
|
||||
<Radio
|
||||
value={ConnectionType.Attributes}
|
||||
disabled={controller.isConnecting}
|
||||
mod={['primary']}
|
||||
>
|
||||
{translate('customConnection_connectionType_custom')}
|
||||
</Radio>
|
||||
<Radio
|
||||
value={ConnectionType.URL}
|
||||
disabled={controller.isConnecting}
|
||||
mod={['primary']}
|
||||
>
|
||||
{translate('customConnection_connectionType_url')}
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</connection-type>
|
||||
</FormGroup>
|
||||
{controller.connectionType === ConnectionType.Attributes ? (
|
||||
<ParametersForm controller={controller} embedded={driver?.embedded} />
|
||||
) : (
|
||||
<FormGroup>
|
||||
<InputField
|
||||
type="text"
|
||||
name="url"
|
||||
value={controller.config.url}
|
||||
disabled={controller.isConnecting}
|
||||
mod='surface'
|
||||
onChange={value => controller.onChange('url', value)}
|
||||
>
|
||||
{translate('customConnection_url_JDBC')}
|
||||
</InputField>
|
||||
</FormGroup>
|
||||
)}
|
||||
{controller.authModel && (
|
||||
<>
|
||||
<FormGroup>
|
||||
<InputGroup>{translate('connections_connection_edit_authentication')}</InputGroup>
|
||||
</FormGroup>
|
||||
<ObjectPropertyInfoForm
|
||||
autofillToken='new-password'
|
||||
properties={controller.authModel.properties}
|
||||
credentials={controller.config.credentials}
|
||||
disabled={controller.isConnecting}
|
||||
/>
|
||||
<FormGroup>
|
||||
<FieldCheckbox
|
||||
name="saveCredentials"
|
||||
value={controller.authModel.id}
|
||||
state={controller.config}
|
||||
checkboxLabel={translate('connections_connection_edit_save_credentials')}
|
||||
disabled={controller.isConnecting}
|
||||
mod='surface'
|
||||
/>
|
||||
</FormGroup>
|
||||
</>
|
||||
)}
|
||||
</FormBoxElement>
|
||||
</FormBox>
|
||||
</SubmittingForm>
|
||||
);
|
||||
});
|
||||
|
||||
+8
-3
@@ -7,13 +7,12 @@
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import styled, { use } from 'reshadow';
|
||||
import styled, { css, use } from 'reshadow';
|
||||
|
||||
import { InputField } from '@cloudbeaver/core-blocks';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { formStyles } from './formStyles';
|
||||
import { IFormController } from './IFormController';
|
||||
|
||||
interface ParametersFormProps {
|
||||
@@ -21,13 +20,19 @@ interface ParametersFormProps {
|
||||
embedded?: boolean;
|
||||
}
|
||||
|
||||
const parametersFormStyles = css`
|
||||
sub-label {
|
||||
composes: theme-typography--caption from global;
|
||||
line-height: 14px;
|
||||
}`;
|
||||
|
||||
export const ParametersForm = observer(function ParametersForm({
|
||||
controller,
|
||||
embedded,
|
||||
}: ParametersFormProps) {
|
||||
const translate = useTranslate();
|
||||
|
||||
return styled(useStyles(formStyles))(
|
||||
return styled(useStyles(parametersFormStyles))(
|
||||
<>
|
||||
{!embedded && (
|
||||
<layout-grid-inner as="div">
|
||||
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { css } from 'reshadow';
|
||||
|
||||
export const formStyles = css`
|
||||
connection-form {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 18px 24px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
connection-type {
|
||||
padding: 12px;
|
||||
}
|
||||
Radio {
|
||||
composes: theme-typography--body1 from global;
|
||||
font-weight: 500;
|
||||
padding: 0 12px;
|
||||
}
|
||||
sub-label {
|
||||
composes: theme-typography--caption from global;
|
||||
line-height: 14px;
|
||||
}
|
||||
group {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
}
|
||||
hr {
|
||||
margin-left: 24px;
|
||||
margin-right: 24px;
|
||||
}
|
||||
`;
|
||||
+2
-2
@@ -40,8 +40,8 @@ const styles = composes(
|
||||
box-sizing: border-box;
|
||||
}
|
||||
CommonDialogWrapper {
|
||||
max-height: 550px;
|
||||
min-height: 550px;
|
||||
max-height: 594px;
|
||||
min-height: 594px;
|
||||
}
|
||||
SubmittingForm {
|
||||
flex: 1;
|
||||
|
||||
+2
@@ -39,6 +39,7 @@ implements IInitializableController, IDestructibleController {
|
||||
url: '',
|
||||
properties: {},
|
||||
credentials: {},
|
||||
saveCredentials: false,
|
||||
};
|
||||
|
||||
readonly error = new GQLErrorCatcher();
|
||||
@@ -126,6 +127,7 @@ implements IInitializableController, IDestructibleController {
|
||||
if (this.authModel) {
|
||||
config.authModelId = this.config.authModelId;
|
||||
config.credentials = this.config.credentials;
|
||||
config.saveCredentials = this.config.saveCredentials;
|
||||
}
|
||||
if (Object.keys(this.config.properties).length > 0) {
|
||||
config.properties = this.config.properties;
|
||||
|
||||
Reference in New Issue
Block a user