Commit 4b3d3112 authored by Jose Vargas's avatar Jose Vargas

Make chart panels focusable via keyboard

This makes the chart panels inside the
monitoring dashboard focusable via the
tab key, this changes depending if the panel
has an empty state or if the panel contains a
chart with the actions dropdown
parent 2dfaf90c
......@@ -266,6 +266,9 @@ export default {
this.$delete(this.allAlerts, alertPath);
}
},
openActionsDropdown() {
this.$refs.actionsDropdown.show();
},
},
panelTypes,
};
......@@ -277,6 +280,7 @@ export default {
<h5
ref="graphTitle"
class="prometheus-graph-title gl-font-lg font-weight-bold text-truncate append-right-8"
tabindex="0"
>
{{ title }}
</h5>
......@@ -301,14 +305,20 @@ export default {
ref="contextualMenu"
data-qa-selector="prometheus_graph_widgets"
>
<div class="d-flex align-items-center">
<div
data-testid="actions-dropdown-container"
class="d-flex align-items-center"
@keyup.enter="openActionsDropdown"
>
<gl-dropdown
ref="actionsDropdown"
v-gl-tooltip
toggle-class="btn btn-transparent border-0"
data-qa-selector="prometheus_widgets_dropdown"
right
no-caret
:title="__('More actions')"
tabindex="0"
>
<template slot="button-content">
<gl-icon name="ellipsis_v" class="text-secondary" />
......
......@@ -52,10 +52,17 @@ export default {
</script>
<template>
<div v-if="showPanels" ref="graph-group" class="card prometheus-panel">
<div v-if="showPanels" ref="graph-group" class="card prometheus-panel" tabindex="0">
<div class="card-header d-flex align-items-center">
<h4 class="flex-grow-1">{{ name }}</h4>
<a role="button" class="js-graph-group-toggle" @click="collapse">
<a
data-testid="group-toggle-button"
role="button"
class="js-graph-group-toggle gl-text-gray-900"
tabindex="0"
@click="collapse"
@keyup.enter="collapse"
>
<icon :size="16" :aria-label="__('Toggle collapse')" :name="caretIcon" />
</a>
</div>
......
---
title: Make chart panels focusable via keyboard
merge_request: 28603
author:
type: added
......@@ -56,6 +56,9 @@ describe('Dashboard Panel', () => {
const findTimeChart = () => wrapper.find({ ref: 'timeSeriesChart' });
const findTitle = () => wrapper.find({ ref: 'graphTitle' });
const findContextualMenu = () => wrapper.find({ ref: 'contextualMenu' });
const findActionsDropdown = () => wrapper.find({ ref: 'actionsDropdown' });
const findActionsDropdownContainer = () =>
wrapper.find('[data-testid="actions-dropdown-container"]');
const createWrapper = (props, options) => {
wrapper = shallowMount(DashboardPanel, {
......@@ -126,6 +129,10 @@ describe('Dashboard Panel', () => {
expect(wrapper.find(MonitorEmptyChart).exists()).toBe(true);
expect(wrapper.find(MonitorEmptyChart).isVueInstance()).toBe(true);
});
it('does not contain a tabindex attribute', () => {
expect(wrapper.find(MonitorEmptyChart).contains('[tabindex]')).toBe(false);
});
});
describe('When graphData is null', () => {
......@@ -194,6 +201,21 @@ describe('Dashboard Panel', () => {
});
});
it('should set a tabindex for the actions dropdown', () => {
const actionsDropdown = findActionsDropdown();
expect(actionsDropdown.contains('[tabindex]')).toBe(true);
});
it('should open the actions dropdown when enter is pressed', () => {
const openDropdownSpy = jest.spyOn(wrapper.vm, 'openActionsDropdown').mockImplementation();
const container = findActionsDropdownContainer();
container.trigger('keyup.enter');
expect(openDropdownSpy).toHaveBeenCalled();
});
it('includes a default group id', () => {
expect(wrapper.vm.groupId).toBe('dashboard-panel');
});
......
......@@ -8,6 +8,7 @@ describe('Graph group component', () => {
const findGroup = () => wrapper.find({ ref: 'graph-group' });
const findContent = () => wrapper.find({ ref: 'graph-group-content' });
const findCaretIcon = () => wrapper.find(Icon);
const findToggleButton = () => wrapper.find('[data-testid="group-toggle-button"]');
const createComponent = propsData => {
wrapper = shallowMount(GraphGroup, {
......@@ -41,6 +42,16 @@ describe('Graph group component', () => {
});
});
it('should contain a tabindex', () => {
expect(findGroup().contains('[tabindex]')).toBe(true);
});
it('should contain a tab index for the collapse button', () => {
const groupToggle = wrapper.find('.js-graph-group-toggle');
expect(groupToggle.contains('[tabindex]')).toBe(true);
});
it('should show the open the group when collapseGroup is set to true', () => {
wrapper.setProps({
collapseGroup: true,
......@@ -69,6 +80,15 @@ describe('Graph group component', () => {
expect(wrapper.vm.caretIcon).toBe('angle-down');
});
it('should call the collapse function when the button listen to a keyup enter trigger', () => {
const collapseSpy = jest.spyOn(wrapper.vm, 'collapse');
const button = findToggleButton();
button.trigger('keyup.enter');
expect(collapseSpy).toHaveBeenCalled();
});
});
describe('When groups can not be collapsed', () => {
......
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