Add aria-label to icon-only badges for accessibility
What does this MR do and why?
Add aria-label to icon-only badges for accessibility
This change adds proper aria-label attributes to icon-only GlBadge components to improve accessibility for screen reader users.
Previously, these badges relied on the icon name as a fallback aria-label (e.g., 'merge-request', 'flag', 'bulb', 'archive'). With upcoming changes in GitLab UI, icon-only badges without explicit aria-label will have no label at all.
Changes:
- Add aria-label to merge request badge in security dashboard
- Add aria-label to policy violation badge in security dashboard
- Add aria-label to solution badge in security dashboard
- Add aria-label to archival badge in vulnerabilities
Changelog: changed
References
Related to gitlab-org/gitlab-services/design.gitlab.com!5370 which will change the behaviour of icon only badges without an aria-label.
gitlab-org/gitlab-services/design.gitlab.com#3197
Screenshots or screen recordings
These are icon-only badges that appear in the Security Dashboard. The visual appearance remains unchanged - this MR only improves screen reader accessibility.
| Before | After |
|---|---|
| [Add screenshot] | [Add screenshot] |
How to set up and validate locally
Where to find these badges in the UI:
Seed a project with vulnerabilities following the docs.
1. Merge Request Badge:
- Navigate to Security > Vulnerability Report in a project
- Find a vulnerability that has an auto-remediation merge request
- The merge request icon badge appears in the vulnerability row
note: this requires conditions I wasn't fully able to determine. Force this to show by applying the following patch
diff --git a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
index 664f69b0c6f8..025dada1814a 100644
--- a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
+++ b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
@@ -130,12 +130,36 @@ export default {
data() {
return {
selectedVulnerabilities: {},
+ fakeMergeRequest: {
+ id: 'gid://gitlab/MergeRequest/123456',
+ iid: '1234',
+ title: 'Fix: Security vulnerability in authentication',
+ webUrl: 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1234',
+ state: 'opened',
+ author: {
+ name: 'John Doe',
+ username: 'johndoe',
+ human: true,
+ },
+ },
};
},
i18n: {
image: s__('Vulnerability|Image: %{linkStart}%{image}%{linkEnd}'),
},
computed: {
+ vulnerabilitiesWithFakeMR() {
+ // Add fake merge request to the first vulnerability for testing
+ if (this.vulnerabilities.length > 0) {
+ return this.vulnerabilities.map((vuln, index) => {
+ if (index === 0) {
+ return { ...vuln, mergeRequest: this.fakeMergeRequest };
+ }
+ return vuln;
+ });
+ }
+ return this.vulnerabilities;
+ },
displayFields() {
// Add the checkbox field if the user can use the bulk select feature.
return this.canAdminVulnerability ? [FIELDS.CHECKBOX, ...this.fields] : this.fields;
@@ -367,7 +391,7 @@ export default {
class="vulnerability-list"
:busy="isLoading"
:fields="displayFields"
- :items="vulnerabilities"
+ :items="vulnerabilitiesWithFakeMR"
:thead-class="{
'below-selection-summary': shouldShowSelectionSummary,
'gl-bg-default': true,
@@ -539,7 +563,7 @@ export default {
:data-qa-badge-description="item.title || item.name"
/>
<ai-fixed-badge v-if="hasAiMergeRequest(item)" />
- <merge-request-badge v-if="item.mergeRequest" :merge-request="item.mergeRequest" />
+ <merge-request-badge :merge-request="item.mergeRequest" />
<ai-possible-fp-badge
v-if="hasAiExperimentSastFpDetection(item)"
data-testid="false-positive-vulnerability"
2. Policy Violation Badge:
- Configure a security policy in warn mode (Security > Policies)
- Create a merge request that triggers the policy
- The flag icon badge appears next to vulnerabilities that were bypassed
note: this requires security policies set up on GDK. Force this to show by applying the following patch
diff --git a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
index 664f69b0c6f8..537f3e8896e2 100644
--- a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
+++ b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
@@ -567,7 +567,7 @@ export default {
v-if="hasAiFalsePositiveCheckInProgress(item)"
:workflow-name="$options.WORKFLOW_NAMES.SAST_FP_DETECTION"
/>
- <policy-violation-badge v-if="shouldRenderPolicyViolationBadge(item)" />
+ <policy-violation-badge />
</div>
</template>
3. Solution Badge:
- Navigate to Security > Vulnerability Report
- Find a vulnerability with an available solution (e.g., dependency update)
- The bulb icon badge appears in the vulnerability row
note: this requires AI features set up on GDK. Force this to show by applying the following patch
diff --git a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
index 664f69b0c6f8..f180987376bb 100644
--- a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
+++ b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
@@ -550,7 +550,7 @@ export default {
v-else-if="item.falsePositive"
data-testid="false-positive-vulnerability"
/>
- <solution-badge v-if="item.hasRemediations" />
+ <solution-badge />
<ai-resolution-badge
v-if="
item.aiResolutionAvailable &&
4. Archival Badge:
- Navigate to a vulnerability detail page
- If the vulnerability is scheduled for archival, the archive icon badge appears in the header
note: this requires the feature flag to be turned on and vulnerabilits to be over a certain age. Force this to show by applying the following patch
diff --git a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
index 664f69b0c6f8..e22f8452a43c 100644
--- a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
+++ b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
@@ -130,6 +130,7 @@ export default {
data() {
return {
selectedVulnerabilities: {},
+ fakeArchivalDate: '2025-12-31',
};
},
i18n: {
@@ -522,10 +523,7 @@ export default {
<template #cell(activity)="{ item }">
<div class="gl-flex gl-justify-end gl-gap-3">
- <archival-badge
- v-if="item.archivalInformation && item.archivalInformation.aboutToBeArchived"
- :expected-date="item.archivalInformation.expectedToBeArchivedOn"
- />
+ <archival-badge :expected-date="fakeArchivalDate" />
<resolution-badge
v-if="item.resolvedOnDefaultBranch"
data-testid="vulnerability-resolution-badge-content"
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist.