From 0bd10c0e122e463d9621a26f4c3a73deea2a9c40 Mon Sep 17 00:00:00 2001 From: nsedrickm Date: Fri, 17 Jun 2022 02:42:31 +0100 Subject: [PATCH] mgr/dashboard: Improve accessibility for dashboard health page * Add new color variables to meet WCAG level AA color contrast for info cards and cluster health label * Increase font size of cluster health label for better legibility with updated color * Apply darker warning color for logs summary description and increase their font size and font-weight * Add accessible names for info group icons * Replace health status labels HEALTH_OK, HEALTH_WARN and HEALTH_ERR with OK, WARNING and ERROR Fixes: https://tracker.ceph.com/issues/55867 Signed-off-by: nsedrickm --- .../dashboard/health/health.component.html | 11 +++++---- .../dashboard/health/health.component.scss | 4 ++++ .../dashboard/health/health.component.spec.ts | 4 ++-- .../info-card/info-card-popover.scss | 12 ++++++++++ .../info-card/info-card.component.scss | 4 ++++ .../info-group/info-group.component.html | 4 +++- .../info-group/info-group.component.scss | 6 +++++ .../telemetry-notification.component.scss | 6 +++++ .../src/app/shared/enum/health-color.enum.ts | 2 +- .../src/app/shared/enum/health-label.enum.ts | 5 ++++ .../shared/pipes/health-color.pipe.spec.ts | 2 +- .../shared/pipes/health-label.pipe.spec.ts | 24 +++++++++++++++++++ .../src/app/shared/pipes/health-label.pipe.ts | 12 ++++++++++ .../src/app/shared/pipes/pipes.module.ts | 3 +++ .../styles/defaults/_bootstrap-defaults.scss | 2 ++ 15 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-label.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-label.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-label.pipe.ts diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html index 71aac66d9d2fb..7b666f7cd49aa 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html @@ -21,7 +21,9 @@ @@ -29,13 +31,14 @@ [ngStyle]="healthData.health.status | healthColor" [ngbPopover]="healthChecks" popoverClass="info-card-popover-cluster-status"> - {{ healthData.health.status }} + {{ healthData.health.status | healthLabel | uppercase }} +
- {{ healthData.health.status }} + {{ healthData.health.status | healthLabel | uppercase }}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss index 1294f5922db52..61128949cd78a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss @@ -24,6 +24,10 @@ cd-info-card { .logs-link { text-align: center; + + a { + color: vv.$primary-wcag-aa-large-text; + } } .card-text-error { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts index cedcd06b6975c..3e25e92287837 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts @@ -197,7 +197,7 @@ describe('HealthComponent', () => { ); const clickableContent = clusterStatusCard.query(By.css('.info-card-content-clickable')); expect(clickableContent).toBeNull(); - expect(clusterStatusCard.nativeElement.textContent).toEqual(` ${healthPayload.health.status} `); + expect(clusterStatusCard.nativeElement.textContent).toEqual(' OK '); }); it('should render "Cluster Status" card text that is clickable (popover)', () => { @@ -216,7 +216,7 @@ describe('HealthComponent', () => { By.css('cd-info-card[cardTitle="Cluster Status"]') ); const clickableContent = clusterStatusCard.query(By.css('.info-card-content-clickable')); - expect(clickableContent.nativeElement.textContent).toEqual(` ${payload.health.status} `); + expect(clickableContent.nativeElement.textContent).toEqual(' WARNING '); }); it('event binding "prepareReadWriteRatio" is called', () => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss index 43cbe18ffcf09..8131ad5f0e31d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss @@ -9,6 +9,17 @@ max-height: 19vh; max-width: 100%; overflow: auto; + + li { + span { + font-size: 1.1em; + font-weight: bold; + } + + span.health-warn-description { + color: vv.$health-color-warning-wcag-aa-regular-text !important; + } + } } } @@ -33,6 +44,7 @@ border: 1px solid vv.$gray-200; border-radius: 3px; cursor: pointer; + font-size: 1.25em; padding: 7px; } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss index 897d09a9a4b93..95ed689739b94 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss @@ -25,6 +25,10 @@ $card-font-max-size: 21px; position: absolute; top: -0.3rem; } + + .card-title > a { + color: vv.$primary-wcag-aa-large-text; + } } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html index 722824a8fe8cb..25c9c54e9c9f4 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html @@ -6,7 +6,9 @@ {{ groupTitle }} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss index 52bcddb96a1b7..e5ffb4e59548e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss @@ -1,8 +1,14 @@ +@use './src/styles/vendor/variables' as vv; + .info-group-title { font-size: 1.75rem; margin: 0 0 0.5vw 0.5vw; } +.popover-icon { + color: vv.$primary-wcag-aa-large-text; +} + .popover-icon:focus { box-shadow: none; } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.scss index cf8aa33d3bae4..f3e3b333ce7d6 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.scss @@ -1,6 +1,7 @@ @use './src/styles/vendor/variables' as vv; .no-margin-bottom { + font-size: 0.875rem; margin-bottom: 0; } @@ -15,3 +16,8 @@ color: vv.$gray-700; font-weight: bold; } + +a { + color: darken(vv.$primary-wcag-aa-large-text, 10); + font-weight: bold; +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-color.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-color.enum.ts index 042394225166b..7cfea5bc2dd5a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-color.enum.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-color.enum.ts @@ -1,5 +1,5 @@ export enum HealthColor { HEALTH_ERR = 'health-color-error', - HEALTH_WARN = 'health-color-warning', + HEALTH_WARN = 'health-color-warning-wcag-aa-large-text', HEALTH_OK = 'health-color-healthy' } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-label.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-label.enum.ts new file mode 100644 index 0000000000000..e2e1c0b62d159 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-label.enum.ts @@ -0,0 +1,5 @@ +export enum HealthLabel { + HEALTH_ERR = 'error', + HEALTH_WARN = 'warning', + HEALTH_OK = 'ok' +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.spec.ts index f5e937ce37757..c45276bb54624 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.spec.ts @@ -6,7 +6,7 @@ class CssHelperStub extends CssHelper { if (propertyName === 'health-color-healthy') { return 'fakeGreen'; } - if (propertyName === 'health-color-warning') { + if (propertyName === 'health-color-warning-wcag-aa-large-text') { return 'fakeOrange'; } if (propertyName === 'health-color-error') { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-label.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-label.pipe.spec.ts new file mode 100644 index 0000000000000..fb40c3d09f91d --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-label.pipe.spec.ts @@ -0,0 +1,24 @@ +import { HealthLabelPipe } from './health-label.pipe'; + +describe('HealthLabelPipe', () => { + const pipe = new HealthLabelPipe(); + it('create an instance', () => { + expect(pipe).toBeTruthy(); + }); + + it('transforms "HEALTH_OK"', () => { + expect(pipe.transform('HEALTH_OK')).toEqual('ok'); + }); + + it('transforms "HEALTH_WARN"', () => { + expect(pipe.transform('HEALTH_WARN')).toEqual('warning'); + }); + + it('transforms "HEALTH_ERR"', () => { + expect(pipe.transform('HEALTH_ERR')).toEqual('error'); + }); + + it('transforms others', () => { + expect(pipe.transform('abc')).toBe(null); + }); +}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-label.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-label.pipe.ts new file mode 100644 index 0000000000000..cb91d5a55b2ba --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-label.pipe.ts @@ -0,0 +1,12 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +import { HealthLabel } from '~/app/shared/enum/health-label.enum'; + +@Pipe({ + name: 'healthLabel' +}) +export class HealthLabelPipe implements PipeTransform { + transform(value: any): any { + return Object.keys(HealthLabel).includes(value as HealthLabel) ? HealthLabel[value] : null; + } +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts index 91d611c0a55fc..5094a9913355e 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts @@ -15,6 +15,7 @@ import { EmptyPipe } from './empty.pipe'; import { EncodeUriPipe } from './encode-uri.pipe'; import { FilterPipe } from './filter.pipe'; import { HealthColorPipe } from './health-color.pipe'; +import { HealthLabelPipe } from './health-label.pipe'; import { IopsPipe } from './iops.pipe'; import { IscsiBackstorePipe } from './iscsi-backstore.pipe'; import { JoinPipe } from './join.pipe'; @@ -40,6 +41,7 @@ import { UpperFirstPipe } from './upper-first.pipe'; DimlessBinaryPipe, DimlessBinaryPerSecondPipe, HealthColorPipe, + HealthLabelPipe, DimlessPipe, CephShortVersionPipe, CephReleaseNamePipe, @@ -71,6 +73,7 @@ import { UpperFirstPipe } from './upper-first.pipe'; DimlessBinaryPipe, DimlessBinaryPerSecondPipe, HealthColorPipe, + HealthLabelPipe, DimlessPipe, CephShortVersionPipe, CephReleaseNamePipe, diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_bootstrap-defaults.scss b/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_bootstrap-defaults.scss index 9cb81de0e1993..c95f87a01ebcf 100644 --- a/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_bootstrap-defaults.scss +++ b/src/pybind/mgr/dashboard/frontend/src/styles/defaults/_bootstrap-defaults.scss @@ -65,6 +65,8 @@ $body-bg-alt: $gray-200 !default; $health-color-error: #f00 !default; $health-color-healthy: $green !default; $health-color-warning: #ffa500 !default; +$health-color-warning-wcag-aa-large-text: #d48200 !default; +$health-color-warning-wcag-aa-regular-text: #ae6200 !default; // Chart colors. $chart-color-red: #c9190b !default; -- 2.39.5