mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
CB-4067 removes config from form state
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { action, makeObservable, observable, runInAction, toJS } from 'mobx';
|
||||
|
||||
import { AppAuthService, UserInfoResource } from '@cloudbeaver/core-authentication';
|
||||
@@ -269,13 +270,6 @@ export class ConnectionInfoResource extends CachedMapResource<IConnectionInfoPar
|
||||
return this.sessionUpdate;
|
||||
}
|
||||
|
||||
getEmptyConfig(): ConnectionConfig {
|
||||
return {
|
||||
template: false,
|
||||
saveCredentials: false,
|
||||
};
|
||||
}
|
||||
|
||||
isConnecting(key: IConnectionInfoParams): boolean;
|
||||
isConnecting(key: ResourceKeyList<IConnectionInfoParams>): boolean;
|
||||
isConnecting(key: ResourceKey<IConnectionInfoParams>): boolean;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { makeObservable, observable } from 'mobx';
|
||||
|
||||
import { makeObservable, observable, runInAction } from 'mobx';
|
||||
|
||||
import { ConfirmationDialog } from '@cloudbeaver/core-blocks';
|
||||
import { ConnectionInfoResource, ConnectionsManagerService, createConnectionParam } from '@cloudbeaver/core-connections';
|
||||
@@ -15,7 +16,7 @@ import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { ExecutorInterrupter, type IExecutorHandler } from '@cloudbeaver/core-executor';
|
||||
import type { AdminConnectionSearchInfo } from '@cloudbeaver/core-sdk';
|
||||
import { OptionsPanelService } from '@cloudbeaver/core-ui';
|
||||
import { ConnectionFormService, ConnectionFormState } from '@cloudbeaver/plugin-connections';
|
||||
import { ConnectionFormService, ConnectionFormState, getConnectionFormOptionsPart } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import { SearchDatabase } from './SearchDatabase.js';
|
||||
|
||||
@@ -102,13 +103,17 @@ export class ConnectionSearchService {
|
||||
this.close();
|
||||
};
|
||||
|
||||
get optionsPart() {
|
||||
return this.formState ? getConnectionFormOptionsPart(this.formState) : null;
|
||||
}
|
||||
|
||||
private async showUnsavedChangesDialog(): Promise<boolean> {
|
||||
if (
|
||||
!this.formState ||
|
||||
!this.optionsPanelService.isOpen(formGetter) ||
|
||||
(this.formState.state.config.connectionId &&
|
||||
(this.optionsPart?.state.connectionId &&
|
||||
this.formState.state.projectId !== null &&
|
||||
!this.connectionInfoResource.has(createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId)))
|
||||
!this.connectionInfoResource.has(createConnectionParam(this.formState.state.projectId, this.optionsPart.state.connectionId)))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -148,18 +153,19 @@ export class ConnectionSearchService {
|
||||
|
||||
if (!this.formState) {
|
||||
this.formState = new ConnectionFormState(this.serviceProvider, this.connectionFormService, {
|
||||
config: {
|
||||
...this.connectionInfoResource.getEmptyConfig(),
|
||||
host: database.host,
|
||||
port: String(database.port),
|
||||
driverId: database.defaultDriver,
|
||||
},
|
||||
submitType: null,
|
||||
projectId: projects[0]!.id,
|
||||
availableDrivers: database.possibleDrivers,
|
||||
type: 'public',
|
||||
requiredNetworkHandlersIds: [],
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.optionsPart!.state.host = database.host;
|
||||
this.optionsPart!.state.port = String(database.port);
|
||||
this.optionsPart!.state.driverId = database.defaultDriver;
|
||||
});
|
||||
|
||||
this.formState.disposeTask.addHandler(this.goBack.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -1,15 +1,16 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { observer } from 'mobx-react-lite';
|
||||
|
||||
import { Loader, s, useS } from '@cloudbeaver/core-blocks';
|
||||
import { type IConnectionInfoParams } from '@cloudbeaver/core-connections';
|
||||
import { ConnectionFormLoader, useConnectionFormState } from '@cloudbeaver/plugin-connections';
|
||||
import { ConnectionFormLoader, getConnectionFormOptionsPart, useConnectionFormState } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import styles from './ConnectionEdit.module.css';
|
||||
import { FormMode } from '@cloudbeaver/core-ui';
|
||||
@@ -22,9 +23,10 @@ interface Props {
|
||||
export const ConnectionEdit = observer<Props>(function ConnectionEditNew({ item }) {
|
||||
const data = useConnectionFormState(item, state => {
|
||||
state.setMode(FormMode.Edit);
|
||||
const optionsPart = getConnectionFormOptionsPart(state);
|
||||
|
||||
runInAction(() => {
|
||||
state.state.config.connectionId = item.connectionId;
|
||||
optionsPart.state.connectionId = item.connectionId;
|
||||
state.state.projectId = item.projectId;
|
||||
state.state.type = 'admin';
|
||||
});
|
||||
|
||||
+5
-3
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { observer } from 'mobx-react-lite';
|
||||
|
||||
import {
|
||||
@@ -25,7 +26,7 @@ import {
|
||||
import { DBDriverResource } from '@cloudbeaver/core-connections';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { TabListStyles, TabPanelList, TabPanelStyles, TabsState, TabStyles } from '@cloudbeaver/core-ui';
|
||||
import { ConnectionFormLoader } from '@cloudbeaver/plugin-connections';
|
||||
import { ConnectionFormLoader, getConnectionFormOptionsPart } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import { CreateConnectionService } from '../CreateConnectionService.js';
|
||||
import styles from './shared/CreateConnection.module.css';
|
||||
@@ -48,7 +49,8 @@ export const CreateConnection = observer<Props>(function CreateConnection({ meth
|
||||
const style = useS(styles);
|
||||
const createConnectionService = useService(CreateConnectionService);
|
||||
const translate = useTranslate();
|
||||
const driver = useResource(CreateConnection, DBDriverResource, createConnectionService.data?.state.config.driverId || null);
|
||||
const optionsPart = createConnectionService.data ? getConnectionFormOptionsPart(createConnectionService.data) : null;
|
||||
const driver = useResource(CreateConnection, DBDriverResource, optionsPart?.state.driverId || null);
|
||||
|
||||
if (createConnectionService.data) {
|
||||
return (
|
||||
|
||||
+3
-4
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { ConnectionInfoResource } from '@cloudbeaver/core-connections';
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
|
||||
import { CreateConnectionService } from '../../CreateConnectionService.js';
|
||||
@@ -20,7 +20,7 @@ export class ConnectionManualService {
|
||||
this.createConnectionService.disabled = value;
|
||||
}
|
||||
|
||||
constructor(private readonly connectionInfoResource: ConnectionInfoResource, private readonly createConnectionService: CreateConnectionService) {
|
||||
constructor(private readonly createConnectionService: CreateConnectionService) {
|
||||
this.select = this.select.bind(this);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ export class ConnectionManualService {
|
||||
this.createConnectionService.setConnectionTemplate(
|
||||
projectId,
|
||||
{
|
||||
...this.connectionInfoResource.getEmptyConfig(),
|
||||
template: true,
|
||||
driverId,
|
||||
},
|
||||
|
||||
+13
-3
@@ -5,13 +5,13 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { action, makeObservable, observable } from 'mobx';
|
||||
import { action, makeObservable, observable, runInAction } from 'mobx';
|
||||
|
||||
import { AdministrationScreenService } from '@cloudbeaver/core-administration';
|
||||
import { injectable, IServiceProvider } from '@cloudbeaver/core-di';
|
||||
import type { ConnectionConfig } from '@cloudbeaver/core-sdk';
|
||||
import { TabsContainer } from '@cloudbeaver/core-ui';
|
||||
import { ConnectionFormService, ConnectionFormState } from '@cloudbeaver/plugin-connections';
|
||||
import { ConnectionFormService, ConnectionFormState, getConnectionFormOptionsPart } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import { ConnectionsAdministrationNavService } from './ConnectionsAdministrationNavService.js';
|
||||
|
||||
@@ -104,16 +104,26 @@ export class CreateConnectionService {
|
||||
this.activateMethod(defaultId);
|
||||
}
|
||||
|
||||
get optionsPart() {
|
||||
return this.data ? getConnectionFormOptionsPart(this.data) : null;
|
||||
}
|
||||
|
||||
setConnectionTemplate(projectId: string, config: ConnectionConfig, availableDrivers: string[]): void {
|
||||
this.data?.dispose();
|
||||
this.data = new ConnectionFormState(this.serviceProvider, this.connectionFormService, {
|
||||
projectId,
|
||||
availableDrivers,
|
||||
config,
|
||||
submitType: null,
|
||||
type: 'admin',
|
||||
requiredNetworkHandlersIds: [],
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.optionsPart!.state = {
|
||||
...this.optionsPart!.state,
|
||||
...config,
|
||||
};
|
||||
});
|
||||
this.data.disposeTask.addHandler(this.cancelCreate.bind(this));
|
||||
}
|
||||
|
||||
|
||||
+12
-10
@@ -5,6 +5,7 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { action, computed, observable } from 'mobx';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useMemo, useState } from 'react';
|
||||
@@ -29,11 +30,10 @@ import type { TLocalizationToken } from '@cloudbeaver/core-localization';
|
||||
import { CachedMapAllKey, CachedResourceOffsetPageListKey } from '@cloudbeaver/core-resource';
|
||||
import { FormMode, type TabContainerPanelComponent, useTab } from '@cloudbeaver/core-ui';
|
||||
import type { IConnectionFormProps } from '@cloudbeaver/plugin-connections';
|
||||
|
||||
import { getConnectionFormOptionsPart } from '@cloudbeaver/plugin-connections';
|
||||
import styles from './ConnectionAccess.module.css';
|
||||
import { ConnectionAccessGrantedList } from './ConnectionAccessGrantedList.js';
|
||||
import { ConnectionAccessList } from './ConnectionAccessList.js';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { getConnectionFormAccessPart } from './getConnectionFormAccessPart.js';
|
||||
|
||||
export const ConnectionAccess: TabContainerPanelComponent<IConnectionFormProps> = observer(function ConnectionAccess({ tabId, formState }) {
|
||||
@@ -74,14 +74,12 @@ export const ConnectionAccess: TabContainerPanelComponent<IConnectionFormProps>
|
||||
[accessPart.state, teams.resource],
|
||||
);
|
||||
|
||||
if (!selected) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const connectionInfoService = useService(ConnectionInfoResource);
|
||||
const originInfoService = useService(ConnectionInfoOriginResource);
|
||||
const connectionInfo = connectionInfoService.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
const originInfo = originInfoService.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const key = createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!);
|
||||
const connectionInfoResource = useResource(ConnectionAccess, ConnectionInfoResource, key);
|
||||
const originInfoResource = useResource(ConnectionAccess, ConnectionInfoOriginResource, key);
|
||||
const connectionInfo = connectionInfoResource.data;
|
||||
const originInfo = originInfoResource.data;
|
||||
const loading = users.isLoading() || teams.isLoading() || accessPart.isLoading();
|
||||
const cloud = connectionInfo && originInfo?.origin ? isCloudConnection(originInfo.origin) : false;
|
||||
const disabled = loading || !accessPart.isLoaded() || formState.isDisabled || cloud;
|
||||
@@ -93,6 +91,10 @@ export const ConnectionAccess: TabContainerPanelComponent<IConnectionFormProps>
|
||||
info = 'cloud_connections_access_placeholder';
|
||||
}
|
||||
|
||||
if (!selected) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Loader className={s(style, { loader: true })} state={[users, teams, accessPart]}>
|
||||
{() => (
|
||||
|
||||
+7
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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.
|
||||
@@ -11,7 +11,7 @@ import { AdministrationScreenService } from '@cloudbeaver/core-administration';
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { isGlobalProject, ProjectInfoResource } from '@cloudbeaver/core-projects';
|
||||
import { EAdminPermission, PermissionsService } from '@cloudbeaver/core-root';
|
||||
import { ConnectionFormService } from '@cloudbeaver/plugin-connections';
|
||||
import { ConnectionFormService, getConnectionFormOptionsPart } from '@cloudbeaver/plugin-connections';
|
||||
import { getConnectionFormAccessPart } from './getConnectionFormAccessPart.js';
|
||||
|
||||
const ConnectionAccess = React.lazy(async () => {
|
||||
@@ -41,7 +41,11 @@ export class ConnectionAccessTabService extends Bootstrap {
|
||||
order: 4,
|
||||
stateGetter: context => () => getConnectionFormAccessPart(context.formState),
|
||||
isHidden: (_, context) => !context || !this.isAccessTabActive(context.formState.state.projectId),
|
||||
isDisabled: (tabId, props) => !props?.formState.state.config.driverId || this.administrationScreenService.isConfigurationMode,
|
||||
isDisabled: (tabId, props) => {
|
||||
const optionsPart = props?.formState ? getConnectionFormOptionsPart(props.formState) : null;
|
||||
|
||||
return !optionsPart?.state.driverId || this.administrationScreenService.isConfigurationMode;
|
||||
},
|
||||
panel: () => ConnectionAccess,
|
||||
});
|
||||
}
|
||||
|
||||
+5
-16
@@ -9,7 +9,7 @@ import { FormPart, formStatusContext, type IFormState } from '@cloudbeaver/core-
|
||||
import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { createConnectionParam, type ConnectionInfoResource } from '@cloudbeaver/core-connections';
|
||||
import { action, makeObservable } from 'mobx';
|
||||
import type { IConnectionFormState } from '@cloudbeaver/plugin-connections';
|
||||
import { getConnectionFormOptionsPart, type IConnectionFormState } from '@cloudbeaver/plugin-connections';
|
||||
import { getSubjectDifferences } from '@cloudbeaver/core-utils';
|
||||
|
||||
function getDefaultState(): string[] {
|
||||
@@ -29,21 +29,9 @@ export class ConnectionFormAccessPart extends FormPart<string[], IConnectionForm
|
||||
});
|
||||
}
|
||||
|
||||
override isOutdated(): boolean {
|
||||
const connectionId = this.formState.state.config.connectionId;
|
||||
const projectId = this.formState.state.projectId;
|
||||
|
||||
if (!connectionId || !projectId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const key = createConnectionParam(projectId, connectionId);
|
||||
|
||||
return this.connectionInfoResource.isOutdated(key);
|
||||
}
|
||||
|
||||
protected override async loader(): Promise<void> {
|
||||
const connectionId = this.formState.state.config.connectionId;
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
const connectionId = optionsPart.state.connectionId;
|
||||
const projectId = this.formState.state.projectId;
|
||||
|
||||
if (!connectionId || !projectId) {
|
||||
@@ -62,7 +50,8 @@ export class ConnectionFormAccessPart extends FormPart<string[], IConnectionForm
|
||||
contexts: IExecutionContextProvider<IFormState<IConnectionFormState>>,
|
||||
): Promise<void> {
|
||||
const status = contexts.getContext(formStatusContext);
|
||||
const connectionId = this.formState.state.config.connectionId;
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
const connectionId = optionsPart.state.connectionId;
|
||||
|
||||
if (this.formState.state.submitType === 'test' || !data.state.projectId || !status.saved || !connectionId || !this.loaded) {
|
||||
return;
|
||||
|
||||
@@ -19,6 +19,7 @@ import type { ConnectionFormState } from './ConnectionFormState.js';
|
||||
import { getFirstException } from '@cloudbeaver/core-utils';
|
||||
import { ConnectionFormService } from './ConnectionFormService.js';
|
||||
import { ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections';
|
||||
import { getConnectionFormOptionsPart } from './Options/getConnectionFormOptionsPart.js';
|
||||
|
||||
export interface ConnectionFormProps {
|
||||
formState: ConnectionFormState;
|
||||
@@ -41,7 +42,8 @@ export const ConnectionForm = observer<ConnectionFormProps>(function ConnectionF
|
||||
|
||||
const initialMode = formState.mode;
|
||||
const saved = await formState.save();
|
||||
const info = connectionInfoResource.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const info = connectionInfoResource.get(createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!));
|
||||
|
||||
if (saved) {
|
||||
if (formState.state.submitType === 'submit') {
|
||||
@@ -75,9 +77,10 @@ export const ConnectionForm = observer<ConnectionFormProps>(function ConnectionF
|
||||
function save(data, contexts) {
|
||||
const validation = contexts.getContext(formValidationContext);
|
||||
const state = contexts.getContext(formStatusContext);
|
||||
const optionsPart = getConnectionFormOptionsPart(data);
|
||||
|
||||
if (validation.valid && state.saved && data.state.submitType === 'submit') {
|
||||
props.onSave(data.state.config);
|
||||
props.onSave(optionsPart.state);
|
||||
}
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { observer } from 'mobx-react-lite';
|
||||
import { useContext } from 'react';
|
||||
|
||||
@@ -16,7 +17,7 @@ import { ServerConfigResource } from '@cloudbeaver/core-root';
|
||||
import { ConnectionFormActionsContext } from './ConnectFormActionsContext.js';
|
||||
import type { IConnectionFormProps } from './IConnectionFormState.js';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
|
||||
import { getConnectionFormOptionsPart } from './Options/getConnectionFormOptionsPart.js';
|
||||
export const ConnectionFormBaseActions: PlaceholderComponent<IConnectionFormProps> = observer(function ConnectionFormBaseActions({ formState }) {
|
||||
const actions = useContext(ConnectionFormActionsContext);
|
||||
|
||||
@@ -25,24 +26,25 @@ export const ConnectionFormBaseActions: PlaceholderComponent<IConnectionFormProp
|
||||
}
|
||||
|
||||
const translate = useTranslate();
|
||||
const driverMap = useResource(ConnectionFormBaseActions, DBDriverResource, formState.state.config.driverId || null);
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const driverMap = useResource(ConnectionFormBaseActions, DBDriverResource, optionsPart.state.driverId || null);
|
||||
|
||||
const connectionInfoService = useService(ConnectionInfoResource);
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!));
|
||||
|
||||
const driver = driverMap.data;
|
||||
const serverConfigResource = useResource(ConnectionFormBaseActions, ServerConfigResource, undefined);
|
||||
const { data: authModel } = useResource(
|
||||
ConnectionFormBaseActions,
|
||||
DatabaseAuthModelsResource,
|
||||
getComputed(() => formState.state.config.authModelId || info?.authModel || driver?.defaultAuthModel || null),
|
||||
getComputed(() => optionsPart.state.authModelId || info?.authModel || driver?.defaultAuthModel || null),
|
||||
);
|
||||
const authentication = useAuthenticationAction({
|
||||
providerId: authModel?.requiredAuth ?? info?.requiredAuth ?? AUTH_PROVIDER_LOCAL_ID,
|
||||
});
|
||||
|
||||
const authorized = authentication.providerId === AUTH_PROVIDER_LOCAL_ID || authentication.authorized;
|
||||
const disableTest = serverConfigResource.data?.distributed && !!formState.state.config.sharedCredentials;
|
||||
const disableTest = serverConfigResource.data?.distributed && !!optionsPart.state.sharedCredentials;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -10,52 +10,45 @@ import { FormState } from '@cloudbeaver/core-ui';
|
||||
|
||||
import { ConnectionFormService } from './ConnectionFormService.js';
|
||||
import type { IConnectionFormState } from './IConnectionFormState.js';
|
||||
import { ProjectInfoResource, ProjectsService } from '@cloudbeaver/core-projects';
|
||||
import { ConnectionInfoResource, createConnectionParam, type IConnectionInfoParams } from '@cloudbeaver/core-connections';
|
||||
import type { ResourceKeySimple } from '@cloudbeaver/core-resource';
|
||||
|
||||
export class ConnectionFormState extends FormState<IConnectionFormState> {
|
||||
constructor(
|
||||
private readonly serviceProvider: IServiceProvider,
|
||||
service: ConnectionFormService,
|
||||
config: IConnectionFormState,
|
||||
) {
|
||||
constructor(serviceProvider: IServiceProvider, service: ConnectionFormService, config: IConnectionFormState) {
|
||||
super(serviceProvider, service, config);
|
||||
|
||||
const projectInfoResource = serviceProvider.getService(ProjectInfoResource);
|
||||
const projectsService = serviceProvider.getService(ProjectsService);
|
||||
const resource = serviceProvider.getService(ConnectionInfoResource);
|
||||
// const projectInfoResource = serviceProvider.getService(ProjectInfoResource);
|
||||
// const projectsService = serviceProvider.getService(ProjectsService);
|
||||
// const resource = serviceProvider.getService(ConnectionInfoResource);
|
||||
|
||||
resource.onItemUpdate.removeHandler(this.syncInfo.bind(this));
|
||||
projectInfoResource.onDataUpdate.removeHandler(this.syncProject.bind(this));
|
||||
projectsService.onActiveProjectChange.removeHandler(this.syncProject.bind(this));
|
||||
// resource.onItemUpdate.removeHandler(this.syncInfo.bind(this));
|
||||
// projectInfoResource.onDataUpdate.removeHandler(this.syncProject.bind(this));
|
||||
// projectsService.onActiveProjectChange.removeHandler(this.syncProject.bind(this));
|
||||
}
|
||||
|
||||
private async syncInfo(key: ResourceKeySimple<IConnectionInfoParams>) {
|
||||
const resource = this.serviceProvider.getService(ConnectionInfoResource);
|
||||
// private async syncInfo(key: ResourceKeySimple<IConnectionInfoParams>) {
|
||||
// const resource = this.serviceProvider.getService(ConnectionInfoResource);
|
||||
|
||||
if (
|
||||
!this.state.config.connectionId ||
|
||||
this.state.projectId === null ||
|
||||
!resource.isIntersect(key, createConnectionParam(this.state.projectId, this.state.config.connectionId))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// if (
|
||||
// !this.state.config.connectionId ||
|
||||
// this.state.projectId === null ||
|
||||
// !resource.isIntersect(key, createConnectionParam(this.state.projectId, this.state.config.connectionId))
|
||||
// ) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
await this.reload();
|
||||
}
|
||||
// await this.reload();
|
||||
// }
|
||||
|
||||
private async syncProject() {
|
||||
if (!this.state.projectId) {
|
||||
return;
|
||||
}
|
||||
// private async syncProject() {
|
||||
// if (!this.state.projectId) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
const projectInfoResource = this.serviceProvider.getService(ProjectInfoResource);
|
||||
const projectsService = this.serviceProvider.getService(ProjectsService);
|
||||
// const projectInfoResource = this.serviceProvider.getService(ProjectInfoResource);
|
||||
// const projectsService = this.serviceProvider.getService(ProjectsService);
|
||||
|
||||
const project = projectInfoResource.get(this.state.projectId);
|
||||
if (!project?.canEditDataSources || !projectsService.activeProjects.includes(project)) {
|
||||
await this.dispose();
|
||||
}
|
||||
}
|
||||
// const project = projectInfoResource.get(this.state.projectId);
|
||||
// if (!project?.canEditDataSources || !projectsService.activeProjects.includes(project)) {
|
||||
// await this.dispose();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
+7
-4
@@ -1,15 +1,15 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
|
||||
import { DriverPropertiesLoader } from './DriverPropertiesLoader.js';
|
||||
import { ConnectionFormService } from '../ConnectionFormService.js';
|
||||
import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js';
|
||||
|
||||
@injectable()
|
||||
export class ConnectionDriverPropertiesTabService extends Bootstrap {
|
||||
@@ -25,9 +25,12 @@ export class ConnectionDriverPropertiesTabService extends Bootstrap {
|
||||
order: 2,
|
||||
panel: () => DriverPropertiesLoader,
|
||||
isDisabled: (tabId, props) => {
|
||||
if (props?.formState.state.config.driverId) {
|
||||
return !props.formState.state.config.driverId;
|
||||
const optionsPart = props?.formState ? getConnectionFormOptionsPart(props.formState) : null;
|
||||
|
||||
if (optionsPart?.state.driverId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
+15
-6
@@ -10,6 +10,8 @@ import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections';
|
||||
import type { IConnectionFormState } from '../IConnectionFormState.js';
|
||||
import type { IConnectionProperties } from '../Options/IConnectionConfig.js';
|
||||
import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js';
|
||||
import { runInAction } from 'mobx';
|
||||
|
||||
function getDefaultState(): IConnectionProperties {
|
||||
return {};
|
||||
@@ -23,19 +25,17 @@ export class ConnectionFormDriverPropertiesPart extends FormPart<IConnectionProp
|
||||
super(formState, getDefaultState());
|
||||
}
|
||||
|
||||
override isOutdated(): boolean {
|
||||
return this.connectionInfoResource.isOutdated(createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId!));
|
||||
get optionsPart() {
|
||||
return getConnectionFormOptionsPart(this.formState);
|
||||
}
|
||||
|
||||
protected override async loader(): Promise<void> {
|
||||
if (!this.formState.state.config.connectionId || !this.formState.state.projectId) {
|
||||
if (!this.optionsPart.state.connectionId || !this.formState.state.projectId) {
|
||||
this.setInitialState(getDefaultState());
|
||||
return;
|
||||
}
|
||||
|
||||
const connection = this.connectionInfoResource.get(
|
||||
createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId),
|
||||
);
|
||||
const connection = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.optionsPart.state.connectionId!));
|
||||
|
||||
if (connection?.properties) {
|
||||
this.setInitialState({ ...connection.properties });
|
||||
@@ -59,5 +59,14 @@ export class ConnectionFormDriverPropertiesPart extends FormPart<IConnectionProp
|
||||
this.state[key] = this.state[key].trim();
|
||||
}
|
||||
}
|
||||
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
|
||||
runInAction(() => {
|
||||
optionsPart.state.properties = {
|
||||
...optionsPart.state.properties,
|
||||
...this.state,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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.
|
||||
@@ -17,12 +17,13 @@ import { uuid } from '@cloudbeaver/core-utils';
|
||||
import styles from './DriverProperties.module.css';
|
||||
import { getConnectionFormDriverPropertiesPart } from './getConnectionFormDriverPropertiesPart.js';
|
||||
import type { IConnectionFormProps } from '../IConnectionFormState.js';
|
||||
import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js';
|
||||
|
||||
export const DriverProperties: TabContainerPanelComponent<IConnectionFormProps> = observer(function DriverProperties({ tabId, formState }) {
|
||||
const { selected } = useTab(tabId);
|
||||
const style = useS(styles);
|
||||
const driverPropertiesPart = getConnectionFormDriverPropertiesPart(formState);
|
||||
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const [state] = useState(() => {
|
||||
const propertiesList: IProperty[] = observable([]);
|
||||
|
||||
@@ -44,7 +45,7 @@ export const DriverProperties: TabContainerPanelComponent<IConnectionFormProps>
|
||||
});
|
||||
|
||||
const driver = useResource(DriverProperties, DBDriverResource, {
|
||||
key: (selected && formState.state.config.driverId) || null,
|
||||
key: (selected && optionsPart.state.driverId) || null,
|
||||
includes: ['includeDriverProperties'] as const,
|
||||
});
|
||||
|
||||
|
||||
@@ -7,13 +7,11 @@
|
||||
*/
|
||||
|
||||
import { schema } from '@cloudbeaver/core-utils';
|
||||
import { CONNECTION_CONFIG_SCHEMA } from './Options/IConnectionConfig.js';
|
||||
import type { IFormProps } from '@cloudbeaver/core-ui';
|
||||
|
||||
export const CONNECTION_FORM_STATE_SCHEMA = schema
|
||||
.object({
|
||||
projectId: schema.string(),
|
||||
config: CONNECTION_CONFIG_SCHEMA,
|
||||
submitType: schema.enum(['submit', 'test']).nullable(),
|
||||
availableDrivers: schema.array(schema.string()),
|
||||
requiredNetworkHandlersIds: schema.array(schema.string()),
|
||||
|
||||
+98
-66
@@ -6,7 +6,13 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { FormMode, FormPart, formStateContext, formValidationContext, type IFormState } from '@cloudbeaver/core-ui';
|
||||
import { DriverConfigurationType, type ConnectionConfig, type ObjectPropertyInfo, type TestConnectionMutation } from '@cloudbeaver/core-sdk';
|
||||
import {
|
||||
DriverConfigurationType,
|
||||
type ConnectionConfig,
|
||||
type DatabaseAuthModel,
|
||||
type ObjectPropertyInfo,
|
||||
type TestConnectionMutation,
|
||||
} from '@cloudbeaver/core-sdk';
|
||||
import { ExecutorInterrupter, type IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import {
|
||||
ConnectionInfoProjectKey,
|
||||
@@ -16,6 +22,7 @@ import {
|
||||
DBDriverResource,
|
||||
isJDBCConnection,
|
||||
type DatabaseConnection,
|
||||
type DBDriver,
|
||||
} from '@cloudbeaver/core-connections';
|
||||
import type { ProjectInfoResource } from '@cloudbeaver/core-projects';
|
||||
import { AUTH_PROVIDER_LOCAL_ID, AuthProvidersResource, UserInfoResource } from '@cloudbeaver/core-authentication';
|
||||
@@ -40,6 +47,7 @@ const defaultStateGetter = () =>
|
||||
configurationType: DriverConfigurationType.Manual,
|
||||
keepAliveInterval: 0,
|
||||
credentials: {},
|
||||
template: false,
|
||||
mainPropertyValues: {},
|
||||
networkHandlersConfig: [],
|
||||
saveCredentials: false,
|
||||
@@ -66,19 +74,15 @@ export class ConnectionFormOptionsPart extends FormPart<IConnectionFormOptionsSt
|
||||
this.formState.loadedTask.addPostHandler(this.formAuthState.bind(this));
|
||||
}
|
||||
|
||||
override isOutdated(): boolean {
|
||||
return this.connectionInfoResource.isOutdated(createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId!));
|
||||
}
|
||||
|
||||
private async formAuthState(data: IFormState<IConnectionFormState>, contexts: IExecutionContextProvider<IFormState<IConnectionFormState>>) {
|
||||
const stateContext = contexts.getContext(formStateContext);
|
||||
const info = this.connectionInfoResource.get(createConnectionParam(data.state.projectId, data.state.config.connectionId!));
|
||||
const info = this.connectionInfoResource.get(createConnectionParam(data.state.projectId, this.state.connectionId!));
|
||||
|
||||
if (!this.formState.state.config.driverId || !this.formState.state.projectId) {
|
||||
if (!this.state.driverId || !this.formState.state.projectId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const driver = await this.dbDriverResource.load(this.formState.state.config.driverId, ['includeProviderProperties', 'includeMainProperties']);
|
||||
const driver = await this.dbDriverResource.load(this.state.driverId, ['includeProviderProperties', 'includeMainProperties']);
|
||||
const [authModel] = await Promise.all([this.databaseAuthModelsResource.load(driver.defaultAuthModel), this.userInfoResource.load()]);
|
||||
const providerId = authModel.requiredAuth ?? info?.requiredAuth ?? AUTH_PROVIDER_LOCAL_ID;
|
||||
|
||||
@@ -93,22 +97,19 @@ export class ConnectionFormOptionsPart extends FormPart<IConnectionFormOptionsSt
|
||||
}
|
||||
|
||||
private async askCredentials(data: IFormState<IConnectionFormState>, contexts: IExecutionContextProvider<IFormState<IConnectionFormState>>) {
|
||||
if (
|
||||
this.formState.state.submitType !== 'test' ||
|
||||
(!this.formState.state.config.authModelId && !this.formState.state.requiredNetworkHandlersIds.length)
|
||||
) {
|
||||
if (this.formState.state.submitType !== 'test' || (!this.state.authModelId && !this.formState.state.requiredNetworkHandlersIds.length)) {
|
||||
return;
|
||||
}
|
||||
|
||||
runInAction(() => {
|
||||
if (this.formState.state.config.authModelId) {
|
||||
if (this.state.authModelId) {
|
||||
this.state.credentials = observable(this.state.credentials!);
|
||||
}
|
||||
});
|
||||
|
||||
const result = await this.commonDialogService.open(ConnectionAuthenticationDialogLoader, {
|
||||
config: this.state,
|
||||
authModelId: this.formState.state.config.authModelId ?? null,
|
||||
authModelId: this.state.authModelId ?? null,
|
||||
networkHandlers: this.formState.state.requiredNetworkHandlersIds,
|
||||
projectId: data.state.projectId,
|
||||
});
|
||||
@@ -120,30 +121,28 @@ export class ConnectionFormOptionsPart extends FormPart<IConnectionFormOptionsSt
|
||||
|
||||
protected override async loader(): Promise<void> {
|
||||
if (this.formState.mode === 'create') {
|
||||
await this.setDefaults();
|
||||
const defaults = await this.getDefaults();
|
||||
|
||||
this.setInitialState({
|
||||
...defaultStateGetter(),
|
||||
...this.formState.state.config,
|
||||
...defaults,
|
||||
...this.state,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.formState.state.config.connectionId || !this.formState.state.projectId) {
|
||||
if (!this.state.connectionId || !this.formState.state.projectId) {
|
||||
console.error('Connection id and project id should be defined');
|
||||
return;
|
||||
}
|
||||
|
||||
const info = await this.connectionInfoResource.load(
|
||||
createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId),
|
||||
[
|
||||
'includeAuthProperties',
|
||||
'includeCredentialsSaved',
|
||||
'customIncludeOptions',
|
||||
'includeProperties',
|
||||
'includeProviderProperties',
|
||||
'includeNetworkHandlersConfig',
|
||||
],
|
||||
);
|
||||
const info = await this.connectionInfoResource.load(createConnectionParam(this.formState.state.projectId, this.state.connectionId), [
|
||||
'includeAuthProperties',
|
||||
'includeCredentialsSaved',
|
||||
'customIncludeOptions',
|
||||
'includeProperties',
|
||||
'includeProviderProperties',
|
||||
'includeNetworkHandlersConfig',
|
||||
]);
|
||||
|
||||
const config: ConnectionConfig = defaultStateGetter();
|
||||
|
||||
@@ -188,55 +187,97 @@ export class ConnectionFormOptionsPart extends FormPart<IConnectionFormOptionsSt
|
||||
}
|
||||
|
||||
this.formState.state.availableDrivers = [info.driverId];
|
||||
this.formState.state.config = config;
|
||||
this.setInitialState(config);
|
||||
|
||||
this.setInitialState({ ...config });
|
||||
}
|
||||
|
||||
private async setDefaults() {
|
||||
if (!this.formState.state.config.driverId) {
|
||||
return;
|
||||
isNameAutoFill() {
|
||||
const isAutoFill = this.state.name === this.initialState.name || this.initialState.name === null;
|
||||
|
||||
return isAutoFill && this.formState.mode === 'create';
|
||||
}
|
||||
|
||||
updateNameTemplate(driver: DBDriver | undefined) {
|
||||
runInAction(() => {
|
||||
const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.state.connectionId!));
|
||||
if (isJDBCConnection(driver, info)) {
|
||||
this.state.name = this.state.url || '';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!driver) {
|
||||
this.state.name = 'New connection';
|
||||
return;
|
||||
}
|
||||
|
||||
const name = getConnectionName(driver.name || '', this.state.host, this.state.port, driver.defaultPort);
|
||||
|
||||
this.state.name = name;
|
||||
});
|
||||
}
|
||||
|
||||
setAuthModel(model: DatabaseAuthModel) {
|
||||
this.state.credentials = {};
|
||||
const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.state.connectionId!));
|
||||
|
||||
if (model.id === info?.authModel) {
|
||||
if (info.authProperties) {
|
||||
for (const property of info.authProperties) {
|
||||
if (!property.features.includes('password')) {
|
||||
this.state.credentials[property.id!] = property.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const driver = await this.dbDriverResource.load(this.formState.state.config.driverId, ['includeProviderProperties']);
|
||||
this.state.authModelId = model.id;
|
||||
}
|
||||
|
||||
this.formState.state.config.authModelId = driver?.defaultAuthModel;
|
||||
this.formState.state.config.configurationType = getDefaultConfigurationType(driver);
|
||||
private async getDefaults() {
|
||||
const config = defaultStateGetter();
|
||||
|
||||
if (!this.formState.state.config.host) {
|
||||
this.formState.state.config.host = driver?.defaultServer || 'localhost';
|
||||
if (!this.state.driverId) {
|
||||
config.name = 'New connection';
|
||||
return config;
|
||||
}
|
||||
|
||||
if (!this.formState.state.config.port) {
|
||||
this.formState.state.config.port = driver?.defaultPort;
|
||||
const driver = await this.dbDriverResource.load(this.state.driverId, ['includeProviderProperties']);
|
||||
|
||||
config.authModelId = driver?.defaultAuthModel;
|
||||
config.configurationType = getDefaultConfigurationType(driver);
|
||||
|
||||
if (!this.state.host) {
|
||||
config.host = driver?.defaultServer || 'localhost';
|
||||
}
|
||||
|
||||
this.formState.state.config.databaseName = driver?.defaultDatabase;
|
||||
this.formState.state.config.url = driver?.sampleURL;
|
||||
if (!this.state.port) {
|
||||
config.port = driver?.defaultPort;
|
||||
}
|
||||
|
||||
config.databaseName = driver?.defaultDatabase;
|
||||
config.url = driver?.sampleURL;
|
||||
|
||||
if (isJDBCConnection(driver)) {
|
||||
this.formState.state.config.name = this.formState.state.config.url;
|
||||
config.name = config.url;
|
||||
} else {
|
||||
this.formState.state.config.name = getConnectionName(
|
||||
driver.name || '',
|
||||
this.formState.state.config.host,
|
||||
this.formState.state.config.port,
|
||||
driver.defaultPort,
|
||||
);
|
||||
config.name = getConnectionName(driver.name || '', config.host, config.port, driver.defaultPort);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
protected override async format(
|
||||
data: IFormState<IConnectionFormState>,
|
||||
contexts: IExecutionContextProvider<IFormState<IConnectionFormState>>,
|
||||
): Promise<void> {
|
||||
if (!this.formState.state.config.driverId || !this.formState.state.projectId) {
|
||||
if (!this.state.driverId || !this.formState.state.projectId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const driver = await this.dbDriverResource.load(this.formState.state.config.driverId, ['includeProviderProperties', 'includeMainProperties']);
|
||||
const driver = await this.dbDriverResource.load(this.state.driverId, ['includeProviderProperties', 'includeMainProperties']);
|
||||
|
||||
if (this.formState.mode === 'edit') {
|
||||
this.state.connectionId = this.formState.state.config.connectionId;
|
||||
this.state.connectionId = this.state.connectionId;
|
||||
}
|
||||
|
||||
this.formState.state.requiredNetworkHandlersIds = observable([]);
|
||||
@@ -278,21 +319,15 @@ export class ConnectionFormOptionsPart extends FormPart<IConnectionFormOptionsSt
|
||||
}
|
||||
|
||||
if ((this.state.authModelId || driver.defaultAuthModel) && !driver.anonymousAccess) {
|
||||
this.state.authModelId = this.formState.state.config.authModelId || driver.defaultAuthModel;
|
||||
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.projectId, this.formState.state.config.connectionId!));
|
||||
const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.state.connectionId!));
|
||||
|
||||
const properties = await this.getConnectionAuthModelProperties(this.state.authModelId, info);
|
||||
|
||||
if (isCredentialsChanged(properties, this.state.credentials!)) {
|
||||
this.state.credentials = prepareDynamicProperties(properties, toJS(this.state.credentials!));
|
||||
}
|
||||
|
||||
if (this.state.saveCredentials) {
|
||||
delete this.formState.state.config.authModelId;
|
||||
} else {
|
||||
this.formState.state.config.authModelId = this.state.authModelId;
|
||||
}
|
||||
}
|
||||
|
||||
if (driver.providerProperties.length > 0) {
|
||||
@@ -388,13 +423,10 @@ export class ConnectionFormOptionsPart extends FormPart<IConnectionFormOptionsSt
|
||||
|
||||
if (this.formState.state.submitType === 'submit') {
|
||||
if (this.formState.mode === 'edit') {
|
||||
await this.connectionInfoResource.update(
|
||||
createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId!),
|
||||
this.state,
|
||||
);
|
||||
await this.connectionInfoResource.update(createConnectionParam(this.formState.state.projectId, this.state.connectionId!), this.state);
|
||||
} else {
|
||||
const connection = await this.connectionInfoResource.create(this.formState.state.projectId, this.state);
|
||||
this.formState.state.config.connectionId = connection.id;
|
||||
this.state.connectionId = connection.id;
|
||||
this.formState.setMode(FormMode.Edit);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -42,5 +42,4 @@ export const CONNECTION_CONFIG_SCHEMA = schema.object({
|
||||
userPassword: schema.string().optional(),
|
||||
});
|
||||
|
||||
export type IConnectionConfig = schema.infer<typeof CONNECTION_CONFIG_SCHEMA>;
|
||||
export type IConnectionProperties = schema.infer<typeof CONNECTION_PROPERTIES_SCHEMA>;
|
||||
|
||||
@@ -60,9 +60,9 @@ import { AdvancedPropertiesForm } from './AdvancedPropertiesForm.js';
|
||||
import styles from './Options.module.css';
|
||||
import { ParametersForm } from './ParametersForm.js';
|
||||
import { ProviderPropertiesForm } from './ProviderPropertiesForm.js';
|
||||
import { useOptions } from './useOptions.js';
|
||||
import { getConnectionFormOptionsPart } from './getConnectionFormOptionsPart.js';
|
||||
import type { IConnectionFormProps } from '../IConnectionFormState.js';
|
||||
import { runInAction } from 'mobx';
|
||||
|
||||
const PROFILE_AUTH_MODEL_ID = 'profile';
|
||||
|
||||
@@ -97,39 +97,32 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
const isSharedProject = projectInfoResource.isProjectShared(formState.state.projectId);
|
||||
const connectionInfoService = useService(ConnectionInfoResource);
|
||||
const connectionInfoOriginResource = useService(ConnectionInfoOriginResource);
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
const originInfo = connectionInfoOriginResource.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const config = optionsPart.state;
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!));
|
||||
const key = createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!);
|
||||
const originInfo = key ? connectionInfoOriginResource.get(key) : null;
|
||||
|
||||
//@TODO it's here until the profile implementation in the CloudBeaver
|
||||
const readonly = formState.isDisabled || info?.authModel === PROFILE_AUTH_MODEL_ID;
|
||||
|
||||
useFormValidator(formState.validationTask, formRef.current);
|
||||
const optionsHook = useOptions(formState, optionsPart.state);
|
||||
const { credentialsSavingEnabled } = useAdministrationSettings();
|
||||
|
||||
const driverMap = useResource(
|
||||
Options,
|
||||
DBDriverResource,
|
||||
{ key: formState.state.config.driverId || config.driverId || null, includes: ['includeProviderProperties', 'includeMainProperties'] as const },
|
||||
{
|
||||
onData: data => {
|
||||
optionsHook.setDefaults(data);
|
||||
},
|
||||
},
|
||||
);
|
||||
const driverMap = useResource(Options, DBDriverResource, {
|
||||
key: optionsPart.state.driverId || null,
|
||||
includes: ['includeProviderProperties', 'includeMainProperties'] as const,
|
||||
});
|
||||
|
||||
const driver = driverMap.data;
|
||||
const configurationTypes = driverConfiguration.filter(configuration => driver && configuration.isVisible(driver));
|
||||
|
||||
function handleFormChange(value?: unknown, name?: string) {
|
||||
if (name !== 'name' && optionsHook.isNameAutoFill()) {
|
||||
optionsHook.updateNameTemplate(driver);
|
||||
if (name !== 'name' && optionsPart.isNameAutoFill()) {
|
||||
optionsPart.updateNameTemplate(driver);
|
||||
}
|
||||
|
||||
if (config.template) {
|
||||
config.folder = undefined;
|
||||
if (optionsPart.state.template) {
|
||||
optionsPart.state.folder = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,9 +131,9 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
const authModelLoader = useResource(
|
||||
Options,
|
||||
DatabaseAuthModelsResource,
|
||||
getComputed(() => config.authModelId || info?.authModel || driver?.defaultAuthModel || null),
|
||||
getComputed(() => optionsPart.state.authModelId || info?.authModel || driver?.defaultAuthModel || null),
|
||||
{
|
||||
onData: optionsHook.setAuthModel,
|
||||
onData: optionsPart.setAuthModel.bind(optionsPart),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -157,7 +150,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
return;
|
||||
}
|
||||
|
||||
await optionsHook.setAuthModel(model);
|
||||
optionsPart.setAuthModel(model);
|
||||
}
|
||||
|
||||
const authentication = useAuthenticationAction({
|
||||
@@ -181,11 +174,11 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
|
||||
let properties = authModel?.properties;
|
||||
|
||||
if (info?.authProperties && info.authProperties.length > 0 && config.authModelId === info.authModel) {
|
||||
if (info?.authProperties && info.authProperties.length > 0 && optionsPart.state.authModelId === info.authModel) {
|
||||
properties = info.authProperties;
|
||||
}
|
||||
|
||||
const sharedCredentials = config.sharedCredentials && serverConfigResource.data?.distributed;
|
||||
const sharedCredentials = optionsPart.state.sharedCredentials && serverConfigResource.data?.distributed;
|
||||
|
||||
function openCredentialsTab(event: React.MouseEvent<HTMLAnchorElement>) {
|
||||
event.preventDefault();
|
||||
@@ -197,7 +190,10 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
return;
|
||||
}
|
||||
|
||||
formState.state.config.driverId = driverId;
|
||||
runInAction(() => {
|
||||
optionsPart.state.driverId = driverId;
|
||||
});
|
||||
|
||||
await formState.reload();
|
||||
}
|
||||
|
||||
@@ -218,7 +214,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
<Container wrap gap>
|
||||
<Combobox
|
||||
name="driverId"
|
||||
state={config}
|
||||
state={optionsPart.state}
|
||||
items={drivers}
|
||||
onSelect={reloadForm}
|
||||
keySelector={driver => driver.id}
|
||||
@@ -237,7 +233,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
{configurationTypes.length > 1 && (
|
||||
<FormFieldDescription label={translate('connections_connection_configuration')} tiny>
|
||||
<Container gap>
|
||||
<RadioGroup name="configurationType" state={config}>
|
||||
<RadioGroup name="configurationType" state={optionsPart.state}>
|
||||
{configurationTypes.map(conf => (
|
||||
<Radio
|
||||
key={conf.value}
|
||||
@@ -256,29 +252,29 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
</FormFieldDescription>
|
||||
)}
|
||||
</Container>
|
||||
{config.configurationType === DriverConfigurationType.Url && (
|
||||
{optionsPart.state.configurationType === DriverConfigurationType.Url && (
|
||||
<InputField
|
||||
type="text"
|
||||
name="url"
|
||||
state={config}
|
||||
state={optionsPart.state}
|
||||
readOnly={readonly || formState.isDisabled}
|
||||
autoComplete={`section-${config.driverId || 'driver'} section-jdbc`}
|
||||
autoComplete={`section-${optionsPart.state.driverId || 'driver'} section-jdbc`}
|
||||
>
|
||||
{translate('plugin_connections_connection_form_part_main_url_jdbc')}
|
||||
</InputField>
|
||||
)}
|
||||
|
||||
{config.configurationType === DriverConfigurationType.Manual &&
|
||||
{optionsPart.state.configurationType === DriverConfigurationType.Manual &&
|
||||
(driver?.useCustomPage ? (
|
||||
<ObjectPropertyInfoForm
|
||||
state={config.mainPropertyValues}
|
||||
state={optionsPart.state.mainPropertyValues}
|
||||
properties={driver.mainProperties ?? EMPTY_ARRAY}
|
||||
disabled={formState.isDisabled}
|
||||
readOnly={readonly}
|
||||
/>
|
||||
) : (
|
||||
<ParametersForm
|
||||
config={config}
|
||||
config={optionsPart.state}
|
||||
embedded={driver?.embedded}
|
||||
requiresServerName={driver?.requiresServerName}
|
||||
disabled={formState.isDisabled}
|
||||
@@ -290,10 +286,10 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
</Group>
|
||||
<Group form gap>
|
||||
<Container wrap gap>
|
||||
<InputField type="text" name="name" minLength={1} state={config} readOnly={readonly || formState.isDisabled} required fill>
|
||||
<InputField type="text" name="name" minLength={1} state={optionsPart.state} readOnly={readonly || formState.isDisabled} required fill>
|
||||
{translate('connections_connection_name')}
|
||||
</InputField>
|
||||
{!config.template && (
|
||||
{!optionsPart.state.template && (
|
||||
<ProjectSelect
|
||||
value={formState.state.projectId}
|
||||
readOnly={readonly || edit}
|
||||
@@ -302,12 +298,12 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
onChange={setProject}
|
||||
/>
|
||||
)}
|
||||
{!config.template && (
|
||||
{!optionsPart.state.template && (
|
||||
<InputField
|
||||
type="text"
|
||||
name="folder"
|
||||
state={config}
|
||||
autoComplete={`section-${config.driverId || 'driver'} section-folder`}
|
||||
state={optionsPart.state}
|
||||
autoComplete={`section-${optionsPart.state.driverId || 'driver'} section-folder`}
|
||||
autoHide
|
||||
readOnly
|
||||
tiny
|
||||
@@ -317,7 +313,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
</InputField>
|
||||
)}
|
||||
</Container>
|
||||
<Textarea name="description" rows={3} state={config} readOnly={readonly || formState.isDisabled}>
|
||||
<Textarea name="description" rows={3} state={optionsPart.state} readOnly={readonly || formState.isDisabled}>
|
||||
{translate('connections_connection_description')}
|
||||
</Textarea>
|
||||
</Group>
|
||||
@@ -328,10 +324,10 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
<GroupTitle>{translate('connections_connection_edit_authentication')}</GroupTitle>
|
||||
{serverConfigResource.resource.distributed && isSharedProject && (
|
||||
<FieldCheckbox
|
||||
id={config.connectionId + 'isShared'}
|
||||
id={optionsPart.state.connectionId + 'isShared'}
|
||||
name="sharedCredentials"
|
||||
title={translate('connections_connection_share_credentials_tooltip')}
|
||||
state={config}
|
||||
state={optionsPart.state}
|
||||
disabled={formState.isDisabled || readonly}
|
||||
keepSize
|
||||
>
|
||||
@@ -339,7 +335,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
</FieldCheckbox>
|
||||
)}
|
||||
<ConnectionAuthModelSelector
|
||||
authModelCredentialsState={config}
|
||||
authModelCredentialsState={optionsPart.state}
|
||||
applicableAuthModels={applicableAuthModels}
|
||||
readonlyAuthModelId={!originLocal}
|
||||
readonly={readonly}
|
||||
@@ -350,7 +346,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
<>
|
||||
{properties && (
|
||||
<ConnectionAuthModelCredentialsForm
|
||||
credentials={config.credentials}
|
||||
credentials={optionsPart.state.credentials}
|
||||
properties={properties}
|
||||
readonly={readonly}
|
||||
disabled={formState.isDisabled}
|
||||
@@ -365,12 +361,12 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
</Link>
|
||||
</FormFieldDescription>
|
||||
)}
|
||||
{!sharedCredentials && authModel && credentialsSavingEnabled && !config.template && (
|
||||
{!sharedCredentials && authModel && credentialsSavingEnabled && !optionsPart.state.template && (
|
||||
<FieldCheckbox
|
||||
id={config.connectionId + 'authNeeded'}
|
||||
id={optionsPart.state.connectionId + 'authNeeded'}
|
||||
name="saveCredentials"
|
||||
state={config}
|
||||
disabled={formState.isDisabled || readonly || config.sharedCredentials}
|
||||
state={optionsPart.state}
|
||||
disabled={formState.isDisabled || readonly || optionsPart.state.sharedCredentials}
|
||||
mod={['primary']}
|
||||
title={translate(
|
||||
!isSharedProject || serverConfigResource.data?.distributed
|
||||
@@ -389,10 +385,15 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
|
||||
</Group>
|
||||
)}
|
||||
{driver?.providerProperties && (
|
||||
<ProviderPropertiesForm config={config} properties={driver.providerProperties} disabled={formState.isDisabled} readonly={readonly} />
|
||||
<ProviderPropertiesForm
|
||||
config={optionsPart.state}
|
||||
properties={driver.providerProperties}
|
||||
disabled={formState.isDisabled}
|
||||
readonly={readonly}
|
||||
/>
|
||||
)}
|
||||
|
||||
<AdvancedPropertiesForm config={config} disabled={formState.isDisabled} readonly={readonly} />
|
||||
<AdvancedPropertiesForm config={optionsPart.state} disabled={formState.isDisabled} readonly={readonly} />
|
||||
</Container>
|
||||
</ColoredContainer>
|
||||
</Form>
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 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 { runInAction } from 'mobx';
|
||||
|
||||
import { useObjectRef } from '@cloudbeaver/core-blocks';
|
||||
import { ConnectionInfoResource, createConnectionParam, type DBDriver, DBDriverResource, isJDBCConnection } from '@cloudbeaver/core-connections';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import type { ConnectionConfig, DatabaseAuthModel } from '@cloudbeaver/core-sdk';
|
||||
import { getConnectionName } from './getConnectionName.js';
|
||||
import { getDefaultConfigurationType } from './getDefaultConfigurationType.js';
|
||||
import type { IFormState } from '@cloudbeaver/core-ui';
|
||||
import type { IConnectionFormState } from '../IConnectionFormState.js';
|
||||
|
||||
export function useOptions(formState: IFormState<IConnectionFormState>, config: ConnectionConfig) {
|
||||
const mode = formState.mode;
|
||||
const connectionInfoService = useService(ConnectionInfoResource);
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
|
||||
const dbDriverResource = useService(DBDriverResource);
|
||||
const refObject = useObjectRef(
|
||||
() => ({
|
||||
prevName: null as string | null,
|
||||
prevDriverId: null as string | null,
|
||||
}),
|
||||
{
|
||||
config,
|
||||
info,
|
||||
mode,
|
||||
formState,
|
||||
},
|
||||
);
|
||||
|
||||
return useObjectRef({
|
||||
updateNameTemplate(driver: DBDriver | undefined) {
|
||||
runInAction(() => {
|
||||
const { config, info } = refObject;
|
||||
|
||||
if (isJDBCConnection(driver, info)) {
|
||||
refObject.prevName = config.url || '';
|
||||
config.name = config.url || '';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!driver) {
|
||||
config.name = 'New connection';
|
||||
return;
|
||||
}
|
||||
|
||||
const name = getConnectionName(driver.name || '', config.host, config.port, driver.defaultPort);
|
||||
|
||||
refObject.prevName = name;
|
||||
config.name = name;
|
||||
});
|
||||
},
|
||||
setDefaults(driver: DBDriver | undefined) {
|
||||
runInAction(() => {
|
||||
const { config, info, prevDriverId } = refObject;
|
||||
|
||||
if (info || driver?.id !== config.driverId) {
|
||||
return;
|
||||
}
|
||||
|
||||
let prevDriver: DBDriver | undefined;
|
||||
|
||||
if (prevDriverId) {
|
||||
prevDriver = dbDriverResource.get(prevDriverId);
|
||||
}
|
||||
|
||||
refObject.prevDriverId = driver?.id || null;
|
||||
|
||||
if (!config.configurationType || !driver?.configurationTypes.includes(config.configurationType)) {
|
||||
config.configurationType = getDefaultConfigurationType(driver);
|
||||
}
|
||||
|
||||
if ((!prevDriver && config.host === undefined) || config.host === prevDriver?.defaultServer) {
|
||||
config.host = driver?.defaultServer || 'localhost';
|
||||
}
|
||||
|
||||
if ((!prevDriver && config.port === undefined) || config.port === prevDriver?.defaultPort) {
|
||||
config.port = driver?.defaultPort;
|
||||
}
|
||||
|
||||
if ((!prevDriver && config.databaseName === undefined) || config.databaseName === prevDriver?.defaultDatabase) {
|
||||
config.databaseName = driver?.defaultDatabase;
|
||||
}
|
||||
|
||||
if ((!prevDriver && config.url === undefined) || config.url === prevDriver?.sampleURL) {
|
||||
config.url = driver?.sampleURL;
|
||||
}
|
||||
|
||||
if (this.isNameAutoFill()) {
|
||||
this.updateNameTemplate(driver);
|
||||
}
|
||||
|
||||
if (driver?.id !== prevDriver?.id) {
|
||||
config.credentials = {};
|
||||
config.providerProperties = {};
|
||||
config.authModelId = driver?.defaultAuthModel;
|
||||
}
|
||||
});
|
||||
},
|
||||
async setAuthModel(model: DatabaseAuthModel) {
|
||||
const { config, info, formState } = refObject;
|
||||
|
||||
config.credentials = {};
|
||||
|
||||
if (model.id === info?.authModel) {
|
||||
if (info.authProperties) {
|
||||
for (const property of info.authProperties) {
|
||||
if (!property.features.includes('password')) {
|
||||
config.credentials[property.id!] = property.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await formState.reload();
|
||||
},
|
||||
|
||||
isNameAutoFill() {
|
||||
const { prevName, config, mode } = refObject;
|
||||
|
||||
const isAutoFill = config.name === prevName || prevName === null;
|
||||
|
||||
return isAutoFill && mode === 'create';
|
||||
},
|
||||
});
|
||||
}
|
||||
+10
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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.
|
||||
@@ -13,18 +13,20 @@ import { ConnectionInfoResource, createConnectionParam, DatabaseAuthModelsResour
|
||||
|
||||
import type { IConnectionFormProps } from '../IConnectionFormState.js';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js';
|
||||
|
||||
export const AuthenticationButton: PlaceholderComponent<IConnectionFormProps> = observer(function ConnectionFormAuthenticationAction({ formState }) {
|
||||
const translate = useTranslate();
|
||||
const driverMap = useResource(ConnectionFormAuthenticationAction, DBDriverResource, formState.state.config.driverId || null);
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const driverMap = useResource(ConnectionFormAuthenticationAction, DBDriverResource, optionsPart.state.driverId || null);
|
||||
const connectionInfoService = useService(ConnectionInfoResource);
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!));
|
||||
|
||||
const driver = driverMap.data;
|
||||
const { data: authModel } = useResource(
|
||||
ConnectionFormAuthenticationAction,
|
||||
DatabaseAuthModelsResource,
|
||||
getComputed(() => formState.state.config.authModelId || info?.authModel || driver?.defaultAuthModel || null),
|
||||
getComputed(() => optionsPart.state.authModelId || info?.authModel || driver?.defaultAuthModel || null),
|
||||
);
|
||||
|
||||
const authentication = useAuthenticationAction({
|
||||
@@ -46,15 +48,16 @@ export const AuthenticationButton: PlaceholderComponent<IConnectionFormProps> =
|
||||
export const ConnectionFormAuthenticationAction: PlaceholderComponent<IConnectionFormProps> = observer(function ConnectionFormAuthenticationAction({
|
||||
formState,
|
||||
}) {
|
||||
const driverMap = useResource(ConnectionFormAuthenticationAction, DBDriverResource, formState.state.config.driverId || null);
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const driverMap = useResource(ConnectionFormAuthenticationAction, DBDriverResource, optionsPart.state.driverId || null);
|
||||
const connectionInfoService = useService(ConnectionInfoResource);
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!));
|
||||
|
||||
const driver = driverMap.data;
|
||||
const { data: authModel } = useResource(
|
||||
ConnectionFormAuthenticationAction,
|
||||
DatabaseAuthModelsResource,
|
||||
getComputed(() => formState.state.config.authModelId || info?.authModel || driver?.defaultAuthModel || null),
|
||||
getComputed(() => optionsPart.state.authModelId || info?.authModel || driver?.defaultAuthModel || null),
|
||||
);
|
||||
|
||||
if (!authModel?.requiredAuth && !info?.requiredAuth) {
|
||||
|
||||
+12
-28
@@ -42,22 +42,23 @@ export class ConnectionFormOriginInfoFormPart extends FormPart<IConnectionFormOr
|
||||
});
|
||||
}
|
||||
|
||||
get optionsPart() {
|
||||
return getConnectionFormOptionsPart(this.formState);
|
||||
}
|
||||
|
||||
get providerId(): string | null {
|
||||
if (!this.formState.state.projectId || !this.formState.state.config.driverId) {
|
||||
if (!this.formState.state.projectId || !this.optionsPart.state.driverId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const driver = this.dbDriverResource.get(this.formState.state.config.driverId);
|
||||
const driver = this.dbDriverResource.get(this.optionsPart.state.driverId);
|
||||
|
||||
if (!driver) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, optionsPart.state.connectionId!));
|
||||
const authModel = this.databaseAuthModelsResource.get(
|
||||
this.formState.state.config.authModelId ?? info?.authModel ?? driver?.defaultAuthModel ?? null,
|
||||
);
|
||||
const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.optionsPart.state.connectionId!));
|
||||
const authModel = this.databaseAuthModelsResource.get(this.optionsPart.state.authModelId ?? info?.authModel ?? driver?.defaultAuthModel ?? null);
|
||||
const providerId = authModel?.requiredAuth ?? info?.requiredAuth ?? AUTH_PROVIDER_LOCAL_ID;
|
||||
|
||||
return providerId;
|
||||
@@ -71,29 +72,12 @@ export class ConnectionFormOriginInfoFormPart extends FormPart<IConnectionFormOr
|
||||
return this.userInfoResource.hasToken(this.providerId);
|
||||
}
|
||||
|
||||
override isOutdated(): boolean {
|
||||
const isDriverOutdated = this.dbDriverResource.isOutdated(this.formState.state.config.driverId);
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
const connectionId = optionsPart.state.connectionId;
|
||||
|
||||
const isConnectionOutdated = connectionId
|
||||
? this.connectionInfoResource.isOutdated(createConnectionParam(this.formState.state.projectId, connectionId))
|
||||
: false;
|
||||
const isAuthModelOutdated = this.authModelId ? this.databaseAuthModelsResource.isOutdated(this.authModelId) : false;
|
||||
// TODO why is app goes to infinite loop when this is uncommented?
|
||||
// const isOriginInfoOutdated = connectionId
|
||||
// ? this.connectionInfoOriginDetailsResource.isOutdated(createConnectionParam(this.formState.state.projectId, connectionId))
|
||||
// : false;
|
||||
|
||||
return isDriverOutdated || isConnectionOutdated || isAuthModelOutdated || this.userInfoResource.isOutdated() || optionsPart.isOutdated();
|
||||
}
|
||||
|
||||
get authModelId(): string | null {
|
||||
const driver = this.dbDriverResource.get(this.formState.state.config.driverId!)!;
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
const driver = this.dbDriverResource.get(optionsPart.state.driverId!)!;
|
||||
const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, optionsPart.state.connectionId!));
|
||||
|
||||
return this.formState.state.config.authModelId ?? info?.authModel ?? driver?.defaultAuthModel ?? null;
|
||||
return optionsPart.state.authModelId ?? info?.authModel ?? driver?.defaultAuthModel ?? null;
|
||||
}
|
||||
|
||||
protected override async loader(): Promise<void> {
|
||||
@@ -101,12 +85,12 @@ export class ConnectionFormOriginInfoFormPart extends FormPart<IConnectionFormOr
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
const connectionId = optionsPart.state.connectionId;
|
||||
|
||||
if (!connectionId || !this.formState.state.projectId || !this.formState.state.config.driverId) {
|
||||
if (!connectionId || !this.formState.state.projectId || !optionsPart.state.driverId) {
|
||||
this.setInitialState(state);
|
||||
return;
|
||||
}
|
||||
|
||||
await this.dbDriverResource.load(this.formState.state.config.driverId);
|
||||
await this.dbDriverResource.load(optionsPart.state.driverId);
|
||||
|
||||
if (!this.authModelId) {
|
||||
throw new Error('Auth model is not defined');
|
||||
|
||||
+3
-2
@@ -12,7 +12,7 @@ import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { ConnectionFormService } from '../ConnectionFormService.js';
|
||||
import { importLazyComponent } from '@cloudbeaver/core-blocks';
|
||||
import { CachedMapAllKey, getCachedMapResourceLoaderState } from '@cloudbeaver/core-resource';
|
||||
|
||||
import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js';
|
||||
export const ConnectionFormAuthenticationAction = importLazyComponent(() =>
|
||||
import('./ConnectionFormAuthenticationAction.js').then(m => m.ConnectionFormAuthenticationAction),
|
||||
);
|
||||
@@ -38,7 +38,8 @@ export class ConnectionOriginInfoTabService extends Bootstrap {
|
||||
getLoader: () => getCachedMapResourceLoaderState(this.connectionInfoOriginResource, () => CachedMapAllKey),
|
||||
isHidden: (tabId, props) => {
|
||||
const projectId = props?.formState.state.projectId;
|
||||
const connectionId = props?.formState.state.config.connectionId;
|
||||
const optionsPart = props?.formState ? getConnectionFormOptionsPart(props.formState) : null;
|
||||
const connectionId = optionsPart?.state.connectionId;
|
||||
|
||||
if (!projectId || !connectionId) {
|
||||
return true;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { observer } from 'mobx-react-lite';
|
||||
|
||||
import { AuthProvidersResource } from '@cloudbeaver/core-authentication';
|
||||
@@ -30,6 +29,7 @@ import styles from './OriginInfo.module.css';
|
||||
import type { IConnectionFormProps } from '../IConnectionFormState.js';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { getConnectionFormOriginInfoFormPart } from './getConnectionFormOriginInfoFormPart.js';
|
||||
import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js';
|
||||
|
||||
export const OriginInfo: TabContainerPanelComponent<IConnectionFormProps> = observer(function OriginInfo({ tabId, formState }) {
|
||||
const tab = useTab(tabId);
|
||||
@@ -37,7 +37,8 @@ export const OriginInfo: TabContainerPanelComponent<IConnectionFormProps> = obse
|
||||
const originInfoPart = getConnectionFormOriginInfoFormPart(formState);
|
||||
const style = useS(styles);
|
||||
const connectionInfoService = useService(ConnectionInfoResource);
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!));
|
||||
const providerLoader = useResource(OriginInfo, AuthProvidersResource, originInfoPart.providerId);
|
||||
const connectionId = tab.selected && info ? createConnectionParam(info.projectId, info.id) : null;
|
||||
const isAuthenticated = getComputed(() => originInfoPart.isAuthenticated);
|
||||
|
||||
@@ -12,12 +12,13 @@ import { Tab, type TabContainerTabComponent, TabTitle } from '@cloudbeaver/core-
|
||||
|
||||
import type { IConnectionFormProps } from '../IConnectionFormState.js';
|
||||
import { ConnectionInfoOriginResource, createConnectionParam } from '@cloudbeaver/core-connections';
|
||||
|
||||
import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js';
|
||||
export const OriginInfoTab: TabContainerTabComponent<IConnectionFormProps> = observer(function OriginInfoTab({ formState, ...rest }) {
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const connectionInfoOriginResource = useResource(
|
||||
OriginInfoTab,
|
||||
ConnectionInfoOriginResource,
|
||||
createConnectionParam(formState.state.projectId, formState.state.config.connectionId!),
|
||||
createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!),
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -42,18 +42,18 @@ export class ConnectionFormSSHPart extends FormPart<INetworkHandlerConfig, IConn
|
||||
super(formState, getDefaultState());
|
||||
}
|
||||
|
||||
override isOutdated(): boolean {
|
||||
return this.connectionInfoResource.isOutdated(createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId!));
|
||||
get optionsPart() {
|
||||
return getConnectionFormOptionsPart(this.formState);
|
||||
}
|
||||
|
||||
protected override async loader(): Promise<void> {
|
||||
if (!this.formState.state.config.connectionId || !this.formState.state.projectId) {
|
||||
if (!this.optionsPart.state.connectionId || !this.formState.state.projectId) {
|
||||
this.setInitialState(getDefaultState());
|
||||
return;
|
||||
}
|
||||
|
||||
const connection = await this.connectionInfoResource.load(
|
||||
createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId),
|
||||
createConnectionParam(this.formState.state.projectId, this.optionsPart.state.connectionId!),
|
||||
);
|
||||
|
||||
this.setInitialState(connection?.networkHandlersConfig?.find(h => h.id === SSH_TUNNEL_ID) ?? getDefaultState());
|
||||
@@ -68,8 +68,8 @@ export class ConnectionFormSSHPart extends FormPart<INetworkHandlerConfig, IConn
|
||||
data: IFormState<IConnectionFormState>,
|
||||
contexts: IExecutionContextProvider<IFormState<IConnectionFormState>>,
|
||||
): void | Promise<void> {
|
||||
const urlType = this.formState.state.config.configurationType === DriverConfigurationType.Url;
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
const urlType = optionsPart.state.configurationType === DriverConfigurationType.Url;
|
||||
|
||||
if (urlType) {
|
||||
return;
|
||||
|
||||
+5
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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.
|
||||
@@ -40,9 +40,10 @@ export class ConnectionSSHTabService extends Bootstrap {
|
||||
tab: () => SSHTab,
|
||||
panel: () => SSHPanel,
|
||||
isHidden: (tabId, props) => {
|
||||
if (props?.formState.state.config.driverId) {
|
||||
const driver = this.dbDriverResource.get(props?.formState.state.config.driverId);
|
||||
const optionsPart = getConnectionFormOptionsPart(props.formState);
|
||||
const optionsPart = props?.formState ? getConnectionFormOptionsPart(props.formState) : null;
|
||||
|
||||
if (optionsPart?.state.driverId) {
|
||||
const driver = this.dbDriverResource.get(optionsPart.state.driverId);
|
||||
const urlType = optionsPart.state.configurationType === DriverConfigurationType.Url;
|
||||
|
||||
return urlType || !driver?.applicableNetworkHandlers.includes(SSH_TUNNEL_ID);
|
||||
|
||||
@@ -44,25 +44,18 @@ export class ConnectionFormSSLPart extends FormPart<INetworkHandlerConfig, IConn
|
||||
super(formState, getDefaultState());
|
||||
}
|
||||
|
||||
override isOutdated(): boolean {
|
||||
const isDriverOutdated = this.dbDriverResource.isOutdated(this.formState.state.config.driverId);
|
||||
const isNetworkHandlerOutdated = this.networkHandlerResource.isOutdated(this.state.id);
|
||||
const isConnectionOutdated = this.connectionInfoResource.isOutdated(
|
||||
createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId!),
|
||||
);
|
||||
|
||||
return isDriverOutdated || isNetworkHandlerOutdated || isConnectionOutdated;
|
||||
get optionsPart() {
|
||||
return getConnectionFormOptionsPart(this.formState);
|
||||
}
|
||||
|
||||
protected override async loader(): Promise<void> {
|
||||
if (!this.formState.state.config.driverId) {
|
||||
if (!this.optionsPart.state.driverId) {
|
||||
this.setInitialState(getDefaultState());
|
||||
return;
|
||||
}
|
||||
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
const [driver, handlers] = await Promise.all([
|
||||
this.dbDriverResource.load(this.formState.state.config.driverId),
|
||||
this.dbDriverResource.load(this.optionsPart.state.driverId),
|
||||
this.networkHandlerResource.load(CachedMapAllKey),
|
||||
]);
|
||||
const handler = getSSLDriverHandler(handlers, driver?.applicableNetworkHandlers ?? []);
|
||||
@@ -72,10 +65,10 @@ export class ConnectionFormSSLPart extends FormPart<INetworkHandlerConfig, IConn
|
||||
return;
|
||||
}
|
||||
|
||||
const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId!));
|
||||
const info = this.connectionInfoResource.get(createConnectionParam(this.formState.state.projectId, this.optionsPart.state.connectionId!));
|
||||
const initialConfig = info?.networkHandlersConfig?.find(h => h.id === handler.id);
|
||||
|
||||
if (!optionsPart.state.networkHandlersConfig?.some(state => state.id === handler.id)) {
|
||||
if (!this.optionsPart.state.networkHandlersConfig?.some(state => state.id === handler.id)) {
|
||||
const config: NetworkHandlerConfigInput = initialConfig ? toJS(initialConfig) : getSSLDefaultConfig(handler.id);
|
||||
|
||||
if (config.secureProperties) {
|
||||
@@ -93,11 +86,12 @@ export class ConnectionFormSSLPart extends FormPart<INetworkHandlerConfig, IConn
|
||||
data: IFormState<IConnectionFormState>,
|
||||
contexts: IExecutionContextProvider<IFormState<IConnectionFormState>>,
|
||||
): Promise<void> {
|
||||
if (!this.formState.state.config.driverId) {
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
|
||||
if (!optionsPart.state.driverId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const optionsPart = getConnectionFormOptionsPart(this.formState);
|
||||
const handlers = await this.networkHandlerResource.load(CachedMapAllKey);
|
||||
const descriptor = handlers.find(h => h.id === this.state?.id);
|
||||
|
||||
|
||||
+6
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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.
|
||||
@@ -9,7 +9,7 @@ import React from 'react';
|
||||
|
||||
import { DBDriverResource, NetworkHandlerResource } from '@cloudbeaver/core-connections';
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
|
||||
import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js';
|
||||
import { getSSLDriverHandler } from './getSSLDriverHandler.js';
|
||||
import { ConnectionFormService } from '../ConnectionFormService.js';
|
||||
|
||||
@@ -39,8 +39,10 @@ export class ConnectionSSLTabService extends Bootstrap {
|
||||
tab: () => SSLTab,
|
||||
panel: () => SSLPanel,
|
||||
isHidden: (_, props) => {
|
||||
if (props?.formState.state.config.driverId) {
|
||||
const driver = this.dbDriverResource.get(props?.formState.state.config.driverId);
|
||||
const optionsPart = props?.formState ? getConnectionFormOptionsPart(props.formState) : null;
|
||||
|
||||
if (optionsPart?.state.driverId) {
|
||||
const driver = this.dbDriverResource.get(optionsPart.state.driverId);
|
||||
const handler = getSSLDriverHandler(this.networkHandlerResource.values, driver?.applicableNetworkHandlers ?? []);
|
||||
return !handler;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { observer } from 'mobx-react-lite';
|
||||
import React from 'react';
|
||||
|
||||
@@ -53,12 +54,12 @@ export const SSL: TabContainerPanelComponent<Props> = observer(function SSL({ fo
|
||||
const disabled = formState.isDisabled;
|
||||
const enabled = handlerState.enabled || false;
|
||||
const connectionInfoService = useService(ConnectionInfoResource);
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, formState.state.config.connectionId!));
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
const info = connectionInfoService.get(createConnectionParam(formState.state.projectId, optionsPart.state.connectionId!));
|
||||
const initialHandler = info?.networkHandlersConfig?.find(h => h.id === handler.id);
|
||||
const autofillToken = isSafari ? 'section-connection-authentication-ssl section-ssl' : 'new-password';
|
||||
const projectInfoResource = useService(ProjectInfoResource);
|
||||
const isSharedProject = projectInfoResource.isProjectShared(formState.state.projectId);
|
||||
const optionsPart = getConnectionFormOptionsPart(formState);
|
||||
|
||||
useAutoLoad(SSL, optionsPart);
|
||||
|
||||
|
||||
@@ -16,10 +16,12 @@ import { getSSLDriverHandler } from './getSSLDriverHandler.js';
|
||||
import { SSL } from './SSL.js';
|
||||
import { getConnectionFormSSLPart } from './getConnectionFormSSLPart.js';
|
||||
import type { IConnectionFormProps } from '../IConnectionFormState.js';
|
||||
import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js';
|
||||
|
||||
export const SSLPanel: TabContainerTabComponent<IConnectionFormProps> = observer(function SSLPanel(props) {
|
||||
const networkHandlerResource = useResource(SSLPanel, NetworkHandlerResource, CachedMapAllKey);
|
||||
const dbDriverResource = useResource(SSLPanel, DBDriverResource, props.formState.state.config.driverId ?? null);
|
||||
const optionsPart = getConnectionFormOptionsPart(props.formState);
|
||||
const dbDriverResource = useResource(SSLPanel, DBDriverResource, optionsPart.state.driverId ?? null);
|
||||
|
||||
const handler = getSSLDriverHandler(networkHandlerResource.resource.values, dbDriverResource.data?.applicableNetworkHandlers ?? []);
|
||||
const sslPart = getConnectionFormSSLPart(props.formState);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { observer } from 'mobx-react-lite';
|
||||
|
||||
import { Translate, useResource } from '@cloudbeaver/core-blocks';
|
||||
@@ -14,10 +15,12 @@ import { Tab, type TabContainerTabComponent, TabTitle } from '@cloudbeaver/core-
|
||||
|
||||
import { getSSLDriverHandler } from './getSSLDriverHandler.js';
|
||||
import type { IConnectionFormProps } from '../IConnectionFormState.js';
|
||||
import { getConnectionFormOptionsPart } from '../Options/getConnectionFormOptionsPart.js';
|
||||
|
||||
export const SSLTab: TabContainerTabComponent<IConnectionFormProps> = observer(function SSLTab(props) {
|
||||
const networkHandlerResource = useResource(SSLTab, NetworkHandlerResource, CachedMapAllKey);
|
||||
const dbDriverResource = useResource(SSLTab, DBDriverResource, props.formState.state.config.driverId ?? null);
|
||||
const optionsPart = getConnectionFormOptionsPart(props.formState);
|
||||
const dbDriverResource = useResource(SSLTab, DBDriverResource, optionsPart.state.driverId ?? null);
|
||||
|
||||
const handler = getSSLDriverHandler(networkHandlerResource.resource.values, dbDriverResource.data?.applicableNetworkHandlers ?? []);
|
||||
|
||||
|
||||
@@ -11,10 +11,11 @@ import { ConnectionFormState } from './ConnectionFormState.js';
|
||||
import { ConnectionFormService } from './ConnectionFormService.js';
|
||||
import type { IConnectionFormState } from './IConnectionFormState.js';
|
||||
import type { IConnectionInfoParams } from '@cloudbeaver/core-connections';
|
||||
import { getConnectionFormOptionsPart } from './Options/getConnectionFormOptionsPart.js';
|
||||
import { runInAction } from 'mobx';
|
||||
|
||||
const EMPTY_CONNECTION_INFO_PARAMS: IConnectionFormState = {
|
||||
projectId: '',
|
||||
config: {},
|
||||
submitType: 'submit',
|
||||
availableDrivers: [],
|
||||
type: 'admin',
|
||||
@@ -25,17 +26,21 @@ export function useConnectionFormState(params: IConnectionInfoParams, configure?
|
||||
const serviceProvider = useService(IServiceProvider);
|
||||
const service = useService(ConnectionFormService);
|
||||
const ref = useRef<ConnectionFormState>(null);
|
||||
let optionsPart = ref.current ? getConnectionFormOptionsPart(ref.current) : null;
|
||||
|
||||
if (ref.current?.state.config.connectionId !== params.connectionId || ref.current?.state.projectId !== params.projectId) {
|
||||
if (optionsPart?.state.connectionId !== params.connectionId || ref.current?.state.projectId !== params.projectId) {
|
||||
ref.current?.dispose();
|
||||
ref.current = new ConnectionFormState(serviceProvider, service, {
|
||||
...EMPTY_CONNECTION_INFO_PARAMS,
|
||||
projectId: params.projectId,
|
||||
config: {
|
||||
...EMPTY_CONNECTION_INFO_PARAMS.config,
|
||||
connectionId: params.connectionId,
|
||||
},
|
||||
});
|
||||
|
||||
optionsPart = getConnectionFormOptionsPart(ref.current);
|
||||
|
||||
runInAction(() => {
|
||||
optionsPart!.state.connectionId = params.connectionId;
|
||||
});
|
||||
|
||||
configure?.(ref.current);
|
||||
}
|
||||
|
||||
|
||||
+28
-13
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
* 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 { action, makeObservable, observable } from 'mobx';
|
||||
|
||||
import { action, makeObservable, observable, runInAction } from 'mobx';
|
||||
|
||||
import { UserInfoResource } from '@cloudbeaver/core-authentication';
|
||||
import { ConfirmationDialog, importLazyComponent } from '@cloudbeaver/core-blocks';
|
||||
@@ -21,6 +22,7 @@ import { AuthenticationService } from '@cloudbeaver/plugin-authentication';
|
||||
|
||||
import { ConnectionFormState } from '../ConnectionForm/ConnectionFormState.js';
|
||||
import { ConnectionFormService } from '../ConnectionForm/ConnectionFormService.js';
|
||||
import { getConnectionFormOptionsPart } from '../ConnectionForm/Options/getConnectionFormOptionsPart.js';
|
||||
|
||||
const PublicConnectionForm = importLazyComponent(() => import('./PublicConnectionForm.js').then(m => m.PublicConnectionForm));
|
||||
|
||||
@@ -74,11 +76,18 @@ export class PublicConnectionFormService {
|
||||
this.formState = new ConnectionFormState(this.serviceProvider, this.connectionFormService, {
|
||||
projectId,
|
||||
availableDrivers: availableDrivers ?? [],
|
||||
config,
|
||||
submitType: 'submit',
|
||||
type: 'public',
|
||||
requiredNetworkHandlersIds: [],
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.optionsPart!.state = {
|
||||
...this.optionsPart!.state,
|
||||
...config,
|
||||
};
|
||||
});
|
||||
|
||||
this.formState.disposeTask.addHandler(this.close.bind(this, true));
|
||||
}
|
||||
|
||||
@@ -114,9 +123,11 @@ export class PublicConnectionFormService {
|
||||
}
|
||||
|
||||
async save(): Promise<void> {
|
||||
const optionsPart = this.formState ? getConnectionFormOptionsPart(this.formState) : null;
|
||||
|
||||
const key =
|
||||
this.formState && this.formState.state.config.connectionId && this.formState.state.projectId !== null
|
||||
? createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId)
|
||||
this.formState && optionsPart?.state.connectionId && this.formState.state.projectId !== null
|
||||
? createConnectionParam(this.formState.state.projectId, optionsPart.state.connectionId)
|
||||
: null;
|
||||
|
||||
await this.close(true);
|
||||
@@ -126,24 +137,26 @@ export class PublicConnectionFormService {
|
||||
}
|
||||
}
|
||||
|
||||
get optionsPart() {
|
||||
return this.formState ? getConnectionFormOptionsPart(this.formState) : null;
|
||||
}
|
||||
|
||||
private readonly closeRemoved: IExecutorHandler<ResourceKey<IConnectionInfoParams>> = (data, contexts) => {
|
||||
if (!this.formState || !this.formState.state.config.connectionId || this.formState.state.projectId === null) {
|
||||
if (!this.formState || !this.optionsPart?.state.connectionId || this.formState.state.projectId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.connectionInfoResource.has(createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId))) {
|
||||
if (!this.connectionInfoResource.has(createConnectionParam(this.formState.state.projectId, this.optionsPart.state.connectionId!))) {
|
||||
this.close(true);
|
||||
}
|
||||
};
|
||||
|
||||
private readonly closeDeleted: IExecutorHandler<ResourceKeySimple<IConnectionInfoParams>> = (data, contexts) => {
|
||||
if (!this.formState || !this.formState.state.config.connectionId || this.formState.state.projectId === null) {
|
||||
if (!this.formState || !this.optionsPart?.state.connectionId || this.formState.state.projectId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
this.connectionInfoResource.isIntersect(data, createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId))
|
||||
) {
|
||||
if (this.connectionInfoResource.isIntersect(data, createConnectionParam(this.formState.state.projectId, this.optionsPart.state.connectionId!))) {
|
||||
this.close(true);
|
||||
}
|
||||
};
|
||||
@@ -157,12 +170,14 @@ export class PublicConnectionFormService {
|
||||
};
|
||||
|
||||
private async showUnsavedChangesDialog(): Promise<boolean> {
|
||||
const optionsPart = this.formState ? getConnectionFormOptionsPart(this.formState) : null;
|
||||
|
||||
if (
|
||||
!this.formState ||
|
||||
!this.optionsPanelService.isOpen(formGetter) ||
|
||||
(this.formState.state.config.connectionId &&
|
||||
(optionsPart?.state.connectionId &&
|
||||
this.formState.state.projectId !== null &&
|
||||
!this.connectionInfoResource.has(createConnectionParam(this.formState.state.projectId, this.formState.state.config.connectionId)))
|
||||
!this.connectionInfoResource.has(createConnectionParam(this.formState.state.projectId, optionsPart.state.connectionId)))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user