fix(core-connections): CB-327 new connections saved credentials event them not filled

This commit is contained in:
Wroud
2020-10-14 00:26:03 +03:00
parent 6dfa2f7aee
commit 933a81c009
20 changed files with 106 additions and 116 deletions
@@ -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<Props> = observer(function ObjectPropertyInfoForm({
properties,
credentials,
disabled,
autofillToken = '',
className,
}: Props) {
onFocus,
}) {
const style = useStyles(formStyles);
const handleFocus = useCallback((e: React.FocusEvent<HTMLInputElement>) => {
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 <TextPlaceholder>Properties empty</TextPlaceholder>;
@@ -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({
<Tab tabId='driver_properties' disabled={!controller.driver}>
<TabTitle>{translate('customConnection_properties')}</TabTitle>
</Tab>
<Tab tabId='access' disabled={!controller.driver || configurationWizard}>
<Tab tabId='access' disabled={!controller.driver || !controller.isTabAvailable('access')}>
<TabTitle>{translate('connections_connection_edit_access')}</TabTitle>
</Tab>
<fill as="div" />
@@ -218,13 +210,6 @@ export const ConnectionForm = observer(function ConnectionForm({
</TabPanel>
</>
)}
{controller.error.responseMessage && (
<ErrorMessage
text={controller.error.responseMessage}
hasDetails={controller.error.hasDetails}
onShowDetails={controller.onShowDetails}
/>
)}
</content-box>
</box>
</TabsState>
@@ -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);
}
}
}
@@ -169,7 +169,18 @@ export const Options = observer(function Options({
properties={controller.authModel.properties}
credentials={model.credentials}
disabled={disabled}
onFocus={controller.resetPassword}
/>
<group as="div">
<FieldCheckbox
name="saveCredentials"
value={model.connection.id + 'authNeeded'}
state={model.connection}
checkboxLabel={translate('connections_connection_edit_save_credentials')}
disabled={disabled}
mod='surface'
/>
</group>
</>
)}
</box-element>
@@ -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<void> => 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;
}
}
@@ -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<string, boolean>(new Map());
readonly expandedItems = observable<string, boolean>(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<void> => {
try {
await this.connectionsResource.refresh('all');
} catch (exception) {
@@ -66,7 +65,7 @@ export class ConnectionsAdministrationController {
}
};
delete = async () => {
delete = async (): Promise<void> => {
if (this.isProcessing) {
return;
}
@@ -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 {
@@ -50,7 +50,11 @@ export const ConnectionEdit = observer(function ConnectionEdit({
return styled(useStyles(styles))(
<box as='div'>
{controller.connection && (
<ConnectionForm model={controller as IConnectionFormModel} onBack={collapse} onCancel={collapse} />
<ConnectionForm
model={controller as IConnectionFormModel}
onBack={collapse}
onCancel={collapse}
/>
)}
</box>
);
@@ -183,7 +183,6 @@ export const CreateConnection = observer(function CreateConnection({
<connection-create-content as='div'>
<ConnectionForm
model={controller as IConnectionFormModel}
configurationWizard={configurationWizard}
onBack={controller.back}
onCancel={handleConnectionCancel}
/>
@@ -94,7 +94,7 @@ export class CreateConnectionController {
this.availableDrivers = database.possibleDrivers;
};
back = () => {
back = (): void => {
this.connection = null;
this.availableDrivers = [];
};
@@ -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))(
<ListItem onClick={select}>
<ListItemIcon>
{orderedDrivers.map(driverId => <StaticImage key={driverId} icon={drivers.get(driverId)?.icon} />)}
</ListItemIcon>
<ListItemName>{database.host}:{database.port}</ListItemName>
<ListItemName>{name}</ListItemName>
</ListItem>
);
});
@@ -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<string, ConnectionInfo> {
@@ -44,7 +41,7 @@ export class ConnectionsResource extends CachedMapResource<string, ConnectionInf
this.metadata = new MetadataMap(() => 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<string, ConnectionInf
return this.data.has(id);
}
isNew(id: string) {
isNew(id: string): boolean {
if (!this.has(id)) {
return false;
}
return NEW_CONNECTION_SYMBOL in this.get(id)!;
}
isSearched(id: string) {
return isSearchedConnection(this.get(id));
}
async loadAll() {
async loadAll(): Promise<Map<string, ConnectionInfo>> {
await this.load('all');
return this.data;
}
async searchDatabases(hosts: string[]) {
async searchDatabases(hosts: string[]): Promise<AdminConnectionSearchInfo[]> {
const { databases } = await this.graphQLService.sdk.searchDatabases({ hosts });
return databases;
@@ -95,13 +88,13 @@ export class ConnectionsResource extends CachedMapResource<string, ConnectionInf
});
}
async update(id: string, config: ConnectionConfig) {
async update(id: string, config: ConnectionConfig): Promise<ConnectionInfo> {
await this.performUpdate(id, () => this.updateConnection(id, config));
await this.graphQLService.sdk.refreshSessionConnections();
return this.get(id)!;
}
async delete(key: ResourceKey<string>) {
async delete(key: ResourceKey<string>): Promise<void> {
await this.performUpdate(key, () => this.deleteConnectionTask(key));
await this.graphQLService.sdk.refreshSessionConnections();
}
@@ -112,7 +105,7 @@ export class ConnectionsResource extends CachedMapResource<string, ConnectionInf
return subjects;
}
async setAccessSubjects(connectionId: string, subjects: string[]) {
async setAccessSubjects(connectionId: string, subjects: string[]): Promise<void> {
await this.graphQLService.sdk.setConnectionAccess({ connectionId, subjects });
}
@@ -158,9 +151,3 @@ export class ConnectionsResource extends CachedMapResource<string, ConnectionInf
this.set(id, connection as ConnectionInfo);
}
}
export function isSearchedConnection(
connection: ConnectionInfo | undefined
): connection is ConnectionSearch {
return !!connection && SEARCH_CONNECTION_SYMBOL in connection;
}
@@ -8,6 +8,7 @@ export default [
['connections_administration_configuration_wizard_message', 'Here you can create database connections manually or using a database server search feature.\nYou can skip this step and configure connections later.'],
['connections_connection_create_custom', 'Custom'],
['connections_connection_create_search_database', 'Search'],
['connections_connection_edit_save_credentials', 'Remember Password'],
['connections_connection_edit_authentication', 'Authentication'],
['connections_connection_edit_access', 'Access'],
['connections_connection_edit_access_load_failed', 'Connection access loading failed'],
@@ -7,6 +7,7 @@ export default [
['connections_administration_configuration_wizard_step_description', 'Подключения к базам'],
['connections_connection_create_custom', 'Настроить'],
['connections_connection_create_search_database', 'Найти'],
['connections_connection_edit_save_credentials', ' Запомнить пароль'],
['connections_connection_edit_authentication', 'Авторизация'],
['connections_connection_edit_access', 'Доступ'],
['connections_connection_edit_access_load_failed', 'Не удалось загрузить информацию доступа'],
@@ -8,6 +8,7 @@ query createConnectionConfiguration($config: ConnectionConfig!) {
template
connected
readOnly
saveCredentials
host
port
@@ -8,6 +8,7 @@ query getConnections {
template
connected
readOnly
saveCredentials
host
port
@@ -1,5 +1,6 @@
query searchDatabases($hosts: [String!]!) {
databases: searchConnections(hostNames: $hosts) {
displayName
host
port
possibleDrivers
@@ -8,6 +8,7 @@ query updateConnectionConfiguration($id: ID!, $config: ConnectionConfig!) {
template
connected
readOnly
saveCredentials
host
port
@@ -11,7 +11,6 @@ query getAuthModels {
description
category
dataType
value
validValues
defaultValue
features
+12 -6
View File
@@ -440,6 +440,7 @@ export interface ServerConfig {
supportsConnectionBrowser?: Maybe<Scalars['Boolean']>;
supportsWorkspaces?: Maybe<Scalars['Boolean']>;
sessionExpireTime?: Maybe<Scalars['Int']>;
localHostAddress?: Maybe<Scalars['String']>;
configurationMode?: Maybe<Scalars['Boolean']>;
developmentMode?: Maybe<Scalars['Boolean']>;
supportedLanguages: ServerLanguage[];
@@ -517,6 +518,7 @@ export interface ConnectionInfo {
connected: Scalars['Boolean'];
provided: Scalars['Boolean'];
readOnly: Scalars['Boolean'];
saveCredentials: Scalars['Boolean'];
connectTime?: Maybe<Scalars['String']>;
connectionError?: Maybe<ServerError>;
serverVersion?: Maybe<Scalars['String']>;
@@ -739,6 +741,7 @@ export interface AdminConnectionGrantInfo {
}
export interface AdminConnectionSearchInfo {
displayName: Scalars['String'];
host: Scalars['String'];
port: Scalars['Int'];
possibleDrivers: Array<Scalars['ID']>;
@@ -932,7 +935,7 @@ export type CreateConnectionConfigurationQueryVariables = Exact<{
export interface CreateConnectionConfigurationQuery {
connection: (
Pick<ConnectionInfo, 'id' | 'name' | 'description' | 'driverId' | 'template' | 'connected' | 'readOnly' | 'host' | 'port' | 'databaseName' | 'url' | 'properties' | 'features' | 'authNeeded' | 'authModel'>
Pick<ConnectionInfo, 'id' | 'name' | 'description' | 'driverId' | 'template' | 'connected' | 'readOnly' | 'saveCredentials' | 'host' | 'port' | 'databaseName' | 'url' | 'properties' | 'features' | 'authNeeded' | 'authModel'>
& { authProperties: Array<Pick<ObjectPropertyInfo, 'id' | 'value' | 'features'>> }
);
}
@@ -953,7 +956,7 @@ export type GetConnectionsQueryVariables = Exact<{ [key: string]: never }>;
export interface GetConnectionsQuery {
connections: Array<(
Pick<ConnectionInfo, 'id' | 'name' | 'description' | 'driverId' | 'template' | 'connected' | 'readOnly' | 'host' | 'port' | 'databaseName' | 'url' | 'properties' | 'authNeeded' | 'authModel' | 'features' | 'supportedDataFormats'>
Pick<ConnectionInfo, 'id' | 'name' | 'description' | 'driverId' | 'template' | 'connected' | 'readOnly' | 'saveCredentials' | 'host' | 'port' | 'databaseName' | 'url' | 'properties' | 'authNeeded' | 'authModel' | 'features' | 'supportedDataFormats'>
& { authProperties: Array<Pick<ObjectPropertyInfo, 'id' | 'value' | 'features'>> }
)>;
}
@@ -962,7 +965,7 @@ export type SearchDatabasesQueryVariables = Exact<{
hosts: Array<Scalars['String']>;
}>;
export interface SearchDatabasesQuery { databases: Array<Pick<AdminConnectionSearchInfo, 'host' | 'port' | 'possibleDrivers' | 'defaultDriver'>> }
export interface SearchDatabasesQuery { databases: Array<Pick<AdminConnectionSearchInfo, 'displayName' | 'host' | 'port' | 'possibleDrivers' | 'defaultDriver'>> }
export type SetConnectionAccessQueryVariables = Exact<{
connectionId: Scalars['ID'];
@@ -978,7 +981,7 @@ export type UpdateConnectionConfigurationQueryVariables = Exact<{
export interface UpdateConnectionConfigurationQuery {
connection: (
Pick<ConnectionInfo, 'id' | 'name' | 'description' | 'driverId' | 'template' | 'connected' | 'readOnly' | 'host' | 'port' | 'databaseName' | 'url' | 'properties' | 'authNeeded' | 'authModel' | 'features' | 'supportedDataFormats'>
Pick<ConnectionInfo, 'id' | 'name' | 'description' | 'driverId' | 'template' | 'connected' | 'readOnly' | 'saveCredentials' | 'host' | 'port' | 'databaseName' | 'url' | 'properties' | 'authNeeded' | 'authModel' | 'features' | 'supportedDataFormats'>
& { authProperties: Array<Pick<ObjectPropertyInfo, 'id' | 'value' | 'features'>> }
);
}
@@ -1039,7 +1042,7 @@ export type GetAuthModelsQueryVariables = Exact<{ [key: string]: never }>;
export interface GetAuthModelsQuery {
models: Array<(
Pick<DatabaseAuthModel, 'id' | 'displayName' | 'description' | 'icon'>
& { properties: Array<Pick<ObjectPropertyInfo, 'id' | 'displayName' | 'description' | 'category' | 'dataType' | 'value' | 'validValues' | 'defaultValue' | 'features'>> }
& { properties: Array<Pick<ObjectPropertyInfo, 'id' | 'displayName' | 'description' | 'category' | 'dataType' | 'validValues' | 'defaultValue' | 'features'>> }
)>;
}
@@ -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