Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,15 @@ export const Checkbox: CheckboxType = observer(function Checkbox({
return null;
}

let checked = state ? state[name] : checkedControlled;
let checked = checkedControlled;

if (state) {
if (typeof state[name] === 'string') {
checked = state[name] === 'true';
} else {
checked = state[name];
}
}

if (Array.isArray(checked)) {
checked = checked.includes(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ interface ICheckboxMarkupProps extends React.InputHTMLAttributes<HTMLInputElemen
indeterminate?: boolean;
}

export const CheckboxMarkup: React.FC<ICheckboxMarkupProps> = function CheckboxMarkup({ label, className, ...rest }) {
export const CheckboxMarkup: React.FC<ICheckboxMarkupProps> = function CheckboxMarkup({
label, className, title, ...rest
}) {
return styled(useStyles(checkboxStyles, checkboxMod.primary, rest.disabled
&& checkboxState.disabled, rest.checked && checkboxState.checked))(
<checkbox-container className={className} as='div'>
<checkbox-container className={className} title={title} as='div'>
<checkbox as='div'>
<checkbox-input as='input' type='checkbox' {...rest} />
<checkbox-background as='div'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { InputField } from '@cloudbeaver/core-blocks';
import type { ObjectPropertyInfo } from '@cloudbeaver/core-sdk';
import { useStyles } from '@cloudbeaver/core-theming';

import { FieldCheckbox } from '../FormControls/Checkboxes/FieldCheckbox';
import { FormFieldDescription } from '../FormControls/FormFieldDescription';
import { FormGroup } from '../FormControls/FormGroup';
import { isControlPresented } from '../FormControls/isControlPresented';
Expand Down Expand Up @@ -48,6 +49,7 @@ const RenderField: React.FC<RenderFieldProps> = observer(function RenderField({
}) {
const href = property.features.includes('href');
const password = property.features.includes('password');
const checkbox = property.dataType === 'Boolean';
let description: string | undefined;

if (href) {
Expand All @@ -73,6 +75,19 @@ const RenderField: React.FC<RenderFieldProps> = observer(function RenderField({
description = 'Password saved';
}

if (checkbox) {
return (
<FieldCheckbox
name={property.id!}
state={state}
checkboxLabel={property.displayName}
title={property.description}
disabled={disabled}
mod='surface'
/>
);
}

return (
<InputField
type={password ? 'password' : 'text'}
Expand All @@ -93,7 +108,7 @@ const RenderField: React.FC<RenderFieldProps> = observer(function RenderField({

interface ObjectPropertyFormProps {
properties: ObjectPropertyInfo[] | undefined;
credentials: Record<string, string | number>;
state: Record<string, string | number>;
editable?: boolean;
autofillToken?: string;
className?: string;
Expand All @@ -106,7 +121,7 @@ interface ObjectPropertyFormProps {

export const ObjectPropertyInfoForm: React.FC<ObjectPropertyFormProps> = observer(function ObjectPropertyInfoForm({
properties,
credentials,
state,
editable = true,
autofillToken = '',
className,
Expand Down Expand Up @@ -134,7 +149,7 @@ export const ObjectPropertyInfoForm: React.FC<ObjectPropertyFormProps> = observe
<FormGroup key={property.id}>
<RenderField
property={property}
state={credentials}
state={state}
editable={editable}
autofillToken={autofillToken}
disabled={disabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface IValidationStatus {
}
@injectable()
export class ConnectionFormController
implements IInitializableController {
implements IInitializableController {
isSaving: boolean;

readonly afterSave: IExecutor<string>;
Expand Down Expand Up @@ -80,7 +80,10 @@ implements IInitializableController {
const connectionConfig = this.getConnectionConfig();
const validation = this.validate(connectionConfig);
if (!validation.status) {
this.notificationService.logError({ title: this.model.editing ? 'connections_administration_connection_save_error' : 'connections_administration_connection_create_error', message: validation.errorMessage });
this.notificationService.logError({
title: this.model.editing ? 'connections_administration_connection_save_error' : 'connections_administration_connection_create_error',
message: validation.errorMessage,
});
return;
}

Expand Down Expand Up @@ -133,7 +136,7 @@ implements IInitializableController {
if (!config.name?.length) {
validationStatus.errorMessage = "Field 'name' can't be empty";
} else if (this.model.editing && this.isConnectionNameAlreadyExists(config.name)) {
validationStatus.errorMessage = 'Connection with this name already exists';
validationStatus.errorMessage = `Connection with ${config.name} name already exists`;
}

validationStatus.status = !validationStatus.errorMessage;
Expand Down Expand Up @@ -173,6 +176,10 @@ implements IInitializableController {
}
config.networkHandlersConfig = this.model.networkHandlersState;

if (Object.keys(this.model.connection.providerProperties).length > 0) {
config.providerProperties = this.model.connection.providerProperties;
}

return config;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export const Options = observer(function Options({
<ObjectPropertyInfoForm
autofillToken='new-password'
properties={controller.properties}
credentials={model.credentials}
state={model.credentials}
disabled={disabled}
showRememberTip
/>
Expand All @@ -157,6 +157,18 @@ export const Options = observer(function Options({
</>
)}
</FormBoxElement>
{controller.providerProperties && controller.providerProperties.length > 0 && (
<FormBoxElement>
<FormGroup>
<InputGroup>{translate('connections_connection_edit_settings')}</InputGroup>
</FormGroup>
<ObjectPropertyInfoForm
properties={controller.providerProperties}
state={model.connection.providerProperties}
disabled={disabled}
/>
</FormBoxElement>
)}
</FormBox>
</SubmittingForm>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { IConnectionFormModel } from '../IConnectionFormModel';

@injectable()
export class OptionsController
implements IInitializableController {
implements IInitializableController {
get drivers(): DBDriver[] {
return Array.from(this.dbDriverResource.data.values())
.filter(({ id }) => this.model.availableDrivers.includes(id));
Expand Down Expand Up @@ -46,6 +46,10 @@ implements IInitializableController {
return this.authModel?.properties;
}

get providerProperties(): ObjectPropertyInfo[] | undefined {
return this.dbDriverResource.get(this.model.connection.driverId)?.providerProperties;
}

private model!: IConnectionFormModel;
/** we want to save prev generated connection name to detect if user changed "name" field to turn off autofill */
private prevGeneratedName: string | null = null;
Expand Down Expand Up @@ -87,6 +91,7 @@ implements IInitializableController {
this.setDefaultParameters(prevDriverId);
this.cleanCredentials();
this.model.connection.properties = {};
this.model.connection.providerProperties = {};
this.model.connection.authModel = this.driver?.defaultAuthModel;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { observer } from 'mobx-react-lite';

import { TextPlaceholder, useTab, ObjectPropertyInfoForm, FormBox, FormBoxElement, FormGroup, InputGroup, Loader, useTabState, ExceptionMessage } from '@cloudbeaver/core-blocks';
import { TextPlaceholder, useTab, ObjectPropertyInfoForm, FormBox, FormBoxElement, FormGroup, Loader, useTabState, ExceptionMessage } from '@cloudbeaver/core-blocks';
import type { TabContainerPanelComponent } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { useTranslate } from '@cloudbeaver/core-localization';
Expand Down Expand Up @@ -94,7 +94,7 @@ export const OriginInfo: TabContainerPanelComponent<IConnectionFormProps> = obse
<FormGroup><br /></FormGroup>
<ObjectPropertyInfoForm
properties={state.properties}
credentials={state.state}
state={state.state}
editable={false}
autoHide
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export class ConnectionsResource extends CachedMapResource<string, AdminConnecti
useUrl: false,
authProperties: [],
properties: {},
providerProperties: {},
origin: {
type: 'local',
displayName: 'Local',
Expand Down
31 changes: 16 additions & 15 deletions webapp/packages/core-connections/src/DBDriverResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,22 @@ import {
import { MetadataMap } from '@cloudbeaver/core-utils';

export type DBDriver = Pick<
DriverInfo,
| 'id'
| 'name'
| 'icon'
| 'description'
| 'defaultPort'
| 'defaultDatabase'
| 'defaultServer'
| 'defaultUser'
| 'sampleURL'
| 'embedded'
| 'anonymousAccess'
| 'promotedScore'
| 'defaultAuthModel'
| 'applicableNetworkHandlers'
DriverInfo,
| 'id'
| 'name'
| 'icon'
| 'description'
| 'defaultPort'
| 'defaultDatabase'
| 'defaultServer'
| 'defaultUser'
| 'sampleURL'
| 'embedded'
| 'anonymousAccess'
| 'promotedScore'
| 'defaultAuthModel'
| 'applicableNetworkHandlers'
| 'providerProperties'
>;

@injectable()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export const DatabaseAuthDialog = observer(function DatabaseAuthDialog({
<ObjectPropertyInfoForm
autofillToken={`section-${connection.connectionInfo?.id || ''} section-auth`}
properties={connection.connectionInfo?.authProperties}
credentials={controller.config.credentials}
state={controller.config.credentials}
disabled={controller.isAuthenticating}
/>
<FormGroup>
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-connections/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default [
['connections_connection_create_search_database', 'Search'],
['connections_connection_edit_save_credentials', 'Save credentials'],
['connections_connection_edit_authentication', 'Authentication'],
['connections_connection_edit_settings', 'Settings'],
['connections_connection_edit_access', 'Access'],
['connections_connection_edit_access_load_failed', 'Fail to get connection access'],
['connections_connection_edit_access_role', 'Role'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-connections/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default [
['connections_connection_create_search_database', 'Найти'],
['connections_connection_edit_save_credentials', ' Запомнить данные'],
['connections_connection_edit_authentication', 'Авторизация'],
['connections_connection_edit_settings', 'Настройки'],
['connections_connection_edit_access', 'Доступ'],
['connections_connection_edit_access_load_failed', 'Не удалось загрузить информацию доступа'],
['connections_connection_edit_access_role', 'Роль'],
Expand Down
14 changes: 13 additions & 1 deletion webapp/packages/core-sdk/src/queries/connections/driverList.gql
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ query driverList {

defaultAuthModel
# applicableAuthModel

providerProperties {
id
displayName
description
category
dataType
defaultValue
validValues
features
order
}
applicableNetworkHandlers
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ fragment AdminConnection on ConnectionInfo {
databaseName
url
properties
providerProperties

features

Expand Down
Loading