]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Improve accessibility for dashboard health page
authornsedrickm <nsedrick101@gmail.com>
Fri, 17 Jun 2022 01:42:31 +0000 (02:42 +0100)
committerNizamudeen A <nia@redhat.com>
Thu, 12 Jan 2023 10:35:00 +0000 (16:05 +0530)
* 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 <nsedrick101@gmail.com>
(cherry picked from commit 0bd10c0e122e463d9621a26f4c3a73deea2a9c40)

15 files changed:
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss
src/pybind/mgr/dashboard/frontend/src/app/shared/components/telemetry-notification/telemetry-notification.component.scss
src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-color.enum.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/enum/health-label.enum.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-label.pipe.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-label.pipe.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts
src/pybind/mgr/dashboard/frontend/src/styles/defaults/_bootstrap-defaults.scss

index 71aac66d9d2fb800612aa847eb4e675949f44096..7b666f7cd49aaf2e2919349a56b2f58a7accf175 100644 (file)
@@ -21,7 +21,9 @@
           <ng-container *ngTemplateOutlet="logsLink"></ng-container>
           <ul>
             <li *ngFor="let check of healthData.health.checks">
-              <span [ngStyle]="check.severity | healthColor">{{ check.type }}</span>: {{ check.summary.message }}
+              <span [ngStyle]="check.severity | healthColor"
+                    [class.health-warn-description]="check.severity === 'HEALTH_WARN'">
+              {{ check.type }}</span>: {{ check.summary.message }}
             </li>
           </ul>
         </ng-template>
              [ngStyle]="healthData.health.status | healthColor"
              [ngbPopover]="healthChecks"
              popoverClass="info-card-popover-cluster-status">
-          {{ healthData.health.status }} <i *ngIf="healthData.health?.status != 'HEALTH_OK'"
-                                            class="fa fa-exclamation-triangle"></i>
+          {{ healthData.health.status | healthLabel | uppercase }}
+          <i *ngIf="healthData.health?.status != 'HEALTH_OK'"
+             class="fa fa-exclamation-triangle"></i>
         </div>
       </ng-container>
       <ng-container *ngIf="!healthData.health?.checks?.length">
         <div [ngStyle]="healthData.health.status | healthColor">
-          {{ healthData.health.status }}
+          {{ healthData.health.status | healthLabel | uppercase }}
         </div>
       </ng-container>
     </cd-info-card>
index 1294f5922db523756d6137ff25f73e4dfade659f..61128949cd78af5f82193436ad5e8432e84777a7 100644 (file)
@@ -24,6 +24,10 @@ cd-info-card {
 
 .logs-link {
   text-align: center;
+
+  a {
+    color: vv.$primary-wcag-aa-large-text;
+  }
 }
 
 .card-text-error {
index cedcd06b6975ce07862bc040a47e8fb45156a357..3e25e922878379952d7a20473ebcc379ba7debe9 100644 (file)
@@ -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', () => {
index 43cbe18ffcf09bfa20cebec2d4904a5ffd2eec24..8131ad5f0e31d4b04501eab2d8efc7fac3bdce71 100644 (file)
@@ -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;
 }
 
index 897d09a9a4b937d20dee95636059c29eda0883b9..95ed689739b942f91aac7dc931847442aa715970 100644 (file)
@@ -25,6 +25,10 @@ $card-font-max-size: 21px;
       position: absolute;
       top: -0.3rem;
     }
+
+    .card-title > a {
+      color: vv.$primary-wcag-aa-large-text;
+    }
   }
 }
 
index 722824a8fe8cbbb5088bf6846c54ca50b4c18a8e..25c9c54e9c9f4453f6225323ca1c2d5cd012b276 100644 (file)
@@ -6,7 +6,9 @@
     <span>{{ groupTitle }}</span>
     <button type="button"
             class="popover-icon btn btn-link p-0"
-            (click)="popInfo.toggle()">
+            (click)="popInfo.toggle()"
+            aria-label="learn more"
+            i18n-aria-label>
       <i [ngClass]="[icons.infoCircle, icons.large]"></i>
     </button>
   </div>
index 52bcddb96a1b71168f1e4a2df43b71229d1bf61b..e5ffb4e59548ebb4c55adec33dddf6f863eb06b9 100644 (file)
@@ -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;
 }
index cf8aa33d3bae4112a0515daa2e349b37f764a7b8..f3e3b333ce7d6846014c5a645b3ceab6e89b4337 100644 (file)
@@ -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;
+}
index 042394225166b14949f099541840e605bb6879a6..7cfea5bc2dd5a9dedc25e54399d223088e38f85e 100644 (file)
@@ -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 (file)
index 0000000..e2e1c0b
--- /dev/null
@@ -0,0 +1,5 @@
+export enum HealthLabel {
+  HEALTH_ERR = 'error',
+  HEALTH_WARN = 'warning',
+  HEALTH_OK = 'ok'
+}
index f5e937ce377579bd97704ae3d521b70fe0c65e03..c45276bb546247187e9e75343574f0f35665a8b5 100644 (file)
@@ -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 (file)
index 0000000..fb40c3d
--- /dev/null
@@ -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 (file)
index 0000000..cb91d5a
--- /dev/null
@@ -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;
+  }
+}
index 91d611c0a55fc5c982bb7821d847e5772f0593bb..5094a9913355e6f61596dd23ba6dcb76dd24f9f4 100755 (executable)
@@ -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,
index 9cb81de0e19934258d4ac1dafcb0d9cb57c4463d..c95f87a01ebcfa2aced139940a21e88e5c73f14a 100644 (file)
@@ -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;