]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Improve level A accessibility for missing aria labels in tabs and...
authornsedrickm <nsedrick101@gmail.com>
Sat, 23 Jul 2022 11:18:46 +0000 (12:18 +0100)
committerNizamudeen A <nia@redhat.com>
Fri, 3 Feb 2023 12:50:35 +0000 (18:20 +0530)
Replace tab component ul and li elements with navs and ng-containers

Fixes: https://tracker.ceph.com/issues/55872
Signed-off-by: nsedrickm <nsedrick101@gmail.com>
30 files changed:
src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/osds.e2e-spec.ts
src/pybind/mgr/dashboard/frontend/cypress/integration/page-helper.po.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-tabs/rbd-tabs.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/smart-list/smart-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.html
src/pybind/mgr/dashboard/frontend/src/styles/ceph-custom/_basics.scss
src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts

index e68d03bd542b0a6708b2c474f1965a0bf227e261..2fc148a1788c38339d379d96c10945f6a1185745 100644 (file)
@@ -39,7 +39,7 @@ describe('OSDs page', () => {
       });
 
       it('should show the correct text for the tab labels', () => {
-        cy.get('#tabset-osd-details > li > a').then(($tabs) => {
+        cy.get('#tabset-osd-details > a').then(($tabs) => {
           const tabHeadings = $tabs.map((_i, e) => e.textContent).get();
 
           expect(tabHeadings).to.eql([
index 4531a70bb7fedfdbc8ea20efcfa313993c0c79b1..8b9104ed387e682539543fcd673311ba58757c4b 100644 (file)
@@ -72,11 +72,11 @@ export abstract class PageHelper {
   }
 
   getTabs() {
-    return cy.get('.nav.nav-tabs li');
+    return cy.get('.nav.nav-tabs a');
   }
 
   getTab(tabName: string) {
-    return cy.contains('.nav.nav-tabs li', tabName);
+    return cy.contains('.nav.nav-tabs a', tabName);
   }
 
   getTabText(index: number) {
index 3d328cb6bf324a50ca51209ca9b7c4fc946bc212..ec4d07e235a2f31e9ce53335ea8d7e7de37a8a43 100644 (file)
@@ -1,14 +1,16 @@
-<ul ngbNav
-    #nav="ngbNav"
-    [activeId]="router.url"
-    (navChange)="router.navigate([$event.nextId])"
-    class="nav-tabs">
-  <li ngbNavItem="/block/iscsi/overview">
-    <a ngbNavLink
+<ul class="nav nav-tabs">
+  <li class="nav-item">
+    <a class="nav-link"
+       routerLink="/block/iscsi/overview"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
        i18n>Overview</a>
   </li>
-  <li ngbNavItem="/block/iscsi/targets">
-    <a ngbNavLink
+  <li class="nav-item">
+    <a class="nav-link"
+       routerLink="/block/iscsi/targets"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
        i18n>Targets</a>
   </li>
 </ul>
index d4d21361bcdd58ed9487759970b73ff70ec02df3..6631339538e01419de73231af15d8a386eb1c18e 100644 (file)
@@ -1,11 +1,8 @@
 import { Component } from '@angular/core';
-import { Router } from '@angular/router';
 
 @Component({
   selector: 'cd-iscsi-tabs',
   templateUrl: './iscsi-tabs.component.html',
   styleUrls: ['./iscsi-tabs.component.scss']
 })
-export class IscsiTabsComponent {
-  constructor(public router: Router) {}
-}
+export class IscsiTabsComponent {}
index d4972a41c13536042a88896c59c20d2179e9c235..ef72663cde90da9b0be5eb0374caa62eb4ec84d5 100644 (file)
@@ -1,8 +1,8 @@
-<ul ngbNav
-    #nav="ngbNav"
-    class="nav-tabs"
-    cdStatefulTab="image-list">
-  <li ngbNavItem="issues">
+<nav ngbNav
+     #nav="ngbNav"
+     class="nav-tabs"
+     cdStatefulTab="image-list">
+  <ng-container ngbNavItem="issues">
     <a ngbNavLink
        i18n>Issues ({{ image_error.data.length }})</a>
     <ng-template ngbNavContent>
@@ -14,8 +14,8 @@
                 [status]="tableStatus">
       </cd-table>
     </ng-template>
-  </li>
-  <li ngbNavItem="syncing">
+  </ng-container>
+  <ng-container ngbNavItem="syncing">
     <a ngbNavLink
        i18n>Syncing ({{ image_syncing.data.length }})</a>
     <ng-template ngbNavContent>
@@ -27,8 +27,8 @@
                 [status]="tableStatus">
       </cd-table>
     </ng-template>
-  </li>
-  <li ngbNavItem="ready">
+  </ng-container>
+  <ng-container ngbNavItem="ready">
     <a ngbNavLink
        i18n>Ready ({{ image_ready.data.length }})</a>
     <ng-template ngbNavContent>
@@ -40,8 +40,8 @@
                 [status]="tableStatus">
       </cd-table>
     </ng-template>
-  </li>
-</ul>
+  </ng-container>
+</nav>
 
 <div [ngbNavOutlet]="nav"></div>
 
index 83331773f5762c26ba2c120f2c37fe872d0418f7..17b466e72f13032fc70c0e2ee306818b593659d8 100644 (file)
@@ -3,11 +3,11 @@
 </ng-template>
 
 <ng-container *ngIf="selection && selection.source !== 'REMOVING'">
-  <ul ngbNav
-      #nav="ngbNav"
-      class="nav-tabs"
-      cdStatefulTab="rbd-details">
-    <li ngbNavItem="details">
+  <nav ngbNav
+       #nav="ngbNav"
+       class="nav-tabs"
+       cdStatefulTab="rbd-details">
+    <ng-container ngbNavItem="details">
       <a ngbNavLink
          i18n>Details</a>
       <ng-template ngbNavContent>
           </tbody>
         </table>
       </ng-template>
-    </li>
-    <li ngbNavItem="snapshots">
+    </ng-container>
+    <ng-container ngbNavItem="snapshots">
       <a ngbNavLink
          i18n>Snapshots</a>
       <ng-template ngbNavContent>
                               [mirroring]="selection.mirror_mode"
                               [rbdName]="selection.name"></cd-rbd-snapshot-list>
       </ng-template>
-    </li>
-    <li ngbNavItem="configuration">
+    </ng-container>
+    <ng-container ngbNavItem="configuration">
       <a ngbNavLink
          i18n>Configuration</a>
       <ng-template ngbNavContent>
         <cd-rbd-configuration-table [data]="selection['configuration']"></cd-rbd-configuration-table>
       </ng-template>
-    </li>
+    </ng-container>
 
-    <li ngbNavItem="performance">
+    <ng-container ngbNavItem="performance">
       <a ngbNavLink
          i18n>Performance</a>
       <ng-template ngbNavContent>
                     grafanaStyle="one">
         </cd-grafana>
       </ng-template>
-    </li>
-  </ul>
+    </ng-container>
+  </nav>
 
   <div [ngbNavOutlet]="nav"></div>
 </ng-container>
index 657568c2230cc889434a3be8ddb4ebcbbf30aeae..e11beb9bd5e68a7452db9c1cd0c6007f1dde07d2 100644 (file)
@@ -1,23 +1,35 @@
-<ul ngbNav
-    #nav="ngbNav"
-    [activeId]="router.url"
-    (navChange)="router.navigate([$event.nextId])"
-    class="nav-tabs">
-  <li ngbNavItem="/block/rbd">
-    <a ngbNavLink
+<ul class="nav nav-tabs">
+  <li class="nav-item">
+    <a class="nav-link"
+       routerLink="/block/rbd"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
+       [routerLinkActiveOptions]="{exact: true}"
        i18n>Images</a>
   </li>
-  <li ngbNavItem="/block/rbd/namespaces">
-    <a ngbNavLink
+  <li class="nav-item">
+    <a class="nav-link"
+       routerLink="/block/rbd/namespaces"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
+       [routerLinkActiveOptions]="{exact: true}"
        i18n>Namespaces</a>
   </li>
-  <li ngbNavItem="/block/rbd/trash">
-    <a ngbNavLink
+  <li class="nav-item">
+    <a class="nav-link"
+       routerLink="/block/rbd/trash"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
+       [routerLinkActiveOptions]="{exact: true}"
        i18n>Trash</a>
   </li>
-  <li ngbNavItem="/block/rbd/performance"
+  <li class="nav-item"
       *ngIf="grafanaPermission.read">
-    <a ngbNavLink
+    <a class="nav-link"
+       routerLink="/block/rbd/performance"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
+       [routerLinkActiveOptions]="{exact: true}"
        i18n>Overall Performance</a>
   </li>
 </ul>
index 056cb1764583c7f3729863cf55796285cc210c42..a9a57bfcdbcf5accc1237a826b7af109272d1afd 100644 (file)
@@ -1,5 +1,4 @@
 import { Component } from '@angular/core';
-import { Router } from '@angular/router';
 
 import { Permission } from '~/app/shared/models/permissions';
 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
@@ -13,7 +12,7 @@ export class RbdTabsComponent {
   grafanaPermission: Permission;
   url: string;
 
-  constructor(private authStorageService: AuthStorageService, public router: Router) {
+  constructor(private authStorageService: AuthStorageService) {
     this.grafanaPermission = this.authStorageService.getPermissions().grafana;
   }
 }
index d2f7ad4b05b8b9ec83671989cbffbe3aef031137..a4f88004435d9f008cae2f2bd0a77024ebb9d23d 100644 (file)
@@ -1,18 +1,18 @@
 <ng-container *ngIf="selection">
-  <ul ngbNav
-      #nav="ngbNav"
-      (navChange)="softRefresh()"
-      class="nav-tabs"
-      cdStatefulTab="cephfs-tabs">
-    <li ngbNavItem="details">
+  <nav ngbNav
+       #nav="ngbNav"
+       (navChange)="softRefresh()"
+       class="nav-tabs"
+       cdStatefulTab="cephfs-tabs">
+    <ng-container ngbNavItem="details">
       <a ngbNavLink
          i18n>Details</a>
       <ng-template ngbNavContent>
         <cd-cephfs-detail [data]="details">
         </cd-cephfs-detail>
       </ng-template>
-    </li>
-    <li ngbNavItem="clients">
+    </ng-container>
+    <ng-container ngbNavItem="clients">
       <a ngbNavLink>
         <ng-container i18n>Clients</ng-container>
         <span class="badge badge-pill badge-tab ml-1">{{ clients.data.length }}</span>
                            (triggerApiUpdate)="refresh()">
         </cd-cephfs-clients>
       </ng-template>
-    </li>
-    <li ngbNavItem="directories">
+    </ng-container>
+    <ng-container ngbNavItem="directories">
       <a ngbNavLink
          i18n>Directories</a>
       <ng-template ngbNavContent>
         <cd-cephfs-directories [id]="id"></cd-cephfs-directories>
       </ng-template>
-    </li>
-    <li ngbNavItem="performance-details">
+    </ng-container>
+    <ng-container ngbNavItem="performance-details">
       <a ngbNavLink
          i18n>Performance Details</a>
       <ng-template ngbNavContent>
@@ -43,8 +43,8 @@
                     grafanaStyle="one">
         </cd-grafana>
       </ng-template>
-    </li>
-  </ul>
+    </ng-container>
+  </nav>
 
   <div [ngbNavOutlet]="nav"></div>
 </ng-container>
index 7bda5c520a61cf9a7219c8755591add9949cb6d7..386d5b3c99b8b825a9bb0174155ca7017244ea17 100644 (file)
@@ -1,25 +1,25 @@
 <ng-container *ngIf="selection">
-  <ul ngbNav
-      #nav="ngbNav"
-      class="nav-tabs"
-      cdStatefulTab="host-details">
-    <li ngbNavItem="devices">
+  <nav ngbNav
+       #nav="ngbNav"
+       class="nav-tabs"
+       cdStatefulTab="host-details">
+    <ng-container ngbNavItem="devices">
       <a ngbNavLink
          i18n>Devices</a>
       <ng-template ngbNavContent>
         <cd-device-list [hostname]="selection['hostname']"></cd-device-list>
       </ng-template>
-    </li>
-    <li ngbNavItem="inventory"
-        *ngIf="permissions.hosts.read">
+    </ng-container>
+    <ng-container ngbNavItem="inventory"
+                  *ngIf="permissions.hosts.read">
       <a ngbNavLink
          i18n>Physical Disks</a>
       <ng-template ngbNavContent>
         <cd-inventory [hostname]="selectedHostname"></cd-inventory>
       </ng-template>
-    </li>
-    <li ngbNavItem="daemons"
-        *ngIf="permissions.hosts.read">
+    </ng-container>
+    <ng-container ngbNavItem="daemons"
+                  *ngIf="permissions.hosts.read">
       <a ngbNavLink
          i18n>Daemons</a>
       <ng-template ngbNavContent>
@@ -28,9 +28,9 @@
                                 [hiddenColumns]="['hostname']">
         </cd-service-daemon-list>
       </ng-template>
-    </li>
-    <li ngbNavItem="performance-details"
-        *ngIf="permissions.grafana.read">
+    </ng-container>
+    <ng-container ngbNavItem="performance-details"
+                  *ngIf="permissions.grafana.read">
       <a ngbNavLink
          i18n>Performance Details</a>
       <ng-template ngbNavContent>
                     grafanaStyle="four">
         </cd-grafana>
       </ng-template>
-    </li>
-    <li ngbNavItem="device-health">
+    </ng-container>
+    <ng-container ngbNavItem="device-health">
       <a ngbNavLink
          i18n>Device health</a>
       <ng-template ngbNavContent>
         <cd-smart-list *ngIf="selectedHostname; else noHostname"
                        [hostname]="selectedHostname"></cd-smart-list>
       </ng-template>
-    </li>
-  </ul>
+    </ng-container>
+  </nav>
 
   <div [ngbNavOutlet]="nav"></div>
 </ng-container>
index a6c597cd823a594cce886d00b0dc974af8a01c58..aef7697da2f204685eb16027936ea05331a8aef5 100644 (file)
@@ -1,7 +1,7 @@
-<ul ngbNav
-    #nav="ngbNav"
-    class="nav-tabs">
-  <li ngbNavItem>
+<nav ngbNav
+     #nav="ngbNav"
+     class="nav-tabs">
+  <ng-container ngbNavItem>
     <a ngbNavLink
        i18n>Hosts List</a>
     <ng-template ngbNavContent>
         </cd-host-details>
       </cd-table>
     </ng-template>
-  </li>
-  <li ngbNavItem
-      *ngIf="permissions.grafana.read">
+  </ng-container>
+  <ng-container ngbNavItem
+                *ngIf="permissions.grafana.read">
+  </ng-container>
+  <ng-container ngbNavItem
+                *ngIf="permissions.grafana.read">
     <a ngbNavLink
        i18n>Overall Performance</a>
     <ng-template ngbNavContent>
@@ -43,8 +46,8 @@
                   grafanaStyle="two">
       </cd-grafana>
     </ng-template>
-  </li>
-</ul>
+  </ng-container>
+</nav>
 
 <div [ngbNavOutlet]="nav"></div>
 
index f233617422f9555dffac67f04c79b803e51b5030..bd4a25e7596c0956c3eca3b02532a0f7a0754266 100644 (file)
@@ -1,11 +1,11 @@
 <div *ngIf="contentData">
   <ng-container *ngTemplateOutlet="logFiltersTpl"></ng-container>
 
-  <ul ngbNav
-      #nav="ngbNav"
-      class="nav-tabs"
-      cdStatefulTab="logs">
-    <li ngbNavItem="cluster-logs">
+  <nav ngbNav
+       #nav="ngbNav"
+       class="nav-tabs"
+       cdStatefulTab="logs">
+    <ng-container ngbNavItem="cluster-logs">
       <a ngbNavLink
          i18n>Cluster Logs</a>
       <ng-template ngbNavContent>
@@ -35,8 +35,8 @@
           </div>
         </div>
       </ng-template>
-    </li>
-    <li ngbNavItem="audit-logs">
+    </ng-container>
+    <ng-container ngbNavItem="audit-logs">
       <a ngbNavLink
          i18n>Audit Logs</a>
       <ng-template ngbNavContent>
@@ -66,8 +66,8 @@
           </div>
         </div>
       </ng-template>
-    </li>
-    <li ngbNavItem="daemon-logs">
+    </ng-container>
+    <ng-container ngbNavItem="daemon-logs">
       <a ngbNavLink
          i18n>Daemon Logs</a>
       <ng-template ngbNavContent>
@@ -83,8 +83,8 @@
           </div>
         </ng-container>
       </ng-template>
-    </li>
-  </ul>
+    </ng-container>
+  </nav>
 
   <div [ngbNavOutlet]="nav"></div>
 </div>
index 4e107dc9cfc87359475c497d8f2a6ac844713028..2b73a710ac34883fe916943b9cdd95325d538254 100644 (file)
@@ -1,10 +1,10 @@
 <ng-container *ngIf="selection">
-  <ul ngbNav
-      #nav="ngbNav"
-      id="tabset-osd-details"
-      class="nav-tabs"
-      cdStatefulTab="osd-details">
-    <li ngbNavItem="devices">
+  <nav ngbNav
+       #nav="ngbNav"
+       id="tabset-osd-details"
+       class="nav-tabs"
+       cdStatefulTab="osd-details">
+    <ng-container ngbNavItem="devices">
       <a ngbNavLink
          i18n>Devices</a>
       <ng-template ngbNavContent>
                         [hostname]="selection?.host.name"
                         [osdList]="true"></cd-device-list>
       </ng-template>
-    </li>
-    <li ngbNavItem="attributes">
+    </ng-container>
+    <ng-container ngbNavItem="attributes">
       <a ngbNavLink
          i18n>Attributes (OSD map)</a>
       <ng-template ngbNavContent>
         <cd-table-key-value [data]="osd?.details?.osd_map">
         </cd-table-key-value>
       </ng-template>
-    </li>
-    <li ngbNavItem="metadata">
+    </ng-container>
+    <ng-container ngbNavItem="metadata">
       <a ngbNavLink
          i18n>Metadata</a>
       <ng-template ngbNavContent>
                           i18n>Metadata not available</cd-alert-panel>
         </ng-template>
       </ng-template>
-    </li>
-    <li ngbNavItem="device-health">
+    </ng-container>
+    <ng-container ngbNavItem="device-health">
       <a ngbNavLink
          i18n>Device health</a>
       <ng-template ngbNavContent>
         <cd-smart-list [osdId]="osd?.id"></cd-smart-list>
       </ng-template>
-    </li>
-    <li ngbNavItem="performance-counter">
+    </ng-container>
+    <ng-container ngbNavItem="performance-counter">
       <a ngbNavLink
          i18n>Performance counter</a>
       <ng-template ngbNavContent>
@@ -51,9 +51,9 @@
                                       [serviceId]="osd?.id">
         </cd-table-performance-counter>
       </ng-template>
-    </li>
-    <li ngbNavItem="performance-details"
-        *ngIf="grafanaPermission.read">
+    </ng-container>
+    <ng-container ngbNavItem="performance-details"
+                  *ngIf="grafanaPermission.read">
       <a ngbNavLink
          i18n>Performance Details</a>
       <ng-template ngbNavContent>
@@ -65,8 +65,8 @@
                     grafanaStyle="three">
         </cd-grafana>
       </ng-template>
-    </li>
-  </ul>
+    </ng-container>
+  </nav>
 
   <div [ngbNavOutlet]="nav"></div>
 </ng-container>
index 646064ec8b13525d63e6e05da76b9995b090b88a..e09bb086c96bc114b1d5c2b88a7a65abd9f476d6 100644 (file)
@@ -1,7 +1,7 @@
-<ul ngbNav
-    #nav="ngbNav"
-    class="nav-tabs">
-  <li ngbNavItem>
+<nav ngbNav
+     #nav="ngbNav"
+     class="nav-tabs">
+  <ng-container ngbNavItem>
     <a ngbNavLink
        i18n>OSDs List</a>
     <ng-template ngbNavContent>
         </cd-osd-details>
       </cd-table>
     </ng-template>
-  </li>
+  </ng-container>
 
-  <li ngbNavItem
-      *ngIf="permissions.grafana.read">
+  <ng-container ngbNavItem
+                *ngIf="permissions.grafana.read">
     <a ngbNavLink
        i18n>Overall Performance</a>
     <ng-template ngbNavContent>
@@ -51,8 +51,8 @@
                   grafanaStyle="four">
       </cd-grafana>
     </ng-template>
-  </li>
-</ul>
+  </ng-container>
+</nav>
 
 <div [ngbNavOutlet]="nav"></div>
 
index 3be6091a584c3d849a49c789a574a3fc1720c6df..273982caf26ff58f38b42ec190b7ef6001aae299 100644 (file)
@@ -1,22 +1,30 @@
-<ul ngbNav
-    #nav="ngbNav"
-    [activeId]="router.url"
-    (navChange)="router.navigate([$event.nextId])"
-    class="nav-tabs">
-  <li ngbNavItem="/monitoring/active-alerts">
-    <a ngbNavLink
+<ul class="nav nav-tabs">
+  <li class="nav-item">
+    <a class="nav-link"
+       routerLink="/monitoring/active-alerts"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
+       [routerLinkActiveOptions]="{exact: true}"
        i18n>Active Alerts
     <small *ngIf="prometheusAlertService.activeCriticalAlerts > 0"
         class="badge badge-danger ml-1">{{ prometheusAlertService.activeCriticalAlerts }}</small>
     <small *ngIf="prometheusAlertService.activeWarningAlerts > 0"
         class="badge badge-warning ml-1">{{ prometheusAlertService.activeWarningAlerts }}</small></a>
   </li>
-  <li ngbNavItem="/monitoring/alerts">
-    <a ngbNavLink
+  <li class="nav-item">
+    <a class="nav-link"
+       routerLink="/monitoring/alerts"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
+       [routerLinkActiveOptions]="{exact: true}"
        i18n>Alerts</a>
   </li>
-  <li ngbNavItem="/monitoring/silences">
-    <a ngbNavLink
+  <li class="nav-item">
+    <a class="nav-link"
+       routerLink="/monitoring/silences"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
+       [routerLinkActiveOptions]="{exact: true}"
        i18n>Silences</a>
   </li>
 </ul>
index cccce1d92e33c9b3cbcdc8814f0036a95ab9aa31..136fe939177ee5d503233fd35f7a8b37e72dc395 100644 (file)
@@ -1,5 +1,4 @@
 import { Component } from '@angular/core';
-import { Router } from '@angular/router';
 
 import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service';
 
@@ -9,5 +8,5 @@ import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.s
   styleUrls: ['./prometheus-tabs.component.scss']
 })
 export class PrometheusTabsComponent {
-  constructor(public router: Router, public prometheusAlertService: PrometheusAlertService) {}
+  constructor(public prometheusAlertService: PrometheusAlertService) {}
 }
index fc782c5658d1f168abf17c726d4746a27cf809b5..14ec015d1b8ee4848547d5935462189c0a798be0 100644 (file)
@@ -6,18 +6,18 @@
 
 <ng-template #serviceDetailsTpl>
   <ng-container>
-    <ul ngbNav
-        #nav="ngbNav"
-        class="nav-tabs"
-        cdStatefulTab="service-details">
-      <li ngbNavItem="details">
+    <nav ngbNav
+         #nav="ngbNav"
+         class="nav-tabs"
+         cdStatefulTab="service-details">
+      <ng-container ngbNavItem="details">
         <a ngbNavLink
            i18n>Details</a>
         <ng-template ngbNavContent>
           <ng-container *ngTemplateOutlet="serviceDaemonDetailsTpl"></ng-container>
         </ng-template>
-      </li>
-      <li ngbNavItem="service_events">
+      </ng-container>
+      <ng-container ngbNavItem="service_events">
         <a ngbNavLink
            i18n>Service Events</a>
         <ng-template ngbNavContent>
@@ -29,8 +29,8 @@
                     (fetchData)="getServices($event)">
           </cd-table>
         </ng-template>
-      </li>
-    </ul>
+      </ng-container>
+    </nav>
     <div [ngbNavOutlet]="nav"></div>
   </ng-container>
 </ng-template>
index a79287e2f048e5b09e2aaa4e0e8c992266a330bb..feea20883efeb6c6bff69152511170ead290fa3a 100644 (file)
@@ -5,24 +5,24 @@
   <cd-refresh-selector></cd-refresh-selector>
 
   <ng-container *ngIf="hasGrafana">
-    <ul ngbNav
-        #nav="ngbNav"
-        class="nav-tabs">
-      <li ngbNavItem>
+    <nav ngbNav
+         #nav="ngbNav"
+         class="nav-tabs">
+      <ng-container ngbNavItem>
         <a ngbNavLink
            i18n>Health</a>
         <ng-template ngbNavContent>
           <cd-health></cd-health>
         </ng-template>
-      </li>
-      <li ngbNavItem>
+      </ng-container>
+      <ng-container ngbNavItem>
         <a ngbNavLink
            i18n>Statistics</a>
         <ng-template ngbNavContent>
         </ng-template>
-      </li>
+      </ng-container>
 
-    </ul>
+    </nav>
 
     <div [ngbNavOutlet]="nav"></div>
   </ng-container>
index 2a8b9453f3fa13e2ebfc5a1e3d309e7321479cfe..042c9f664580289483119159b82b8c1315e08ff5 100644 (file)
@@ -1,17 +1,17 @@
 <ng-container *ngIf="selection">
-  <ul ngbNav
-      #nav="ngbNav"
-      class="nav-tabs"
-      cdStatefulTab="nfs-details">
-    <li ngbNavItem="details">
+  <nav ngbNav
+       #nav="ngbNav"
+       class="nav-tabs"
+       cdStatefulTab="nfs-details">
+    <ng-container ngbNavItem="details">
       <a ngbNavLink
          i18n>Details</a>
       <ng-template ngbNavContent>
         <cd-table-key-value [data]="data">
         </cd-table-key-value>
       </ng-template>
-    </li>
-    <li ngbNavItem="clients">
+    </ng-container>
+    <ng-container ngbNavItem="clients">
       <a ngbNavLink
          i18n>Clients ({{ clients.length }})</a>
       <ng-template ngbNavContent>
@@ -25,8 +25,8 @@
                   selectionType="">
         </cd-table>
       </ng-template>
-    </li>
-  </ul>
+    </ng-container>
+  </nav>
 
   <div [ngbNavOutlet]="nav"></div>
 </ng-container>
index fcf5305393cba5a345a07bab57369e11bafb3d48..8e78c589a2c297f4cff37b847d9b5f21ba5f9a4b 100644 (file)
@@ -90,7 +90,7 @@ describe('NfsDetailsComponent', () => {
   });
 
   it('should have 1 client', () => {
-    expect(elem('ul.nav-tabs li:nth-of-type(2) a').nativeElement.textContent).toBe('Clients (1)');
+    expect(elem('nav.nav-tabs a:nth-of-type(2)').nativeElement.textContent).toBe('Clients (1)');
     expect(component.clients).toEqual([
       {
         access_type: 'RW',
index b9c197aefda2914382411f42518f3011f75a75e0..07823eedfffade17158a82c6759f08ecbee76cd6 100644 (file)
@@ -1,10 +1,10 @@
 <ng-container *ngIf="selection"
               cdTableDetail>
-  <ul ngbNav
-      #nav="ngbNav"
-      class="nav-tabs"
-      cdStatefulTab="pool-details">
-    <li ngbNavItem="details">
+  <nav ngbNav
+       #nav="ngbNav"
+       class="nav-tabs"
+       cdStatefulTab="pool-details">
+    <ng-container ngbNavItem="details">
       <a ngbNavLink
          i18n>Details</a>
       <ng-template ngbNavContent>
@@ -13,9 +13,9 @@
                             [autoReload]="false">
         </cd-table-key-value>
       </ng-template>
-    </li>
-    <li ngbNavItem="performance-details"
-        *ngIf="permissions.grafana.read">
+    </ng-container>
+    <ng-container ngbNavItem="performance-details"
+                  *ngIf="permissions.grafana.read">
       <a ngbNavLink
          i18n>Performance Details</a>
       <ng-template ngbNavContent>
                     grafanaStyle="three">
         </cd-grafana>
       </ng-template>
-    </li>
-    <li ngbNavItem="configuration"
-        *ngIf="selection.type === 'replicated'">
+    </ng-container>
+    <ng-container ngbNavItem="configuration"
+                  *ngIf="selection.type === 'replicated'">
       <a ngbNavLink
          i18n>Configuration</a>
       <ng-template ngbNavContent>
         <cd-rbd-configuration-table [data]="selectedPoolConfiguration"></cd-rbd-configuration-table>
       </ng-template>
-    </li>
-    <li ngbNavItem="cache-tiers-details"
-        *ngIf="selection['tiers']?.length > 0">
+    </ng-container>
+    <ng-container ngbNavItem="cache-tiers-details"
+                  *ngIf="selection['tiers']?.length > 0">
       <a ngbNavLink
          i18n>Cache Tiers Details</a>
       <ng-template ngbNavContent>
@@ -47,8 +47,8 @@
                   columnMode="flex">
         </cd-table>
       </ng-template>
-    </li>
-  </ul>
+    </ng-container>
+  </nav>
 
   <div [ngbNavOutlet]="nav"></div>
 </ng-container>
index 2df480edab26af314ef8bdcf3f11204304ead428..e12e36c6391bce5aaeced1b3098049d6ce63b847 100644 (file)
               <span class="form-text text-muted"
                     id="ecp-info-block"
                     *ngIf="data.erasureInfo && form.getValue('erasureProfile')">
-                <ul ngbNav
-                    #ecpInfoTabs="ngbNav"
-                    class="nav-tabs">
-                  <li ngbNavItem="ecp-info">
+                <nav ngbNav
+                     #ecpInfoTabs="ngbNav"
+                     class="nav-tabs">
+                  <ng-container ngbNavItem="ecp-info">
                     <a ngbNavLink
                        i18n>Profile</a>
                     <ng-template ngbNavContent>
                                           [autoReload]="false">
                       </cd-table-key-value>
                     </ng-template>
-                  </li>
-                  <li ngbNavItem="used-by-pools">
+                  </ng-container>
+                  <ng-container ngbNavItem="used-by-pools">
                     <a ngbNavLink
                        i18n>Used by pools</a>
                     <ng-template ngbNavContent>
                         </li>
                       </ul>
                     </ng-template>
-                  </li>
-                </ul>
+                  </ng-container>
+                </nav>
 
                 <div [ngbNavOutlet]="ecpInfoTabs"></div>
               </span>
                 <div class="form-text text-muted"
                      id="crush-info-block"
                      *ngIf="data.crushInfo && form.getValue('crushRule')">
-                  <ul ngbNav
-                      #crushInfoTabs="ngbNav"
-                      class="nav-tabs">
-                    <li ngbNavItem="crush-rule-info">
+                  <nav ngbNav
+                       #crushInfoTabs="ngbNav"
+                       class="nav-tabs">
+                    <ng-container ngbNavItem="crush-rule-info">
                       <a ngbNavLink
                          i18n>Crush rule</a>
                       <ng-template ngbNavContent>
                                             [autoReload]="false">
                         </cd-table-key-value>
                       </ng-template>
-                    </li>
-                    <li ngbNavItem="crush-rule-steps">
+                    </ng-container>
+                    <ng-container ngbNavItem="crush-rule-steps">
                       <a ngbNavLink
                          i18n>Crush steps</a>
                       <ng-template ngbNavContent>
                           </li>
                         </ol>
                       </ng-template>
-                    </li>
-                    <li ngbNavItem="used-by-pools">
+                    </ng-container>
+                    <ng-container ngbNavItem="used-by-pools">
                       <a ngbNavLink
                          i18n>Used by pools</a>
                       <ng-template ngbNavContent>
                           </li>
                         </ul>
                       </ng-template>
-                    </li>
-                  </ul>
+                    </ng-container>
+                  </nav>
 
                   <div [ngbNavOutlet]="crushInfoTabs"></div>
                 </div>
index 61af5c260b1eecd568352682fc2297c47db8c913..cfbcdaaf184aaa5810a96dcf3f7ea228cc83a802 100644 (file)
@@ -1,7 +1,7 @@
-<ul ngbNav
-    #nav="ngbNav"
-    class="nav-tabs">
-  <li ngbNavItem>
+<nav ngbNav
+     #nav="ngbNav"
+     class="nav-tabs">
+  <ng-container ngbNavItem>
     <a ngbNavLink
        i18n>Pools List</a>
     <ng-template ngbNavContent>
         </cd-pool-details>
       </cd-table>
     </ng-template>
-  </li>
+  </ng-container>
 
-  <li ngbNavItem
-      *cdScope="'grafana'">
+  <ng-container ngbNavItem
+                *cdScope="'grafana'">
     <a ngbNavLink
        i18n>Overall Performance</a>
     <ng-template ngbNavContent>
@@ -45,8 +45,8 @@
                   grafanaStyle="two">
       </cd-grafana>
     </ng-template>
-  </li>
-</ul>
+  </ng-container>
+</nav>
 
 <div [ngbNavOutlet]="nav"></div>
 
index 20b3f5ed8c5c613c80f44975987c68461da19982..868a803e46ce4e39fc9e9dfaf0621b3bbe66f264 100644 (file)
@@ -1,9 +1,9 @@
 <ng-container *ngIf="selection">
-  <ul ngbNav
-      #nav="ngbNav"
-      class="nav-tabs"
-      cdStatefulTab="rgw-daemon-details">
-    <li ngbNavItem="details">
+  <nav ngbNav
+       #nav="ngbNav"
+       class="nav-tabs"
+       cdStatefulTab="rgw-daemon-details">
+    <ng-container ngbNavItem="details">
       <a ngbNavLink
          i18n>Details</a>
       <ng-template ngbNavContent>
@@ -11,8 +11,8 @@
                             (fetchData)="getMetaData()">
         </cd-table-key-value>
       </ng-template>
-    </li>
-    <li ngbNavItem="performance-counters">
+    </ng-container>
+    <ng-container ngbNavItem="performance-counters">
       <a ngbNavLink
          i18n>Performance Counters</a>
       <ng-template ngbNavContent>
@@ -20,9 +20,9 @@
                                       [serviceId]="serviceMapId">
         </cd-table-performance-counter>
       </ng-template>
-    </li>
-    <li ngbNavItem="performance-details"
-        *ngIf="grafanaPermission.read">
+    </ng-container>
+    <ng-container ngbNavItem="performance-details"
+                  *ngIf="grafanaPermission.read">
       <a ngbNavLink
          i18n>Performance Details</a>
       <ng-template ngbNavContent>
@@ -34,8 +34,8 @@
                     grafanaStyle="one">
         </cd-grafana>
       </ng-template>
-    </li>
-  </ul>
+    </ng-container>
+  </nav>
 
   <div [ngbNavOutlet]="nav"></div>
 </ng-container>
index 88e82314f21c7cf1a1d192264bb5cd43be4c9445..fbd7d32633015ebe8342e63497ffce2ca729c516 100644 (file)
@@ -1,7 +1,7 @@
-<ul ngbNav
-    #nav="ngbNav"
-    class="nav-tabs">
-  <li ngbNavItem>
+<nav ngbNav
+     #nav="ngbNav"
+     class="nav-tabs">
+  <ng-container ngbNavItem>
     <a ngbNavLink
        i18n>Daemons List</a>
     <ng-template ngbNavContent>
         </cd-rgw-daemon-details>
       </cd-table>
     </ng-template>
-  </li>
+  </ng-container>
 
-  <li ngbNavItem
-      *ngIf="grafanaPermission.read">
+  <ng-container ngbNavItem
+                *ngIf="grafanaPermission.read">
     <a ngbNavLink
        i18n>Overall Performance</a>
     <ng-template ngbNavContent>
                   grafanaStyle="two">
       </cd-grafana>
     </ng-template>
-  </li>
+  </ng-container>
 
-  <li ngbNavItem
-      *ngIf="grafanaPermission.read && isMultiSite">
+  <ng-container ngbNavItem
+                *ngIf="grafanaPermission.read && isMultiSite">
     <a ngbNavLink
        i18n>Sync Performance</a>
     <ng-template ngbNavContent>
@@ -46,7 +46,7 @@
                   grafanaStyle="two">
       </cd-grafana>
     </ng-template>
-  </li>
-</ul>
+  </ng-container>
+</nav>
 
 <div [ngbNavOutlet]="nav"></div>
index 2283f4c546f053982c7def5fbd5d9937c9abc555..992a98ac83fc4ecb9ab0b205f99136998ef090d3 100644 (file)
@@ -1,9 +1,9 @@
 <ng-container *ngIf="selection">
-  <ul ngbNav
-      #nav="ngbNav"
-      class="nav-tabs"
-      cdStatefulTab="rgw-user-details">
-    <li ngbNavItem="details">
+  <nav ngbNav
+       #nav="ngbNav"
+       class="nav-tabs"
+       cdStatefulTab="rgw-user-details">
+    <ng-container ngbNavItem="details">
       <a ngbNavLink
          i18n>Details</a>
       <ng-template ngbNavContent>
           </div>
         </div>
       </ng-template>
-    </li>
-    <li ngbNavItem="keys"
-        *ngIf="keys.length">
+    </ng-container>
+    <ng-container ngbNavItem="keys"
+                  *ngIf="keys.length">
       <a ngbNavLink
          i18n>Keys</a>
       <ng-template ngbNavContent>
           </div>
         </cd-table>
       </ng-template>
-    </li>
-  </ul>
+    </ng-container>
+  </nav>
 
   <div [ngbNavOutlet]="nav"></div>
 </ng-container>
index 805d7558e3df7eed48fa9b1d2e631ea513180280..909f3e7ed6deb335e377ec6da3016e2a726d7ac3 100644 (file)
                     i18n>No SMART data available.</cd-alert-panel>
 
     <ng-container *ngIf="!(data | pipeFunction:isEmpty)">
-      <ul ngbNav
-          #nav="ngbNav"
-          class="nav-tabs">
-        <li ngbNavItem
-            *ngFor="let device of data | keyvalue">
+      <nav ngbNav
+           #nav="ngbNav"
+           class="nav-tabs">
+        <ng-container ngbNavItem
+                      *ngFor="let device of data | keyvalue">
           <a ngbNavLink>{{ device.value.device }} ({{ device.value.identifier }})</a>
           <ng-template ngbNavContent>
             <ng-container *ngIf="device.value.error; else noError">
@@ -55,9 +55,9 @@
             </ng-template>
 
             <ng-container *ngIf="!(device.value.info | pipeFunction:isEmpty) || !(device.value.smart | pipeFunction:isEmpty)">
-              <ul ngbNav
-                  #innerNav="ngbNav"
-                  class="nav-tabs">
+              <nav ngbNav
+                   #innerNav="ngbNav"
+                   class="nav-tabs">
                 <li [ngbNavItem]="1">
                   <a ngbNavLink
                      i18n>Device Information</a>
                                     i18n>No SMART data available for this device.</cd-alert-panel>
                   </ng-template>
                 </li>
-              </ul>
+              </nav>
 
               <div [ngbNavOutlet]="innerNav"></div>
             </ng-container>
           </ng-template>
-        </li>
-      </ul>
+        </ng-container>
+      </nav>
 
       <div [ngbNavOutlet]="nav"></div>
     </ng-container>
index 3c102cf6676c0a922e5435956cab53566801679c..1ab4e1743b39d67235ffe3f7458a32a794841c0d 100644 (file)
@@ -1,14 +1,18 @@
-<ul ngbNav
-    #nav="ngbNav"
-    [activeId]="router.url"
-    (navChange)="router.navigate([$event.nextId])"
-    class="nav-tabs">
-  <li ngbNavItem="/user-management/users">
-    <a ngbNavLink
+<ul class="nav nav-tabs">
+  <li class="nav-item">
+    <a class="nav-link"
+       routerLink="/user-management/users"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
+       [routerLinkActiveOptions]="{exact: true}"
        i18n>Users</a>
   </li>
-  <li ngbNavItem="/user-management/roles">
-    <a ngbNavLink
+  <li class="nav-item">
+    <a class="nav-link"
+       routerLink="/user-management/roles"
+       routerLinkActive="active"
+       ariaCurrentWhenActive="page"
+       [routerLinkActiveOptions]="{exact: true}"
        i18n>Roles</a>
   </li>
 </ul>
index 7a618f704fc1ee4ec7af0ead9f05b93e2cc0c8cb..8ee05900c3eb6d7f272a1b71ff00c4cf87e0f0b2 100644 (file)
@@ -141,3 +141,7 @@ mark {
     }
   }
 }
+
+a.nav-link {
+  color: vv.$primary-wcag-aa-large-text;
+}
index 574919d08ec268ebe51df706d7a60f705809799f..668cdfe0c17bd4f6919f8b31d85b196a61e7ef95 100644 (file)
@@ -4,7 +4,7 @@ import { AbstractControl } from '@angular/forms';
 import { By } from '@angular/platform-browser';
 import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
 
-import { NgbModal, NgbNav, NgbNavItem } from '@ng-bootstrap/ng-bootstrap';
+import { NgbModal, NgbNav, NgbNavItem, NgbNavLink } from '@ng-bootstrap/ng-bootstrap';
 import _ from 'lodash';
 import { configureTestSuite } from 'ng-bullet';
 import { of } from 'rxjs';
@@ -622,7 +622,7 @@ export class TabHelper {
 
   private static getNgbNavItemsDebugElems(fixture: ComponentFixture<any>) {
     const debugElem: DebugElement = fixture.debugElement;
-    return debugElem.queryAll(By.directive(NgbNavItem));
+    return debugElem.queryAll(By.directive(NgbNavLink));
   }
 }