From 933a81c009e9e9dcfed45a5cca7a3ee908658ea2 Mon Sep 17 00:00:00 2001 From: Wroud Date: Wed, 14 Oct 2020 00:26:03 +0300 Subject: [PATCH] fix(core-connections): CB-327 new connections saved credentials event them not filled --- .../ObjectPropertyInfoForm.tsx | 11 +++-- .../ConnectionForm/ConnectionForm.tsx | 17 +------ .../Connections/ConnectionForm/Controller.ts | 49 +++++++------------ .../ConnectionForm/Options/Options.tsx | 11 +++++ .../Options/OptionsController.ts | 41 ++++++++-------- .../ConnectionsAdministrationController.ts | 19 ++++--- .../ConnectionsTable/Connection.tsx | 4 +- .../ConnectionsTable/ConnectionEdit.tsx | 6 ++- .../CreateConnection/CreateConnection.tsx | 1 - .../CreateConnectionController.tsx | 2 +- .../Connections/CreateConnection/Database.tsx | 5 +- .../src/Administration/ConnectionsResource.ts | 31 ++++-------- .../core-connections/src/locales/en.ts | 1 + .../core-connections/src/locales/ru.ts | 1 + .../createConnectionConfiguration.gql | 1 + .../administration/getConnections.gql | 1 + .../administration/searchDatabases.gql | 1 + .../updateConnectionConfiguration.gql | 1 + .../src/queries/connections/getAuthModels.gql | 1 - webapp/packages/core-sdk/src/sdk.ts | 18 ++++--- 20 files changed, 106 insertions(+), 116 deletions(-) diff --git a/webapp/packages/core-blocks/src/ObjectPropertyInfoForm/ObjectPropertyInfoForm.tsx b/webapp/packages/core-blocks/src/ObjectPropertyInfoForm/ObjectPropertyInfoForm.tsx index 42a62abe3c..f00e8a347f 100644 --- a/webapp/packages/core-blocks/src/ObjectPropertyInfoForm/ObjectPropertyInfoForm.tsx +++ b/webapp/packages/core-blocks/src/ObjectPropertyInfoForm/ObjectPropertyInfoForm.tsx @@ -23,20 +23,25 @@ interface Props { disabled?: boolean; autofillToken?: string; className?: string; + onFocus?: (name: string) => void; } const RESERVED_KEYWORDS = ['no', 'off', 'new-password']; -export const ObjectPropertyInfoForm = observer(function ObjectPropertyInfoForm({ +export const ObjectPropertyInfoForm: React.FC = observer(function ObjectPropertyInfoForm({ properties, credentials, disabled, autofillToken = '', className, -}: Props) { + onFocus, +}) { const style = useStyles(formStyles); const handleFocus = useCallback((e: React.FocusEvent) => { + if (onFocus) { + onFocus(e.target.name); + } if (e.target.type !== 'password') { return; } @@ -46,7 +51,7 @@ export const ObjectPropertyInfoForm = observer(function ObjectPropertyInfoForm({ if (property?.value === e.target.value) { credentials[e.target.name] = ''; } - }, [properties, credentials]); + }, [properties, credentials, onFocus]); if (!properties || properties.length === 0) { return Properties empty; diff --git a/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/ConnectionForm.tsx b/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/ConnectionForm.tsx index f125384cf4..d56141aa69 100644 --- a/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/ConnectionForm.tsx +++ b/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/ConnectionForm.tsx @@ -98,12 +98,6 @@ const styles = composes( } } - ErrorMessage { - position: sticky; - bottom: 0; - padding: 8px 24px; - } - fill { flex: 1; } @@ -121,14 +115,12 @@ const styles = composes( interface Props { model: IConnectionFormModel; - configurationWizard?: boolean; onBack?: () => void; onCancel?: () => void; } export const ConnectionForm = observer(function ConnectionForm({ model, - configurationWizard, onBack = () => {}, onCancel = () => {}, }: Props) { @@ -145,7 +137,7 @@ export const ConnectionForm = observer(function ConnectionForm({ {translate('customConnection_properties')} - + {translate('connections_connection_edit_access')} @@ -218,13 +210,6 @@ export const ConnectionForm = observer(function ConnectionForm({ )} - {controller.error.responseMessage && ( - - )} diff --git a/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Controller.ts b/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Controller.ts index 98b7e0be03..0f79fab015 100644 --- a/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Controller.ts +++ b/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Controller.ts @@ -8,13 +8,12 @@ import { observable, computed } from 'mobx'; +import { AdministrationScreenService } from '@cloudbeaver/core-administration'; import { - injectable, IInitializableController, IDestructibleController + injectable, IInitializableController } from '@cloudbeaver/core-di'; -import { CommonDialogService } from '@cloudbeaver/core-dialogs'; import { NotificationService } from '@cloudbeaver/core-events'; -import { ErrorDetailsDialog } from '@cloudbeaver/core-notifications'; -import { ConnectionConfig, GQLErrorCatcher } from '@cloudbeaver/core-sdk'; +import { ConnectionConfig } from '@cloudbeaver/core-sdk'; import { DBDriverResource } from '../../../DBDriverResource'; import { ConnectionsResource } from '../../ConnectionsResource'; @@ -23,7 +22,7 @@ import { IConnectionFormModel } from './IConnectionFormModel'; @injectable() export class Controller -implements IInitializableController, IDestructibleController { +implements IInitializableController { @observable connectionType = EConnectionType.Parameters; @observable isLoading = false; @observable isSaving = false; @@ -37,34 +36,36 @@ implements IInitializableController, IDestructibleController { return this.dbDriverResource.get(this.model.connection.driverId) || null; } - readonly error = new GQLErrorCatcher(); - @computed private get accessLoaded() { return !!this.model.grantedSubjects; } private accessChanged = false; - private isDistructed = false; private model!: IConnectionFormModel; private close!: () => void; constructor( + private administrationScreenService: AdministrationScreenService, private connectionsResource: ConnectionsResource, private notificationService: NotificationService, - private commonDialogService: CommonDialogService, private dbDriverResource: DBDriverResource ) { } init( model: IConnectionFormModel, close: () => void - ) { + ): void { this.model = model; this.close = close; } - destruct(): void { - this.isDistructed = true; + isTabAvailable(tabId: string): boolean { + if (this.administrationScreenService.isConfigurationMode) { + if (tabId === 'access') { + return false; + } + } + return true; } setType = (type: EConnectionType) => { @@ -73,7 +74,6 @@ implements IInitializableController, IDestructibleController { save = async () => { this.isSaving = true; - this.error.clear(); try { if (this.model.editing) { const connection = await this.connectionsResource.update(this.model.connection.id, this.getConnectionConfig()); @@ -95,9 +95,8 @@ implements IInitializableController, IDestructibleController { test = async () => { this.isSaving = true; - this.error.clear(); try { - await this.connectionsResource.test(this.getConnectionConfig()); + await this.connectionsResource.test(this.getConnectionConfig(true)); this.notificationService.logInfo({ title: 'Connection is established' }); } catch (exception) { this.notificationService.logException(exception, 'connections_connection_test_fail'); @@ -106,12 +105,6 @@ implements IInitializableController, IDestructibleController { } }; - onShowDetails = () => { - if (this.error.exception) { - this.commonDialogService.open(ErrorDetailsDialog, this.error.exception); - } - }; - handleAccessChange = () => { this.accessChanged = true; }; loadAccessSubjects = async () => { @@ -139,7 +132,7 @@ implements IInitializableController, IDestructibleController { this.accessChanged = false; } - private getConnectionConfig(): ConnectionConfig { + private getConnectionConfig(withCredentials?: boolean): ConnectionConfig { const config: ConnectionConfig = {}; if (this.model.editing) { @@ -162,8 +155,8 @@ implements IInitializableController, IDestructibleController { } if (this.model.connection.authModel || this.driver!.defaultAuthModel) { config.authModelId = this.model.connection.authModel || this.driver!.defaultAuthModel; - config.saveCredentials = this.isCredentialsChanged(); - if (config.saveCredentials) { + config.saveCredentials = withCredentials || this.model.connection.saveCredentials; + if (this.isCredentialsChanged()) { config.credentials = this.model.credentials; } } @@ -179,16 +172,10 @@ implements IInitializableController, IDestructibleController { return true; } for (const property of this.model.connection.authProperties) { - if (this.model.credentials[property.id!] !== property.value) { + if (property.value !== null && this.model.credentials[property.id!] !== property.value) { return true; } } return false; } - - private showError(exception: Error, message: string) { - if (!this.error.catch(exception) || this.isDistructed) { - this.notificationService.logException(exception, message); - } - } } diff --git a/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Options/Options.tsx b/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Options/Options.tsx index 28d973368d..6737e8a477 100644 --- a/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Options/Options.tsx +++ b/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Options/Options.tsx @@ -169,7 +169,18 @@ export const Options = observer(function Options({ properties={controller.authModel.properties} credentials={model.credentials} disabled={disabled} + onFocus={controller.resetPassword} /> + + + )} diff --git a/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Options/OptionsController.ts b/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Options/OptionsController.ts index e7206ec322..aa5947cfbb 100644 --- a/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Options/OptionsController.ts +++ b/webapp/packages/core-connections/src/Administration/Connections/ConnectionForm/Options/OptionsController.ts @@ -10,31 +10,32 @@ import { action, computed } from 'mobx'; import { injectable, IInitializableController } from '@cloudbeaver/core-di'; import { NotificationService } from '@cloudbeaver/core-events'; +import { DatabaseAuthModel } from '@cloudbeaver/core-sdk'; import { DatabaseAuthModelsResource } from '../../../../DatabaseAuthModelsResource'; -import { DBDriverResource } from '../../../../DBDriverResource'; +import { DBDriver, DBDriverResource } from '../../../../DBDriverResource'; import { IConnectionFormModel } from '../IConnectionFormModel'; @injectable() export class OptionsController implements IInitializableController { - @computed get drivers() { + @computed get drivers(): DBDriver[] { return Array.from(this.dbDriverResource.data.values()) .filter(({ id }) => this.model.availableDrivers.includes(id)); } - @computed get driver() { + @computed get driver(): DBDriver | undefined { return this.dbDriverResource.get(this.model.connection.driverId); } - @computed get authModel() { + @computed get authModel(): DatabaseAuthModel | null { if (!this.model.connection?.authModel && !this.driver) { return null; } return this.dbAuthModelsResource.get(this.model.connection?.authModel || this.driver!.defaultAuthModel) || null; } - @computed get authModelLoading() { + @computed get authModelLoading(): boolean { return this.dbAuthModelsResource.isLoading(); } @@ -47,7 +48,7 @@ implements IInitializableController { private dbDriverResource: DBDriverResource ) { } - init(model: IConnectionFormModel) { + init(model: IConnectionFormModel): void { this.model = model; this.loadDrivers(); } @@ -56,11 +57,11 @@ implements IInitializableController { driverId: string | null, name: string | undefined, prevValue: string | null - ) => this.loadDriver(driverId, prevValue); + ): Promise => this.loadDriver(driverId, prevValue); - onFormChange = () => { + onFormChange = (value?: unknown, name?: string): void => { this.updateName(); - this.resetPassword(); + this.resetPassword(name || ''); }; @action @@ -71,23 +72,23 @@ implements IInitializableController { this.cleanCredentials(); } - private resetPassword() { - if (this.isCredentialsChanged()) { - for (const property of this.model.connection.authProperties) { - if (property.features.includes('password') && this.model.credentials[property.id!] === property.value) { - this.model.credentials[property.id!] = ''; - return; - } + resetPassword = (name: string): void => { + const passwordProperty = this.model.connection.authProperties.find(property => property.features.includes('password')); + + if (passwordProperty && (this.isCredentialsChanged() || passwordProperty.id === name)) { + if (this.model.credentials[passwordProperty.id!] === passwordProperty.value) { + this.model.credentials[passwordProperty.id!] = ''; + this.model.connection.saveCredentials = false; } } - } + }; private isCredentialsChanged() { - if (!this.model.connection.authProperties.length) { - return true; + if (!Object.keys(this.model.credentials).length) { + return false; } for (const property of this.model.connection.authProperties) { - if (this.model.credentials[property.id!] !== property.value) { + if (property.value !== null && this.model.credentials[property.id!] !== property.value) { return true; } } diff --git a/webapp/packages/core-connections/src/Administration/Connections/ConnectionsAdministrationController.ts b/webapp/packages/core-connections/src/Administration/Connections/ConnectionsAdministrationController.ts index ab9fce10ec..73f2d4b47a 100644 --- a/webapp/packages/core-connections/src/Administration/Connections/ConnectionsAdministrationController.ts +++ b/webapp/packages/core-connections/src/Administration/Connections/ConnectionsAdministrationController.ts @@ -11,9 +11,9 @@ import { observable, computed } from 'mobx'; import { injectable } from '@cloudbeaver/core-di'; import { CommonDialogService, ConfirmationDialog } from '@cloudbeaver/core-dialogs'; import { NotificationService } from '@cloudbeaver/core-events'; -import { resourceKeyList } from '@cloudbeaver/core-sdk'; +import { ConnectionInfo, resourceKeyList } from '@cloudbeaver/core-sdk'; -import { ConnectionsResource, isSearchedConnection } from '../ConnectionsResource'; +import { ConnectionsResource } from '../ConnectionsResource'; import { ConnectionsAdministrationNavService } from './ConnectionsAdministrationNavService'; @injectable() @@ -22,9 +22,8 @@ export class ConnectionsAdministrationController { readonly selectedItems = observable(new Map()); readonly expandedItems = observable(new Map()); @computed - get connections() { + get connections(): ConnectionInfo[] { return Array.from(this.connectionsResource.data.values()) - .filter(connection => !isSearchedConnection(connection)) .sort((a, b) => { const isANew = this.connectionsResource.isNew(a.id); const isBNew = this.connectionsResource.isNew(b.id); @@ -42,7 +41,7 @@ export class ConnectionsAdministrationController { } @computed - get isLoading() { + get isLoading(): boolean { return this.connectionsResource.isLoading() || this.isProcessing; } @@ -53,12 +52,12 @@ export class ConnectionsAdministrationController { private connectionsAdministrationNavService: ConnectionsAdministrationNavService ) { } - setCreateMethod = (method: string) => this.connectionsAdministrationNavService.navToCreate(method); - cancelCreate = () => this.connectionsAdministrationNavService.navToRoot(); + setCreateMethod = (method: string): void => this.connectionsAdministrationNavService.navToCreate(method); + cancelCreate = (): void => this.connectionsAdministrationNavService.navToRoot(); - create = () => this.connectionsAdministrationNavService.navToCreate('driver'); + create = (): void => this.connectionsAdministrationNavService.navToCreate('driver'); - update = async () => { + update = async (): Promise => { try { await this.connectionsResource.refresh('all'); } catch (exception) { @@ -66,7 +65,7 @@ export class ConnectionsAdministrationController { } }; - delete = async () => { + delete = async (): Promise => { if (this.isProcessing) { return; } diff --git a/webapp/packages/core-connections/src/Administration/Connections/ConnectionsTable/Connection.tsx b/webapp/packages/core-connections/src/Administration/Connections/ConnectionsTable/Connection.tsx index cad4f059ea..034eb0dd81 100644 --- a/webapp/packages/core-connections/src/Administration/Connections/ConnectionsTable/Connection.tsx +++ b/webapp/packages/core-connections/src/Administration/Connections/ConnectionsTable/Connection.tsx @@ -7,18 +7,16 @@ */ import { observer } from 'mobx-react'; -import styled, { use, css } from 'reshadow'; +import styled, { css } from 'reshadow'; import { TableItem, TableColumnValue, TableItemSelect, TableItemExpand, StaticImage, Checkbox } from '@cloudbeaver/core-blocks'; import { DBDriverResource } from '@cloudbeaver/core-connections'; import { useService } from '@cloudbeaver/core-di'; -import { useTranslate } from '@cloudbeaver/core-localization'; import { ConnectionInfo } from '@cloudbeaver/core-sdk'; import { useStyles } from '@cloudbeaver/core-theming'; -import { ConnectionsResource, isSearchedConnection, SEARCH_CONNECTION_SYMBOL } from '../../ConnectionsResource'; import { ConnectionEdit } from './ConnectionEdit'; interface Props { diff --git a/webapp/packages/core-connections/src/Administration/Connections/ConnectionsTable/ConnectionEdit.tsx b/webapp/packages/core-connections/src/Administration/Connections/ConnectionsTable/ConnectionEdit.tsx index 42b6001dd4..0a87f5d0d1 100644 --- a/webapp/packages/core-connections/src/Administration/Connections/ConnectionsTable/ConnectionEdit.tsx +++ b/webapp/packages/core-connections/src/Administration/Connections/ConnectionsTable/ConnectionEdit.tsx @@ -50,7 +50,11 @@ export const ConnectionEdit = observer(function ConnectionEdit({ return styled(useStyles(styles))( {controller.connection && ( - + )} ); diff --git a/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/CreateConnection.tsx b/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/CreateConnection.tsx index da37fd4cba..b1edcb5246 100644 --- a/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/CreateConnection.tsx +++ b/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/CreateConnection.tsx @@ -183,7 +183,6 @@ export const CreateConnection = observer(function CreateConnection({ diff --git a/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/CreateConnectionController.tsx b/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/CreateConnectionController.tsx index ffdef85321..e860a129e5 100644 --- a/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/CreateConnectionController.tsx +++ b/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/CreateConnectionController.tsx @@ -94,7 +94,7 @@ export class CreateConnectionController { this.availableDrivers = database.possibleDrivers; }; - back = () => { + back = (): void => { this.connection = null; this.availableDrivers = []; }; diff --git a/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/Database.tsx b/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/Database.tsx index c90b8d4364..b22e0fc15d 100644 --- a/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/Database.tsx +++ b/webapp/packages/core-connections/src/Administration/Connections/CreateConnection/Database.tsx @@ -69,12 +69,15 @@ export const Database = observer(function Database({ database, onSelect }: Props }) ), [database]); + const host = database.host + ':' + database.port; + const name = database.displayName !== database.host ? database.displayName + ' (' + host + ')' : host; + return styled(useStyles(styles))( {orderedDrivers.map(driverId => )} - {database.host}:{database.port} + {name} ); }); diff --git a/webapp/packages/core-connections/src/Administration/ConnectionsResource.ts b/webapp/packages/core-connections/src/Administration/ConnectionsResource.ts index 8acd9b677c..74b8e23d1c 100644 --- a/webapp/packages/core-connections/src/Administration/ConnectionsResource.ts +++ b/webapp/packages/core-connections/src/Administration/ConnectionsResource.ts @@ -17,16 +17,13 @@ import { ResourceKey, isResourceKeyList, AdminConnectionGrantInfo, - AdminConnectionSearchInfo, - ObjectPropertyInfo + AdminConnectionSearchInfo } from '@cloudbeaver/core-sdk'; -import { uuid, MetadataMap } from '@cloudbeaver/core-utils'; +import { MetadataMap } from '@cloudbeaver/core-utils'; export const NEW_CONNECTION_SYMBOL = Symbol('new-connection'); -export const SEARCH_CONNECTION_SYMBOL = Symbol('search-connection'); export type ConnectionNew = ConnectionInfo & { [NEW_CONNECTION_SYMBOL]: boolean }; -export type ConnectionSearch = ConnectionNew & { [SEARCH_CONNECTION_SYMBOL]: AdminConnectionSearchInfo }; @injectable() export class ConnectionsResource extends CachedMapResource { @@ -44,7 +41,7 @@ export class ConnectionsResource extends CachedMapResource false); } - has(id: string) { + has(id: string): boolean { if (this.metadata.has(id)) { return this.metadata.get(id); } @@ -52,23 +49,19 @@ export class ConnectionsResource extends CachedMapResource> { await this.load('all'); return this.data; } - async searchDatabases(hosts: string[]) { + async searchDatabases(hosts: string[]): Promise { const { databases } = await this.graphQLService.sdk.searchDatabases({ hosts }); return databases; @@ -95,13 +88,13 @@ export class ConnectionsResource extends CachedMapResource { await this.performUpdate(id, () => this.updateConnection(id, config)); await this.graphQLService.sdk.refreshSessionConnections(); return this.get(id)!; } - async delete(key: ResourceKey) { + async delete(key: ResourceKey): Promise { await this.performUpdate(key, () => this.deleteConnectionTask(key)); await this.graphQLService.sdk.refreshSessionConnections(); } @@ -112,7 +105,7 @@ export class ConnectionsResource extends CachedMapResource { await this.graphQLService.sdk.setConnectionAccess({ connectionId, subjects }); } @@ -158,9 +151,3 @@ export class ConnectionsResource extends CachedMapResource; supportsWorkspaces?: Maybe; sessionExpireTime?: Maybe; + localHostAddress?: Maybe; configurationMode?: Maybe; developmentMode?: Maybe; supportedLanguages: ServerLanguage[]; @@ -517,6 +518,7 @@ export interface ConnectionInfo { connected: Scalars['Boolean']; provided: Scalars['Boolean']; readOnly: Scalars['Boolean']; + saveCredentials: Scalars['Boolean']; connectTime?: Maybe; connectionError?: Maybe; serverVersion?: Maybe; @@ -739,6 +741,7 @@ export interface AdminConnectionGrantInfo { } export interface AdminConnectionSearchInfo { + displayName: Scalars['String']; host: Scalars['String']; port: Scalars['Int']; possibleDrivers: Array; @@ -932,7 +935,7 @@ export type CreateConnectionConfigurationQueryVariables = Exact<{ export interface CreateConnectionConfigurationQuery { connection: ( - Pick + Pick & { authProperties: Array> } ); } @@ -953,7 +956,7 @@ export type GetConnectionsQueryVariables = Exact<{ [key: string]: never }>; export interface GetConnectionsQuery { connections: Array<( - Pick + Pick & { authProperties: Array> } )>; } @@ -962,7 +965,7 @@ export type SearchDatabasesQueryVariables = Exact<{ hosts: Array; }>; -export interface SearchDatabasesQuery { databases: Array> } +export interface SearchDatabasesQuery { databases: Array> } export type SetConnectionAccessQueryVariables = Exact<{ connectionId: Scalars['ID']; @@ -978,7 +981,7 @@ export type UpdateConnectionConfigurationQueryVariables = Exact<{ export interface UpdateConnectionConfigurationQuery { connection: ( - Pick + Pick & { authProperties: Array> } ); } @@ -1039,7 +1042,7 @@ export type GetAuthModelsQueryVariables = Exact<{ [key: string]: never }>; export interface GetAuthModelsQuery { models: Array<( Pick - & { properties: Array> } + & { properties: Array> } )>; } @@ -1524,6 +1527,7 @@ export const CreateConnectionConfigurationDocument = ` template connected readOnly + saveCredentials host port databaseName @@ -1564,6 +1568,7 @@ export const GetConnectionsDocument = ` template connected readOnly + saveCredentials host port databaseName @@ -1584,6 +1589,7 @@ export const GetConnectionsDocument = ` export const SearchDatabasesDocument = ` query searchDatabases($hosts: [String!]!) { databases: searchConnections(hostNames: $hosts) { + displayName host port possibleDrivers @@ -1606,6 +1612,7 @@ export const UpdateConnectionConfigurationDocument = ` template connected readOnly + saveCredentials host port databaseName @@ -1757,7 +1764,6 @@ export const GetAuthModelsDocument = ` description category dataType - value validValues defaultValue features