]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: fix html lint errors according to new rules
authorNizamudeen A <nia@redhat.com>
Thu, 9 Jul 2026 07:52:58 +0000 (13:22 +0530)
committerNizamudeen A <nia@redhat.com>
Fri, 10 Jul 2026 10:50:48 +0000 (16:20 +0530)
mostly accessibility issues like

 - A label component must be associated with a form element
   Fixed by adding `for` to labels and sometimes replacing label with
legend

 - Elements with interaction handlers must be focusable
 - click must be accompanied by either keyup, keydown or keypress event for accessibility
 - <button> should have content

Fixes: https://tracker.ceph.com/issues/77112
Signed-off-by: Nizamudeen A <nia@redhat.com>
58 files changed:
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-gateway-group/nvmeof-gateway-group-delete-guard-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-group-form/nvmeof-group-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-namespaces-form/nvmeof-namespaces-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystem-overview/nvmeof-subsystem-overview.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems-form/nvmeof-subsystem-step-2/nvmeof-subsystem-step-2.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-auth-modal/cephfs-auth-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-mirroring-error/cephfs-mirroring-error.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-step-2/create-cluster-step-2.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-indiv-modal/osd-flags-indiv-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/upgrade/upgrade-progress/upgrade-progress.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/upgrade/upgrade.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/alerts-card/overview-alerts-card.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/health-card/overview-health-card.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/storage-card/overview-storage-card.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-multisite-zone-deletion-form/rgw-multisite-zone-deletion-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-multisite-zonegroup-deletion-form/rgw-multisite-zonegroup-deletion-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-wizard/rgw-multisite-wizard.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-zonegroup-form/rgw-multisite-zonegroup-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-storage-class-details/rgw-storage-class-details.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-topic-form/rgw-topic-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/auth/login-password-form/login-password-form.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/layouts/login-layout/login-layout.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notification-panel/notification-area/notification-area.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notification-panel/notification-header/notification-header.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/alert-panel/alert-panel.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/card-row/card-row.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/copy2clipboard-button/copy2clipboard-button.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/details-card/details-card.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/download-button/download-button.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/inline-message/inline-message.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/side-panel/side-panel.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/tearsheet/tearsheet.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/upgradable/upgradable.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/vertical-navigation/vertical-navigation.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-pagination/table-pagination.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html

index cbffd558b6c0261e30a864412db9892cbedba8af..694eeb3c64c0817e391fc053b89e6603074f4160 100644 (file)
                       i18n>No items added.</span>
 
                 <button (click)="addInitiator(); false"
-                        class="btn btn-light float-end">
+                        class="btn btn-light float-end"
+                        type="button">
                   <svg [cdsIcon]="icons.add"
                        [size]="icons.size16"
                        ></svg>
                       i18n>No items added.</span>
 
                 <button (click)="addGroup(); false"
-                        class="btn btn-light float-end">
+                        class="btn btn-light float-end"
+                        type="button">
                   <svg [cdsIcon]="icons.add"
                        [size]="icons.size16"
                        ></svg>
index 9614ac7505f0fdb35be91b0cf9f6c3f46f7179ef..f292bf624b16062b923fff748c07fff68097b24a 100644 (file)
@@ -55,6 +55,7 @@
         <div class="form-group row">
           <div class="col-sm-12">
             <label class="col-form-label"
+                   for="backstore"
                    i18n>Backstore</label>
             <select id="backstore"
                     name="backstore"
