mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-13 07:47:05 +08:00
CB-3546 add mac specific keys property (#1744)
* CB-3546 add mac specific keys property * CB-3546 use common and OS specific keys, add windows keys * CB-3546 remove label, use keys for label --------- Co-authored-by: dariamarutkina <125263541+dariamarutkina@users.noreply.github.com> Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com>
This commit is contained in:
co-authored by
dariamarutkina
mr-anton-t
parent
3b8620cdfe
commit
869a87fa13
@@ -11,7 +11,7 @@ import { MenuItem, MenuItemCheckbox, MenuItemRadio } from 'reakit/Menu';
|
||||
import styled, { use } from 'reshadow';
|
||||
|
||||
import { Checkbox, MenuItemElement, menuPanelStyles, Radio, useStyles } from '@cloudbeaver/core-blocks';
|
||||
import type { IMenuActionItem } from '@cloudbeaver/core-view';
|
||||
import { getBindingLabel, IMenuActionItem } from '@cloudbeaver/core-view';
|
||||
|
||||
import type { IContextMenuItemProps } from './IContextMenuItemProps';
|
||||
|
||||
@@ -23,6 +23,10 @@ export const MenuActionElement = observer<IMenuActionElementProps>(function Menu
|
||||
const styles = useStyles(menuPanelStyles, style);
|
||||
const actionInfo = item.action.actionInfo;
|
||||
const loading = item.action.isLoading();
|
||||
let binding;
|
||||
if (item.action.binding !== null) {
|
||||
binding = getBindingLabel(item.action.binding.binding);
|
||||
}
|
||||
|
||||
function handleClick() {
|
||||
onClick();
|
||||
@@ -84,7 +88,7 @@ export const MenuActionElement = observer<IMenuActionElementProps>(function Menu
|
||||
<MenuItemElement
|
||||
label={actionInfo.label}
|
||||
icon={actionInfo.icon}
|
||||
binding={item.action.binding?.binding.label}
|
||||
binding={binding}
|
||||
tooltip={actionInfo.tooltip}
|
||||
loading={loading}
|
||||
style={style}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2023 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
export enum OperatingSystem {
|
||||
windowsOS,
|
||||
macOS,
|
||||
linuxOS,
|
||||
unixOS,
|
||||
iOS,
|
||||
androidOS,
|
||||
}
|
||||
|
||||
export function getOS(): OperatingSystem {
|
||||
const operatingSystemOptions: Array<[string, OperatingSystem]> = [
|
||||
['Win', OperatingSystem.windowsOS],
|
||||
['like Mac', OperatingSystem.iOS],
|
||||
['Mac', OperatingSystem.macOS],
|
||||
['Android', OperatingSystem.androidOS],
|
||||
['Linux', OperatingSystem.linuxOS],
|
||||
['X11', OperatingSystem.unixOS],
|
||||
];
|
||||
|
||||
const userAgent = window.navigator.userAgent;
|
||||
const OS = operatingSystemOptions.find(([testString]) => userAgent.includes(testString))?.[1] ?? OperatingSystem.windowsOS;
|
||||
return OS;
|
||||
}
|
||||
@@ -18,6 +18,7 @@ export * from './isNotNullDefined';
|
||||
export * from './flat';
|
||||
export * from './generateFileName';
|
||||
export * from './getMIME';
|
||||
export * from './getOS';
|
||||
export * from './getPathName';
|
||||
export * from './getPathParent';
|
||||
export * from './getPathParents';
|
||||
|
||||
@@ -9,7 +9,6 @@ import { createKeyBinding } from '../createKeyBinding';
|
||||
|
||||
export const KEY_BINDING_OPEN_IN_TAB = createKeyBinding({
|
||||
id: 'open-in-tab',
|
||||
label: 'Alt + T',
|
||||
keys: 'alt+t',
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ import { createKeyBinding } from '../createKeyBinding';
|
||||
|
||||
export const KEY_BINDING_REDO = createKeyBinding({
|
||||
id: 'redo',
|
||||
label: 'Ctrl + Y',
|
||||
keys: ['ctrl+y', 'ctrl+shift+z', 'shift+cmd+z', 'cmd+y'],
|
||||
keys: ['ctrl+y', 'ctrl+shift+z'],
|
||||
keysMac: ['shift+cmd+z', 'cmd+y'],
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ import { createKeyBinding } from '../createKeyBinding';
|
||||
|
||||
export const KEY_BINDING_UNDO = createKeyBinding({
|
||||
id: 'undo',
|
||||
label: 'Ctrl + Z',
|
||||
keys: ['ctrl+z', 'cmd+z'],
|
||||
keys: 'ctrl+z',
|
||||
keysMac: 'cmd+z',
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
|
||||
export interface IKeyBinding {
|
||||
id: string;
|
||||
label: string;
|
||||
preventDefault?: boolean;
|
||||
keys: string | string[];
|
||||
keys?: string | string[];
|
||||
keysWin?: string | string[];
|
||||
keysMac?: string | string[];
|
||||
}
|
||||
|
||||
@@ -9,9 +9,10 @@ import type { IKeyBinding } from './IKeyBinding';
|
||||
|
||||
interface IKeyBindingOptions {
|
||||
id: string;
|
||||
label: string;
|
||||
preventDefault?: boolean;
|
||||
keys: string | string[];
|
||||
keys?: string | string[];
|
||||
keysWin?: string | string[];
|
||||
keysMac?: string | string[];
|
||||
}
|
||||
|
||||
export function createKeyBinding(options: IKeyBindingOptions): IKeyBinding {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2023 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 { getOSSpecificKeys } from './getCommonAndOSSpecificKeys';
|
||||
import type { IKeyBinding } from './IKeyBinding';
|
||||
|
||||
export function getBindingLabel(binding: IKeyBinding) {
|
||||
let bindingLabel = getOSSpecificKeys(binding) ?? binding.keys;
|
||||
if (Array.isArray(bindingLabel)) {
|
||||
bindingLabel = bindingLabel[0];
|
||||
}
|
||||
|
||||
return bindingLabel?.replace(/\+/g, ' + ').replace(/\b\w/g, letter => letter.toUpperCase());
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2023 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 { getOS, OperatingSystem } from '@cloudbeaver/core-utils';
|
||||
|
||||
import type { IKeyBinding } from './IKeyBinding';
|
||||
|
||||
export function getCommonAndOSSpecificKeys(keyBinding: IKeyBinding | undefined): string[] {
|
||||
if (keyBinding === undefined) {
|
||||
return [];
|
||||
}
|
||||
const specificKeys = getOSSpecificKeys(keyBinding);
|
||||
let keys: string[] = [];
|
||||
|
||||
if (keyBinding.keys !== undefined) {
|
||||
keys = Array.isArray(keyBinding.keys) ? keyBinding.keys : [keyBinding.keys];
|
||||
}
|
||||
|
||||
if (specificKeys !== undefined) {
|
||||
if (Array.isArray(specificKeys)) {
|
||||
keys.push(...specificKeys);
|
||||
} else {
|
||||
keys.push(specificKeys);
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
export function getOSSpecificKeys(keyBinding: IKeyBinding): string | string[] | undefined {
|
||||
const OS = getOS();
|
||||
if (OS === OperatingSystem.windowsOS) {
|
||||
return keyBinding.keysWin;
|
||||
}
|
||||
|
||||
if (OS === OperatingSystem.macOS) {
|
||||
return keyBinding.keysMac;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import { useService } from '@cloudbeaver/core-di';
|
||||
|
||||
import { ActionService } from '../Action/ActionService';
|
||||
import type { IActionItem } from '../Action/IActionItem';
|
||||
import { getCommonAndOSSpecificKeys } from '../Action/KeyBinding/getCommonAndOSSpecificKeys';
|
||||
import { CaptureViewContext } from './CaptureViewContext';
|
||||
import type { IView } from './IView';
|
||||
import { useActiveView } from './useActiveView';
|
||||
@@ -44,7 +45,7 @@ export const CaptureView = observer<React.PropsWithChildren<Props>>(function Cap
|
||||
.filter(Boolean) as IActionItem[];
|
||||
|
||||
let keys = actionItems
|
||||
.map(item => item.binding?.binding.keys)
|
||||
.map(item => getCommonAndOSSpecificKeys(item.binding?.binding))
|
||||
.flat()
|
||||
.join(', ');
|
||||
|
||||
@@ -59,7 +60,10 @@ export const CaptureView = observer<React.PropsWithChildren<Props>>(function Cap
|
||||
return;
|
||||
}
|
||||
|
||||
const action = actionItems.find(action => action.binding?.binding.keys === handler.key || action.binding?.binding.keys.includes(handler.key));
|
||||
const action = actionItems.find(action => {
|
||||
const commonAndSpecificKeys = getCommonAndOSSpecificKeys(action.binding?.binding);
|
||||
return commonAndSpecificKeys.includes(handler.key);
|
||||
});
|
||||
|
||||
if (action?.binding?.binding.preventDefault) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -26,6 +26,9 @@ export * from './Action/IAction';
|
||||
export * from './Action/IActionHandler';
|
||||
export * from './Action/IActionInfo';
|
||||
export * from './Action/IActionItem';
|
||||
export * from './Action/KeyBinding/IKeyBinding';
|
||||
export * from './Action/KeyBinding/getCommonAndOSSpecificKeys';
|
||||
export * from './Action/KeyBinding/getBindingLabel';
|
||||
export * from './DataContext/createDataContext';
|
||||
export * from './DataContext/DataContext';
|
||||
export * from './DataContext/DynamicDataContext';
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { KEY_BINDING_OPEN_IN_TAB, KEY_BINDING_REDO, KEY_BINDING_UNDO } from '@cloudbeaver/core-view';
|
||||
import { getCommonAndOSSpecificKeys, IKeyBinding, KEY_BINDING_OPEN_IN_TAB, KEY_BINDING_REDO, KEY_BINDING_UNDO } from '@cloudbeaver/core-view';
|
||||
import { KEY_BINDING_COLLAPSE_ALL, KEY_BINDING_ENABLE_FILTER, KEY_BINDING_LINK_OBJECT } from '@cloudbeaver/plugin-navigation-tree';
|
||||
import {
|
||||
KEY_BINDING_SQL_EDITOR_EXECUTE,
|
||||
@@ -51,57 +51,55 @@ export const DATA_VIEWER_SHORTCUTS: IShortcut[] = [
|
||||
export const SQL_EDITOR_SHORTCUTS: IShortcut[] = [
|
||||
{
|
||||
label: 'sql_editor_shortcut_execute_statement',
|
||||
code: transformKeys(KEY_BINDING_SQL_EDITOR_EXECUTE.keys),
|
||||
code: transformKeys(KEY_BINDING_SQL_EDITOR_EXECUTE),
|
||||
},
|
||||
{
|
||||
label: 'sql_editor_shortcut_execute_statement_new_tab',
|
||||
code: transformKeys(KEY_BINDING_SQL_EDITOR_EXECUTE_NEW.keys),
|
||||
code: transformKeys(KEY_BINDING_SQL_EDITOR_EXECUTE_NEW),
|
||||
},
|
||||
{
|
||||
label: 'sql_editor_shortcut_execute_script',
|
||||
code: transformKeys(KEY_BINDING_SQL_EDITOR_EXECUTE_SCRIPT.keys),
|
||||
code: transformKeys(KEY_BINDING_SQL_EDITOR_EXECUTE_SCRIPT),
|
||||
},
|
||||
{
|
||||
label: 'sql_editor_shortcut_show_execution_plan',
|
||||
code: transformKeys(KEY_BINDING_SQL_EDITOR_SHOW_EXECUTION_PLAN.keys),
|
||||
code: transformKeys(KEY_BINDING_SQL_EDITOR_SHOW_EXECUTION_PLAN),
|
||||
},
|
||||
{
|
||||
label: 'sql_editor_shortcut_format',
|
||||
code: transformKeys(KEY_BINDING_SQL_EDITOR_FORMAT.keys),
|
||||
code: transformKeys(KEY_BINDING_SQL_EDITOR_FORMAT),
|
||||
},
|
||||
{
|
||||
label: 'sql_editor_shortcut_undo',
|
||||
code: transformKeys(KEY_BINDING_UNDO.keys),
|
||||
code: transformKeys(KEY_BINDING_UNDO),
|
||||
},
|
||||
{
|
||||
label: 'sql_editor_shortcut_redo',
|
||||
code: transformKeys(KEY_BINDING_REDO.keys),
|
||||
code: transformKeys(KEY_BINDING_REDO),
|
||||
},
|
||||
{
|
||||
label: 'sql_editor_shortcut_open_editor_in_new_tab',
|
||||
code: transformKeys(KEY_BINDING_OPEN_IN_TAB.keys),
|
||||
code: transformKeys(KEY_BINDING_OPEN_IN_TAB),
|
||||
},
|
||||
];
|
||||
|
||||
export const NAVIGATION_TREE_SHORTCUTS: IShortcut[] = [
|
||||
{
|
||||
label: 'navigation_tree_shortcut_enable_filter',
|
||||
code: transformKeys(KEY_BINDING_ENABLE_FILTER.keys),
|
||||
code: transformKeys(KEY_BINDING_ENABLE_FILTER),
|
||||
},
|
||||
{
|
||||
label: 'app_navigationTree_action_collapse_all',
|
||||
code: transformKeys(KEY_BINDING_COLLAPSE_ALL.keys),
|
||||
code: transformKeys(KEY_BINDING_COLLAPSE_ALL),
|
||||
},
|
||||
{
|
||||
label: 'app_navigationTree_action_link_with_editor',
|
||||
code: transformKeys(KEY_BINDING_LINK_OBJECT.keys),
|
||||
code: transformKeys(KEY_BINDING_LINK_OBJECT),
|
||||
},
|
||||
];
|
||||
|
||||
function transformKeys(keys: string | string[]): string[] {
|
||||
if (!Array.isArray(keys)) {
|
||||
keys = [keys];
|
||||
}
|
||||
function transformKeys(keyBinding: IKeyBinding): string[] {
|
||||
const keys = getCommonAndOSSpecificKeys(keyBinding);
|
||||
|
||||
return keys.map(key => key.toLocaleUpperCase().replace(/\+/gi, ' + '));
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { useStyles, useTranslate } from '@cloudbeaver/core-blocks';
|
||||
import { useTranslate } from '@cloudbeaver/core-blocks';
|
||||
|
||||
import type { IShortcut } from './IShortcut';
|
||||
|
||||
|
||||
+6
-2
@@ -13,6 +13,7 @@ import {
|
||||
ACTION_FILTER,
|
||||
ActionService,
|
||||
DATA_CONTEXT_MENU,
|
||||
getBindingLabel,
|
||||
IAction,
|
||||
IDataContextProvider,
|
||||
KeyBindingService,
|
||||
@@ -60,14 +61,17 @@ export class ElementsTreeToolsMenuService {
|
||||
getActionInfo: (context, action) => {
|
||||
switch (action) {
|
||||
case ACTION_LINK_OBJECT: {
|
||||
const tooltip = this.localizationService.translate('app_navigationTree_action_link_with_editor') + ` (${KEY_BINDING_LINK_OBJECT.label})`;
|
||||
const bindingLabel = getBindingLabel(KEY_BINDING_LINK_OBJECT);
|
||||
const tooltip =
|
||||
this.localizationService.translate('app_navigationTree_action_link_with_editor') + (bindingLabel ? ` (${bindingLabel})` : '');
|
||||
return {
|
||||
...action.info,
|
||||
tooltip,
|
||||
};
|
||||
}
|
||||
case ACTION_COLLAPSE_ALL: {
|
||||
const tooltip = this.localizationService.translate('app_navigationTree_action_collapse_all') + ` (${KEY_BINDING_COLLAPSE_ALL.label})`;
|
||||
const bindingLabel = getBindingLabel(KEY_BINDING_COLLAPSE_ALL);
|
||||
const tooltip = this.localizationService.translate('app_navigationTree_action_collapse_all') + (bindingLabel ? ` (${bindingLabel})` : '');
|
||||
return {
|
||||
...action.info,
|
||||
tooltip,
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import { createKeyBinding } from '@cloudbeaver/core-view';
|
||||
|
||||
export const KEY_BINDING_ENABLE_FILTER = createKeyBinding({
|
||||
id: 'enable-filter',
|
||||
label: 'Ctrl + F',
|
||||
keys: 'ctrl+f',
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import { createKeyBinding } from '@cloudbeaver/core-view';
|
||||
|
||||
export const KEY_BINDING_COLLAPSE_ALL = createKeyBinding({
|
||||
id: 'collapse-all',
|
||||
label: 'Ctrl + Shift + /',
|
||||
keys: 'ctrl+shift+/',
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import { createKeyBinding } from '@cloudbeaver/core-view';
|
||||
|
||||
export const KEY_BINDING_LINK_OBJECT = createKeyBinding({
|
||||
id: 'link-object',
|
||||
label: 'Ctrl + Shift + ,',
|
||||
keys: 'ctrl+shift+,',
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import { createKeyBinding } from '@cloudbeaver/core-view';
|
||||
|
||||
export const KEY_BINDING_SQL_EDITOR_EXECUTE = createKeyBinding({
|
||||
id: 'sql-editor-execute',
|
||||
label: 'Ctrl + Enter',
|
||||
keys: 'ctrl+enter',
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import { createKeyBinding } from '@cloudbeaver/core-view';
|
||||
|
||||
export const KEY_BINDING_SQL_EDITOR_EXECUTE_NEW = createKeyBinding({
|
||||
id: 'sql-editor-execute-new',
|
||||
label: 'Ctrl + \\ or Shift + Ctrl + Enter',
|
||||
keys: ['ctrl+\\', 'shift+ctrl+enter'],
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import { createKeyBinding } from '@cloudbeaver/core-view';
|
||||
|
||||
export const KEY_BINDING_SQL_EDITOR_EXECUTE_SCRIPT = createKeyBinding({
|
||||
id: 'sql-editor-execute-script',
|
||||
label: 'Alt + X',
|
||||
keys: 'alt+x',
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import { createKeyBinding } from '@cloudbeaver/core-view';
|
||||
|
||||
export const KEY_BINDING_SQL_EDITOR_FORMAT = createKeyBinding({
|
||||
id: 'sql-editor-format',
|
||||
label: 'Shift + Ctrl + F',
|
||||
keys: 'shift+ctrl+f',
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import { createKeyBinding } from '@cloudbeaver/core-view';
|
||||
|
||||
export const KEY_BINDING_SQL_EDITOR_SHOW_EXECUTION_PLAN = createKeyBinding({
|
||||
id: 'sql-editor-show-execution-plan',
|
||||
label: 'Shift + Ctrl + E',
|
||||
keys: 'shift+ctrl+e',
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user