Skip to content

Commit 89772c5

Browse files
mabaasitgribnoysup
andauthored
feat(aggregations): add keyboard shortcuts COMPASS-6391 (#4031)
Co-authored-by: Sergey Petushkov <[email protected]>
1 parent 18f4f19 commit 89772c5

File tree

1 file changed

+129
-40
lines changed

1 file changed

+129
-40
lines changed

packages/compass-aggregations/src/components/focus-mode/focus-mode-modal-header.tsx

Lines changed: 129 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
Body,
23
Button,
34
css,
45
Icon,
@@ -8,8 +9,9 @@ import {
89
Select,
910
spacing,
1011
Toggle,
12+
Tooltip,
1113
} from '@mongodb-js/compass-components';
12-
import React, { useState } from 'react';
14+
import React, { useEffect, useState } from 'react';
1315
import { connect } from 'react-redux';
1416
import type { RootState } from '../../modules';
1517
import {
@@ -47,12 +49,27 @@ const fakeToggleLabelStyles = css({
4749
)}ch`,
4850
});
4951

52+
const menuStyles = css({
53+
width: '240px',
54+
});
55+
5056
const menuItemStyles = css({
5157
'&:after': {
5258
content: 'attr(data-hotkey)',
59+
whiteSpace: 'nowrap',
5360
},
5461
});
5562

63+
const tooltipContentStyles = css({
64+
display: 'flex',
65+
alignItems: 'center',
66+
gap: spacing[3],
67+
});
68+
69+
const tooltipContentItemStyles = css({
70+
flexShrink: 0,
71+
});
72+
5673
export const FocusModeModalHeader: React.FunctionComponent<
5774
FocusModeModalHeaderProps
5875
> = ({
@@ -64,8 +81,62 @@ export const FocusModeModalHeader: React.FunctionComponent<
6481
onStageDisabledToggleClick,
6582
}) => {
6683
const [menuOpen, setMenuOpen] = useState(false);
84+
85+
const keyEventListener = (e: KeyboardEvent) => {
86+
const isShiftKey = e.shiftKey;
87+
const isCtrlOrMetaKey = e.ctrlKey || e.metaKey;
88+
if (!isShiftKey || !isCtrlOrMetaKey) {
89+
return;
90+
}
91+
92+
switch (e.key) {
93+
case '9':
94+
return onPreviousStage();
95+
case '0':
96+
return onNextStage();
97+
case 'a':
98+
return onAddStageAfter();
99+
case 'b':
100+
return onAddStageBefore();
101+
default:
102+
return;
103+
}
104+
};
105+
106+
useEffect(() => {
107+
window.addEventListener('keydown', keyEventListener);
108+
return () => {
109+
window.removeEventListener('keydown', keyEventListener);
110+
};
111+
}, [keyEventListener]);
112+
67113
const isFirst = stageIndex === 0;
68114
const isLast = stages.length - 1 === stageIndex;
115+
116+
const onPreviousStage = () => {
117+
if (isFirst) {
118+
return;
119+
}
120+
onStageSelect(stageIndex - 1);
121+
};
122+
123+
const onNextStage = () => {
124+
if (isLast) {
125+
return;
126+
}
127+
onStageSelect(stageIndex + 1);
128+
};
129+
130+
const onAddStageBefore = () => {
131+
onAddStageClick(stageIndex - 1);
132+
setMenuOpen(false);
133+
};
134+
135+
const onAddStageAfter = () => {
136+
onAddStageClick(stageIndex);
137+
setMenuOpen(false);
138+
};
139+
69140
const stageSelectLabels = stages.map((stageName, index) => {
70141
return `Stage ${index + 1}: ${stageName ?? 'select'}`;
71142
});
@@ -82,22 +153,34 @@ export const FocusModeModalHeader: React.FunctionComponent<
82153
return (
83154
<div className={controlsContainerStyles}>
84155
<div className={controlContainerStyles}>
85-
<Button
86-
size="xsmall"
87-
disabled={isFirst}
88-
onClick={() => {
89-
onStageSelect(stageIndex - 1);
90-
}}
91-
aria-label="Edit previous stage"
156+
<Tooltip
157+
isDisabled={isFirst}
158+
trigger={({ children, ...props }) => (
159+
<span {...props}>
160+
{children}
161+
<Button
162+
size="xsmall"
163+
disabled={isFirst}
164+
onClick={onPreviousStage}
165+
aria-label="Edit previous stage"
166+
>
167+
<Icon
168+
size="xsmall"
169+
title={null}
170+
role="presentation"
171+
glyph="ChevronLeft"
172+
></Icon>
173+
</Button>
174+
</span>
175+
)}
92176
>
93-
<Icon
94-
size="xsmall"
95-
title={null}
96-
role="presentation"
97-
glyph="ChevronLeft"
98-
></Icon>
99-
</Button>
100-
177+
<Body className={tooltipContentStyles}>
178+
<span className={tooltipContentItemStyles}>
179+
Go to previous stage
180+
</span>
181+
<span className={tooltipContentItemStyles}>Ctrl + Shift + 9</span>
182+
</Body>
183+
</Tooltip>
101184
{/* @ts-expect-error leafygreen unresonably expects a labelledby here */}
102185
<Select
103186
allowDeselect={false}
@@ -118,21 +201,32 @@ export const FocusModeModalHeader: React.FunctionComponent<
118201
})}
119202
</Select>
120203

121-
<Button
122-
size="xsmall"
123-
disabled={isLast}
124-
onClick={() => {
125-
onStageSelect(stageIndex + 1);
126-
}}
127-
aria-label="Edit next stage"
204+
<Tooltip
205+
isDisabled={isLast}
206+
trigger={({ children, ...props }) => (
207+
<span {...props}>
208+
{children}
209+
<Button
210+
size="xsmall"
211+
disabled={isLast}
212+
onClick={onNextStage}
213+
aria-label="Edit next stage"
214+
>
215+
<Icon
216+
size="xsmall"
217+
title={null}
218+
role="presentation"
219+
glyph="ChevronRight"
220+
></Icon>
221+
</Button>
222+
</span>
223+
)}
128224
>
129-
<Icon
130-
size="xsmall"
131-
title={null}
132-
role="presentation"
133-
glyph="ChevronRight"
134-
></Icon>
135-
</Button>
225+
<Body className={tooltipContentStyles}>
226+
<span>Go to next stage</span>
227+
<span>Ctrl + Shift + 0</span>
228+
</Body>
229+
</Tooltip>
136230
</div>
137231

138232
<div className={controlContainerStyles}>
@@ -150,6 +244,7 @@ export const FocusModeModalHeader: React.FunctionComponent<
150244
</div>
151245

152246
<Menu
247+
className={menuStyles}
153248
open={menuOpen}
154249
setOpen={setMenuOpen}
155250
trigger={({ onClick, children }: any) => {
@@ -182,21 +277,15 @@ export const FocusModeModalHeader: React.FunctionComponent<
182277
>
183278
<MenuItem
184279
className={menuItemStyles}
185-
data-hotkey="A+"
186-
onClick={() => {
187-
onAddStageClick(stageIndex);
188-
setMenuOpen(false);
189-
}}
280+
onClick={onAddStageAfter}
281+
data-hotkey="Ctrl + Shift + A"
190282
>
191283
Add stage after
192284
</MenuItem>
193285
<MenuItem
194286
className={menuItemStyles}
195-
data-hotkey="B+"
196-
onClick={() => {
197-
onAddStageClick(stageIndex - 1);
198-
setMenuOpen(false);
199-
}}
287+
onClick={onAddStageBefore}
288+
data-hotkey="Ctrl + Shift + B"
200289
>
201290
Add stage before
202291
</MenuItem>

0 commit comments

Comments
 (0)