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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,11 @@ public WebConnectionInfo copyConnectionFromNode(

ServletApplication app = ServletAppUtils.getServletApplication();
if (app instanceof WebApplication webApplication) {
newDataSource.setNavigatorSettings(webApplication.getAppConfiguration().getDefaultNavigatorSettings());
newDataSource.setNavigatorSettings(
dataSourceTemplate.isExternallyProvided() ?
webApplication.getAppConfiguration().getDefaultNavigatorSettings() :
dataSourceTemplate.getNavigatorSettings().getOriginalSettings()
);
}

WebConnectionConfig config = project.getConnectionConfigInput(connectionConfig);
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export default [
['ui_no_matches_placeholder', 'Your search returned no matches.'],
['ui_information', 'Information'],
['ui_clipboard', 'Clipboard'],
['ui_copy', 'Copy'],
['ui_copy_to_clipboard', 'Copy'],
['ui_copy_to_clipboard_copied', 'Copied'],
['ui_copy_to_clipboard_failed_to_copy', 'Failed to copy'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export default [
['ui_no_matches_placeholder', "Votre recherche n'a retourné aucun résultat."],
['ui_information', 'Information'],
['ui_clipboard', 'Presse-papiers'],
['ui_copy', 'Copier'],
['ui_copy_to_clipboard', 'Copier'],
['ui_copy_to_clipboard_copied', 'Copié'],
['ui_copy_to_clipboard_failed_to_copy', 'Échec de la copie'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export default [
['ui_no_matches_placeholder', 'La tua ricerca non ha prodotto risultati.'],
['ui_information', 'Informazioni'],
['ui_clipboard', 'Appunti'],
['ui_copy', 'Copia'],
['ui_copy_to_clipboard', 'Copia'],
['ui_copy_to_clipboard_copied', 'Copiato'],
['ui_copy_to_clipboard_failed_to_copy', 'Fallimento della copia'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export default [
['ui_data_delete_confirmation', 'Подтвердите удаление'],
['ui_information', 'Информация'],
['ui_clipboard', 'Буфер обмена'],
['ui_copy', 'Копия'],
['ui_copy_to_clipboard', 'Копировать'],
['ui_copy_to_clipboard_copied', 'Скопировано'],
['ui_copy_to_clipboard_failed_to_copy', 'Не удалось скопировать'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/vi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export default [
['ui_no_matches_placeholder', 'Tìm kiếm của bạn không có kết quả phù hợp.'],
['ui_information', 'Thông tin'],
['ui_clipboard', 'Clipboard'],
['ui_copy', 'Sao chép'],
['ui_copy_to_clipboard', 'Sao chép'],
['ui_copy_to_clipboard_copied', 'Đã sao chép'],
['ui_copy_to_clipboard_failed_to_copy', 'Sao chép thất bại'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export default [
['ui_no_matches_placeholder', '您的搜索没有返回匹配项。'],
['ui_information', '信息'],
['ui_clipboard', '剪贴板'],
['ui_copy', '复制'],
['ui_copy_to_clipboard', '复制'],
['ui_copy_to_clipboard_copied', '已复制'],
['ui_copy_to_clipboard_failed_to_copy', '复制失败'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2026 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 { createAction } from '@cloudbeaver/core-view';

export const ACTION_CONNECTION_CLONE = createAction('connection-clone', {
label: 'plugin_connections_connection_clone',
});
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 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 {
ConnectionInfoAuthPropertiesResource,
ConnectionInfoProjectKey,
ConnectionInfoResource,
ConnectionsManagerService,
ConnectionsSettingsService,
createConnectionParam,
DATA_CONTEXT_CONNECTION,
} from '@cloudbeaver/core-connections';
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { LocalizationService } from '@cloudbeaver/core-localization';
import { NotificationService } from '@cloudbeaver/core-events';
import { DATA_CONTEXT_NAV_NODE, EObjectFeature } from '@cloudbeaver/core-navigation-tree';
import { getCachedMapResourceLoaderState } from '@cloudbeaver/core-resource';
import { ServerConfigResource } from '@cloudbeaver/core-root';
import { getUniqueName } from '@cloudbeaver/core-utils';
import { ACTION_DELETE, ActionService, MenuService } from '@cloudbeaver/core-view';
import { MENU_APP_ACTIONS } from '@cloudbeaver/plugin-top-app-bar';

import { PublicConnectionFormService } from '../PublicConnectionForm/PublicConnectionFormService.js';
import { ACTION_CONNECTION_CHANGE_CREDENTIALS } from './Actions/ACTION_CONNECTION_CHANGE_CREDENTIALS.js';
import { ACTION_CONNECTION_CLONE } from './Actions/ACTION_CONNECTION_CLONE.js';
import { ACTION_CONNECTION_DISCONNECT } from './Actions/ACTION_CONNECTION_DISCONNECT.js';
import { ACTION_CONNECTION_DISCONNECT_ALL } from './Actions/ACTION_CONNECTION_DISCONNECT_ALL.js';
import { ACTION_CONNECTION_EDIT } from './Actions/ACTION_CONNECTION_EDIT.js';
Expand All @@ -38,6 +42,7 @@ import { MENU_CONNECTIONS } from './MENU_CONNECTIONS.js';
PublicConnectionFormService,
ConnectionsSettingsService,
ServerConfigResource,
LocalizationService,
])
export class ConnectionMenuBootstrap extends Bootstrap {
constructor(
Expand All @@ -50,6 +55,7 @@ export class ConnectionMenuBootstrap extends Bootstrap {
private readonly publicConnectionFormService: PublicConnectionFormService,
private readonly connectionsSettingsService: ConnectionsSettingsService,
private readonly serverConfigResource: ServerConfigResource,
private readonly localizationService: LocalizationService,
) {
super();
}
Expand All @@ -64,6 +70,7 @@ export class ConnectionMenuBootstrap extends Bootstrap {
...items,
ACTION_CONNECTION_CHANGE_CREDENTIALS,
ACTION_CONNECTION_EDIT,
ACTION_CONNECTION_CLONE,
ACTION_CONNECTION_DISCONNECT,
ACTION_CONNECTION_DISCONNECT_ALL,
],
Expand All @@ -75,6 +82,7 @@ export class ConnectionMenuBootstrap extends Bootstrap {
ACTION_DELETE,
ACTION_CONNECTION_CHANGE_CREDENTIALS,
ACTION_CONNECTION_EDIT,
ACTION_CONNECTION_CLONE,
ACTION_CONNECTION_DISCONNECT,
ACTION_CONNECTION_DISCONNECT_ALL,
],
Expand Down Expand Up @@ -108,6 +116,10 @@ export class ConnectionMenuBootstrap extends Bootstrap {
return !(connection.canEdit || connection.canViewSettings);
}

if (action === ACTION_CONNECTION_CLONE) {
return !connection.canEdit;
}

if (action === ACTION_CONNECTION_CHANGE_CREDENTIALS) {
const auth = this.connectionInfoAuthPropertiesResource.get(connectionKey);
return !this.serverConfigResource.distributed || !!auth?.sharedCredentials;
Expand Down Expand Up @@ -152,6 +164,27 @@ export class ConnectionMenuBootstrap extends Bootstrap {
await this.connectionsManagerService.requireConnection({ connectionId: connection.id, projectId: connection.projectId }, true);
break;
}
case ACTION_CONNECTION_CLONE: {
try {
// Load all connections for the project first to ensure we have them all to generate a unique name for the cloned connection
const projectConnections = await this.connectionInfoResource.load(ConnectionInfoProjectKey(connection.projectId));
Comment on lines +169 to +170
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is possibly a heavy operation; maybe we should pass it to the backend side, so we can call the clone method without specifying the name, and the backend will choose the right one

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we've talked about it on standup call. backend said this is not a heavy calculation

const connectionNames = projectConnections.map(connection => connection.name);
const uniqueName = getUniqueName(
connection.name.concat(` ${this.localizationService.translate('ui_copy').toLowerCase()}`),
connectionNames,
);

if (!connection.nodePath) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its strange that we are relying on the nodePath and its optional, probably we need a new method where we can use connection Id to clone it

this.notificationService.logException(new Error('Connection node path is undefined'), 'plugin_connections_connection_clone_error');
return;
}

await this.connectionInfoResource.createFromNode(connection.projectId, connection.nodePath, uniqueName);
} catch (exception: any) {
this.notificationService.logException(exception, 'plugin_connections_connection_clone_error');
}
break;
}
}
},
});
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/plugin-connections/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export default [
['plugin_connections_connection_form_part_main_folder', 'Folder'],

['plugin_connections_connection_edit_menu_item_title', 'Edit Connection'],
['plugin_connections_connection_clone', 'Clone'],
['plugin_connections_connection_clone_error', 'Failed to clone connection'],
['plugin_connections_connection_edit_cancel_title', 'Cancel confirmation'],
['plugin_connections_connection_edit_cancel_message', "You're going to cancel connection changes. Unsaved changes will be lost. Are you sure?"],
['plugin_connections_connection_edit_reconnect_title', 'Connection updated'],
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/plugin-connections/src/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export default [
['plugin_connections_new_connection_dialog_title', 'Nuova connessione'],

['plugin_connections_connection_edit_menu_item_title', 'Modifica Connessione'],
['plugin_connections_connection_clone', 'Clona'],
['plugin_connections_connection_clone_error', 'Impossibile clonare la connessione'],
['plugin_connections_connection_edit_cancel_title', "Conferma l'annullamento"],
[
'plugin_connections_connection_edit_cancel_message',
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/plugin-connections/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export default [
['plugin_connections_new_connection_dialog_title', 'Новое подключение'],

['plugin_connections_connection_edit_menu_item_title', 'Изменить подключение'],
['plugin_connections_connection_clone', 'Клонировать'],
['plugin_connections_connection_clone_error', 'Не удалось клонировать подключение'],
['plugin_connections_connection_edit_cancel_title', 'Отмена редактирования'],
['plugin_connections_connection_edit_cancel_message', 'Вы собираетесь закрыть редактор, несохраненные изменения не будут применены. Вы уверены?'],
['plugin_connections_connection_edit_reconnect_title', 'Подключение обновлено'],
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/plugin-connections/src/locales/vi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export default [
['plugin_connections_connection_form_part_main_folder', 'Thư mục'],

['plugin_connections_connection_edit_menu_item_title', 'Chỉnh sửa Kết nối'],
['plugin_connections_connection_clone', 'Sao chép'],
['plugin_connections_connection_clone_error', 'Không thể sao chép kết nối'],
['plugin_connections_connection_edit_cancel_title', 'Xác nhận Hủy'],
['plugin_connections_connection_edit_cancel_message', 'Bạn sắp hủy các thay đổi của kết nối. Các thay đổi chưa lưu sẽ bị mất. Bạn có chắc không?'],
['plugin_connections_connection_edit_reconnect_title', 'Kết nối đã được cập nhật'],
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/plugin-connections/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export default [
['plugin_connections_new_connection_dialog_title', '新连接'],

['plugin_connections_connection_edit_menu_item_title', '编辑连接'],
['plugin_connections_connection_clone', '克隆'],
['plugin_connections_connection_clone_error', '克隆连接失败'],
['plugin_connections_connection_edit_cancel_title', '取消确认'],
['plugin_connections_connection_edit_cancel_message', '您将取消连接更改。未保存的更改将丢失。您确定吗?'],
['plugin_connections_connection_edit_reconnect_title', '连接已更新'],
Expand Down
Loading