index 433265ed5441e301293f7ed226c077f84091bf64..4a231f214ff1f6f6d827d2a25129063a0122de71 100644 (file)
@@ -20,7 +20,9 @@
       @for (sub of connectedSubsystems; track sub.nqn) {
       <div class="cds--mb-04">
         <a class="cds--link cds--type-body-01"
-           (click)="navigateToSubsystem(sub.nqn)">
+           tabindex="0"
+           (click)="navigateToSubsystem(sub.nqn)"
+           (keydown.enter)="navigateToSubsystem(sub.nqn)">
           <span class="cds--mr-03">{{ sub.nqn }}</span>
           <cd-icon type="launch"></cd-icon>
         </a>
index 70dfb6453fba03bb22304307d74ff22a6e1fbbc9..7665b73915e9c65a8dda65f33601936b5bcccecd 100644 (file)
@@ -79,6 +79,7 @@
               <div cdsCol>
                 <div class="cds--stack cds--stack-horizontal">
                   <label class="cds--type-label-01"
+                         for="enableEncryption"
                          i18n>Enable encryption</label>
                   <cds-tag type="green"
                            size="sm"
             <div cdsRow class="form-item">
               <div cdsCol>
                 <div class="cds--stack cds--stack-horizontal cds-mb-3">
-                  <label class="cds--type-label-01" i18n>Enable Mutual TLS (mTLS)</label>
+                  <label class="cds--type-label-01" for="enableMtls" i18n>Enable Mutual TLS (mTLS)</label>
                 </div>
                 <cds-checkbox id="enableMtls" formControlName="enableMtls">
                   <span
             @if (groupForm.controls.enableMtls.value) {
             <div cdsRow class="form-item">
               <div cdsCol>
-                <label class="cds--label fw-bold"
+                <label class="cds--label fw-bold" for="certificateType"
                 i18n>Choose Certificate Authority</label>
                 <cds-radio-group
                   formControlName="certificateType"
index 77c6700f7243bb1ec312a12def934d121da6cd1c..54308a6c43e8ad260c7fe99c257f983163ae5915 100644 (file)
 
           <div class="form-item">
             <label
+              for="rbd_image_name"
               class="cds--type-label-01"
               i18n>Image name (optional)</label>
             <cds-text-label
index 922b0d0399080f689793077200962183d13320f5..d09dc0804b03deed64fc619bf56c261771e422b3 100644 (file)
@@ -33,7 +33,9 @@
               <a cdsLink
                  class="cds-ml-2"
                  (click)="openEditAuthModal()"
+                 (keydown.enter)="openEditAuthModal()"
                  [cdsStack]="'horizontal'"
+                 tabindex="0"
                  [gap]="1">
                 <span i18n>Edit</span>
                 <cd-icon type="edit"></cd-icon>
               <span>{{ detail.value ? 'Allow all hosts' : 'Restrict to specific hosts' }}</span>
               <a cdsLink
                  (click)="openEditHostAccessModal()"
+                 (keydown.enter)="openEditHostAccessModal()"
                  [cdsStack]="'horizontal'"
                  class="cds-ml-2"
+                 tabindex="0"
                  [gap]="1">
                 <span i18n>Edit</span>
                 <cd-icon type="edit"></cd-icon>
index b06f9548b764a0ff70c843124153178e9c36c907..773f192b50e672c45ad59ef6172daebab28a2bcc 100644 (file)
@@ -86,6 +86,7 @@
             [disabled]="host.isInvalid"
             size="md"
             class="cds-mt-3"
+            type="button"
             (click)="addHost()">
             <span i18n>Add</span>
             <cd-icon type="add"></cd-icon>
   <button
     i18n
     cdsButton="ghost"
+    type="button"
     (click)="removeAll($event)">
     Remove all
   </button>
index 6e704a0124f2d168de176e3e592051411940b9f0..85b830cf025dbe2239df0e33f63a5ddfb81c744e 100644 (file)
@@ -5,7 +5,9 @@
   <div *ngFor="let section of rbdConfigurationService.sections">
     <h5 class="cd-header">
       <legend (click)="toggleSectionVisibility(section.class)"
-              class="collapsible">
+              class="collapsible"
+              tabindex="0"
+              (keydown.enter)="toggleSectionVisibility(section.class)">
         {{ section.heading }}&nbsp;
         <svg [cdsIcon]="!sectionVisibility[section.class] ? icons.addCircle : icons.minusCircle"
              [size]="icons.size20"
index 8eb79386c8d95b96de37c22ab24e2c4909118ec2..6e1955c85080bf3c170b4a1ceabe0b922a10348a 100644 (file)
       <!-- Permissions -->
       <div class="form-item">
         <fieldset>
-          <label class="cds--label"
-                 i18n>Permissions</label>
+          <legend class="cds--label"
+                 i18n>Permissions</legend>
             <ng-container *ngFor="let permission of clientPermissions">
               <cds-checkbox i18n-label
                             [id]="permission.name"
index 314be40ce2958f47d7da78e98a149b4da6c8c85e..9acab5fde4f58d9c7c5ce63822d77ffbba1d3d68 100644 (file)
@@ -72,5 +72,7 @@
              let-row="data.row"
              let-value="data.value">
   <span class="quota-origin"
+        tabindex="0"
+        (keydown.enter)="selectOrigin(value)"
         (click)="selectOrigin(value)">{{value}}</span>
 </ng-template>
index 5141bb2460d60c717bec0c782d3e1b620e8f849d..d209a6cc9c0c44bf9e1c37cc1f231a44d5f9397d 100644 (file)
@@ -15,6 +15,7 @@
      i18n>Turn on CephFS Mirroring to start creating mirror links and synchronizing data across clusters. After enabling, you can add mirror links.</p>
   <button cdsButton="primary"
           (click)="enableModule()"
+          type="button"
           i18n>Enable CephFS Mirroring</button>
 </cds-tile>
 <div cdsGrid
index 4c802c8fd072e0ed8b01a371b03de609dfcac2a0..873814adacccfde8a1cfc8bc88c9c2e91cc2b89b 100644 (file)
           cdsRow
           class="form-item"
         >
-          <label
+          <legend
             class="cds--label"
             i18n
-          >Description</label>
+          >Description</legend>
           <p class="cds--type-body-01 mb-0">{{ response.long_desc }}</p>
         </div>
         }
             cdsCol
             [columnNumbers]="{ sm: 2, md: 2, lg: 2 }"
           >
-            <label
+            <legend
               class="cds--label mb-0"
               i18n
-            >Services</label>
+            >Services</legend>
           </div>
           <div
             cdsCol
index b95d40920865c1da81158d668a1e22480003b1fa..0b160412a79b3859bf62765dda28ffb979cdfcd1 100644 (file)
@@ -27,6 +27,7 @@
             id="skipStepBtn"
             (click)="onSkip()"
             aria-label="Skip this step"
+            type="button"
             i18n>Skip</button>
   </div>
 </div>
index 08dcae08f4fc19f410765b9cb535ff1198f6127a..7ade7992055c41fa4f1ffa3c1b2be29f10876465 100644 (file)
                 class="me-3"
                 (click)="createCluster()"
                 aria-label="Add Storage"
+                type="button"
                 i18n>
           Add storage
           <cd-icon
         <button cdsButton="tertiary"
                 (click)="skipClusterCreation()"
                 aria-label="View cluster overview"
+                type="button"
                 i18n>
           View cluster overview
           <cd-icon
index 9fed18accfbcd2671e6a29c5a79629e54ef48473..3af0f126eb3ca4b30497f570d2a3933df91117e3 100644 (file)
     </div>
 
     <div class="col-md-5">
-      <label i18n
-             class="fw-bold">Time range:</label>
+      <legend i18n
+             class="cds--label fw-bold">Time range:</legend>
       <div class="d-flex">
       <ngb-timepicker [spinners]="false"
                       [(ngModel)]="startTime"
index 97e27b280c44e81c8a931378edeea2d5172354f5..500ecc2c5f1984a6cd5d8f875adeb2d1ed1d2c24 100644 (file)
@@ -26,7 +26,8 @@
              *ngIf="managedByConfig['MANAGED_BY_CLUSTERS'].length === 0">
           <div class="text-center">
             <button class="btn btn-primary"
-                    (click)="openConnectClusterForm()">
+                    (click)="openConnectClusterForm()"
+                    type="button">
               <i class="mx-auto"
                  [ngClass]="icons.add">
               </i> Connect Cluster
index 69762c681978c5420ee0ca253fe2846bab628f2e..1bc4a90cb61cb8bc289529d3c2888ec3cf08772e 100644 (file)
     <cds-button-set>
       <button cdsButton="secondary"
               (click)="closeModal()"
+              type="button"
               i18n>
         Cancel
       </button>
       <button cdsButton="secondary"
               (click)="resetSelection()"
+              type="button"
               i18n>
         Reset
       </button>
index 7b3aa5a4eb8262666e286bcc27876837be0b00bf..d8981bd41ceb761c8c3b517ef76f1c405510f2a4 100644 (file)
@@ -41,6 +41,7 @@
     <cds-button-set>
       <button cdsButton="secondary"
               (click)="closeModal()"
+              type="button"
               i18n>
         Cancel
       </button>
index fa263672246a803cc4e834f2f2e5ffb96df75476..e2c1fc2a4c5540f835570cca2ce8d05c6e2488ca 100644 (file)
           <div class="col-sm-12">
             <a class="pull-right margin-right-md"
                (click)="advancedEnabled = true"
+               (keydown.enter)="advancedEnabled = true"
                *ngIf="!advancedEnabled"
-               i18n>Advanced...</a>
+               i18n
+               tabindex="0">Advanced...</a>
           </div>
         </div>
         <div *ngIf="advancedEnabled">
index b6e9374e006fe4a1671e4bc6fba2826ab2e44030..dad834e153702338a5a3e8c47be2a8501be5449a 100644 (file)
@@ -16,6 +16,8 @@
                       spacingClass="mb-3"
                       i18n>
         <a class="text-decoration-underline"
+           tabindex="0"
+           (keydown.enter)="createMultisiteSetup()"
            (click)="createMultisiteSetup()">
           Click here</a> to create a new Realm/Zonegroup/Zone
       </cd-alert-panel>
       <div class="form-item">
         <fieldset class="cds--fieldset">
           <label class="cds--label"
+                 for="enable_mtls"
                  i18n>Encryption</label>
           <cds-checkbox i18n-label
                         id="enable_mtls"
   <!-- Current Certificate Section - Only shown in Edit mode when certificate exists -->
   @if (editing && currentCertificate?.has_certificate) {
   <div class="form-item">
-    <label class="cds--label cds--type-heading-compact-01"
-           i18n>Current Certificate</label>
+    <legend class="cds--label cds--type-heading-compact-01"
+           i18n>Current Certificate</legend>
     <div class="row">
       <div class="col-6">
-        <label class="cds--label"
-               i18n>Certificate</label>
+        <legend class="cds--label"
+               i18n>Certificate</legend>
         <div>{{ currentCertificate.cert_name }}</div>
       </div>
       <div class="col-6">
-        <label class="cds--label"
-               i18n>Valid Until</label>
+        <legend class="cds--label"
+               i18n>Valid Until</legend>
         <div>{{ currentCertificate.expiry_date | cdDate }} â€¢ {{ currentCertificate.days_to_expiration }} <span i18n>days left</span></div>
       </div>
     </div>
     <div class="row mt-3">
       <div class="col-6">
-        <label class="cds--label"
-               i18n>Status</label>
+        <legend class="cds--label"
+               i18n>Status</legend>
         <div class="align-items-center">
           <cd-icon [type]="statusIconMap[currentCertificate.status] || statusIconMap['default']"></cd-icon>
           @switch (currentCertificate.status) {
         </div>
       </div>
       <div class="col-6">
-        <label class="cds--label"
-               i18n>Issuer</label>
+        <legend class="cds--label"
+               i18n>Issuer</legend>
         <div>
           @if (currentCertificate.signed_by === 'cephadm') {
           <span i18n>Internal (Cephadm CA)</span>
   <!-- Certificate Authority Selection -->
   <div class="form-item">
     <label class="cds--label cds--type-heading-compact-01"
+           for="certificateType"
            i18n>Choose Certificate Authority</label>
     <cds-radio-group formControlName="certificateType"
                      orientation="horizontal"
index 162d031aedea0e9cd123778152ddd164073a6b47..5df12a3f3076bc5315a4500cc765bab27f45913d 100644 (file)
       <button class="btn btn-light"
               aria-label="Go back"
               routerLink="/upgrade"
+              type="button"
               i18n>Back</button>
       <button *ngIf="upgradeStatus.in_progress && !upgradeStatus.is_paused"
               (click)="pauseUpgrade()"
               class="btn btn-light m-2"
               aria-label="Pause Upgrade"
+              type="button"
               i18n>Pause</button>
       <button *ngIf="upgradeStatus.in_progress && upgradeStatus.is_paused"
               (click)="resumeUpgrade()"
               class="btn btn-light m-2"
               aria-label="Resume Upgrade"
+              type="button"
               i18n>Resume</button>
       <button *ngIf="upgradeStatus.in_progress"
               (click)="stopUpgradeModal()"
               class="btn btn-danger"
               aria-label="Stop Upgrade"
+              type="button"
               i18n>Stop</button>
     </div>
   </ng-container>
index 33023c7755b1396304b5c47e487a66a27b6ae4f7..aa0377065387aaf172a8b52ff8c101c2b5a740b5 100644 (file)
                     aria-label="Upgrade now"
                     (click)="upgradeNow(info.versions[info.versions.length - 1])"
                     [disabled]="(healthData.mgr_map | mgrSummary)?.total <= 1"
+                    type="button"
                     i18n>Upgrade to {{ info.versions[info.versions.length - 1] }}</button>
           </div>
           <a class="cds--link cds-mb-3"
              (click)="startUpgradeModal()"
+             tabindex="0"
+             (keydown.enter)="startUpgradeModal()"
              i18n>Select another version...</a>
         </ng-container>
       </div>
   </span>
   <a class="cds--link cds-mb-3"
      (click)="startUpgradeModal()"
+     tabindex="0"
+     (keydown.enter)="startUpgradeModal()"
      i18n>Upgrade using custom image...</a>
 </ng-template>
 
             id="upgrade"
             aria-label="Upgrade now"
             [disabled]="true"
+            type="button"
             i18n>Checking for upgrades
       <cds-inline-loading></cds-inline-loading>
     </button>
     </span>
     <a class="cds--link cds-mb-3"
        (click)="startUpgradeModal()"
+       tabindex="0"
+       (keydown.enter)="startUpgradeModal()"
        i18n>Upgrade using custom image...</a>
   </div>
 </ng-template>
index af0faf512190b02ba418f5e20f811e8b315afa53..d7b89cd9d6929976246f23d229d258e31e2129af 100644 (file)
@@ -10,6 +10,7 @@
       cdsButton="ghost"
       size="sm"
       [routerLink]="['/monitoring/active-alerts']"
+      type="button"
       i18n
     >
       View all
index 0ecd3b5eb518aab6efc0905491826a8990d28709..421e21402683d0c89aff040bf0e388e1ba1644da 100644 (file)
           <button
             cdsButton="tertiary"
             size="sm"
+            type="button"
             (click)="onViewPGStatesClick()">
             <span
               i18n
index f3505da166badcea3186c778fbab504c42bfc8da..94f4f9b6b9b9848295a98f3d4333cd211b5167dd 100644 (file)
@@ -67,6 +67,7 @@
         i18n
         size="sm"
         [routerLink]="['/add-storage']"
+        type="button"
         >
         Add storage
         <cd-icon
index 58f64b0d8dab1e7bd044c94c53850b377297d6fa..84cc7ccc23cb4ddd049d96c4c2cafd0935629493 100644 (file)
     <section cdsModalContent>
       <form [formGroup]="zoneForm"
             novalidate>
-        <label class="cds--label-description"
+        <legend class="cds--label-description"
                i18n>
           This will delete your <strong>{{ zone?.name }}</strong> Zone.
-        </label>
+        </legend>
         @if (includedPools.size) {
-        <label class="cds--label-description"
+        <legend class="cds--label-description"
                i18n>
           Do you want to delete the associated pools with the
           <strong>{{ zone?.name }}</strong> Zone?
-        </label>
-        <label class="cds--label-description"
+        </legend>
+        <legend class="cds--label-description"
                i18n>
           This will delete the following pools and any data stored in these pools:
-        </label>
+        </legend>
 
         <div class="scroll-list">
           @for (pool of includedPools; track pool) {
index aabd7735315a21cecf8422b95d6caece198f1c4d..98ac65ddf6e6d591b0cfdcc424202dfa7be9b837 100644 (file)
       <form name="zonegroupForm"
             [formGroup]="zonegroupForm"
             novalidate>
-        <label class="cds--label-description"
+        <legend class="cds--label-description"
                i18n>
           This will delete your <strong>{{ zonegroup?.name }}</strong> Zonegroup.
-        </label>
+        </legend>
 
       @if (zonesList.length > 0) {
         <ng-container>
-          <label class="cds--label-description"
+          <legend class="cds--label-description"
                  i18n>
             Do you want to delete the associated zones and pools with the <strong>{{zonegroup?.name}}</strong> Zonegroup?
-          </label>
+          </legend>
 
           @if (includedPools.size > 0) {
             <ng-container>
-              <label class="cds--label-description"
+              <legend class="cds--label-description"
                      i18n>
                 This will delete the following:
-              </label>
+              </legend>
             </ng-container>
           }
 
index 0325a18c7a793174c5abcc2470a6fff2aa5159b2..5dc70c285c63ff56fb516e314cf07414747e69a2 100644 (file)
             <button cdsButton="tertiary"
                     id="add-tag"
                     [disabled]="tags.length > 19"
-                    (click)="showTagModal()">
+                    (click)="showTagModal()"
+                    type="button">
               <ng-container i18n>Add tag</ng-container>
               <svg [cdsIcon]="icons.add"
                    [size]="icons.size16"
               <button cdsButton="tertiary"
                       id="example-generator-button"
                       (click)="openUrl('https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html?icmpid=docs_amazons3_console')"
+                      type="button"
                       i18n>Policy examples
                 <svg [cdsIcon]="icons.launch"
                      [size]="icons.size16"
               <button cdsButton="tertiary"
                       id="example-generator-button"
                       (click)="openUrl('https://awspolicygen.s3.amazonaws.com/policygen.html')"
+                      type="button"
                       i18n>Policy generator
                 <svg [cdsIcon]="icons.launch"
                      [size]="icons.size16"
               <button cdsButton="tertiary"
                       id="clear-bucket-policy"
                       (click)="clearTextArea('bucket_policy', '{}')"
+                      type="button"
                       i18n>Clear
                 <svg [cdsIcon]="icons.destroy"
                      [size]="icons.size16"
               <button cdsButton="tertiary"
                       id="lifecycle-examples-button"
                       (click)="openUrl('https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-lifecycle.html#examples')"
+                      type="button"
                       i18n>Policy examples
                 <svg [cdsIcon]="icons.launch"
                      [size]="icons.size16"
               <button cdsButton="tertiary"
                       id="clear-lifecycle"
                       (click)="clearTextArea('lifecycle', '{}')"
+                      type="button"
                       i18n>Clear
                 <svg [cdsIcon]="icons.destroy"
                      [size]="icons.size16"
index dc11cfd1b82c6f3a86f069c6149f013f1dea62c6..94328d0bded6e77576d7848b4c018af97efe18c5 100644 (file)
             name="skip-cluster-selection"
             aria-label="Skip"
             (click)="onSkip()"
+            type="button"
             *ngIf="stepTitles[currentStep.stepIndex]['label'] === 'Select Cluster' && multisiteSetupForm.get('configType').value === 'newRealm'"
             i18n>Skip</button>
     <button cdsButton="secondary"
             (click)="onPreviousStep()"
             [attr.aria-label]="showCancelButtonLabel()"
+            type="button"
             i18n>{{ showCancelButtonLabel() }}</button>
     <button cdsButton="primary"
             (click)="onNextStep()"
             aria-label="Next"
             [disabled]="loading"
+            type="button"
             i18n>{{ showSubmitButtonLabel() }}
       <cds-loading [isActive]="loading"
                    [overlay]="false"
 
 <ng-template #newRealmInfo>
   <div class="form-group row">
-    <label class="cd-col-form-label"
-           i18n>Realm Name:</label>
+    <legend class="cd-col-form-label"
+           i18n>Realm Name:</legend>
     <div class="cd-col-form-input mt-2 text-muted"><b id="realmName">{{ multisiteSetupForm.get('realmName').value }}</b></div>
   </div>
   <div class="form-group row">
-    <label class="cd-col-form-label"
-           i18n>Zonegroup Name:</label>
+    <legend class="cd-col-form-label"
+           i18n>Zonegroup Name:</legend>
     <div class="cd-col-form-input mt-2 text-muted"><b id="zonegroupName">{{ multisiteSetupForm.get('zonegroupName').value }}</b></div>
   </div>
   <div class="form-group row">
-    <label class="cd-col-form-label"
-           i18n>Zonegroup Endpoints:</label>
+    <legend class="cd-col-form-label"
+           i18n>Zonegroup Endpoints:</legend>
     <div class="cd-col-form-input mt-2 text-muted"><b>{{ rgwEndpoints.value.join(', ') }}</b></div>
   </div>
   <div class="form-group row">
-    <label class="cd-col-form-label"
-           i18n>Zone Name:</label>
+    <legend class="cd-col-form-label"
+           i18n>Zone Name:</legend>
     <div class="cd-col-form-input mt-2 text-muted"><b id="zoneName">{{ multisiteSetupForm.get('zoneName').value }}</b></div>
   </div>
   <div class="form-group row">
-    <label class="cd-col-form-label"
-           i18n>Zone Endpoints:</label>
+    <legend class="cd-col-form-label"
+           i18n>Zone Endpoints:</legend>
     <div class="cd-col-form-input mt-2 text-muted"><b>{{ rgwEndpoints.value.join(', ') }}</b></div>
   </div>
   <div class="form-group row">
-    <label class="cd-col-form-label"
-           i18n>Username:</label>
+    <legend class="cd-col-form-label"
+           i18n>Username:</legend>
     <div class="cd-col-form-input mt-2 text-muted"><b>{{ multisiteSetupForm.get('username').value }}</b></div>
   </div>
 </ng-template>
 
 <ng-template #existingRealmInfo>
   <div class="form-group row">
-    <label class="cd-col-form-label"
-           i18n>Selected Realm:</label>
+    <legend class="cd-col-form-label"
+           i18n>Selected Realm:</legend>
     <div class="cd-col-form-input mt-2 text-muted"><b>{{ multisiteSetupForm.get('selectedRealm').value }}</b></div>
   </div>
 </ng-template>
 <ng-template #replicationInfo>
   <div *ngIf="isMultiClusterConfigured && !stepsToSkip['Select Cluster']">
     <div class="form-group row">
-      <label class="cd-col-form-label"
-             i18n>Selected Replication Cluster:</label>
+      <legend class="cd-col-form-label"
+             i18n>Selected Replication Cluster:</legend>
       <div class="cd-col-form-input mt-2 text-muted"><b>{{ selectedCluster }}</b></div>
     </div>
     <div class="form-group row">
-      <label class="cd-col-form-label"
-             i18n>Replication Zone Name:</label>
+      <legend class="cd-col-form-label"
+             i18n>Replication Zone Name:</legend>
       <div class="cd-col-form-input mt-2 text-muted"><b>{{ multisiteSetupForm.get('replicationZoneName').value }}</b></div>
     </div>
   </div>
index 85c8a6890672fc7fe2df9fa9a3da0fbaccec22b9..d5813693335728918371c7ecc13ec4d1b21a3793 100644 (file)
                 <span class="float-end clickable"
                       name="remove_placement_target"
                       (click)="removePlacementTarget(index)"
+                      tabindex="0"
+                      (keydown.enter)="removePlacementTarget(index)"
                       ngbTooltip="Remove">&times;</span>
               </div>
 
index 8f794c69222b34253ee6630e035d70ed6d932a00..04cef06411aff97c6adc69db0134b0975f626c19 100644 (file)
@@ -43,7 +43,9 @@
                 />
                 <button type="button"
                         class="btn btn-light"
-                        cdPasswordButton="access_key"></button>
+                        cdPasswordButton="access_key"
+                        aria-label="Toggle access key visibility"
+                        i18n-aria-label></button>
                 <cd-copy-2-clipboard-button source="access_key"> </cd-copy-2-clipboard-button>
               </div>
             </td>
index 115a408d5fa7d576b74fb11ddb52882d215733fd..7b6a51b86d5cb7ef90c01acbf2a7102669d24c23 100644 (file)
                   <button cdsButton="tertiary"
                           id="example-generator-button"
                           (click)="openUrl('https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html?icmpid=docs_amazons3_console')"
+                          type="button"
                           i18n>
                     Policy examples
                     <svg cdsIcon="launch"
                   </button>
                   <button cdsButton="tertiary"
                           id="example-generator-button"
+                          type="button"
                           (click)="openUrl('https://awspolicygen.s3.amazonaws.com/policygen.html')"
                           i18n>
                     Policy generator
                 <cds-button-set class="float-end mt-1">
                   <button cdsButton="tertiary"
                           id="clear-bucket-policy"
+                          type="button"
                           (click)="clearTextArea('policy', '{}')"
                           i18n>
                     Clear
index 4974611413728fadf9c0e76429afc737055703f6..f34e08c07a51a3856fadadfae4cda7a575e17b40 100755 (executable)
@@ -16,7 +16,8 @@
                autocomplete="new-password"
                autofocus>
         <button class="btn btn-outline-light btn-password"
-                cdPasswordButton="oldpassword">
+                cdPasswordButton="oldpassword"
+                type="button">
         </button>
       </div>
       <span class="invalid-feedback"
@@ -69,7 +70,8 @@
                id="confirmnewpassword"
                formControlName="confirmnewpassword">
         <button class="btn btn-outline-light btn-password"
-                cdPasswordButton="confirmnewpassword">
+                cdPasswordButton="confirmnewpassword"
+                type="button">
         </button>
       </div>
       <span class="invalid-feedback"
index 83626ab9d806f2423f985a01952a86cdfc1c9763..e0dcb07d542abaa1fa4e4be887d52530390b888c 100644 (file)
           <button class="btn btn-primary ms-1"
                   [routerLink]="buttonRoute"
                   *ngIf="!uiConfig; else configureButtonTpl"
+                  type="button"
                   i18n>{{ buttonName }}</button>
           <button class="btn btn-light ms-1"
                   [routerLink]="secondaryButtonRoute"
                   *ngIf="secondaryButtonName && secondaryButtonRoute"
+                  type="button"
                   i18n>{{ secondaryButtonName }}</button>
         </div>
       </div>
@@ -40,6 +42,7 @@
   <button class="btn btn-primary"
           (click)="doConfigure()"
           [attr.title]="buttonTitle"
+          type="button"
           *ngIf="uiConfig"
           i18n>{{ buttonName }}</button>
 </ng-template>
@@ -64,6 +67,7 @@
        *ngIf="!module_name; else enableButton">
     <button class="btn btn-primary"
             [routerLink]="'/overview'"
+            type="button"
             i18n>Go To Overview</button>
   </div>
 </ng-template>
@@ -73,6 +77,7 @@
        *ngIf="module_name && !(buttonName && buttonRoute)">
     <button class="btn btn-primary"
             (click)="enableModule()"
+            type="button"
             i18n>Enable {{ module_name | upperFirst }} module</button>
   </div>
 </ng-template>
index 1222fcc2ad5c3f9e0f5d6c2cb3b0bc52002f963c..bd92995be2d41a88ae32c4a9f22e28026af03ccf 100644 (file)
@@ -1,7 +1,6 @@
 <main class="login full-height">
   <header>
     <nav class="navbar p-4">
-      <a class="navbar-brand"></a>
       <div class="form-inline">
         <cd-language-selector></cd-language-selector>
       </div>
index dfca9e84c4000349654d76dd0c25962f6173a32d..5eac4142b6b04d211ee73bd36ad172adba5a1cdc 100644 (file)
@@ -4,12 +4,14 @@
   <li class="cds--overflow-menu-options__option mb-2">
     <button routerLink="/user-management"
             class="cds--overflow-menu-options__btn"
+            type="button"
             i18n>User management</button>
   </li>
   <li class="cds--overflow-menu-options__option mb-2"
       *ngIf="configOptPermission.read">
     <button routerLink="/telemetry"
             class="cds--overflow-menu-options__btn"
+            type="button"
             i18n>Telemetry configuration</button>
   </li>
 </cds-overflow-menu>
index 8b63e301aac1559fcfc2486ec49892a9aba2545d..c68c88d25c6d5c4e515f8ec400ba2321d2da9530 100644 (file)
@@ -11,6 +11,7 @@
     <button *ngIf="!sso"
             routerLink="/user-profile/edit"
             class="cds--overflow-menu-options__btn"
+            type="button"
             i18n>
     <svg cdsIcon="locked"
          class="me-2"
@@ -21,6 +22,7 @@
     <button (click)="logout()"
             data-testid="logout"
             class="cds--overflow-menu-options__btn"
+            type="button"
             i18n><svg cdsIcon="logout"
                       class="me-2"
                       size="16"></svg>Log out
index 003c48a82593580d455e212d23a467b66082c623..80726f4fe13eba65dbfa7ba56e6a1cd59d1144ac 100644 (file)
@@ -36,7 +36,9 @@
       </cds-header-navigation>
       <div class="cds--btn cds--btn--icon-only cds--header__action"
            data-testid="header-notification-icon"
-           (click)="onNotificationSelected($event)">
+           (click)="onNotificationSelected($event)"
+           tabindex="0"
+           (keydown.enter)="onNotificationSelected($event)">
         <cd-notifications></cd-notifications>
       </div>
       <div class="cds--btn cds--btn--icon-only cds--header__action">
index a8ac59e0d3c4112dda27c1da7c71ee766447239a..623cae5cc2b4a6f9ed4a0c8c42facae291453fac 100644 (file)
@@ -72,7 +72,8 @@
         cdsButton="ghost"
         size="sm"
         class="notification-close"
-        (click)="removeNotification(notification, $event)">
+        (click)="removeNotification(notification, $event)"
+        type="button">
         <cd-icon type="destroy"></cd-icon>
       </button>
     </div>
index 2906f9bba1c12de28ed81603535a1d1fc673dbd3..a7b765d9cd2dfa7a86d9f31f1e181f7c9b86a12f 100644 (file)
@@ -7,6 +7,7 @@
       class="notification-header__dismiss-btn"
       i18n
       cdsButton="ghost"
+      type="button"
       size="sm"
       (click)="onDismissAll()">
       Dismiss all
index 51b218769bb5484eac87c57d29d720a8328380c0..1ce838ceedaf05b51b1a18b4dcf49b86ed11e8d7 100644 (file)
@@ -14,6 +14,7 @@
           [title]="actionName"
           (click)="onAction()"
           *ngIf="actionName"
+          type="button"
           i18n>{{ actionName }}
   </button>
 </ng-template>
index f69c55c18dc94c199662f4b51e46aa6b30378edb..e4976d6f61e59a0f329ec2a2c2d34e9b89f07cce 100644 (file)
     </span>
     <span *ngIf="dropdownData && dropdownData.total.total.total > 0"
           class="position-absolute end-0 me-2">
-      <a (click)="toggleDropdown()"
-         class="dropdown-toggle"
-         [attr.aria-expanded]="dropdownToggled"
-         aria-controls="row-dropdwon"
-         role="button"></a>
+      <button type="button"
+          (click)="toggleDropdown()"
+          class="dropdown-toggle border-0 bg-transparent p-0"
+          [attr.aria-expanded]="dropdownToggled"
+          aria-controls="row-dropdown">
+        <span class="visually-hidden" i18n>Toggle dropdown</span>
+      </button>
     </span>
   </div>
 </li>
index 4046a4e2a21535097975f949b142787f1a71c3da..0bf81d9bf4c6e6999a010aa30477ab1f0833754d 100644 (file)
@@ -5,6 +5,7 @@
         [size]="size"
         description="Copy to Clipboard"
         i18n-description
+        type="button"
         (click)="onClick()">
   @if(text) {
   <span data-toggle="tooltip"
index b0d356e099b7bd671c8ea8592c8a59304a7a22f9..c3a784214b641b1b906adedee39cd856746fbc66 100644 (file)
@@ -13,7 +13,7 @@
       @for (detail of getVisibleDetails(); track detail.label) {
       <div [cdsStack]="'vertical'"
            [gap]="2">
-        <label class="cds--type-label-01">{{ detail.label }}</label>
+        <legend class="cds--type-label-01">{{ detail.label }}</legend>
         <div class="cds--type-body-01">
           @switch (detail.type) {
             @case ('status') {
index 43c1d2d6542bb3878d967f9f5d617fc2c3c9e66a..21ce6a76343eeae8ad8a2daa9d579b77533b55cb 100644 (file)
@@ -11,6 +11,7 @@
   <div ngbDropdownMenu>
     <button ngbDropdownItem
             (click)="download('json')"
+            type="button"
             *ngIf="objectItem">
       <svg [cdsIcon]="icons.code"
            size="16"
@@ -19,7 +20,8 @@
     </button>
     <button ngbDropdownItem
             (click)="download()"
-            *ngIf="textItem">
+            *ngIf="textItem"
+            type="button">
       <svg [cdsIcon]="icons.document"
            size="16"
            ></svg>
index cdb38fcf55531486d8d026518833388c0773f695..bb5b285602a56d918c016ad92def15eb1cd7879b 100644 (file)
@@ -21,6 +21,7 @@
         <button class="btn btn-light ms-3"
                 i18n-title
                 title="Reset Settings"
+                type="button"
                 (click)="reset()">
           <i [ngClass]="[icons.undo]"></i>
         </button>
@@ -29,6 +30,7 @@
         <button class="btn btn-light ms-3"
                 i18n-title
                 title="Show hidden information"
+                type="button"
                 (click)="showMessage = !showMessage">
           <i [ngClass]="[icons.infoCircle, icons.size24]"></i>
         </button>
index 57f368f2456542d09fd0cafbe5e25179f1ab017f..c9e5b3f2ad6f6f0123f9fa206a1705f4a9ce99ef 100644 (file)
@@ -30,7 +30,9 @@
       </div>
       <cds-popover-content>
         <div class="cds--popover-scroll-container"
-             (click)="$event.stopPropagation()">
+             (click)="$event.stopPropagation()"
+             tabindex="0"
+             (keydown.enter)="$event.stopPropagation()">
           <ng-container *ngTemplateOutlet="content"></ng-container>
         </div>
       </cds-popover-content>
index a6af7aace9bb8b3841f7928bc2ac7929576484ec..ee382632f2d7b26d654efd85350fc64ef467184b 100644 (file)
@@ -36,7 +36,8 @@
         <button class="inline-tip-bg-color btn-toggle"
                 cdsButton="ghost"
                 size="md"
-                (click)="toggleContent()">
+                (click)="toggleContent()"
+                type="button">
           <span i18n>{{ isTruncated ? 'Read more' : 'Read less' }}</span>
         </button>
       }
index 70519a36af4ed976d16c98aaff645320c60c5d46..cca8ffc57bde31e924341a12cc0064050a1aa211 100644 (file)
@@ -65,6 +65,7 @@
             <div class="card-body p-1">
               <button class="btn btn-link float-end mt-0 pt-0"
                       title="Remove notification"
+                      type="button"
                       i18n-title
                       (click)="remove(i); $event.stopPropagation()">
                 <svg [cdsIcon]="icons.trash"
@@ -74,6 +75,7 @@
               <button *ngIf="notification.application === 'Prometheus' && notification.type !== 2 && !notification.alertSilenced"
                       class="btn btn-link float-end text-muted mute m-0 p-0"
                       title="Silence Alert"
+                      type="button"
                       i18n-title
                       (click)="silence(notification)">
                 <svg [cdsIcon]="icons.mute"
@@ -83,6 +85,7 @@
               <button *ngIf="notification.application === 'Prometheus' && notification.type !== 2 && notification.alertSilenced"
                       class="btn btn-link float-end text-muted mute m-0 p-0"
                       title="Expire Silence"
+                      type="button"
                       i18n-title
                       (click)="expire(notification)">
                 <svg [cdsIcon]="icons.bell"
index 55b8e564c646e7d152a9a40017b90db51de32293..bef3e49b1ae4fbb6727494cb2a88155ef758f253 100644 (file)
@@ -16,7 +16,9 @@
   <cds-tag class="tag-dark me-2">
     <span class="me-2">{{ dataItem }}</span>
       <a  class="tags-remove"
-          (click)="cdSelect.removeItem(dataItem)">
+          (click)="cdSelect.removeItem(dataItem)"
+          tabindex="0"
+          (keydown.enter)="cdSelect.removeItem(dataItem)">
       <svg [cdsIcon]="icons.destroy"
            [size]="icons.size20"
            class="cds-white"></svg>
index 7d39e6f2d608ab855e02ad530871eb868fc35b06..e6580017b97b28ec57fa0e4ab03382aa9ba34b8a 100644 (file)
@@ -21,7 +21,9 @@
   <div *ngFor="let option of filteredOptions"
        class="select-menu-item"
        [ngClass]="{'help-block disabled': (data.length === selectionLimit || !option.enabled) && !option.selected}"
-       (click)="triggerSelection(option)">
+       (click)="triggerSelection(option)"
+       tabindex="0"
+       (keydown.enter)="triggerSelection(option)">
     <div class="select-menu-item-icon">
       <i [ngClass]="[icons.check]"
          aria-hidden="true"
@@ -40,7 +42,9 @@
   </div>
   <div *ngIf="isCreatable()"
        class="select-menu-item"
-       (click)="addCustomOption()">
+       (click)="addCustomOption()"
+       tabindex="0"
+       (keydown.enter)="addCustomOption()">
     <div class="select-menu-item-icon">
       <i [ngClass]="[icons.tag]"
          aria-hidden="true"></i>
index 0af5a25a4024a2078d4996344748b5c894ef08cf..a591e49fb7df249f97c89962a89be1286e3a530a 100644 (file)
@@ -1,5 +1,7 @@
 <div class="overlay"
      (click)="close()"
+     tabindex="0"
+     (keydown.enter)="close()"
      *ngIf="expanded && overlay"></div>
 
 <cds-panel [expanded]="expanded"
index c1bb0ac8c7ad9b272bde8c0d1e4e174ca9dc07ad..53f974c1109ba781954931e6dca908d0a44a80cc 100644 (file)
                   class="tearsheet-footer-cancel"
                   (click)="closeTearsheet()"
                   size="xl"
+                  type="button"
                   i18n>Cancel</button>
           @if (steps.length > 1) {
           <button cdsButton="secondary"
                   size="xl"
                   [disabled]="currentStep === 0"
                   (click)="onPrevious()"
+                  type="button"
                   i18n>Previous</button>
           }
           @if (currentStep === lastStep) {
@@ -64,6 +66,7 @@
                   class="tearsheet-footer-submit"
                   [disabled]="isSubmitLoading"
                   (click)="onSubmit()"
+                  type="button"
                   i18n>
             @if (isSubmitLoading) {
             <cds-loading
@@ -82,6 +85,7 @@
           <button cdsButton="primary"
                   size="xl"
                   [disabled]="steps[currentStep]?.invalid"
+                  type="button"
                   (click)="onNext()"
                   i18n>Next</button>
           }
         <button cdsButton="ghost"
                 (click)="closeTearsheet()"
                 size="xl"
+                type="button"
                 i18n>Cancel</button>
         @if (steps.length > 1) {
         <button cdsButton="secondary"
                 size="xl"
                 [disabled]="currentStep === 0"
                 (click)="onPrevious()"
+                type="button"
                 i18n>Previous</button>
         }
         @if (currentStep === lastStep) {
                 class="tearsheet-footer-submit"
                 [disabled]="isSubmitLoading"
                 (click)="onSubmit()"
+                type="button"
                 i18n>
           @if (isSubmitLoading) {
           <cds-loading
                 size="xl"
                 [disabled]="steps[currentStep]?.invalid"
                 (click)="onNext()"
+                type="button"
                 i18n>Next</button>
         }
       </cds-modal-footer>
index e356fbb5022e5a40c13f0d3e113eb0a5be80734c..4a4f0a06c33fd212b9de56fc2e9bf076b8cf4d92 100644 (file)
@@ -18,7 +18,9 @@
   <div *ngIf="upgradeInfo$ | async as info"
        i18n>
     <h5 *ngIf="info.versions.length > 0"
-        (click)="upgradeModal()">
+        (click)="upgradeModal()"
+        tabindex="0"
+        (keydown.enter)="upgradeModal()">
       <i [ngClass]="icons.up"></i>
       Upgrade available
     </h5>
index ae48d7fd7fcc9543910393e857f1c092592392a6..10695fbb01028ae87c479e89d181a698d16c22be 100644 (file)
         <a class="nav-link"
            [class.active]="!activeItem"
            (click)="selectItem()"
+           tabindex="0"
+           (keydown.enter)="selectItem()"
            *ngIf="item === ''">_nogroup</a>
         <a class="nav-link text-decoration-none text-break"
            [class.active]="item === activeItem"
            (click)="selectItem(item)"
+           tabindex="0"
+           (keydown.enter)="selectItem(item)"
            *ngIf="item !== ''">{{item}}</a>
       </li>
     </ul>
index a4e9f0c22b69a97583fcefbbbeca99d286b98299..1846c419b9d539c3963a2d0a9674615ee064a7b0 100644 (file)
@@ -19,7 +19,8 @@
             [attr.aria-label]="dropDownOnly"
             [offset]="{ x: -210, y: 65 }"
             [cdsOverflowMenu]="overflowMenuTpl"
-            data-testid="table-action-btn">
+            data-testid="table-action-btn"
+            type="button">
       <svg
            [cdsIcon]="icons.chevronDown"></svg>
     </button>
@@ -44,7 +45,8 @@
 
 <ng-template #caret>
   <button [cdsButton]="currentAction.buttonKind"
-          class="caret-btn">
+          class="caret-btn"
+          type="button">
     <svg class="cds--btn__icon"
          [cdsIcon]="icons.chevronDown"></svg>
   </button>
@@ -74,7 +76,8 @@
 </ng-template>
 
 <ng-template #customTrigger>
-  <button [cdsButton]="dropDownOnlyBtnColor">
+  <button [cdsButton]="dropDownOnlyBtnColor"
+          type="button">
     <span i18n>{{ dropDownOnly }}</span>
     <svg class="override-position-static cds--btn__icon"
          [cdsIcon]="icons.chevronDown"></svg>
index 3be5322f2b143dd152857d2b83187e57415e6091..30f7ebfa9ef75c7b5be7696801ccb31856cfc023 100644 (file)
@@ -7,6 +7,7 @@
     i18n-aria-label
     [disabled]="!canPrevious()"
     (click)="selectPage(1)"
+    type="button"
   >
     <cd-icon type="angleDoubleLeft"></cd-icon>
   </button>
@@ -15,6 +16,7 @@
     aria-label="Go to previous page"
     i18n-aria-label
     [disabled]="!canPrevious()"
+    type="button"
     (click)="prevPage()"
   >
     <cd-icon type="leftArrow"></cd-icon>
@@ -39,6 +41,7 @@
     i18n-aria-label
     (click)="nextPage()"
     [disabled]="!canNext()"
+    type="button"
   >
     <cd-icon type="rightArrow"></cd-icon>
   </button>
@@ -48,6 +51,7 @@
     i18n-aria-label
     [disabled]="!canNext()"
     (click)="selectPage(totalPages)"
+    type="button"
   >
     <cd-icon type="angleDoubleRight"></cd-icon>
   </button>
index 51485d12c04f6652d2feb7c03869b0522cdd6532..637da0ff771021ec9c5ee778e564696d0b21aaf2 100644 (file)
@@ -34,6 +34,7 @@
                 [preserveFragment]="action.preserveFragment ? '' : null"
                 [disabled]="tableActions.disableSelectionAction(action)"
                 [attr.aria-label]="action.name"
+                type="button"
                 i18n>
           {{ action.name }}
         </button>
                 <button
                   cdsButton="tertiary"
                   size="md"
+                  type="button"
                   (click)="addCustomFilter()">Add new filter rule +</button>
               </div>
             </div>
             <button cdsButton="secondary"
                     size="lg"
                     data-testid="clear-filters"
+                    type="button"
                     (click)="onClearFilters()">
               <ng-container i18n>Clear all</ng-container>
             </button>
                     size="lg"
                     data-testid="apply-filters"
                     [disabled]="isApplyFilterDisabled"
+                    type="button"
                     (click)="onSubmitFilter()">
               <ng-container i18n>Apply</ng-container>
             </button>
       <!-- show hide columns -->
       <button cdsButton="ghost"
               class="toolbar-action"
+              type="button"
               [cdsOverflowMenu]="showHideColumnsRef"
               placement="bottom"
               [flip]="true"
       <ng-template #showHideColumnsRef>
         <div class="vstack gap-3 p-3"
              (click)="$event.stopPropagation()"
+             tabindex="0"
+             (keydown.enter)="$event.stopPropagation()"
              [cdsTheme]="theme">
           <ng-container *ngFor="let column of localColumns">
             <cds-checkbox *ngIf="!column?.isInvisible"
           </cds-tooltip>
         }
         <button cdsButton="ghost"
-                (click)="onClearFilters($event)">
+                (click)="onClearFilters($event)"
+                type="button">
           <ng-container i18n>Clear filters</ng-container>
         </button>
       </div>