Improve LDAP accessibility

-Fixes accessibility issues for table sort buttons,
fieldset legend, checkboxes and radio buttons
-Fixes tabbing to checkboxes
-Stops tabbing to disabled sort buttons by adding ng-disabled
-Removes aria-hidden from modals

Tested: Verified no violations using DAP tool.

Signed-off-by: Dixsie Wolmers <dixsiew@gmail.com>
Signed-off-by: Derick Montague <derick.montague@ibm.com>
Change-Id: I9ad240d5ed151a362c0000fdab3ebf1f2997b226
diff --git a/app/access-control/controllers/ldap-controller.html b/app/access-control/controllers/ldap-controller.html
index 294dbb3..cfa929f 100644
--- a/app/access-control/controllers/ldap-controller.html
+++ b/app/access-control/controllers/ldap-controller.html
@@ -13,11 +13,11 @@
   </div>
   <div class="row column">
     <label class="control-check ldap__control-check">
-      <input type="checkbox" id="enable-ldap-checkbox"
-        ng-change="updateServiceEnabled(); ldap__configuration.$setUntouched()"
-        ng-model="ldapProperties.ServiceEnabled" />
+      <input type="checkbox" aria-labelledby="ldap-auth-label"
+      ng-change="updateServiceEnabled(); ldap__configuration.$setUntouched()"
+      ng-model="ldapProperties.ServiceEnabled" />
       <span class="control__indicator"></span>
-      <span class="control__label">
+      <span id="ldap-auth-label" class="control__label">
         <strong>Enable LDAP authentication</strong> <br>
         LDAP authentication must be enabled to modify role groups.
       </span>
@@ -27,13 +27,15 @@
     <form id="ldap__configuration" name="ldap__configuration" ng-class="{'submitted': submitted}"
       class="ldap__configuration" novalidate>
       <fieldset ng-disabled="!ldapProperties.ServiceEnabled">
+        <legend class="screen-reader-offscreen">LDAP Settings</legend>
         <div class="ldap__configure-settings row column">
           <div class="large-3 column ldap__ssl-column">
             <label class="control-check" ng-class="{'disabled' : certificates.length < 1}">
-              <input id="secure-ldap-ssl" type="checkbox" ng-model="ldapProperties.useSSL"
-                ng-checked="ldapProperties.useSSL" ng-disabled="certificates.length < 1" />
+              <input id="secure-ldap-ssl" aria-labelledby="use-ssl" type="checkbox"
+                ng-model="ldapProperties.useSSL" ng-checked="ldapProperties.useSSL"
+                ng-disabled="certificates.length < 1" />
               <span class="control__indicator"></span>
-              <span class="control__label">Secure LDAP using SSL</span>
+              <span class="control__label" id="use-ssl">Secure LDAP using SSL</span>
             </label>
             <div>
               <div class="ldap__certificate-info" ng-if="ldapProperties.ServiceEnabled">
@@ -53,14 +55,14 @@
             <div class="column service-type-column">
               <fieldset class="ldap__server-info-service-type">
                 <legend class="content-label">Service Type</legend>
-                <label class="control-radio control__radio__label" for="open-ldap">Open LDAP
+                <label class="control-radio control__radio__label">Open LDAP
                   <input type="radio" name="service_enabled_type" id="open-ldap" value="ldap"
                     ng-checked="ldapProperties.LDAPServiceEnabled"
                     ng-change="ldapProperties.EnabledServiceUpdated = true" ng-model="ldapProperties.EnabledServiceType"
                     required />
                   <span class="control__indicator control__indicator-on control__indicator-service-type"></span>
                 </label>
-                <label class="control-radio control__radio__label" for="active-directory">Active directory
+                <label class="control-radio control__radio__label">Active directory
                   <input type="radio" name="service_enabled_type" id="active-directory"
                     ng-change="ldapProperties.EnabledServiceUpdated = true" value="ad"
                     ng-checked="ldapProperties.ADServiceEnabled" ng-model="ldapProperties.EnabledServiceType"
@@ -126,7 +128,7 @@
                 class="ldap__optional-field" />
             </div>
             <div class="column ldap__configuration-buttons">
-              <button type="button" class="btn btn-primary" ng-disabled="!ldap__configuration.$valid"
+              <button type="submit" class="btn btn-primary" ng-disabled="!ldap__configuration.$valid"
                 ng-click="$parent.submitted=true; ldap__configuration.$valid && saveLdapSettings(); ldap__configuration.$setUntouched()">Save</button>
               <button type="button" class="btn btn-secondary"
                 ng-click="loadLdap(); ldap__configuration.$setUntouched()">Reset</button>
