diff --git a/webapp/packages/core-connections/src/CONNECTION_INFO_PARAM_SCHEMA.ts b/webapp/packages/core-connections/src/CONNECTION_INFO_PARAM_SCHEMA.ts index 193e981571..96ec0e63de 100644 --- a/webapp/packages/core-connections/src/CONNECTION_INFO_PARAM_SCHEMA.ts +++ b/webapp/packages/core-connections/src/CONNECTION_INFO_PARAM_SCHEMA.ts @@ -7,7 +7,6 @@ */ import { schema } from '@cloudbeaver/core-utils'; -// // TODO add here driverId, submitType export const CONNECTION_INFO_PARAM_SCHEMA = schema .object({ projectId: schema.string(), diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormServiceRefactored.ts b/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormServiceRefactored.ts index a4f66b1975..9d99422b2d 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormServiceRefactored.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormServiceRefactored.ts @@ -5,20 +5,16 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -import type { IConnectionInfoParams } from '@cloudbeaver/core-connections'; import { injectable } from '@cloudbeaver/core-di'; import { NotificationService } from '@cloudbeaver/core-events'; import { LocalizationService } from '@cloudbeaver/core-localization'; import { FormBaseService, type IFormProps } from '@cloudbeaver/core-ui'; +import type { IConnectionFormStateRefactored } from './IConnectionFormStateRefactored.js'; -export interface IConnectionFormRefactoredState { - connectionInfoParams: IConnectionInfoParams; -} - -export type ConnectionFormRefactoredProps = IFormProps; +export type ConnectionFormRefactoredProps = IFormProps; @injectable() -export class ConnectionFormServiceRefactored extends FormBaseService { +export class ConnectionFormServiceRefactored extends FormBaseService { constructor(localizationService: LocalizationService, notificationService: NotificationService) { super(localizationService, notificationService, 'Connection form'); } diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormStateRefactored.ts b/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormStateRefactored.ts index 063b0cad0a..98e6e0b318 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormStateRefactored.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/ConnectionFormStateRefactored.ts @@ -8,10 +8,11 @@ import type { IServiceProvider } from '@cloudbeaver/core-di'; import { FormState } from '@cloudbeaver/core-ui'; -import type { ConnectionFormServiceRefactored, IConnectionFormRefactoredState } from './ConnectionFormServiceRefactored.js'; +import type { ConnectionFormServiceRefactored } from './ConnectionFormServiceRefactored.js'; +import type { IConnectionFormStateRefactored } from './IConnectionFormStateRefactored.js'; -export class ConnectionFormStateRefactored extends FormState { - constructor(serviceProvider: IServiceProvider, service: ConnectionFormServiceRefactored, config: IConnectionFormRefactoredState) { +export class ConnectionFormStateRefactored extends FormState { + constructor(serviceProvider: IServiceProvider, service: ConnectionFormServiceRefactored, config: IConnectionFormStateRefactored) { super(serviceProvider, service, config); } } diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/ConnectionFormDriverPropertiesPart.ts b/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/ConnectionFormDriverPropertiesPart.ts index b67e4ad53b..c05f02dcd1 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/ConnectionFormDriverPropertiesPart.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/ConnectionFormDriverPropertiesPart.ts @@ -6,66 +6,49 @@ * you may not use this file except in compliance with the License. */ import { FormPart, type IFormState } from '@cloudbeaver/core-ui'; -import { type IConnectionFormRefactoredState } from '../ConnectionFormServiceRefactored.js'; -import type { IConnectionFromDriverPropertiesState } from './IConnectionFromDriverPropertiesState.js'; import type { IExecutionContextProvider } from '@cloudbeaver/core-executor'; -import type { ConnectionInfoResource, DBDriverResource } from '@cloudbeaver/core-connections'; +import type { DBDriverResource } from '@cloudbeaver/core-connections'; import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js'; +import type { IConnectionFormStateRefactored } from '../IConnectionFormStateRefactored.js'; -const getDefaultState = () => - ({ - properties: {}, - }) as IConnectionFromDriverPropertiesState; - -export class ConnectionFormDriverPropertiesPart extends FormPart { +export class ConnectionFormDriverPropertiesPart extends FormPart { constructor( - formState: IFormState, - private readonly connectionInfoResource: ConnectionInfoResource, + formState: IFormState, private readonly dbDriverResource: DBDriverResource, ) { - super(formState, getDefaultState()); + super(formState); } - protected override async loader(): Promise { - const info = await this.connectionInfoResource.load({ - connectionId: this.formState.state.connectionInfoParams.connectionId, - projectId: this.formState.state.connectionInfoParams.projectId, - }); + protected override async loader(): Promise {} - this.setInitialState({ - properties: info?.properties, - }); - } - - protected override saveChanges( - data: IFormState, - contexts: IExecutionContextProvider>, - ): Promise { - return Promise.resolve(); - } + protected override async saveChanges( + data: IFormState, + contexts: IExecutionContextProvider>, + ): Promise {} protected override format( - data: IFormState, - contexts: IExecutionContextProvider>, + data: IFormState, + contexts: IExecutionContextProvider>, ): void | Promise { - const optionsPart = getConnectionFormOptionsPart(this.formState); - const config = optionsPart.state.connectionConfig; + const driverId = this.formState.state.driverId; + const config = getConnectionFormOptionsPart(this.formState).state; - // TODO move driverId to formState - if (config.driverId) { - const driver = this.dbDriverResource.get(config.driverId); + if (!config.properties) { + config.properties = {}; + } + + if (driverId) { + const driver = this.dbDriverResource.get(driverId); const defaultDriverProperties = new Set(driver?.driverProperties?.map(property => property.id) ?? []); - for (let key of Object.keys(this.state.properties)) { - const value = this.state.properties[key]; + for (let key of Object.keys(config.properties)) { + const value = config.properties[key]; if (!defaultDriverProperties?.has(key)) { key = key.trim(); } - this.state.properties[key] = typeof value === 'string' ? value.trim() : value; + config.properties[key] = typeof value === 'string' ? value.trim() : value; } - - config.properties = { ...this.state.properties }; } } } diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/IConnectionFromDriverPropertiesState.ts b/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/IConnectionFromDriverPropertiesState.ts deleted file mode 100644 index 6ff682e658..0000000000 --- a/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/IConnectionFromDriverPropertiesState.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2025 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 { schema } from '@cloudbeaver/core-utils'; - -export const CONNECTION_FORM_DRIVER_PROPERTIES_SCHEMA = schema.object({ - properties: schema.record(schema.string(), schema.string().optional()), -}); - -export type IConnectionFromDriverPropertiesState = schema.infer; diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/getConnectionFormDriverPropertiesPart.ts b/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/getConnectionFormDriverPropertiesPart.ts index cf70daae3d..801aeb4e61 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/getConnectionFormDriverPropertiesPart.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/getConnectionFormDriverPropertiesPart.ts @@ -7,20 +7,19 @@ */ import { createDataContext, DATA_CONTEXT_DI_PROVIDER } from '@cloudbeaver/core-data-context'; import type { IFormState } from '@cloudbeaver/core-ui'; -import type { IConnectionFormRefactoredState } from '../ConnectionFormServiceRefactored.js'; import { ConnectionFormDriverPropertiesPart } from './ConnectionFormDriverPropertiesPart.js'; -import { ConnectionInfoResource, DBDriverResource } from '@cloudbeaver/core-connections'; +import { DBDriverResource } from '@cloudbeaver/core-connections'; +import type { IConnectionFormStateRefactored } from '../IConnectionFormStateRefactored.js'; const DATA_CONTEXT_CONNECTION_FORM_DRIVER_PROPERTIES_PART = createDataContext( 'Connection Form Driver Properties Part', ); -export function getConnectionFormSSHPart(formState: IFormState): ConnectionFormDriverPropertiesPart { +export function getConnectionFormSSHPart(formState: IFormState): ConnectionFormDriverPropertiesPart { return formState.getPart(DATA_CONTEXT_CONNECTION_FORM_DRIVER_PROPERTIES_PART, context => { const di = context.get(DATA_CONTEXT_DI_PROVIDER)!; - const connectionInfoResource = di.getService(ConnectionInfoResource); const dbDriverResource = di.getService(DBDriverResource); - return new ConnectionFormDriverPropertiesPart(formState, connectionInfoResource, dbDriverResource); + return new ConnectionFormDriverPropertiesPart(formState, dbDriverResource); }); } diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/IConnectionFormStateRefactored.ts b/webapp/packages/plugin-connections/src/ConnectionForm/IConnectionFormStateRefactored.ts new file mode 100644 index 0000000000..95f44676c8 --- /dev/null +++ b/webapp/packages/plugin-connections/src/ConnectionForm/IConnectionFormStateRefactored.ts @@ -0,0 +1,21 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2025 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 { schema } from '@cloudbeaver/core-utils'; + +export const CONNECTION_FORM_STATE_SCHEMA = schema + .object({ + projectId: schema.string(), + connectionId: schema.string(), + driverId: schema.string(), + submitType: schema.enum(['submit', 'test']), + }) + .required() + .strict(); + +export type IConnectionFormStateRefactored = schema.infer; diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/Options/ConnectionFormOpitonsPart.ts b/webapp/packages/plugin-connections/src/ConnectionForm/Options/ConnectionFormOpitonsPart.ts index c8b5920f74..2ec7fdf1ed 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/Options/ConnectionFormOpitonsPart.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/Options/ConnectionFormOpitonsPart.ts @@ -6,7 +6,6 @@ * you may not use this file except in compliance with the License. */ import { FormPart, formStateContext, formStatusContext, formValidationContext, type IFormState } from '@cloudbeaver/core-ui'; -import { type IConnectionFormRefactoredState } from '../ConnectionFormServiceRefactored.js'; import { DriverConfigurationType, isObjectPropertyInfoStateEqual, type ConnectionConfig, type ObjectPropertyInfo } from '@cloudbeaver/core-sdk'; import type { IExecutionContextProvider } from '@cloudbeaver/core-executor'; import { @@ -25,57 +24,50 @@ import { getUniqueName, isNotNullDefined, isValuesEqual } from '@cloudbeaver/cor import { getDefaultConfigurationType } from './getDefaultConfigurationType.js'; import { getConnectionName } from './getConnectionName.js'; import type { LocalizationService } from '@cloudbeaver/core-localization'; -import type { IConnectionFormOptionsState } from './IConnectionFormOptionsState.js'; import { connectionCredentialsStateContext } from '../Contexts/connectionCredentialsStateContext.js'; +import type { IConnectionFormOptionsState } from './IConnectionFormOptionsState.js'; +import type { IConnectionFormStateRefactored } from '../IConnectionFormStateRefactored.js'; const MAIN_PROPERTY_DATABASE_KEY = 'database'; const MAIN_PROPERTY_HOST_KEY = 'host'; const MAIN_PROPERTY_PORT_KEY = 'port'; const MAIN_PROPERTY_SERVER_KEY = 'server'; -interface ConnectionFormOptionsPartState { - connectionConfig: IConnectionFormOptionsState; - submitType: 'submit' | 'test'; -} - const defaultStateGetter = () => ({ - connectionConfig: { - authModelId: '', - autocommit: false, - configurationType: DriverConfigurationType.Manual, - connectionId: '', - credentials: {}, - dataSourceId: '', - databaseName: '', - description: '', - driverId: '', - folder: '', - host: '', - keepAliveInterval: 0, - mainPropertyValues: {}, - name: '', - networkHandlersConfig: [], - port: '', - properties: {}, - providerProperties: {}, - readOnly: false, - saveCredentials: false, - selectedSecretId: '', - serverName: '', - sharedCredentials: false, - template: false, - templateId: '', - url: '', - userName: '', - userPassword: '', - }, - submitType: 'submit', - }) as ConnectionFormOptionsPartState; + authModelId: '', + autocommit: false, + configurationType: DriverConfigurationType.Manual, + connectionId: '', + credentials: {}, + dataSourceId: '', + databaseName: '', + description: '', + driverId: '', + folder: '', + host: '', + keepAliveInterval: 0, + mainPropertyValues: {}, + name: '', + networkHandlersConfig: [], + port: '', + properties: {}, + providerProperties: {}, + readOnly: false, + saveCredentials: false, + selectedSecretId: '', + serverName: '', + sharedCredentials: false, + template: false, + templateId: '', + url: '', + userName: '', + userPassword: '', + }) as IConnectionFormOptionsState; -export class ConnectionFormOptionsPart extends FormPart { +export class ConnectionFormOptionsPart extends FormPart { constructor( - formState: IFormState, + formState: IFormState, private readonly dbDriverResource: DBDriverResource, private readonly projectInfoResource: ProjectInfoResource, private readonly databaseAuthModelsResource: DatabaseAuthModelsResource, @@ -88,59 +80,54 @@ export class ConnectionFormOptionsPart extends FormPart { - const info = this.connectionInfoResource.get( - createConnectionParam(this.formState.state.connectionInfoParams.projectId, this.formState.state.connectionInfoParams.connectionId), - ); + const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.formState.state.connectionId)); if (!info) { const defaultConnectionConfig = await this.getDefaults(); this.setInitialState({ ...defaultStateGetter(), - connectionConfig: defaultConnectionConfig || this.state.connectionConfig, + ...defaultConnectionConfig, }); return; } - const config = defaultStateGetter().connectionConfig; + const config = defaultStateGetter(); config.connectionId = info.id; config.configurationType = info.configurationType; @@ -184,22 +171,18 @@ export class ConnectionFormOptionsPart extends FormPart, - contexts: IExecutionContextProvider>, + data: IFormState, + contexts: IExecutionContextProvider>, ) { const stateContext = contexts.getContext(formStateContext); - const driver = await this.dbDriverResource.load(this.state.connectionConfig.driverId!, ['includeProviderProperties', 'includeMainProperties']); - const info = this.connectionInfoResource.get( - createConnectionParam(this.formState.state.connectionInfoParams.projectId, this.formState.state.connectionInfoParams.connectionId), - ); - const authModel = await this.databaseAuthModelsResource.load( - this.state.connectionConfig.authModelId ?? info?.authModel ?? driver.defaultAuthModel, - ); + const driver = await this.dbDriverResource.load(this.state.driverId!, ['includeProviderProperties', 'includeMainProperties']); + const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.formState.state.connectionId)); + const authModel = await this.databaseAuthModelsResource.load(this.state.authModelId ?? info?.authModel ?? driver.defaultAuthModel); const providerId = authModel.requiredAuth ?? info?.requiredAuth ?? AUTH_PROVIDER_LOCAL_ID; @@ -228,95 +211,89 @@ export class ConnectionFormOptionsPart extends FormPart, - contexts: IExecutionContextProvider>, + data: IFormState, + contexts: IExecutionContextProvider>, ): Promise { - if (!this.state.connectionConfig.driverId || !this.formState.state.connectionInfoParams.projectId) { + if (!this.state.driverId || !this.formState.state.projectId) { return; } const credentialsState = contexts.getContext(connectionCredentialsStateContext); - const driver = await this.dbDriverResource.load(this.state.connectionConfig.driverId, ['includeProviderProperties', 'includeMainProperties']); + const driver = await this.dbDriverResource.load(this.state.driverId, ['includeProviderProperties', 'includeMainProperties']); if (this.formState.mode === 'edit') { - this.state.connectionConfig.connectionId = this.formState.state.connectionInfoParams.connectionId; + this.state.connectionId = this.formState.state.connectionId; } - this.state.connectionConfig.name = this.state.connectionConfig.name?.trim(); + this.state.name = this.state.name?.trim(); - if (this.state.connectionConfig.name && this.formState.mode === 'create') { - const connections = await this.connectionInfoResource.load(ConnectionInfoProjectKey(this.formState.state.connectionInfoParams.projectId)); + if (this.state.name && this.formState.mode === 'create') { + const connections = await this.connectionInfoResource.load(ConnectionInfoProjectKey(this.formState.state.projectId)); const connectionNames = connections.map(connection => connection.name); - this.state.connectionConfig.name = getUniqueName(this.state.connectionConfig.name, connectionNames); + this.state.name = getUniqueName(this.state.name, connectionNames); } - this.state.connectionConfig.description = this.state.connectionConfig.description?.trim(); - this.state.connectionConfig.keepAliveInterval = Number(this.state.connectionConfig.keepAliveInterval); + this.state.description = this.state.description?.trim(); + this.state.keepAliveInterval = Number(this.state.keepAliveInterval); - if (this.state.connectionConfig.configurationType === DriverConfigurationType.Url) { - this.state.connectionConfig.url = this.state.connectionConfig.url?.trim(); + if (this.state.configurationType === DriverConfigurationType.Url) { + this.state.url = this.state.url?.trim(); } - this.state.connectionConfig.mainPropertyValues = toJS(this.state.connectionConfig.mainPropertyValues); + this.state.mainPropertyValues = toJS(this.state.mainPropertyValues); - if (this.state.connectionConfig.configurationType === DriverConfigurationType.Manual && !driver.useCustomPage) { - this.state.connectionConfig.mainPropertyValues![MAIN_PROPERTY_DATABASE_KEY] = this.state.connectionConfig.databaseName?.trim(); + if (this.state.configurationType === DriverConfigurationType.Manual && !driver.useCustomPage) { + this.state.mainPropertyValues![MAIN_PROPERTY_DATABASE_KEY] = this.state.databaseName?.trim(); if (!driver.embedded) { - this.state.connectionConfig.mainPropertyValues![MAIN_PROPERTY_HOST_KEY] = this.state.connectionConfig.host?.trim(); - this.state.connectionConfig.mainPropertyValues![MAIN_PROPERTY_PORT_KEY] = this.state.connectionConfig.port?.trim(); + this.state.mainPropertyValues![MAIN_PROPERTY_HOST_KEY] = this.state.host?.trim(); + this.state.mainPropertyValues![MAIN_PROPERTY_PORT_KEY] = this.state.port?.trim(); } if (driver.requiresServerName) { - this.state.connectionConfig.mainPropertyValues![MAIN_PROPERTY_SERVER_KEY] = this.state.connectionConfig.serverName?.trim(); + this.state.mainPropertyValues![MAIN_PROPERTY_SERVER_KEY] = this.state.serverName?.trim(); } } - if ((this.state.connectionConfig.authModelId || driver.defaultAuthModel) && !driver.anonymousAccess) { - this.state.connectionConfig.authModelId = this.state.connectionConfig.authModelId || driver.defaultAuthModel; - this.state.connectionConfig.saveCredentials = this.state.connectionConfig.saveCredentials || this.state.connectionConfig.sharedCredentials; + if ((this.state.authModelId || driver.defaultAuthModel) && !driver.anonymousAccess) { + this.state.authModelId = this.state.authModelId || driver.defaultAuthModel; + this.state.saveCredentials = this.state.saveCredentials || this.state.sharedCredentials; - const info = this.connectionInfoResource.get( - createConnectionParam(this.formState.state.connectionInfoParams.projectId, this.formState.state.connectionInfoParams.connectionId), - ); - const properties = await this.getConnectionAuthModelProperties(this.state.connectionConfig.authModelId, info); + const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.formState.state.connectionId)); + const properties = await this.getConnectionAuthModelProperties(this.state.authModelId, info); - if (this.state.connectionConfig.credentials && isCredentialsChanged(properties, this.state.connectionConfig.credentials)) { - this.state.connectionConfig.credentials = prepareDynamicProperties(properties, toJS(this.state.connectionConfig.credentials)); + if (this.state.credentials && isCredentialsChanged(properties, this.state.credentials)) { + this.state.credentials = prepareDynamicProperties(properties, toJS(this.state.credentials)); } - if (!this.state.connectionConfig.saveCredentials) { - credentialsState.requireAuthModel(this.state.connectionConfig.authModelId || driver.defaultAuthModel); + if (!this.state.saveCredentials) { + credentialsState.requireAuthModel(this.state.authModelId || driver.defaultAuthModel); } } - if (driver.providerProperties.length > 0 && this.state.connectionConfig.providerProperties) { - this.state.connectionConfig.providerProperties = prepareDynamicProperties( + if (driver.providerProperties.length > 0 && this.state.providerProperties) { + this.state.providerProperties = prepareDynamicProperties( driver.providerProperties, - toJS(this.state.connectionConfig.providerProperties), - this.state.connectionConfig.configurationType, + toJS(this.state.providerProperties), + this.state.configurationType, ); } - if (driver.useCustomPage && driver.mainProperties.length > 0 && this.state.connectionConfig.mainPropertyValues) { - this.state.connectionConfig.mainPropertyValues = prepareDynamicProperties( - driver.mainProperties, - this.state.connectionConfig.mainPropertyValues, - this.state.connectionConfig.configurationType, - ); + if (driver.useCustomPage && driver.mainProperties.length > 0 && this.state.mainPropertyValues) { + this.state.mainPropertyValues = prepareDynamicProperties(driver.mainProperties, this.state.mainPropertyValues, this.state.configurationType); } } private async getDefaults(): Promise { - if (!this.state.connectionConfig.driverId) { + if (!this.state.driverId) { // TODO remove it? throw new Error('Driver id is not provided'); } - const defaultConnectionConfig: ConnectionConfig = { ...this.state.connectionConfig }; + const defaultConnectionConfig: ConnectionConfig = { ...this.state }; - const driver = await this.dbDriverResource.load(this.state.connectionConfig.driverId, ['includeProviderProperties']); + const driver = await this.dbDriverResource.load(this.state.driverId, ['includeProviderProperties']); defaultConnectionConfig.authModelId = driver?.defaultAuthModel; defaultConnectionConfig.configurationType = getDefaultConfigurationType(driver); @@ -333,7 +310,7 @@ export class ConnectionFormOptionsPart extends FormPart, - contexts: IExecutionContextProvider>, + data: IFormState, + contexts: IExecutionContextProvider>, ): Promise { const validation = contexts.getContext(formValidationContext); - if ( - this.state.connectionConfig.configurationType === DriverConfigurationType.Manual && - this.state.connectionConfig.host?.length === 0 && - this.state.connectionConfig.driverId - ) { - const driver = await this.dbDriverResource.load(this.state.connectionConfig.driverId); + if (this.state.configurationType === DriverConfigurationType.Manual && this.state.host?.length === 0 && this.state.driverId) { + const driver = await this.dbDriverResource.load(this.state.driverId); if (!driver.embedded) { validation.error('plugin_connections_connection_form_host_invalid'); } } - if (!this.state.connectionConfig.name?.length) { + if (!this.state.name?.length) { validation.error('plugin_connections_connection_form_name_invalid'); } - if (this.state.connectionConfig.driverId && this.state.connectionConfig.configurationType) { - const driver = await this.dbDriverResource.load(this.state.connectionConfig.driverId, ['includeProviderProperties']); + if (this.state.driverId && this.state.configurationType) { + const driver = await this.dbDriverResource.load(this.state.driverId, ['includeProviderProperties']); - if (!driver.configurationTypes.includes(this.state.connectionConfig.configurationType)) { + if (!driver.configurationTypes.includes(this.state.configurationType)) { validation.error('plugin_connections_connection_form_host_configuration_invalid'); } } - if (this.formState.state.connectionInfoParams.projectId !== null && this.formState.mode === 'create') { - const project = this.projectInfoResource.get(this.formState.state.connectionInfoParams.projectId); + if (this.formState.state.projectId !== null && this.formState.mode === 'create') { + const project = this.projectInfoResource.get(this.formState.state.projectId); if (!project?.canEditDataSources) { validation.error('plugin_connections_connection_form_project_invalid'); @@ -389,36 +362,33 @@ export class ConnectionFormOptionsPart extends FormPart, - contexts: IExecutionContextProvider>, + data: IFormState, + contexts: IExecutionContextProvider>, ): Promise { const status = contexts.getContext(formStatusContext); - if (!this.formState.state.connectionInfoParams.projectId) { + if (!this.formState.state.projectId) { status.error('connections_connection_create_fail'); return; } try { - if (this.state.submitType === 'submit') { + if (this.formState.state.submitType === 'submit') { if (this.formState.mode === 'edit') { const connection = await this.connectionInfoResource.update( - createConnectionParam(this.formState.state.connectionInfoParams.projectId, this.formState.state.connectionInfoParams.connectionId!), - this.state.connectionConfig, + createConnectionParam(this.formState.state.projectId, this.formState.state.connectionId!), + this.state, ); status.info('Connection was updated'); status.info(connection.name); } else { - const connection = await this.connectionInfoResource.create( - this.formState.state.connectionInfoParams.projectId, - this.state.connectionConfig, - ); - this.formState.state.connectionInfoParams.connectionId = connection.id; + const connection = await this.connectionInfoResource.create(this.formState.state.projectId, this.state); + this.formState.state.connectionId = connection.id; status.info('Connection was created'); status.info(connection.name); } } else { - const info = await this.connectionInfoResource.test(this.formState.state.connectionInfoParams.projectId, this.state.connectionConfig); + const info = await this.connectionInfoResource.test(this.formState.state.projectId, this.state); status.info('Connection is established'); status.info('Client version: ' + info.clientVersion); status.info('Server version: ' + info.serverVersion); @@ -427,7 +397,7 @@ export class ConnectionFormOptionsPart extends FormPart('Connection Form Options Part'); -export function getConnectionFormOptionsPart(formState: IFormState): ConnectionFormOptionsPart { +export function getConnectionFormOptionsPart(formState: IFormState): ConnectionFormOptionsPart { return formState.getPart(DATA_CONTEXT_CONNECTION_FORM_OPTIONS_PART, context => { const di = context.get(DATA_CONTEXT_DI_PROVIDER)!; const dbDriverResource = di.getService(DBDriverResource); diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/SSH/ConnectionFormSSHPart.ts b/webapp/packages/plugin-connections/src/ConnectionForm/SSH/ConnectionFormSSHPart.ts index 85d25b07e4..c2630e4144 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/SSH/ConnectionFormSSHPart.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/SSH/ConnectionFormSSHPart.ts @@ -6,17 +6,18 @@ * you may not use this file except in compliance with the License. */ import { FormPart, formValidationContext, type IFormState } from '@cloudbeaver/core-ui'; -import { type IConnectionFormRefactoredState } from '../ConnectionFormServiceRefactored.js'; + import type { IExecutionContextProvider } from '@cloudbeaver/core-executor'; import { DriverConfigurationType, NetworkHandlerAuthType, type NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk'; import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js'; import { ConnectionInfoResource, createConnectionParam, SSH_TUNNEL_ID } from '@cloudbeaver/core-connections'; import { toJS } from 'mobx'; import { connectionCredentialsStateContext } from '../Contexts/connectionCredentialsStateContext.js'; +import type { IConnectionFormStateRefactored } from '../IConnectionFormStateRefactored.js'; -export class ConnectionFormSSHPart extends FormPart { +export class ConnectionFormSSHPart extends FormPart { constructor( - formState: IFormState, + formState: IFormState, private readonly connectionInfoResource: ConnectionInfoResource, ) { super(formState); @@ -27,18 +28,16 @@ export class ConnectionFormSSHPart extends FormPart handler.id === SSH_TUNNEL_ID); const optionsPart = getConnectionFormOptionsPart(this.formState); - if (!optionsPart.state.connectionConfig.networkHandlersConfig) { - optionsPart.state.connectionConfig.networkHandlersConfig = []; + if (!optionsPart.state.networkHandlersConfig) { + optionsPart.state.networkHandlersConfig = []; } - if (!optionsPart.state.connectionConfig.networkHandlersConfig.some(state => state.id === SSH_TUNNEL_ID)) { - optionsPart.state.connectionConfig.networkHandlersConfig.push({ + if (!optionsPart.state.networkHandlersConfig.some(state => state.id === SSH_TUNNEL_ID)) { + optionsPart.state.networkHandlersConfig.push({ id: SSH_TUNNEL_ID, enabled: false, authType: NetworkHandlerAuthType.Password, @@ -59,23 +58,21 @@ export class ConnectionFormSSHPart extends FormPart, - contexts: IExecutionContextProvider>, + data: IFormState, + contexts: IExecutionContextProvider>, ): Promise { return Promise.resolve(); } protected override format( - data: IFormState, - contexts: IExecutionContextProvider>, + data: IFormState, + contexts: IExecutionContextProvider>, ): void | Promise { const optionsPart = getConnectionFormOptionsPart(this.formState); - const config = optionsPart.state.connectionConfig; + const config = optionsPart.state; const credentialsState = contexts.getContext(connectionCredentialsStateContext); const urlType = config.configurationType === DriverConfigurationType.Url; - const info = this.connectionInfoResource.get( - createConnectionParam(this.formState.state.connectionInfoParams.projectId, this.formState.state.connectionInfoParams.connectionId), - ); + const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.formState.state.connectionId)); if (urlType || !config.networkHandlersConfig || config.networkHandlersConfig.length === 0) { return; @@ -119,20 +116,18 @@ export class ConnectionFormSSHPart extends FormPart, - contexts: IExecutionContextProvider>, + data: IFormState, + contexts: IExecutionContextProvider>, ): void | Promise { const validation = contexts.getContext(formValidationContext); const optionsPart = getConnectionFormOptionsPart(this.formState); - const info = this.connectionInfoResource.get( - createConnectionParam(this.formState.state.connectionInfoParams.projectId, this.formState.state.connectionInfoParams.connectionId), - ); + const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.formState.state.connectionId)); - if (!optionsPart.state.connectionConfig.networkHandlersConfig) { + if (!optionsPart.state.networkHandlersConfig) { return; } - const handler = optionsPart.state.connectionConfig.networkHandlersConfig.find(handler => handler.id === SSH_TUNNEL_ID); + const handler = optionsPart.state.networkHandlersConfig.find(handler => handler.id === SSH_TUNNEL_ID); if (!handler) { return; diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/SSH/getConnectionFormSSHPart.ts b/webapp/packages/plugin-connections/src/ConnectionForm/SSH/getConnectionFormSSHPart.ts index 8496514d2c..cb298013b4 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/SSH/getConnectionFormSSHPart.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/SSH/getConnectionFormSSHPart.ts @@ -8,12 +8,12 @@ import { createDataContext, DATA_CONTEXT_DI_PROVIDER } from '@cloudbeaver/core-data-context'; import type { IFormState } from '@cloudbeaver/core-ui'; import { ConnectionFormSSHPart } from './ConnectionFormSSHPart.js'; -import type { IConnectionFormRefactoredState } from '../ConnectionFormServiceRefactored.js'; import { ConnectionInfoResource } from '@cloudbeaver/core-connections'; +import type { IConnectionFormStateRefactored } from '../IConnectionFormStateRefactored.js'; const DATA_CONTEXT_CONNECTION_FORM_OPTIONS_PART = createDataContext('Connection Form SSH Part'); -export function getConnectionFormSSHPart(formState: IFormState): ConnectionFormSSHPart { +export function getConnectionFormSSHPart(formState: IFormState): ConnectionFormSSHPart { return formState.getPart(DATA_CONTEXT_CONNECTION_FORM_OPTIONS_PART, context => { const di = context.get(DATA_CONTEXT_DI_PROVIDER)!; const connectionInfoResource = di.getService(ConnectionInfoResource); diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/useConnectionFormStateRefactored.ts b/webapp/packages/plugin-connections/src/ConnectionForm/useConnectionFormStateRefactored.ts index 05c21c0875..cba74eeb8e 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/useConnectionFormStateRefactored.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/useConnectionFormStateRefactored.ts @@ -9,13 +9,13 @@ import { useRef } from 'react'; import { IServiceProvider, useService } from '@cloudbeaver/core-di'; import { ConnectionFormStateRefactored } from './ConnectionFormStateRefactored.js'; import { ConnectionFormServiceRefactored } from './ConnectionFormServiceRefactored.js'; -import type { IConnectionInfoParams } from '@cloudbeaver/core-connections'; +import type { IConnectionFormStateRefactored } from './IConnectionFormStateRefactored.js'; -const EMPTY_CONNECTION_INFO_PARAMS: IConnectionInfoParams = { projectId: '', connectionId: '' }; +const EMPTY_CONNECTION_INFO_PARAMS: IConnectionFormStateRefactored = { projectId: '', connectionId: '', driverId: '', submitType: 'submit' }; // TODO is nullable return allowed? export function useConnectionFormStateRefactored( - connectionInfoParams: IConnectionInfoParams | null, + state: IConnectionFormStateRefactored | null, configure?: (state: ConnectionFormStateRefactored) => any, ): ConnectionFormStateRefactored | null { const serviceProvider = useService(IServiceProvider); @@ -23,12 +23,11 @@ export function useConnectionFormStateRefactored( const ref = useRef(null); if ( - ref.current?.state.connectionInfoParams.connectionId !== connectionInfoParams?.connectionId || - ref.current?.state.connectionInfoParams.projectId !== connectionInfoParams?.projectId + ref.current?.state.connectionId !== state?.connectionId || + ref.current?.state.projectId !== state?.projectId || + ref.current?.state.driverId !== state?.driverId ) { - ref.current = new ConnectionFormStateRefactored(serviceProvider, service, { - connectionInfoParams: connectionInfoParams || EMPTY_CONNECTION_INFO_PARAMS, - }); + ref.current = new ConnectionFormStateRefactored(serviceProvider, service, state || EMPTY_CONNECTION_INFO_PARAMS); configure?.(ref.current); }