Commit b845112d authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch 'cngo-improve-iterations-headings' into 'master'

Improve headings structure on Iterations page

See merge request gitlab-org/gitlab!76156
parents cfede9e9 8cb24ea4
...@@ -11,6 +11,7 @@ import { ...@@ -11,6 +11,7 @@ import {
GlTable, GlTable,
GlTooltipDirective, GlTooltipDirective,
} from '@gitlab/ui'; } from '@gitlab/ui';
import { kebabCase } from 'lodash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { isScopedLabel } from '~/lib/utils/common_utils'; import { isScopedLabel } from '~/lib/utils/common_utils';
import { __, n__, sprintf } from '~/locale'; import { __, n__, sprintf } from '~/locale';
...@@ -175,10 +176,13 @@ export default { ...@@ -175,10 +176,13 @@ export default {
nextPage() { nextPage() {
return Number(this.issues.pageInfo.hasNextPage); return Number(this.issues.pageInfo.hasNextPage);
}, },
sectionName() { heading() {
return this.label.title return this.label.title
? sprintf(__('Issues with label %{label}'), { label: this.label.title }) ? sprintf(__('Issues with label %{label}'), { label: this.label.title })
: __('Issues'); : __('All issues');
},
headingId() {
return kebabCase(this.heading);
}, },
badgeAriaLabel() { badgeAriaLabel() {
return n__('%d issue', '%d issues', this.issues.count); return n__('%d issue', '%d issues', this.issues.count);
...@@ -228,7 +232,9 @@ export default { ...@@ -228,7 +232,9 @@ export default {
</script> </script>
<template> <template>
<section :aria-label="sectionName"> <section :aria-labelledby="headingId">
<h4 :id="headingId" class="gl-sr-only">{{ heading }}</h4>
<gl-alert v-if="error" variant="danger" @dismiss="error = ''"> <gl-alert v-if="error" variant="danger" @dismiss="error = ''">
{{ error }} {{ error }}
</gl-alert> </gl-alert>
...@@ -265,8 +271,8 @@ export default { ...@@ -265,8 +271,8 @@ export default {
:items="issues.list" :items="issues.list"
:fields="$options.fields" :fields="$options.fields"
:empty-text="__('No issues found')" :empty-text="__('No issues found')"
:show-empty="true"
fixed fixed
show-empty
stacked="sm" stacked="sm"
:tbody-tr-class="tbodyTrClass" :tbody-tr-class="tbodyTrClass"
data-qa-selector="iteration_issues_container" data-qa-selector="iteration_issues_container"
......
...@@ -135,7 +135,7 @@ export default { ...@@ -135,7 +135,7 @@ export default {
<gl-tabs> <gl-tabs>
<gl-tab title="Issues"> <gl-tab title="Issues">
<template #title> <template #title>
{{ __('Issues') }} <h3 class="gl-font-base gl-m-0">{{ __('Issues') }}</h3>
<gl-badge class="gl-ml-2" size="sm" variant="muted">{{ issueCount }}</gl-badge> <gl-badge class="gl-ml-2" size="sm" variant="muted">{{ issueCount }}</gl-badge>
</template> </template>
......
...@@ -34,6 +34,8 @@ describe('Iterations report issues', () => { ...@@ -34,6 +34,8 @@ describe('Iterations report issues', () => {
const findGlSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader); const findGlSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findGlPagination = () => wrapper.findComponent(GlPagination); const findGlPagination = () => wrapper.findComponent(GlPagination);
const findGlTable = () => wrapper.findComponent(GlTable); const findGlTable = () => wrapper.findComponent(GlTable);
const findHeading = () => wrapper.find('h4');
const findSection = () => wrapper.find('section');
const mountComponent = ({ const mountComponent = ({
props = defaultProps, props = defaultProps,
...@@ -272,10 +274,14 @@ describe('Iterations report issues', () => { ...@@ -272,10 +274,14 @@ describe('Iterations report issues', () => {
}); });
}); });
it('has section name which mentions the label', () => { it('has heading (that contains the label) that is visually hidden', () => {
expect(wrapper.find('section').attributes('aria-label')).toBe( expect(findHeading().text()).toBe(`Issues with label ${label.title}`);
`Issues with label ${label.title}`, expect(findHeading().classes('gl-sr-only')).toBe(true);
); });
it('has section that is labelled by the heading', () => {
const headingId = findHeading().attributes('id');
expect(findSection().attributes('aria-labelledby')).toBe(headingId);
}); });
it('shows button to expand/collapse the table', () => { it('shows button to expand/collapse the table', () => {
...@@ -314,8 +320,14 @@ describe('Iterations report issues', () => { ...@@ -314,8 +320,14 @@ describe('Iterations report issues', () => {
mountComponent(); mountComponent();
}); });
it('has section name which does not mention a label', () => { it('has heading that is visually hidden', () => {
expect(wrapper.find('section').attributes('aria-label')).toBe('Issues'); expect(findHeading().text()).toBe('All issues');
expect(findHeading().classes('gl-sr-only')).toBe(true);
});
it('has section that is labelled by the heading', () => {
const headingId = findHeading().attributes('id');
expect(findSection().attributes('aria-labelledby')).toBe(headingId);
}); });
it('hides button to expand/collapse the table', () => { it('hides button to expand/collapse the table', () => {
......
...@@ -37,7 +37,7 @@ RSpec.shared_examples 'iteration report group by label' do ...@@ -37,7 +37,7 @@ RSpec.shared_examples 'iteration report group by label' do
end end
it 'shows ungrouped issues when label `x` is clicked to remove it', :aggregate_failures do it 'shows ungrouped issues when label `x` is clicked to remove it', :aggregate_failures do
within "section[aria-label=\"Issues with label #{label1.title}\"]" do within 'section' do
click_button 'Remove label' click_button 'Remove label'
end end
......
...@@ -3416,6 +3416,9 @@ msgstr "" ...@@ -3416,6 +3416,9 @@ msgstr ""
msgid "All groups and projects" msgid "All groups and projects"
msgstr "" msgstr ""
msgid "All issues"
msgstr ""
msgid "All issues for this milestone are closed." msgid "All issues for this milestone are closed."
msgstr "" msgstr ""
......
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