From 25247321b83815c844e978ea46a31359be81671f Mon Sep 17 00:00:00 2001 From: Sychev Andrey <44414066+SychevAndrey@users.noreply.github.com> Date: Thu, 25 Sep 2025 12:18:17 +0200 Subject: [PATCH] dbeaver/pro#5471 [CB] Add shortcuts to tooltips data editor toolbar (#3750) * dbeaver/pro#5471 fix: "Delete" data viewer action tooltip * dbeaver/pro#5471 refactor: "merge" save and save as script actions We used to have two buttons with different shortcuts for saving SQL as a script(first save) and saving already created script (updating). On UI they had the same icon and were more or less identical for the user. We decided to use the same shortcut and labels for both buttons (mod + S). * dbeaver/pro#5471 feat: adds Find and Comment shortcuts to the shortcuts list * dbeaver/pro#5471 refactor: use common l10n keys for save/undo/redo * dbeaver/pro#5471 refactor: use key bindings API for Delete action in TableView * dbeaver/pro#5471 refactor: use key bindings API for add, duplicate and revert actions * dbeaver/pro#5471 fix: extra import * dbeaver/pro#5471 refactor: don't use a symbol for delete shortcut --------- Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com> --- .../KeyBinding/Bindings/KEY_BINDING_CANCEL.ts | 14 ++++ .../KeyBinding/Bindings/KEY_BINDING_DELETE.ts | 14 ++++ .../src/Action/KeyBinding/getBindingLabel.ts | 4 +- webapp/packages/core-view/src/index.ts | 2 + .../src/DataGrid/DataGridTable.tsx | 53 +------------ .../TableFooterMenu/TableFooterMenu.tsx | 12 ++- .../TableFooterMenu/TableFooterMenuService.ts | 75 +++++++++++++++++-- .../plugin-data-viewer/src/locales/de.ts | 2 +- .../plugin-data-viewer/src/locales/en.ts | 2 +- .../plugin-data-viewer/src/locales/fr.ts | 2 +- .../plugin-data-viewer/src/locales/ru.ts | 2 +- .../plugin-data-viewer/src/locales/vi.ts | 2 +- .../plugin-data-viewer/src/locales/zh.ts | 2 +- .../src/Shortcuts/SHORTCUTS_DATA.ts | 26 ++++++- webapp/packages/plugin-help/src/locales/en.ts | 5 +- webapp/packages/plugin-help/src/locales/fr.ts | 5 +- webapp/packages/plugin-help/src/locales/it.ts | 5 +- webapp/packages/plugin-help/src/locales/ru.ts | 5 +- webapp/packages/plugin-help/src/locales/vi.ts | 5 +- webapp/packages/plugin-help/src/locales/zh.ts | 5 +- .../KEY_BINDING_SQL_EDITOR_SAVE_AS_SCRIPT.ts | 4 +- .../src/locales/en.ts | 2 +- .../src/locales/fr.ts | 2 +- .../src/locales/it.ts | 2 +- .../src/locales/ru.ts | 2 +- .../src/locales/vi.ts | 2 +- .../src/locales/zh.ts | 2 +- .../plugin-sql-editor/src/MenuBootstrap.ts | 2 +- 28 files changed, 161 insertions(+), 99 deletions(-) create mode 100644 webapp/packages/core-view/src/Action/KeyBinding/Bindings/KEY_BINDING_CANCEL.ts create mode 100644 webapp/packages/core-view/src/Action/KeyBinding/Bindings/KEY_BINDING_DELETE.ts diff --git a/webapp/packages/core-view/src/Action/KeyBinding/Bindings/KEY_BINDING_CANCEL.ts b/webapp/packages/core-view/src/Action/KeyBinding/Bindings/KEY_BINDING_CANCEL.ts new file mode 100644 index 0000000000..6af2d7de48 --- /dev/null +++ b/webapp/packages/core-view/src/Action/KeyBinding/Bindings/KEY_BINDING_CANCEL.ts @@ -0,0 +1,14 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2025 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { createKeyBinding } from '../createKeyBinding.js'; + +export const KEY_BINDING_CANCEL = createKeyBinding({ + id: 'cancel', + keys: ['Escape'], + preventDefault: true, +}); diff --git a/webapp/packages/core-view/src/Action/KeyBinding/Bindings/KEY_BINDING_DELETE.ts b/webapp/packages/core-view/src/Action/KeyBinding/Bindings/KEY_BINDING_DELETE.ts new file mode 100644 index 0000000000..ffa413c9df --- /dev/null +++ b/webapp/packages/core-view/src/Action/KeyBinding/Bindings/KEY_BINDING_DELETE.ts @@ -0,0 +1,14 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2025 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { createKeyBinding } from '../createKeyBinding.js'; + +export const KEY_BINDING_DELETE = createKeyBinding({ + id: 'delete', + keys: ['Delete'], + preventDefault: true, +}); diff --git a/webapp/packages/core-view/src/Action/KeyBinding/getBindingLabel.ts b/webapp/packages/core-view/src/Action/KeyBinding/getBindingLabel.ts index 64e8c9ec2f..e4fe2fe94c 100644 --- a/webapp/packages/core-view/src/Action/KeyBinding/getBindingLabel.ts +++ b/webapp/packages/core-view/src/Action/KeyBinding/getBindingLabel.ts @@ -27,8 +27,8 @@ const FORMAT_SHORTCUT_KEYS_MAP: Record = { right: '→', pageup: 'pageup', pagedown: 'pagedown', - del: '⌦', - delete: '⌦', + del: 'delete', + delete: 'delete', }; const SOURCE_DIVIDER_REGEXP = /\+/gi; const APPLIED_DIVIDER = ' + '; diff --git a/webapp/packages/core-view/src/index.ts b/webapp/packages/core-view/src/index.ts index 5f83863712..a9b39cbad6 100644 --- a/webapp/packages/core-view/src/index.ts +++ b/webapp/packages/core-view/src/index.ts @@ -39,6 +39,8 @@ export * from './Action/KeyBinding/Bindings/KEY_BINDING_UNDO.js'; export * from './Action/KeyBinding/Bindings/KEY_BINDING_SAVE.js'; export * from './Action/KeyBinding/Bindings/KEY_BINDING_ADD.js'; export * from './Action/KeyBinding/Bindings/KEY_BINDING_DUPLICATE.js'; +export * from './Action/KeyBinding/Bindings/KEY_BINDING_DELETE.js'; +export * from './Action/KeyBinding/Bindings/KEY_BINDING_CANCEL.js'; export * from './Action/KeyBinding/KeyBindingService.js'; export * from './Action/KeyBinding/createKeyBinding.js'; export * from './Action/ActionService.js'; diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx index 5dc72d11df..842a4d983e 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx @@ -451,7 +451,7 @@ export const DataGridTable = observer(function DataGridT return {translate('data_grid_table_empty_placeholder')}; } - const handleCellKeyDown: DataGridProps['onCellKeyDown'] = ({ rowIdx, colIdx }, event) => { + const handleCellKeyDown: DataGridProps['onCellKeyDown'] = (_, event) => { gridSelectedCellCopy.onKeydownHandler(event); const cell = selectionAction.getFocusedElement(); @@ -459,56 +459,11 @@ export const DataGridTable = observer(function DataGridT return; } - // we can't edit table cells if table doesn't have row identifier, but we can edit just added/duplicated rows before insert (CB-6063) - const canEdit = model.hasElementIdentifier(resultIndex) || tableData.editor.getElementState(cell) === DatabaseEditChangeType.add; - const activeElements = selectionAction.getActiveElements(); - const activeRows = selectionAction.getActiveRows(); - switch (event.code) { - case 'Escape': { - if (!canEdit) { - return; - } - tableData.editor.revert(...activeElements); - return; - } - case 'KeyR': { - if (event.altKey) { - if (event.shiftKey) { - tableData.editor.duplicate(...activeRows); - } else { - tableData.editor.add(cell); - } - return; - } - return; - } - case 'Delete': { - if (!canEdit) { - return; - } + case 'KeyR': + case 'Escape': + case 'Delete': event.preventGridDefault(); - - const filteredRows = activeRows.filter(cell => tableData.editor.getElementState(cell) !== DatabaseEditChangeType.delete); - - if (filteredRows.length > 0) { - const editor = tableData.editor; - const firstRow = filteredRows[0]!; - const editingState = tableData.editor.getElementState(firstRow); - - editor.delete(...filteredRows); - - if (editingState === DatabaseEditChangeType.add) { - if (rowIdx - 1 > 0) { - handlers.selectCell({ colIdx, rowIdx: rowIdx - 1 }); - } - } else { - if (rowIdx + 1 < tableData.rows.length) { - handlers.selectCell({ colIdx, rowIdx: rowIdx + 1 }); - } - } - } - } } }; diff --git a/webapp/packages/plugin-data-viewer/src/TableViewer/TableFooter/TableFooterMenu/TableFooterMenu.tsx b/webapp/packages/plugin-data-viewer/src/TableViewer/TableFooter/TableFooterMenu/TableFooterMenu.tsx index 237dc6c753..70d362a758 100644 --- a/webapp/packages/plugin-data-viewer/src/TableViewer/TableFooter/TableFooterMenu/TableFooterMenu.tsx +++ b/webapp/packages/plugin-data-viewer/src/TableViewer/TableFooter/TableFooterMenu/TableFooterMenu.tsx @@ -1,17 +1,17 @@ /* * 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 type { HTMLAttributes } from 'react'; +import { type HTMLAttributes } from 'react'; import { CRegistry, s, useS } from '@cloudbeaver/core-blocks'; import { useDataContextLink } from '@cloudbeaver/core-data-context'; import { MenuBar, MenuBarItemStyles, MenuBarStyles } from '@cloudbeaver/core-ui'; -import { useMenu } from '@cloudbeaver/core-view'; +import { useCaptureViewContext, useMenu } from '@cloudbeaver/core-view'; import { DATA_CONTEXT_DV_DDM } from '../../../DatabaseDataModel/DataContext/DATA_CONTEXT_DV_DDM.js'; import { DATA_CONTEXT_DV_DDM_RESULT_INDEX } from '../../../DatabaseDataModel/DataContext/DATA_CONTEXT_DV_DDM_RESULT_INDEX.js'; @@ -32,6 +32,12 @@ export const TableFooterMenu = observer(function TableFooterMenu({ result const styles = useS(MenuBarStyles, MenuBarItemStyles); const menu = useMenu({ menu: DATA_VIEWER_DATA_MODEL_ACTIONS_MENU }); + useCaptureViewContext((context, id) => { + context.set(DATA_CONTEXT_DV_DDM, model, id); + context.set(DATA_CONTEXT_DV_DDM_RESULT_INDEX, resultIndex, id); + context.set(DATA_CONTEXT_DV_SIMPLE, simple, id); + }); + useDataContextLink(menu.context, (context, id) => { context.set(DATA_CONTEXT_DV_DDM, model, id); context.set(DATA_CONTEXT_DV_DDM_RESULT_INDEX, resultIndex, id); diff --git a/webapp/packages/plugin-data-viewer/src/TableViewer/TableFooter/TableFooterMenu/TableFooterMenuService.ts b/webapp/packages/plugin-data-viewer/src/TableViewer/TableFooter/TableFooterMenu/TableFooterMenuService.ts index 70118919f2..330a632d7b 100644 --- a/webapp/packages/plugin-data-viewer/src/TableViewer/TableFooter/TableFooterMenu/TableFooterMenuService.ts +++ b/webapp/packages/plugin-data-viewer/src/TableViewer/TableFooter/TableFooterMenu/TableFooterMenuService.ts @@ -14,9 +14,12 @@ import { ACTION_REVERT, ACTION_SAVE, ActionService, - getBindingLabel, + DATA_CONTEXT_MENU, KEY_BINDING_ADD, + KEY_BINDING_DELETE, KEY_BINDING_DUPLICATE, + KEY_BINDING_CANCEL, + KeyBindingService, MenuService, type IAction, } from '@cloudbeaver/core-view'; @@ -31,17 +34,61 @@ import { DATA_CONTEXT_DV_DDM_RESULT_INDEX } from '../../../DatabaseDataModel/Dat import { DATA_CONTEXT_DV_PRESENTATION, DataViewerPresentationType } from '../../../DatabaseDataModel/DataContext/DATA_CONTEXT_DV_PRESENTATION.js'; import type { IDatabaseDataModel } from '../../../DatabaseDataModel/IDatabaseDataModel.js'; import { DATA_VIEWER_DATA_MODEL_ACTIONS_MENU } from './DATA_VIEWER_DATA_MODEL_ACTIONS_MENU.js'; +import { DataViewerViewService } from '../../DataViewerViewService.js'; -@injectable(() => [ActionService, LocalizationService, MenuService]) +@injectable(() => [ActionService, KeyBindingService, DataViewerViewService, LocalizationService, MenuService]) export class TableFooterMenuService { constructor( private readonly actionService: ActionService, + private readonly keyBindingService: KeyBindingService, + private readonly dataViewerViewService: DataViewerViewService, private readonly localizationService: LocalizationService, private readonly menuService: MenuService, - ) { } + ) {} register(): void { this.registerEditingActions(); + this.keyBindingService.addKeyBindingHandler({ + id: 'table-footer-delete', + binding: KEY_BINDING_DELETE, + contexts: [DATA_CONTEXT_DV_DDM, DATA_CONTEXT_DV_DDM_RESULT_INDEX], + isBindingApplicable(context, action) { + return action === ACTION_DELETE; + }, + handler: this.tableFooterMenuActionHandler.bind(this), + }); + + this.keyBindingService.addKeyBindingHandler({ + id: 'table-footer-cancel', + binding: KEY_BINDING_CANCEL, + contexts: [DATA_CONTEXT_DV_DDM, DATA_CONTEXT_DV_DDM_RESULT_INDEX], + isBindingApplicable(context, action) { + return action === ACTION_CANCEL; + }, + handler: this.tableFooterMenuActionHandler.bind(this), + }); + + this.keyBindingService.addKeyBindingHandler({ + id: 'table-footer-add', + binding: KEY_BINDING_ADD, + contexts: [DATA_CONTEXT_DV_DDM, DATA_CONTEXT_DV_DDM_RESULT_INDEX], + isBindingApplicable(context, action) { + return action === ACTION_ADD; + }, + handler: this.tableFooterMenuActionHandler.bind(this), + }); + + this.keyBindingService.addKeyBindingHandler({ + id: 'table-footer-duplicate', + binding: KEY_BINDING_DUPLICATE, + contexts: [DATA_CONTEXT_DV_DDM, DATA_CONTEXT_DV_DDM_RESULT_INDEX], + isBindingApplicable(context, action) { + return action === ACTION_DUPLICATE; + }, + handler: this.tableFooterMenuActionHandler.bind(this), + }); + + this.dataViewerViewService.registerAction(ACTION_DELETE, ACTION_CANCEL, ACTION_ADD, ACTION_DUPLICATE); } private registerEditingActions() { @@ -62,11 +109,14 @@ export class TableFooterMenuService { this.actionService.addHandler({ id: 'data-base-editing-handler', contexts: [DATA_CONTEXT_DV_DDM, DATA_CONTEXT_DV_DDM_RESULT_INDEX], - menus: [DATA_VIEWER_DATA_MODEL_ACTIONS_MENU], actions: [ACTION_ADD, ACTION_DUPLICATE, ACTION_DELETE, ACTION_REVERT, ACTION_SAVE, ACTION_CANCEL], isActionApplicable(context, action) { const model = context.get(DATA_CONTEXT_DV_DDM)!; const resultIndex = context.get(DATA_CONTEXT_DV_DDM_RESULT_INDEX)!; + const currentMenu = context.getOwn(DATA_CONTEXT_MENU); + if (currentMenu !== undefined && currentMenu !== DATA_VIEWER_DATA_MODEL_ACTIONS_MENU) { + return false; + } if (model.isReadonly(resultIndex)) { return false; @@ -185,23 +235,32 @@ export class TableFooterMenuService { break; } case ACTION_SAVE: - model.save().catch(() => { }); + model.save().catch(() => {}); break; case ACTION_CANCEL: { editor.clear(); break; } } - } private tableFooterMenuGetActionInfo(context: IDataContextProvider, action: IAction) { const t = this.localizationService.translate; switch (action) { case ACTION_ADD: - return { ...action.info, label: '', icon: '/icons/data_add_sm.svg', tooltip: t('data_viewer_action_edit_add') + ' (' + getBindingLabel(KEY_BINDING_ADD) + ')' }; + return { + ...action.info, + label: '', + icon: '/icons/data_add_sm.svg', + tooltip: t('data_viewer_action_edit_add'), + }; case ACTION_DUPLICATE: - return { ...action.info, label: '', icon: '/icons/data_add_copy_sm.svg', tooltip: t('data_viewer_action_edit_add_copy') + ' (' + getBindingLabel(KEY_BINDING_DUPLICATE) + ')' }; + return { + ...action.info, + label: '', + icon: '/icons/data_add_copy_sm.svg', + tooltip: t('data_viewer_action_edit_add_copy'), + }; case ACTION_DELETE: return { ...action.info, label: '', icon: '/icons/data_delete_sm.svg', tooltip: t('data_viewer_action_edit_delete') }; case ACTION_REVERT: diff --git a/webapp/packages/plugin-data-viewer/src/locales/de.ts b/webapp/packages/plugin-data-viewer/src/locales/de.ts index fc9b046096..51255e054e 100644 --- a/webapp/packages/plugin-data-viewer/src/locales/de.ts +++ b/webapp/packages/plugin-data-viewer/src/locales/de.ts @@ -16,7 +16,7 @@ export default [ ['data_viewer_action_auto_refresh_menu_stop_tooltip', 'Stop auto-refreshing data'], ['data_viewer_action_auto_refresh_menu_configure_tooltip', 'Configure auto-refresh settings'], ['data_viewer_action_auto_refresh_interval_tooltip', 'Set auto-refresh interval to {arg:interval}'], - ['data_viewer_action_edit_delete', 'Ausgewählte löschen'], + ['data_viewer_action_edit_delete', 'Ausgewählte Zeilen löschen'], ['data_viewer_action_edit_add', 'Hinzufügen'], ['data_viewer_action_edit_add_copy', 'Duplikat'], ['data_viewer_action_edit_revert', 'Ausgewählt abbrechen'], diff --git a/webapp/packages/plugin-data-viewer/src/locales/en.ts b/webapp/packages/plugin-data-viewer/src/locales/en.ts index e425ce5739..6cbaea7443 100644 --- a/webapp/packages/plugin-data-viewer/src/locales/en.ts +++ b/webapp/packages/plugin-data-viewer/src/locales/en.ts @@ -18,7 +18,7 @@ export default [ ['data_viewer_action_auto_refresh_menu_stop_tooltip', 'Stop auto-refreshing data'], ['data_viewer_action_auto_refresh_menu_configure_tooltip', 'Configure auto-refresh settings'], ['data_viewer_action_auto_refresh_interval_tooltip', 'Set auto-refresh interval to {arg:interval}'], - ['data_viewer_action_edit_delete', 'Delete selected'], + ['data_viewer_action_edit_delete', 'Delete selected rows'], ['data_viewer_action_edit_add', 'Add'], ['data_viewer_action_edit_add_copy', 'Duplicate'], ['data_viewer_action_edit_revert', 'Cancel selected'], diff --git a/webapp/packages/plugin-data-viewer/src/locales/fr.ts b/webapp/packages/plugin-data-viewer/src/locales/fr.ts index 4f23aed7c6..31477750fd 100644 --- a/webapp/packages/plugin-data-viewer/src/locales/fr.ts +++ b/webapp/packages/plugin-data-viewer/src/locales/fr.ts @@ -18,7 +18,7 @@ export default [ ['data_viewer_action_auto_refresh_menu_stop_tooltip', 'Stop auto-refreshing data'], ['data_viewer_action_auto_refresh_menu_configure_tooltip', 'Configure auto-refresh settings'], ['data_viewer_action_auto_refresh_interval_tooltip', 'Set auto-refresh interval to {arg:interval}'], - ['data_viewer_action_edit_delete', 'Supprimer la sélection'], + ['data_viewer_action_edit_delete', 'Supprimer les lignes sélectionnées'], ['data_viewer_action_edit_add', 'Ajouter'], ['data_viewer_action_edit_add_copy', 'Dupliquer'], ['data_viewer_action_edit_revert', 'Annuler la sélection'], diff --git a/webapp/packages/plugin-data-viewer/src/locales/ru.ts b/webapp/packages/plugin-data-viewer/src/locales/ru.ts index de3479de31..5ecad45793 100644 --- a/webapp/packages/plugin-data-viewer/src/locales/ru.ts +++ b/webapp/packages/plugin-data-viewer/src/locales/ru.ts @@ -18,7 +18,7 @@ export default [ ['data_viewer_action_auto_refresh_menu_stop_tooltip', 'Остановить автоматическое обновление данных'], ['data_viewer_action_auto_refresh_menu_configure_tooltip', 'Настроить параметры автоматического обновления'], ['data_viewer_action_auto_refresh_interval_tooltip', 'Установить интервал автоматического обновления в {arg:interval}'], - ['data_viewer_action_edit_delete', 'Удалить'], + ['data_viewer_action_edit_delete', 'Удалить выбранные строки'], ['data_viewer_action_edit_add', 'Добавить'], ['data_viewer_action_edit_add_copy', 'Дублировать'], ['data_viewer_action_edit_revert', 'Отменить'], diff --git a/webapp/packages/plugin-data-viewer/src/locales/vi.ts b/webapp/packages/plugin-data-viewer/src/locales/vi.ts index b6366eed56..065433c698 100644 --- a/webapp/packages/plugin-data-viewer/src/locales/vi.ts +++ b/webapp/packages/plugin-data-viewer/src/locales/vi.ts @@ -18,7 +18,7 @@ export default [ ['data_viewer_action_auto_refresh_menu_stop_tooltip', 'Dừng làm mới dữ liệu tự động'], ['data_viewer_action_auto_refresh_menu_configure_tooltip', 'Cấu hình cài đặt làm mới tự động'], ['data_viewer_action_auto_refresh_interval_tooltip', 'Đặt khoảng thời gian làm mới tự động thành {arg:interval}'], - ['data_viewer_action_edit_delete', 'Xóa mục đã chọn'], + ['data_viewer_action_edit_delete', 'Xóa các hàng đã chọn'], ['data_viewer_action_edit_add', 'Thêm'], ['data_viewer_action_edit_add_copy', 'Sao chép'], ['data_viewer_action_edit_revert', 'Hủy mục đã chọn'], diff --git a/webapp/packages/plugin-data-viewer/src/locales/zh.ts b/webapp/packages/plugin-data-viewer/src/locales/zh.ts index 8335e82a5c..51c7f6d580 100644 --- a/webapp/packages/plugin-data-viewer/src/locales/zh.ts +++ b/webapp/packages/plugin-data-viewer/src/locales/zh.ts @@ -18,7 +18,7 @@ export default [ ['data_viewer_action_auto_refresh_menu_stop_tooltip', '停止自动刷新数据'], ['data_viewer_action_auto_refresh_menu_configure_tooltip', '配置自动刷新'], ['data_viewer_action_auto_refresh_interval_tooltip', '自动刷新间隔设置为 {arg:interval}'], - ['data_viewer_action_edit_delete', '删除选中'], + ['data_viewer_action_edit_delete', '删除选中行'], ['data_viewer_action_edit_add', '添加'], ['data_viewer_action_edit_add_copy', '复制并添加行'], ['data_viewer_action_edit_revert', '还原选中'], diff --git a/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts b/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts index b9b45ee107..337c17e442 100644 --- a/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts +++ b/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. */ import { getOS, OperatingSystem } from '@cloudbeaver/core-utils'; -import { getCommonAndOSSpecificKeys, type IKeyBinding, KEY_BINDING_OPEN_IN_TAB, KEY_BINDING_REDO, KEY_BINDING_UNDO } from '@cloudbeaver/core-view'; +import { createKeyBinding, getCommonAndOSSpecificKeys, type IKeyBinding, KEY_BINDING_OPEN_IN_TAB, KEY_BINDING_REDO, KEY_BINDING_UNDO } from '@cloudbeaver/core-view'; import { KEY_BINDING_ADD_NEW_ROW, KEY_BINDING_DUPLICATE_ROW, @@ -23,6 +23,16 @@ import { } from '@cloudbeaver/plugin-sql-editor'; import { KEY_BINDING_SQL_EDITOR_SAVE_AS_SCRIPT } from '@cloudbeaver/plugin-sql-editor-navigation-tab-script'; +const KEY_BINDING_SQL_EDITOR_COMMENT = createKeyBinding({ + id: 'sql-editor-comment', + keys: ['mod+/'], +}); + +const KEY_BINDING_SQL_EDITOR_FIND = createKeyBinding({ + id: 'sql-editor-find', + keys: ['mod+f'], +}); + import type { IShortcut } from './IShortcut.js'; const FORMAT_SHORTCUT_KEYS_MAP: Record = { @@ -91,17 +101,25 @@ export const SQL_EDITOR_SHORTCUTS: IShortcut[] = [ code: transformKeys(KEY_BINDING_SQL_EDITOR_FORMAT), }, { - label: 'sql_editor_shortcut_save_as_script', + label: 'ui_processing_save', code: transformKeys(KEY_BINDING_SQL_EDITOR_SAVE_AS_SCRIPT), }, { - label: 'sql_editor_shortcut_undo', + label: 'ui_undo', code: transformKeys(KEY_BINDING_UNDO), }, { - label: 'sql_editor_shortcut_redo', + label: 'ui_redo', code: transformKeys(KEY_BINDING_REDO), }, + { + label: 'sql_editor_shortcut_find', + code: transformKeys(KEY_BINDING_SQL_EDITOR_FIND), + }, + { + label: 'sql_editor_shortcut_comment_uncomment_selection', + code: transformKeys(KEY_BINDING_SQL_EDITOR_COMMENT), + }, { label: 'sql_editor_shortcut_open_editor_in_new_tab', code: transformKeys(KEY_BINDING_OPEN_IN_TAB), diff --git a/webapp/packages/plugin-help/src/locales/en.ts b/webapp/packages/plugin-help/src/locales/en.ts index 8858dc2706..09c9c9e3f3 100644 --- a/webapp/packages/plugin-help/src/locales/en.ts +++ b/webapp/packages/plugin-help/src/locales/en.ts @@ -17,10 +17,9 @@ export default [ ['sql_editor_shortcut_execute_script', 'Execute script'], ['sql_editor_shortcut_show_execution_plan', 'Show Execution plan'], ['sql_editor_shortcut_format', 'Format script'], - ['sql_editor_shortcut_save_as_script', 'Save as script'], ['sql_editor_shortcut_open_editor_in_new_tab', 'Open SQL Editor in the separate browser Tab'], - ['sql_editor_shortcut_undo', 'Undo'], - ['sql_editor_shortcut_redo', 'Redo'], + ['sql_editor_shortcut_find', 'Find'], + ['sql_editor_shortcut_comment_uncomment_selection', 'Comment/Uncomment selection'], ['navigation_tree_shortcut_enable_filter', 'Enable filtering'], diff --git a/webapp/packages/plugin-help/src/locales/fr.ts b/webapp/packages/plugin-help/src/locales/fr.ts index aa786f4fcb..13a353a829 100644 --- a/webapp/packages/plugin-help/src/locales/fr.ts +++ b/webapp/packages/plugin-help/src/locales/fr.ts @@ -16,10 +16,9 @@ export default [ ['sql_editor_shortcut_execute_script', 'Exécuter le script'], ['sql_editor_shortcut_show_execution_plan', "Afficher le plan d'exécution"], ['sql_editor_shortcut_format', 'Formater le script'], - ['sql_editor_shortcut_save_as_script', 'Save as script'], ['sql_editor_shortcut_open_editor_in_new_tab', "Ouvrir l'éditeur SQL dans un nouvel onglet"], - ['sql_editor_shortcut_undo', 'Annuler'], - ['sql_editor_shortcut_redo', 'Rétablir'], + ['sql_editor_shortcut_find', 'Rechercher'], + ['sql_editor_shortcut_comment_uncomment_selection', 'Commenter/Décommenter la sélection'], ['navigation_tree_shortcut_enable_filter', 'Activer le filtrage'], ['plugin_help_multi_tab_support_title', "Le multi-onglet n'est pas supporté"], [ diff --git a/webapp/packages/plugin-help/src/locales/it.ts b/webapp/packages/plugin-help/src/locales/it.ts index 3046264a9a..4123ed49ff 100644 --- a/webapp/packages/plugin-help/src/locales/it.ts +++ b/webapp/packages/plugin-help/src/locales/it.ts @@ -17,10 +17,9 @@ export default [ ['sql_editor_shortcut_execute_script', 'Execute script'], ['sql_editor_shortcut_show_execution_plan', 'Show Execution plan'], ['sql_editor_shortcut_format', 'Format script'], - ['sql_editor_shortcut_save_as_script', 'Save as script'], ['sql_editor_shortcut_open_editor_in_new_tab', 'Open SQL Editor in the separate browser Tab'], - ['sql_editor_shortcut_undo', 'Undo'], - ['sql_editor_shortcut_redo', 'Redo'], + ['sql_editor_shortcut_find', 'Find'], + ['sql_editor_shortcut_comment_uncomment_selection', 'Comment/Uncomment selection'], ['navigation_tree_shortcut_enable_filter', 'Enable filtering'], ]; diff --git a/webapp/packages/plugin-help/src/locales/ru.ts b/webapp/packages/plugin-help/src/locales/ru.ts index f90147d76a..cbdd27f2b8 100644 --- a/webapp/packages/plugin-help/src/locales/ru.ts +++ b/webapp/packages/plugin-help/src/locales/ru.ts @@ -17,10 +17,9 @@ export default [ ['sql_editor_shortcut_execute_script', 'Выполнить скрипт'], ['sql_editor_shortcut_show_execution_plan', 'Показать план выполнения'], ['sql_editor_shortcut_format', 'Форматировать скрипт'], - ['sql_editor_shortcut_save_as_script', 'Сохранить как скрипт'], ['sql_editor_shortcut_open_editor_in_new_tab', 'Открыть SQL редактор в новой бразуерной вкладке'], - ['sql_editor_shortcut_undo', 'Отменить'], - ['sql_editor_shortcut_redo', 'Повторить'], + ['sql_editor_shortcut_find', 'Найти'], + ['sql_editor_shortcut_comment_uncomment_selection', 'Закомментировать/раскомментировать выделение'], ['navigation_tree_shortcut_enable_filter', 'Включить фильтрацию'], ]; diff --git a/webapp/packages/plugin-help/src/locales/vi.ts b/webapp/packages/plugin-help/src/locales/vi.ts index 5b695d831a..80c4de6751 100644 --- a/webapp/packages/plugin-help/src/locales/vi.ts +++ b/webapp/packages/plugin-help/src/locales/vi.ts @@ -17,10 +17,9 @@ export default [ ['sql_editor_shortcut_execute_script', 'Thực thi kịch bản'], ['sql_editor_shortcut_show_execution_plan', 'Hiển thị kế hoạch thực thi'], ['sql_editor_shortcut_format', 'Định dạng kịch bản'], - ['sql_editor_shortcut_save_as_script', 'Lưu dưới dạng kịch bản'], ['sql_editor_shortcut_open_editor_in_new_tab', 'Mở Trình chỉnh sửa SQL trong tab riêng biệt'], - ['sql_editor_shortcut_undo', 'Hoàn tác'], - ['sql_editor_shortcut_redo', 'Làm lại'], + ['sql_editor_shortcut_find', 'Tìm kiếm'], + ['sql_editor_shortcut_comment_uncomment_selection', 'Bình luận/Bỏ bình luận lựa chọn'], ['navigation_tree_shortcut_enable_filter', 'Bật lọc'], diff --git a/webapp/packages/plugin-help/src/locales/zh.ts b/webapp/packages/plugin-help/src/locales/zh.ts index c7e086a2af..ed60027e56 100644 --- a/webapp/packages/plugin-help/src/locales/zh.ts +++ b/webapp/packages/plugin-help/src/locales/zh.ts @@ -17,10 +17,9 @@ export default [ ['sql_editor_shortcut_execute_script', '执行脚本'], ['sql_editor_shortcut_show_execution_plan', '显示执行计划'], ['sql_editor_shortcut_format', '格式化脚本'], - ['sql_editor_shortcut_save_as_script', 'Save as script'], ['sql_editor_shortcut_open_editor_in_new_tab', '在单独的浏览器标签下打开SQL编辑器'], - ['sql_editor_shortcut_undo', '撤销'], - ['sql_editor_shortcut_redo', '重做'], + ['sql_editor_shortcut_find', '查找'], + ['sql_editor_shortcut_comment_uncomment_selection', '注释/取消注释所选内容'], ['navigation_tree_shortcut_enable_filter', '启用过滤'], ]; diff --git a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/KEY_BINDING_SQL_EDITOR_SAVE_AS_SCRIPT.ts b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/KEY_BINDING_SQL_EDITOR_SAVE_AS_SCRIPT.ts index 54eab7c52d..9e23577007 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/KEY_BINDING_SQL_EDITOR_SAVE_AS_SCRIPT.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/KEY_BINDING_SQL_EDITOR_SAVE_AS_SCRIPT.ts @@ -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,6 +9,6 @@ import { createKeyBinding } from '@cloudbeaver/core-view'; export const KEY_BINDING_SQL_EDITOR_SAVE_AS_SCRIPT = createKeyBinding({ id: 'save-as-script', - keys: 'shift+mod+s', + keys: 'mod+s', preventDefault: true, }); diff --git a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/en.ts b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/en.ts index f324c2c930..765a01e41e 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/en.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/en.ts @@ -1,5 +1,5 @@ export default [ - ['plugin_sql_editor_navigation_tab_resource_save_script_title', 'Save as script'], + ['plugin_sql_editor_navigation_tab_resource_save_script_title', 'Save'], ['plugin_sql_editor_navigation_tab_script_state_renaming', 'Renaming script...'], ['plugin_sql_editor_navigation_tab_script_state_reading', 'Reading script...'], ['plugin_sql_editor_navigation_tab_script_state_saving', 'Saving script...'], diff --git a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/fr.ts b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/fr.ts index 8fe06ed6a7..466558c563 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/fr.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/fr.ts @@ -1,5 +1,5 @@ export default [ - ['plugin_sql_editor_navigation_tab_resource_save_title', 'Enregistrer comme script'], + ['plugin_sql_editor_navigation_tab_resource_save_title', 'Enregistrer'], ['plugin_sql_editor_navigation_tab_script_state_renaming', 'Renommer le script...'], ['plugin_sql_editor_navigation_tab_script_state_reading', 'Lecture du script...'], ['plugin_sql_editor_navigation_tab_script_state_saving', 'Enregistrement du script...'], diff --git a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/it.ts b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/it.ts index f324c2c930..765a01e41e 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/it.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/it.ts @@ -1,5 +1,5 @@ export default [ - ['plugin_sql_editor_navigation_tab_resource_save_script_title', 'Save as script'], + ['plugin_sql_editor_navigation_tab_resource_save_script_title', 'Save'], ['plugin_sql_editor_navigation_tab_script_state_renaming', 'Renaming script...'], ['plugin_sql_editor_navigation_tab_script_state_reading', 'Reading script...'], ['plugin_sql_editor_navigation_tab_script_state_saving', 'Saving script...'], diff --git a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/ru.ts b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/ru.ts index 5527769668..64344894a3 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/ru.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/ru.ts @@ -1,5 +1,5 @@ export default [ - ['plugin_sql_editor_navigation_tab_resource_save_script_title', 'Сохранить как скрипт'], + ['plugin_sql_editor_navigation_tab_resource_save_script_title', 'Сохранить'], ['plugin_sql_editor_navigation_tab_script_state_renaming', 'Переименовывание скрипта...'], ['plugin_sql_editor_navigation_tab_script_state_reading', 'Чтение скрипта...'], ['plugin_sql_editor_navigation_tab_script_state_saving', 'Сохранение скрипта...'], diff --git a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/vi.ts b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/vi.ts index 51ee8e4c1e..591992965d 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/vi.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/vi.ts @@ -1,5 +1,5 @@ export default [ - ['plugin_sql_editor_navigation_tab_resource_save_script_title', 'Lưu dưới dạng script'], + ['plugin_sql_editor_navigation_tab_resource_save_script_title', 'Lưu'], ['plugin_sql_editor_navigation_tab_script_state_renaming', 'Đang đổi tên script...'], ['plugin_sql_editor_navigation_tab_script_state_reading', 'Đang đọc script...'], ['plugin_sql_editor_navigation_tab_script_state_saving', 'Đang lưu script...'], diff --git a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/zh.ts b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/zh.ts index 50e1d6720f..993382088a 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/zh.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab-script/src/locales/zh.ts @@ -1,5 +1,5 @@ export default [ - ['plugin_sql_editor_navigation_tab_resource_save_script_title', '保存为脚本'], + ['plugin_sql_editor_navigation_tab_resource_save_script_title', '保存'], ['plugin_sql_editor_navigation_tab_script_state_renaming', '重命名脚本中...'], ['plugin_sql_editor_navigation_tab_script_state_reading', '读取脚本中...'], ['plugin_sql_editor_navigation_tab_script_state_saving', '保存脚本中...'], diff --git a/webapp/packages/plugin-sql-editor/src/MenuBootstrap.ts b/webapp/packages/plugin-sql-editor/src/MenuBootstrap.ts index bf0e3afd92..5fa8d5f8fd 100644 --- a/webapp/packages/plugin-sql-editor/src/MenuBootstrap.ts +++ b/webapp/packages/plugin-sql-editor/src/MenuBootstrap.ts @@ -206,7 +206,7 @@ export class MenuBootstrap extends Bootstrap { return !!dataSource?.hasFeature(ESqlDataSourceFeatures.script); }, - getItems: (context, items) => [...items, ACTION_SAVE], + getItems: (context, items) => [ACTION_SAVE, ...items], }); this.menuService.addCreator({