diff --git a/app/access-control/styles/ldap.scss b/app/access-control/styles/ldap.scss
index a18ac70..3a5d930 100644
--- a/app/access-control/styles/ldap.scss
+++ b/app/access-control/styles/ldap.scss
@@ -136,7 +136,7 @@
 
 .password-toggle.disabled {
   background: transparent;
-  color: $base-02--03;
+  color: $base-02--02;
   border: none;
 }
 
@@ -156,6 +156,10 @@
       color: $primary-light;
       font-weight: 700;
       padding: 0;
+
+      .control-check {
+        color: $primary-light;
+      }
     }
 
     .table__row-header.disabled {
diff --git a/app/common/directives/ldap-user-roles.html b/app/common/directives/ldap-user-roles.html
index 1f509b8..e250772 100644
--- a/app/common/directives/ldap-user-roles.html
+++ b/app/common/directives/ldap-user-roles.html
@@ -1,29 +1,60 @@
+<!-- Add & Remove Role Groups Buttons -->
 <div class="row column">
-  <button type="button" ng-class="{'disabled' : roleGroupType === '' }" ng-disabled="roleGroupType === ''"
-    class="btn btn-tertiary" ng-click="addGroupFn(); $parent.newGroup={}">
+  <button
+    type="button"
+    ng-class="{'disabled' : roleGroupType === '' }"
+    ng-disabled="roleGroupType === ''"
+    class="btn btn-tertiary"
+    ng-click="addGroupFn(); $parent.newGroup={}"
+  >
     <icon aria-hidden="true" file="icon-plus.svg"></icon>
     <span>Add role group</span>
   </button>
-  <button type="button" ng-disabled="roleGroupType === '' || !hasSelectedGroup" class="btn btn-tertiary"
-    ng-click="removeMultipleRoleGroupsFn() ">
+  <button
+    type="button"
+    ng-disabled="roleGroupType === '' || !hasSelectedGroup"
+    class="btn btn-tertiary"
+    ng-click="removeMultipleRoleGroupsFn() "
+  >
     <icon aria-hidden="true" file="icon-trashcan.svg"></icon>
     <span>Remove role groups</span>
   </button>
 </div>
+<!-- LDAP Role Groups Table -->
 <div class="ldap__table">
+  <!-- LDAP Role Groups Table Header -->
   <div class="table__row-header row column" ng-class="{'disabled' : !enabled }">
     <div class="row column">
       <div class="table__cell-select">
-        <label class="control-check" aria-label="select or deselect all groups">
-          <input type="checkbox" ng-disabled="!enabled || roleGroups.length < 1 " name="events__check"
-            ng-click="toggleAll()" ng-checked="roleGroupIsSelectedChanged()" ng-model="all" />
+        <label class="control-check">
+          <span class="screen-reader-offscreen" id="select-all-groups"
+            >select or deselect all groups</span
+          >
+          <input
+            type="checkbox"
+            aria-labelledby="select-all-groups"
+            ng-disabled="!enabled || roleGroups.length < 1 "
+            ng-click="toggleAll()"
+            ng-checked="roleGroupIsSelectedChanged()"
+            ng-model="all"
+          />
           <span class="control__indicator"></span>
         </label>
       </div>
       <div class="table__cell-sort">
         <div class="column small-2 sort_button_wrapper">
-          <button class="sort-ascending" ng-click="sortBy('RemoteGroup', false)"></button>
-          <button class="sort-descending" ng-click="sortBy('RemoteGroup', true)"></button>
+          <button
+            class="sort-ascending"
+            aria-label="sort group names in ascending order"
+            ng-click="sortBy('RemoteGroup', false)"
+            ng-disabled="!enabled || roleGroups.length < 1 "
+          ></button>
+          <button
+            class="sort-descending"
+            aria-label="sort group names in descending order"
+            ng-click="sortBy('RemoteGroup', true)"
+            ng-disabled="!enabled || roleGroups.length < 1 "
+          ></button>
         </div>
       </div>
       <div class="table__cell-ldap-group">
@@ -31,8 +62,18 @@
       </div>
       <div class="table__cell-sort">
         <div class="column small-2 sort_button_wrapper">
-          <button class="sort-ascending" ng-click="sortBy('LocalRole', false)"></button>
-          <button class="sort-descending" ng-click="sortBy('LocalRole', true)"></button>
+          <button
+            class="sort-ascending"
+            aria-label="sort group privileges in ascending order"
+            ng-click="sortBy('LocalRole', false)"
+            ng-disabled="!enabled || roleGroups.length < 1 "
+          ></button>
+          <button
+            class="sort-descending"
+            aria-label="sort group privileges in descending order"
+            ng-click="sortBy('LocalRole', true)"
+            ng-disabled="!enabled || roleGroups.length < 1 "
+          ></button>
         </div>
       </div>
       <div class="table__cell-ldap-role">
@@ -40,20 +81,33 @@
       </div>
     </div>
   </div>
+  <!-- LDAP Disabled Role Groups Table Row -->
   <div class="empty__logs" ng-if="roleGroups.length < 1 || !enabled">
-    <p ng-if="roleGroups.length < 1 && roleGroupType === 'ad' ||  roleGroupType === 'ldap'">
+    <p
+      ng-if="roleGroups.length < 1 && roleGroupType === 'ad' ||  roleGroupType === 'ldap'"
+    >
       No role groups have been created yet.
     </p>
     <p ng-if=" roleGroupType === '' " ng-class="{'disabled' : !enabled }">
       LDAP authentication must be enabled before creating role groups.
     </p>
   </div>
-  <div ng-repeat="group in roleGroups | orderBy:sortPropertyName:reverse track by $index ">
+  <div
+    ng-repeat="group in roleGroups | orderBy:sortPropertyName:reverse track by $index "
+  >
+    <!-- Enabled LDAP Role Groups Table Rows -->
     <div class="row column table__row-value" ng-if="enabled">
       <div class="table__cell-select select-header">
-        <label class="control-check" aria-label="select or deselect group">
-          <input type="checkbox" name="events__check" ng-model="group.isSelected"
-            ng-change="roleGroupIsSelectedChanged(); optionToggled()" />
+        <label class="control-check">
+          <span class="screen-reader-offscreen" id="select-group"
+            >select or deselect {{ group.RemoteGroup }}</span
+          >
+          <input
+            type="checkbox"
+            aria-labelledby="select-group"
+            ng-model="group.isSelected"
+            ng-change="roleGroupIsSelectedChanged(); optionToggled()"
+          />
           <span class="control__indicator"></span>
         </label>
       </div>
@@ -64,56 +118,100 @@
         {{ group.LocalRole }}
       </div>
       <div class="table__cell-buttons">
-        <button class="btn btn-tertiary" type="button" aria-label="edit selected role group"
-          ng-click="editGroupFn(group.RemoteGroup, group.LocalRole, $index); newGroup.RemoteGroup = group.RemoteGroup; newGroup.LocalRole = group.LocalRole; selectedGroupIndex = $index">
+        <button
+          class="btn btn-tertiary"
+          type="button"
+          aria-label="edit group {{ group.RemoteGroup }}"
+          ng-click="editGroupFn(group.RemoteGroup, group.LocalRole, $index); newGroup.RemoteGroup = group.RemoteGroup; newGroup.LocalRole = group.LocalRole; selectedGroupIndex = $index"
+        >
           <icon aria-hidden="true" file="icon-edit.svg"></icon>
         </button>
-        <button class="btn btn-tertiary" type="button" aria-label="delete selected role group"
+        <button
+          class="btn btn-tertiary"
+          type="button"
+          aria-label="delete group {{ group.RemoteGroup }}"
           ng-class="{'disabled' : roleGroups.length < 1}"
-          ng-click="removeGroupFn($index); newGroup.RemoteGroup = group.RemoteGroup; newGroup.LocalRole = group.LocalRole; selectedGroupIndex = $index">
+          ng-click="removeGroupFn($index); newGroup.RemoteGroup = group.RemoteGroup; newGroup.LocalRole = group.LocalRole; selectedGroupIndex = $index"
+        >
           <icon aria-hidden="true" file="icon-trashcan.svg"></icon>
         </button>
       </div>
     </div>
   </div>
 </div>
-<section class="modal" aria-hidden="true" role="dialog" ng-class="{'active': addGroup || editGroup}">
-  <h3 class="subhead">{{ addGroup ? "Add new role group" : "Edit group privilege" }}</h3>
+<!-- Add/Edit Role Group Modal -->
+<section
+  class="modal"
+  aria-labelledby="add-or-edit-group"
+  role="dialog"
+  ng-class="{'active': addGroup || editGroup}"
+>
+  <h3 id="add-or-edit-group" class="subhead">
+    {{ addGroup ? "Add new role group" : "Edit group privilege" }}
+  </h3>
   <div class="modal__content-ldap">
+    <!-- Add Role Group Modal Content -->
     <div ng-if="addGroup">
       <form name="add__group__form" id="add__group__form" novalidate>
         <div class="small-9">
           <label for="group_name">Role group name</label>
-          <input type="text" name="group_name" id="group_name" ng-model="newGroup.RemoteGroup" required />
-          <div ng-messages="add__group__form.group_name.$error" class="form-error"
-            ng-class="{'visible' : add__group__form.group_name.$touched}">
+          <input
+            type="text"
+            name="group_name"
+            id="group_name"
+            ng-model="newGroup.RemoteGroup"
+            required
+          />
+          <div
+            ng-messages="add__group__form.group_name.$error"
+            class="form-error"
+            ng-class="{'visible' : add__group__form.group_name.$touched}"
+          >
             <p ng-message="required">Field is required</p>
           </div>
         </div>
         <div class="small-9">
           <label for="group__role">Privilege</label>
-          <select id="group__role" class="select__group-role" name="group__role" ng-model="newGroup.LocalRole" required>
+          <select
+            id="group__role"
+            class="select__group-role"
+            name="group__role"
+            ng-model="newGroup.LocalRole"
+            required
+          >
             <option class="courier-bold" ng-value="">Select an option</option>
             <option class="courier-bold" ng-repeat="privilege in privileges">{{
               privilege
             }}</option>
           </select>
-          <div ng-messages="add__group__form.group__role.$error" class="form-error"
-            ng-class="{'visible' : add__group__form.group__role.$touched}">
+          <div
+            ng-messages="add__group__form.group__role.$error"
+            class="form-error"
+            ng-class="{'visible' : add__group__form.group__role.$touched}"
+          >
             <p ng-message="required">Field is required</p>
           </div>
         </div>
       </form>
       <div class="form-actions">
-        <button type="button" class="btn btn-primary" ng-class="{'disabled' : add__group__form.$invalid}"
-          ng-click="addRoleGroup(); $parent.addGroup=false; $parent.newGroup={}">
+        <button
+          type="button"
+          class="btn btn-primary"
+          ng-class="{'disabled' : add__group__form.$invalid}"
+          ng-click="addRoleGroup(); $parent.addGroup=false; $parent.newGroup={}"
+        >
           Save
         </button>
-        <button type="button" class="btn btn-secondary" ng-click="$parent.addGroup=false; $parent.newGroup={}">
+        <button
+          type="button"
+          class="btn btn-secondary"
+          ng-click="$parent.addGroup=false; $parent.newGroup={}"
+        >
           Cancel
         </button>
       </div>
     </div>
+    <!-- Edit Role Group Modal Content -->
     <div ng-if="editGroup">
       <form name="edit__group__form" id="edit__group__form" novalidate>
         <label>Role group name</label>
@@ -122,64 +220,109 @@
         </div>
         <div class="small-9">
           <label for="group__role__edit">Privilege</label>
-          <select id="group__role__edit" name="group__role__edit" ng-model="newGroup.LocalRole" required>
+          <select
+            id="group__role__edit"
+            name="group__role__edit"
+            ng-model="newGroup.LocalRole"
+            required
+          >
             <option class="courier-bold" ng-repeat="privilege in privileges">{{
               privilege
             }}</option>
           </select>
-          <div ng-messages="edit__group__form.group__role__edit.$error" class="form-error"
-            ng-class="{'visible' : edit__group__form.group__role__edit.$touched}">
+          <div
+            ng-messages="edit__group__form.group__role__edit.$error"
+            class="form-error"
+            ng-class="{'visible' : edit__group__form.group__role__edit.$touched}"
+          >
             <p ng-message="required">Field is required</p>
           </div>
         </div>
       </form>
       <div class="form-actions">
-        <button type="button" class="btn btn-primary"
-          ng-click="editRoleGroup();$parent.editGroup=false; $parent.newGroup={}">
+        <button
+          type="button"
+          class="btn btn-primary"
+          ng-click="editRoleGroup();$parent.editGroup=false; $parent.newGroup={}"
+        >
           Save
         </button>
-        <button type="button" class="btn btn-secondary" ng-click="$parent.editGroup=false; $parent.newGroup={}">
+        <button
+          type="button"
+          class="btn btn-secondary"
+          ng-click="$parent.editGroup=false; $parent.newGroup={}"
+        >
           Cancel
         </button>
       </div>
     </div>
   </div>
 </section>
-<section class="modal" aria-hidden="true" role="dialog" ng-class="{'active': removeGroup}">
-  <h3 class="subhead">Remove role group</h3>
+<!-- Remove Role Groups Modal -->
+<section
+  class="modal"
+  role="dialog"
+  aria-labelledby="remove-role-group"
+  ng-class="{'active': removeGroup}"
+>
+  <h3 id="remove-role-group" class="subhead">Remove role group</h3>
   <div class="modal__content-ldap">
     <p>Are you sure you want to remove "{{ newGroup.RemoteGroup }}"?</p>
   </div>
   <div class="form-actions">
-    <button type="button" class="btn btn-primary" ng-click="removeRoleGroup(); $parent.removeGroup=false; newGroup={}">
+    <button
+      type="button"
+      class="btn btn-primary"
+      ng-click="removeRoleGroup(); $parent.removeGroup=false; newGroup={}"
+    >
       Remove
     </button>
-    <button type="button" class="btn btn-secondary"
-      ng-click="removeGroup=false; $parent.removeGroup=false; newGroup={}">
+    <button
+      type="button"
+      class="btn btn-secondary"
+      ng-click="removeGroup=false; $parent.removeGroup=false; newGroup={}"
+    >
       Cancel
     </button>
   </div>
 </section>
-<section class="modal" aria-hidden="true" role="dialog" ng-class="{'active': removeMultipleGroups}">
+<!-- Remove Multiple Role Groups Modal -->
+<section
+  class="modal"
+  role="dialog"
+  ng-class="{'active': removeMultipleGroups}"
+>
   <div class="page-header">
     <h3>Remove role group</h3>
   </div>
   <div class="modal__content-ldap">
     <p>
       Are you sure you want to remove
-      <span ng-repeat="groups in roleGroups | filter:{isSelected:true}">{{ $last && !$first ? " and " : $first ? "" : ", "
-        }}{{ "'" + groups.RemoteGroup + "'" }}?</span>
+      <span ng-repeat="groups in roleGroups | filter:{isSelected:true}"
+        >{{ $last && !$first ? " and " : $first ? "" : ", "
+        }}{{ "'" + groups.RemoteGroup + "'" }}?</span
+      >
     </p>
   </div>
   <div class="form-actions">
-    <button type="button" class="btn btn-primary"
-      ng-click="removeMultipleRoleGroups();$parent.removeMultipleGroups=false; $parent.newGroup={}">
+    <button
+      type="button"
+      class="btn btn-primary"
+      ng-click="removeMultipleRoleGroups();$parent.removeMultipleGroups=false; $parent.newGroup={}"
+    >
       Remove
     </button>
-    <button type="button" class="btn btn-secondary" ng-click="removeMultipleGroups = false">
+    <button
+      type="button"
+      class="btn btn-secondary"
+      ng-click="removeMultipleGroups = false"
+    >
       Cancel
     </button>
   </div>
 </section>
-<div class="modal-overlay" tabindex="-1"
-  ng-class="{'active': addGroup || editGroup || removeGroup || removeMultipleGroups}"></div>
\ No newline at end of file
+<div
+  class="modal-overlay"
+  tabindex="-1"
+  ng-class="{'active': addGroup || editGroup || removeGroup || removeMultipleGroups}"
+></div>
diff --git a/app/common/directives/ldap-user-roles.js b/app/common/directives/ldap-user-roles.js
index 4e83606..afe30c5 100644
--- a/app/common/directives/ldap-user-roles.js
+++ b/app/common/directives/ldap-user-roles.js
@@ -194,7 +194,7 @@
                   .then(
                       (response) => {
                         toastService.success(
-                            'Groups has been removed successfully.');
+                            'Groups have been removed successfully.');
                       },
                       (error) => {
                         toastService.error('Failed to remove groups.');
diff --git a/app/common/styles/components/form-elements.scss b/app/common/styles/components/form-elements.scss
index 8ee6e66..a25242b 100644
--- a/app/common/styles/components/form-elements.scss
+++ b/app/common/styles/components/form-elements.scss
@@ -143,8 +143,6 @@
 /* Check mark */
 .control__indicator:after,
 .control-check input:not(:checked){
-  position: absolute;
-  display: none;
   content: '';
 }