Commit 44ca0527 by Ivana Huckova Committed by GitHub

Query history: Add keyboard shortcut support for commenting (#24736)

* Shorten filter history label

* Add keyboard shortcuts for update comment in Query history

* Add test coverage for new keyboard shortcuts

* Update changed aria-label in tests

* Add test scenario for enter and ctr key
parent 21425f7e
...@@ -100,6 +100,40 @@ describe('RichHistoryCard', () => { ...@@ -100,6 +100,40 @@ describe('RichHistoryCard', () => {
expect(wrapper.find({ title: 'Add comment' })).toHaveLength(1); expect(wrapper.find({ title: 'Add comment' })).toHaveLength(1);
expect(wrapper.find({ title: 'Edit comment' })).toHaveLength(0); expect(wrapper.find({ title: 'Edit comment' })).toHaveLength(0);
}); });
it('should open update comment form when edit comment button clicked', () => {
const wrapper = setup({ query: starredQueryWithComment });
const editCommentButton = wrapper.find({ title: 'Edit comment' });
editCommentButton.simulate('click');
expect(wrapper.find({ 'aria-label': 'Update comment form' })).toHaveLength(1);
});
it('should close update comment form when escape key pressed', () => {
const wrapper = setup({ query: starredQueryWithComment });
const editCommentButton = wrapper.find({ title: 'Edit comment' });
editCommentButton.simulate('click');
wrapper.simulate('keydown', { key: 'Escape' });
expect(wrapper.find({ 'aria-label': 'Update comment form' })).toHaveLength(0);
});
it('should close update comment form when enter and shift keys pressed', () => {
const wrapper = setup({ query: starredQueryWithComment });
const editCommentButton = wrapper.find({ title: 'Edit comment' });
editCommentButton.simulate('click');
wrapper.simulate('keydown', { key: 'Enter', shiftKey: true });
expect(wrapper.find({ 'aria-label': 'Update comment form' })).toHaveLength(0);
});
it('should close update comment form when enter and ctrl keys pressed', () => {
const wrapper = setup({ query: starredQueryWithComment });
const editCommentButton = wrapper.find({ title: 'Edit comment' });
editCommentButton.simulate('click');
wrapper.simulate('keydown', { key: 'Enter', ctrlKey: true });
expect(wrapper.find({ 'aria-label': 'Update comment form' })).toHaveLength(0);
});
it('should not close update comment form when enter key pressed', () => {
const wrapper = setup({ query: starredQueryWithComment });
const editCommentButton = wrapper.find({ title: 'Edit comment' });
editCommentButton.simulate('click');
wrapper.simulate('keydown', { key: 'Enter', shiftKey: false });
expect(wrapper.find({ 'aria-label': 'Update comment form' })).toHaveLength(1);
});
}); });
describe('starring', () => { describe('starring', () => {
......
...@@ -195,16 +195,26 @@ export function RichHistoryCard(props: Props) { ...@@ -195,16 +195,26 @@ export function RichHistoryCard(props: Props) {
const onUpdateComment = () => { const onUpdateComment = () => {
updateRichHistory(query.ts, 'comment', comment); updateRichHistory(query.ts, 'comment', comment);
toggleActiveUpdateComment(); setActiveUpdateComment(false);
}; };
const onCancelUpdateComment = () => { const onCancelUpdateComment = () => {
toggleActiveUpdateComment(); setActiveUpdateComment(false);
setComment(query.comment); setComment(query.comment);
}; };
const onKeyDown = (keyEvent: React.KeyboardEvent) => {
if (keyEvent.key === 'Enter' && (keyEvent.shiftKey || keyEvent.ctrlKey)) {
onUpdateComment();
}
if (keyEvent.key === 'Escape') {
onCancelUpdateComment();
}
};
const updateComment = ( const updateComment = (
<div className={styles.updateCommentContainer}> <div className={styles.updateCommentContainer} aria-label={comment ? 'Update comment form' : 'Add comment form'}>
<TextArea <TextArea
value={comment} value={comment}
placeholder={comment ? undefined : 'An optional description of what the query does.'} placeholder={comment ? undefined : 'An optional description of what the query does.'}
...@@ -212,7 +222,9 @@ export function RichHistoryCard(props: Props) { ...@@ -212,7 +222,9 @@ export function RichHistoryCard(props: Props) {
className={styles.textArea} className={styles.textArea}
/> />
<div className={styles.commentButtonRow}> <div className={styles.commentButtonRow}>
<Button onClick={onUpdateComment}>Save comment</Button> <Button onClick={onUpdateComment} aria-label="Submit button">
Save comment
</Button>
<Button variant="secondary" onClick={onCancelUpdateComment}> <Button variant="secondary" onClick={onCancelUpdateComment}>
Cancel Cancel
</Button> </Button>
...@@ -240,7 +252,7 @@ export function RichHistoryCard(props: Props) { ...@@ -240,7 +252,7 @@ export function RichHistoryCard(props: Props) {
); );
return ( return (
<div className={styles.queryCard}> <div className={styles.queryCard} onKeyDown={onKeyDown}>
<div className={styles.cardRow}> <div className={styles.cardRow}>
<div className={styles.datasourceContainer}> <div className={styles.datasourceContainer}>
<img src={dsImg} aria-label="Data source icon" /> <img src={dsImg} aria-label="Data source icon" />
......
...@@ -40,7 +40,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme, height: number) => { ...@@ -40,7 +40,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme, height: number) => {
/* 134px is based on the width of the Query history tabs bar, so the content is aligned to right side of the tab */ /* 134px is based on the width of the Query history tabs bar, so the content is aligned to right side of the tab */
const cardWidth = '100% - 134px'; const cardWidth = '100% - 134px';
const sliderHeight = `${height - 200}px`; const sliderHeight = `${height - 180}px`;
return { return {
container: css` container: css`
display: flex; display: flex;
...@@ -161,10 +161,7 @@ export function RichHistoryQueriesTab(props: Props) { ...@@ -161,10 +161,7 @@ export function RichHistoryQueriesTab(props: Props) {
<div className={styles.container}> <div className={styles.container}>
<div className={styles.containerSlider}> <div className={styles.containerSlider}>
<div className={styles.slider}> <div className={styles.slider}>
<div className="label-slider"> <div className="label-slider">Filter history</div>
Filter history <br />
between
</div>
<div className="label-slider">{mapNumbertoTimeInSlider(sliderRetentionFilter[0])}</div> <div className="label-slider">{mapNumbertoTimeInSlider(sliderRetentionFilter[0])}</div>
<div className="slider"> <div className="slider">
<Slider <Slider
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment