Move filter control into table header row
authorStephanie Leary <stephanie.leary@equinoxoli.org>
Fri, 24 Mar 2023 20:10:15 +0000 (20:10 +0000)
committerStephanie Leary <stephanie.leary@equinoxoli.org>
Fri, 24 Mar 2023 20:10:15 +0000 (20:10 +0000)
Signed-off-by: Stephanie Leary <stephanie.leary@equinoxoli.org>
Open-ILS/src/eg2/src/app/share/grid/grid-filter-control.component.html
Open-ILS/src/eg2/src/app/share/grid/grid-header.component.html
Open-ILS/src/eg2/src/app/share/grid/grid.component.css

index 0d117d2..28594c0 100644 (file)
@@ -1,12 +1,13 @@
 
 <!-- drop-down toggle link -->
 <ng-template #dropdownToggle>
-  <span i18n>Filter</span>
   <ng-container *ngIf="!col.isFiltered">
-    <span class="material-icons mat-icon-in-button">filter_alt</span>
+    <span id="filter_toggle_{{col.name}}" i18n hidden>Filter by {{col.name}}</span>
+    <span class="material-icons mat-icon-in-button" attr.aria-hidden="true" title="Filter by {{col.name}}" i18n-title>filter_alt</span>
   </ng-container>
   <ng-container *ngIf="col.isFiltered">
-    <span class="material-icons mat-icon-in-button">create</span>
+    <span id="filter_toggle_{{col.name}}" i18n hidden>Edit {{col.name}} filter</span>
+    <span class="material-icons mat-icon-in-button" attr.aria-hidden="true" title="Edit {{col.name}} filter" i18n-title>create</span>
   </ng-container>
 </ng-template>
 
   </select>
 </ng-template>
 
-<tr *ngIf="col.isFilterable" class="eg-grid-filter-control">
-  <th [ngSwitch]="col.datatype">
-    <div *ngSwitchCase="'link'">
-      <div class="input-group">
-        <div ngbDropdown container="body" class="d-inline-block p-1" [autoClose]="false" placement="bottom-left" 
+
+  <ng-container *ngIf="col.isFilterable" [ngSwitch]="col.datatype">
+    <div *ngSwitchCase="'link'" class="eg-grid-filter-control">
+      
+        <div ngbDropdown container="body"  [autoClose]="false" placement="bottom-left" 
           [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
-          <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
+          <button ngbDropdownToggle class="btn no-dropdown-caret ps-1" attr.aria-labelledby="filter_toggle_{{col.name}}">
             <ng-container *ngTemplateOutlet="dropdownToggle"></ng-container>
-          </a>
+          </button>
           <div ngbDropdownMenu class="eg-grid-filter-menu">
             <div class="dropdown-item">
               <div>
             </div>
           </div>
         </div>
-      </div>
+      
     </div>
-    <div *ngSwitchCase="'bool'">
-      <div class="input-group">
-        <div ngbDropdown container="body" class="d-inline-block p-1" autoClose="outside" placement="bottom-left" 
+    <div *ngSwitchCase="'bool'" class="eg-grid-filter-control">
+      
+        <div ngbDropdown container="body"  autoClose="outside" placement="bottom-left" 
           [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
-          <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
+          <button ngbDropdownToggle class="btn no-dropdown-caret ps-1" attr.aria-labelledby="filter_toggle_{{col.name}}">
             <ng-container *ngTemplateOutlet="dropdownToggle"></ng-container>
-          </a>
+          </button>
           <div ngbDropdownMenu class="eg-grid-filter-menu">
             <div class="dropdown-item">
               <div>
             </div>
           </div>
         </div>
-      </div>
+      
     </div>
-    <div *ngSwitchCase="'text'">
-      <div class="input-group">
-        <div ngbDropdown container="body" class="d-inline-block p-1" autoClose="outside" placement="bottom-left" 
+    <div *ngSwitchCase="'text'" class="eg-grid-filter-control">
+      
+        <div ngbDropdown container="body"  autoClose="outside" placement="bottom-left" 
           [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
-          <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
+          <button ngbDropdownToggle class="btn no-dropdown-caret ps-1" attr.aria-labelledby="filter_toggle_{{col.name}}">
             <ng-container *ngTemplateOutlet="dropdownToggle"></ng-container>
-          </a>
+          </button>
           <div ngbDropdownMenu class="eg-grid-filter-menu">
             <div class="dropdown-item">
               <div>
             </div>
           </div>
         </div>
-      </div>
+      
     </div>
-    <div *ngSwitchCase="'int'">
-      <div class="input-group">
-        <div ngbDropdown container="body" class="d-inline-block p-1" autoClose="outside" placement="bottom-left" 
+    <div *ngSwitchCase="'int'" class="eg-grid-filter-control">
+      
+        <div ngbDropdown container="body"  autoClose="outside" placement="bottom-left" 
           [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
-          <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
+          <button ngbDropdownToggle class="btn no-dropdown-caret ps-1" attr.aria-labelledby="filter_toggle_{{col.name}}">
             <ng-container *ngTemplateOutlet="dropdownToggle"></ng-container>
-          </a>
+          </button>
           <div ngbDropdownMenu class="eg-grid-filter-menu">
             <div class="dropdown-item">
               <div>
             </div>
           </div>
         </div>
-      </div>
+      
     </div>
-    <div *ngSwitchCase="'id'">
-      <div class="input-group">
-        <div ngbDropdown container="body" class="d-inline-block p-1" autoClose="outside" placement="bottom-left" 
+    <div *ngSwitchCase="'id'" class="eg-grid-filter-control">
+      
+        <div ngbDropdown container="body"  autoClose="outside" placement="bottom-left" 
           [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
-          <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
+          <button ngbDropdownToggle class="btn no-dropdown-caret ps-1" attr.aria-labelledby="filter_toggle_{{col.name}}">
             <ng-container *ngTemplateOutlet="dropdownToggle"></ng-container>
-          </a>
+          </button>
           <div ngbDropdownMenu class="eg-grid-filter-menu">
             <div class="dropdown-item">
               <div>
             </div>
           </div>
         </div>
-      </div>
+      
     </div>
-    <div *ngSwitchCase="'float'">
-      <div class="input-group">
-        <div ngbDropdown container="body" class="d-inline-block p-1" autoClose="outside" placement="bottom-left" 
+    <div *ngSwitchCase="'float'" class="eg-grid-filter-control">
+      
+        <div ngbDropdown container="body"  autoClose="outside" placement="bottom-left" 
           [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
-          <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
+          <button ngbDropdownToggle class="btn no-dropdown-caret ps-1" attr.aria-labelledby="filter_toggle_{{col.name}}">
             <ng-container *ngTemplateOutlet="dropdownToggle"></ng-container>
-          </a>
+          </button>
           <div ngbDropdownMenu class="eg-grid-filter-menu">
             <div class="dropdown-item">
               <div>
             </div>
           </div>
         </div>
-      </div>
+      
     </div>
-    <div *ngSwitchCase="'money'">
-      <div class="input-group">
-        <div ngbDropdown container="body" class="d-inline-block p-1" autoClose="outside" placement="bottom-left" 
+    <div *ngSwitchCase="'money'" class="eg-grid-filter-control">
+      
+        <div ngbDropdown container="body"  autoClose="outside" placement="bottom-left" 
           [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
-          <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
+          <button ngbDropdownToggle class="btn no-dropdown-caret ps-1" attr.aria-labelledby="filter_toggle_{{col.name}}">
             <ng-container *ngTemplateOutlet="dropdownToggle"></ng-container>
-          </a>
+          </button>
           <div ngbDropdownMenu class="eg-grid-filter-menu">
             <div class="dropdown-item">
               <div>
             </div>
          </div>
         </div>
-      </div>
+      
     </div>
-    <div *ngSwitchCase="'timestamp'">
-      <div class="input-group">
+    <div *ngSwitchCase="'timestamp'" class="eg-grid-filter-control">
+      
         <!-- [autoClose]="false" because editing the date widgets, which open
              their open popups, registers to the dropdown as clicking 
              outside the dropdown -->
-        <div ngbDropdown container="body" class="d-inline-block p-1" [autoClose]="false" placement="bottom-left" 
+        <div ngbDropdown container="body"  [autoClose]="false" placement="bottom-left" 
           [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
-          <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
+          <button ngbDropdownToggle class="btn no-dropdown-caret ps-1" attr.aria-labelledby="filter_toggle_{{col.name}}">
             <ng-container *ngTemplateOutlet="dropdownToggle"></ng-container>
-          </a>
+          </button>
           <div ngbDropdownMenu class="eg-grid-filter-menu">
             <div class="dropdown-item">
               <div>
             </div>
           </div>
         </div>
-      </div>
+      
     </div>
-    <div *ngSwitchCase="'org_unit'">
-      <div class="input-group">
-        <div ngbDropdown container="body" class="d-inline-block p-1" [autoClose]="false" placement="bottom-left" 
+    <div *ngSwitchCase="'org_unit'" class="eg-grid-filter-control">
+      
+        <div ngbDropdown container="body"  [autoClose]="false" placement="bottom-left" 
           [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
-          <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
+          <button ngbDropdownToggle class="btn no-dropdown-caret ps-1" attr.aria-labelledby="filter_toggle_{{col.name}}">
             <ng-container *ngTemplateOutlet="dropdownToggle"></ng-container>
-          </a>
+          </button>
           <div ngbDropdownMenu class="eg-grid-filter-menu">
             <div class="dropdown-item">
               <div>
             </div>
           </div>
         </div>
-      </div>
+      
     </div>
-    <div *ngSwitchCase="'interval'">
+    <div *ngSwitchCase="'interval'" class="eg-grid-filter-control">
       <!-- this is a short-term fix to prevent *ngSwitchDefault from displaying -->
     </div>
     <div *ngSwitchDefault>I don't know how to filter {{col.name}} - {{col.datatype}}</div>
-  </th>
+  </ng-container>
   <!--
   <span *ngIf="col.datatype !== 'org_unit'" class="eg-grid-filter-operator"><ng-container i18n>Operator:</ng-container>
     <span [ngSwitch]="col.filterOperator">
     </span>
   </span>
   -->
-</tr>
+
index 120386f..c603367 100644 (file)
     [ngClass]="{'dragover' : col.isDragTarget}"
     [attr.aria-sort]="ariaSortDirection(col)"
     class="eg-grid-cell eg-grid-header-cell {{context.setClassNames(row, col)}}">
-    <a class="sortable label-with-material-icon" *ngIf="col.isSortable"
+    <button class="sortable btn d-inline p-0" *ngIf="col.isSortable"
       (click)="sortOneColumn(col)">
-      <span class="eg-grid-header-cell-sort-label">{{col.headerLabel}}</span>
+      <span class="eg-grid-header-cell-sort-label" title="Sort by {{col.headerLabel}}" i18n-title>{{col.headerLabel}}</span>
       <span class="material-icons eg-grid-header-cell-sort-arrow"
         *ngIf="isColumnSorting(col, 'ASC')">arrow_upwards</span>
       <span class="material-icons eg-grid-header-cell-sort-arrow"
         *ngIf="isColumnSorting(col, 'DESC')">arrow_downwards</span>
-    </a>
+    </button>
     <span *ngIf="!col.isSortable">{{col.headerLabel}}</span>
-  </th>
-</tr>
-<tr *ngIf="context.isFilterable" role="row"
-  class="eg-grid-row eg-grid-filter-controls-row">
-  <ng-container *ngIf="!context.disableSelect">
-    <td class="eg-grid-cell eg-grid-header-cell" role="cell"></td>
-  </ng-container>
-  <th scope="col" role="columnheader" class="eg-grid-cell eg-grid-header-cell"></th>
-  <th *ngIf="context.rowFlairIsEnabled" scope="col" role="columnheader"
-    class="eg-grid-cell eg-grid-header-cell {{context.setClassNames(row, col)}}"></th>
 
-  <th *ngFor="let col of context.columnSet.displayColumns()" scope="col" role="columnheader"
-    class="eg-grid-cell eg-grid-filter-control-cell {{context.setClassNames(row, col)}}">
-    <eg-grid-filter-control [context]="context" [col]="col"></eg-grid-filter-control>
+    <ng-container *ngIf="context.isFilterable">
+      <eg-grid-filter-control [context]="context" [col]="col"></eg-grid-filter-control>
+    </ng-container>
   </th>
-</tr>
+</tr>
\ No newline at end of file
index 61702de..a82b443 100644 (file)
@@ -73,6 +73,12 @@ table.table.eg-grid {
   white-space: normal;
 }
 
+.eg-grid-header-cell .btn.sortable {
+  color: #255a88;
+  font-weight: 600;
+  text-align: left;
+}
+
 .eg-grid-header-cell[draggable=true] {
   cursor: grab;
 }
@@ -128,9 +134,22 @@ table.table.eg-grid {
   box-shadow: none;
 }
 
-.eg-grid-filter-control-cell {
-  white-space: normal;
+.eg-grid-filter-control,
+.eg-grid-filter-control .dropdown {
+  display: inline;
+}
+
+.eg-grid-filter-control .material-icons {
+  font-size: 18px;
 }
+
+.eg-grid-filter-control .dropdown-toggle.btn {
+  border-width: 0;
+  color: #255a88; /* match link color */
+  line-height: 1;
+  padding: 0;
+}
+
 .eg-grid-col-is-filtered {
   background: lightblue;
 }