Skip to content

Commit ea5fb47

Browse files
[CB] remove shortcuts intersection for layouts (#4103)
* dbeaver/pro#8104 removes shortcuts intersection * removes check of an active element (handled by the lib) * build fix --------- Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com>
1 parent 89b4d1f commit ea5fb47

File tree

4 files changed

+32
-17
lines changed

4 files changed

+32
-17
lines changed

webapp/packages/core-view/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@cloudbeaver/core-blocks": "workspace:*",
2727
"@cloudbeaver/core-data-context": "workspace:*",
2828
"@cloudbeaver/core-di": "workspace:*",
29+
"@cloudbeaver/core-events": "workspace:*",
2930
"@cloudbeaver/core-extensions": "workspace:*",
3031
"@cloudbeaver/core-localization": "workspace:*",
3132
"@cloudbeaver/core-utils": "workspace:*",

webapp/packages/core-view/src/View/CaptureView.tsx

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
/*
22
* CloudBeaver - Cloud Database Manager
3-
* Copyright (C) 2020-2025 DBeaver Corp and others
3+
* Copyright (C) 2020-2026 DBeaver Corp and others
44
*
55
* Licensed under the Apache License, Version 2.0.
66
* you may not use this file except in compliance with the License.
77
*/
88
import { observer } from 'mobx-react-lite';
99
import { useContext } from 'react';
1010

11-
import { s, useFocus, useHotkeys, useS } from '@cloudbeaver/core-blocks';
11+
import { s, useFocus, useHotkeys, useMergeRefs, useS } from '@cloudbeaver/core-blocks';
1212
import { useService } from '@cloudbeaver/core-di';
13+
import { EventContext, EventStopPropagationFlag } from '@cloudbeaver/core-events';
1314
import { isObjectsEqual } from '@cloudbeaver/core-utils';
1415

1516
import { ActionService } from '../Action/ActionService.js';
@@ -32,24 +33,26 @@ export const CaptureView = observer<React.PropsWithChildren<ICaptureViewProps>>(
3233
const viewContext = useViewContext(view, parentContext);
3334
const actionService = useService(ActionService);
3435
const activeView = useActiveView(view);
35-
const [ref, state] = useFocus<HTMLDivElement>({ onFocus: activeView.focusView, onBlur: activeView.blurView });
36+
const [ref] = useFocus<HTMLDivElement>({ onFocus: activeView.focusView, onBlur: activeView.blurView });
3637
const style = useS(styles);
3738

38-
const actionItems = view.actions
39-
.map(action => actionService.getAction(viewContext, action))
40-
.filter(action => action?.binding && !action.isDisabled())
41-
.filter(Boolean) as IActionItem[];
39+
const allActionItems = view.actions.map(action => actionService.getAction(viewContext, action)).filter(Boolean) as IActionItem[];
40+
const enabledActionItems = allActionItems.filter(action => action?.binding && !action.isDisabled()).filter(Boolean) as IActionItem[];
4241

43-
const keys = actionItems.map(item => getCommonAndOSSpecificKeys(item.binding?.binding)).flat();
42+
const allKeys = allActionItems.map(item => getCommonAndOSSpecificKeys(item.binding?.binding)).flat();
4443

45-
useHotkeys(
46-
keys,
44+
const divRef = useHotkeys(
45+
allKeys,
4746
(event, handler) => {
48-
if (!event.isTrusted || !state.reference?.contains(document.activeElement)) {
47+
/**
48+
* isTrusted - to prevent double handling of the event
49+
* EventContext.has - to prevent handling the event if it was already handled by a child view
50+
*/
51+
if (!event.isTrusted || EventContext.has(event, EventStopPropagationFlag)) {
4952
return;
5053
}
5154

52-
const action = actionItems.find(action => {
55+
const action = enabledActionItems.find(action => {
5356
const commonAndSpecificKeys = getCommonAndOSSpecificKeys(action.binding?.binding);
5457
return commonAndSpecificKeys.some(key => {
5558
const hotkey = parseHotkey(key);
@@ -58,31 +61,38 @@ export const CaptureView = observer<React.PropsWithChildren<ICaptureViewProps>>(
5861
});
5962
});
6063

64+
EventContext.set(event, EventStopPropagationFlag);
6165
action?.activate(true);
6266
},
6367
{
64-
enabled: keys.length > 0,
68+
enabled: allKeys.length > 0,
6569
enableOnFormTags: ['INPUT', 'SELECT', 'TEXTAREA'],
6670
preventDefault(event, handler) {
67-
const action = actionItems.find(action => {
71+
// Don't prevent default if event was already handled by a child view
72+
if (EventContext.has(event, EventStopPropagationFlag)) {
73+
return false;
74+
}
75+
76+
const action = enabledActionItems.find(action => {
6877
const commonAndSpecificKeys = getCommonAndOSSpecificKeys(action.binding?.binding);
6978
return commonAndSpecificKeys.some(key => {
7079
const hotkey = parseHotkey(key);
7180

7281
return isObjectsEqual(hotkey, handler);
7382
});
7483
});
75-
const isAppliedInSelectedScope = Boolean(state.reference?.contains(document.activeElement));
7684

77-
return isAppliedInSelectedScope && action?.binding?.binding.preventDefault === true;
85+
return action?.binding?.binding.preventDefault === true;
7886
},
7987
enableOnContentEditable: true,
8088
},
8189
);
8290

91+
const mergedRef = useMergeRefs(ref, divRef);
92+
8393
return (
8494
<CaptureViewContext.Provider value={viewContext}>
85-
<div ref={ref} className={s(style, { container: true }, className)} tabIndex={0}>
95+
<div ref={mergedRef} className={s(style, { container: true }, className)} tabIndex={0}>
8696
{children}
8797
</div>
8898
</CaptureViewContext.Provider>

webapp/packages/core-view/tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
{
2929
"path": "../core-di"
3030
},
31+
{
32+
"path": "../core-events"
33+
},
3134
{
3235
"path": "../core-extensions"
3336
},

webapp/yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,6 +2333,7 @@ __metadata:
23332333
"@cloudbeaver/core-cli": "workspace:*"
23342334
"@cloudbeaver/core-data-context": "workspace:*"
23352335
"@cloudbeaver/core-di": "workspace:*"
2336+
"@cloudbeaver/core-events": "workspace:*"
23362337
"@cloudbeaver/core-extensions": "workspace:*"
23372338
"@cloudbeaver/core-localization": "workspace:*"
23382339
"@cloudbeaver/core-utils": "workspace:*"

0 commit comments

Comments
 (0)