Fix Bulk Access Management usability issues

- Added aria-labels to trash & select bitstream icon
- Added aria-labels ui-switch components (had to upgrade ngx-ui-switch to 14.1.0)
- Fixed aria-controls pointing to non-existing ids
- Fixed bulk-access-browse not having the tab role on it's tabs
- Fixed role="tablist" not having direct role="tab" by adding role="presentation" on the li elements
- Fixed aria-expanded being set to true when collapsed and backwards for BulkAccessBrowseComponent & BulkAccessSettingsComponent

(cherry picked from commit c300123b78)
This commit is contained in:
Alexandre Vryghem
2023-11-26 21:28:12 +01:00
committed by github-actions[bot]
parent 1c4be7d1fe
commit fc7aa27706
7 changed files with 82 additions and 63 deletions

View File

@@ -121,7 +121,7 @@
"ngx-infinite-scroll": "^15.0.0", "ngx-infinite-scroll": "^15.0.0",
"ngx-pagination": "6.0.3", "ngx-pagination": "6.0.3",
"ngx-sortablejs": "^11.1.0", "ngx-sortablejs": "^11.1.0",
"ngx-ui-switch": "^14.0.3", "ngx-ui-switch": "^14.1.0",
"nouislider": "^15.7.1", "nouislider": "^15.7.1",
"pem": "1.14.7", "pem": "1.14.7",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",

View File

@@ -1,15 +1,15 @@
<ngb-accordion #acc="ngbAccordion" [activeIds]="'browse'"> <ngb-accordion #acc="ngbAccordion" [activeIds]="'browse'">
<ngb-panel [id]="'browse'"> <ngb-panel [id]="'browse'">
<ng-template ngbPanelHeader> <ng-template ngbPanelHeader>
<div class="w-100 d-flex justify-content-between collapse-toggle" ngbPanelToggle (click)="acc.toggle('browse')" <div class="w-100 d-flex gap-3 justify-content-between collapse-toggle" ngbPanelToggle (click)="acc.toggle('browse')"
data-test="browse"> data-test="browse">
<button type="button" class="btn btn-link p-0" (click)="$event.preventDefault()" <button type="button" class="btn btn-link p-0" (click)="$event.preventDefault()"
[attr.aria-expanded]="!acc.isExpanded('browse')" [attr.aria-expanded]="acc.isExpanded('browse')"
aria-controls="collapsePanels"> aria-controls="bulk-access-browse-panel-content">
{{ 'admin.access-control.bulk-access-browse.header' | translate }} {{ 'admin.access-control.bulk-access-browse.header' | translate }}
</button> </button>
<div class="text-right d-flex"> <div class="text-right d-flex gap-2">
<div class="ml-3 d-inline-block"> <div class="d-flex my-auto">
<span *ngIf="acc.isExpanded('browse')" class="fas fa-chevron-up fa-fw"></span> <span *ngIf="acc.isExpanded('browse')" class="fas fa-chevron-up fa-fw"></span>
<span *ngIf="!acc.isExpanded('browse')" class="fas fa-chevron-down fa-fw"></span> <span *ngIf="!acc.isExpanded('browse')" class="fas fa-chevron-down fa-fw"></span>
</div> </div>
@@ -17,51 +17,53 @@
</div> </div>
</ng-template> </ng-template>
<ng-template ngbPanelContent> <ng-template ngbPanelContent>
<ul ngbNav #nav="ngbNav" [(activeId)]="activateId" class="nav-pills"> <div id="bulk-access-browse-panel-content">
<li [ngbNavItem]="'search'"> <ul ngbNav #nav="ngbNav" [(activeId)]="activateId" class="nav-pills">
<a ngbNavLink>{{'admin.access-control.bulk-access-browse.search.header' | translate}}</a> <li [ngbNavItem]="'search'" role="presentation">
<ng-template ngbNavContent> <a ngbNavLink>{{'admin.access-control.bulk-access-browse.search.header' | translate}}</a>
<div class="mx-n3"> <ng-template ngbNavContent>
<ds-themed-search [configuration]="'administrativeBulkAccess'" <div class="mx-n3">
[selectable]="true" <ds-themed-search [configuration]="'administrativeBulkAccess'"
[selectionConfig]="{ repeatable: true, listId: listId }" [selectable]="true"
[showThumbnails]="false"></ds-themed-search> [selectionConfig]="{ repeatable: true, listId: listId }"
</div> [showThumbnails]="false"></ds-themed-search>
</ng-template> </div>
</li> </ng-template>
<li [ngbNavItem]="'selected'"> </li>
<a ngbNavLink> <li [ngbNavItem]="'selected'" role="presentation">
{{'admin.access-control.bulk-access-browse.selected.header' | translate: {number: ((objectsSelected$ | async)?.payload?.totalElements) ? (objectsSelected$ | async)?.payload?.totalElements : '0'} }} <a ngbNavLink>
</a> {{'admin.access-control.bulk-access-browse.selected.header' | translate: {number: ((objectsSelected$ | async)?.payload?.totalElements) ? (objectsSelected$ | async)?.payload?.totalElements : '0'} }}
<ng-template ngbNavContent> </a>
<ds-pagination <ng-template ngbNavContent>
[paginationOptions]="(paginationOptions$ | async)" <ds-pagination
[pageInfoState]="(objectsSelected$|async)?.payload.pageInfo" [paginationOptions]="(paginationOptions$ | async)"
[collectionSize]="(objectsSelected$|async)?.payload?.totalElements" [pageInfoState]="(objectsSelected$|async)?.payload.pageInfo"
[objects]="(objectsSelected$|async)" [collectionSize]="(objectsSelected$|async)?.payload?.totalElements"
[showPaginator]="false" [objects]="(objectsSelected$|async)"
(prev)="pagePrev()" [showPaginator]="false"
(next)="pageNext()"> (prev)="pagePrev()"
<ul *ngIf="(objectsSelected$|async)?.hasSucceeded" class="list-unstyled ml-4"> (next)="pageNext()">
<li *ngFor='let object of (objectsSelected$|async)?.payload?.page | paginate: { itemsPerPage: (paginationOptions$ | async).pageSize, <ul *ngIf="(objectsSelected$|async)?.hasSucceeded" class="list-unstyled ml-4">
currentPage: (paginationOptions$ | async).currentPage, totalItems: (objectsSelected$|async)?.payload?.page.length }; let i = index; let last = last ' <li *ngFor='let object of (objectsSelected$|async)?.payload?.page | paginate: { itemsPerPage: (paginationOptions$ | async).pageSize,
class="mt-4 mb-4 d-flex" currentPage: (paginationOptions$ | async).currentPage, totalItems: (objectsSelected$|async)?.payload?.page.length }; let i = index; let last = last '
[attr.data-test]="'list-object' | dsBrowserOnly"> class="mt-4 mb-4 d-flex"
<ds-selectable-list-item-control [index]="i" [attr.data-test]="'list-object' | dsBrowserOnly">
[object]="object" <ds-selectable-list-item-control [index]="i"
[selectionConfig]="{ repeatable: true, listId: listId }"></ds-selectable-list-item-control> [object]="object"
<ds-listable-object-component-loader [listID]="listId" [selectionConfig]="{ repeatable: true, listId: listId }"></ds-selectable-list-item-control>
[index]="i" <ds-listable-object-component-loader [listID]="listId"
[object]="object" [index]="i"
[showThumbnails]="false" [object]="object"
[viewMode]="'list'"></ds-listable-object-component-loader> [showThumbnails]="false"
</li> [viewMode]="'list'"></ds-listable-object-component-loader>
</ul> </li>
</ds-pagination> </ul>
</ng-template> </ds-pagination>
</li> </ng-template>
</ul> </li>
<div [ngbNavOutlet]="nav" class="mt-5"></div> </ul>
<div [ngbNavOutlet]="nav" class="mt-5"></div>
</div>
</ng-template> </ng-template>
</ngb-panel> </ngb-panel>
</ngb-accordion> </ngb-accordion>

View File

@@ -1,13 +1,13 @@
<ngb-accordion #acc="ngbAccordion" [activeIds]="'settings'"> <ngb-accordion #acc="ngbAccordion" [activeIds]="'settings'">
<ngb-panel [id]="'settings'"> <ngb-panel [id]="'settings'">
<ng-template ngbPanelHeader> <ng-template ngbPanelHeader>
<div class="w-100 d-flex justify-content-between collapse-toggle" ngbPanelToggle (click)="acc.toggle('settings')" data-test="settings"> <div class="w-100 d-flex gap-3 justify-content-between collapse-toggle" ngbPanelToggle (click)="acc.toggle('settings')" data-test="settings">
<button type="button" class="btn btn-link p-0" (click)="$event.preventDefault()" [attr.aria-expanded]="!acc.isExpanded('browse')" <button type="button" class="btn btn-link p-0" (click)="$event.preventDefault()" [attr.aria-expanded]="acc.isExpanded('settings')"
aria-controls="collapsePanels"> aria-controls="bulk-access-settings-panel-content">
{{ 'admin.access-control.bulk-access-settings.header' | translate }} {{ 'admin.access-control.bulk-access-settings.header' | translate }}
</button> </button>
<div class="text-right d-flex"> <div class="text-right d-flex gap-2">
<div class="ml-3 d-inline-block"> <div class="d-flex my-auto">
<span *ngIf="acc.isExpanded('settings')" class="fas fa-chevron-up fa-fw"></span> <span *ngIf="acc.isExpanded('settings')" class="fas fa-chevron-up fa-fw"></span>
<span *ngIf="!acc.isExpanded('settings')" class="fas fa-chevron-down fa-fw"></span> <span *ngIf="!acc.isExpanded('settings')" class="fas fa-chevron-down fa-fw"></span>
</div> </div>
@@ -15,7 +15,7 @@
</div> </div>
</ng-template> </ng-template>
<ng-template ngbPanelContent> <ng-template ngbPanelContent>
<ds-access-control-form-container #dsAccessControlForm [showSubmit]="false"></ds-access-control-form-container> <ds-access-control-form-container id="bulk-access-settings-panel-content" #dsAccessControlForm [showSubmit]="false"></ds-access-control-form-container>
</ng-template> </ng-template>
</ngb-panel> </ngb-panel>
</ngb-accordion> </ngb-accordion>

View File

@@ -92,6 +92,7 @@
<div class="input-group"> <div class="input-group">
<button type="button" class="btn btn-outline-danger" <button type="button" class="btn btn-outline-danger"
[attr.aria-label]="'access-control-remove' | translate"
[disabled]="ngForm.disabled || form.accessControls.length === 1" [disabled]="ngForm.disabled || form.accessControls.length === 1"
(click)="removeAccessControlItem(control.id)"> (click)="removeAccessControlItem(control.id)">
<i class="fas fa-trash"></i> <i class="fas fa-trash"></i>

View File

@@ -4,10 +4,11 @@
<ds-alert <ds-alert
*ngIf="titleMessage" *ngIf="titleMessage"
[type]="AlertType.Info" [type]="AlertType.Info"
[content]="titleMessage"> [content]="titleMessage"
class="d-block pb-3">
</ds-alert> </ds-alert>
<div class="row mt-5"> <div class="row">
<div class="col-12 col-md-6 border-right d-flex flex-column justify-content-between"> <div class="col-12 col-md-6 border-right d-flex flex-column justify-content-between">
<div> <div>
@@ -16,6 +17,7 @@
{{ 'access-control-item-header-toggle' | translate }} {{ 'access-control-item-header-toggle' | translate }}
</h4> </h4>
<ui-switch <ui-switch
[ariaLabel]="(state.bitstream.toggleStatus ? 'access-control-item-toggle.disable' : 'access-control-item-toggle.enable') | translate"
[(ngModel)]="state.item.toggleStatus" [(ngModel)]="state.item.toggleStatus"
(ngModelChange)="handleStatusChange('item', $event)"> (ngModelChange)="handleStatusChange('item', $event)">
</ui-switch> </ui-switch>
@@ -69,6 +71,7 @@
{{'access-control-bitstream-header-toggle' | translate}} {{'access-control-bitstream-header-toggle' | translate}}
</h4> </h4>
<ui-switch <ui-switch
[ariaLabel]="(state.bitstream.toggleStatus ? 'access-control-bitstream-toggle.disable' : 'access-control-bitstream-toggle.enable') | translate"
[(ngModel)]="state.bitstream.toggleStatus" [(ngModel)]="state.bitstream.toggleStatus"
(ngModelChange)="handleStatusChange('bitstream', $event)"> (ngModelChange)="handleStatusChange('bitstream', $event)">
</ui-switch> </ui-switch>
@@ -99,6 +102,7 @@
<button <button
*ngIf="itemRD" *ngIf="itemRD"
[attr.aria-label]="'access-control-bitstreams-select' | translate"
[disabled]="!state.bitstream.toggleStatus || state.bitstream.changesLimit !== 'selected'" [disabled]="!state.bitstream.toggleStatus || state.bitstream.changesLimit !== 'selected'"
(click)="openSelectBitstreamsModal(itemRD.payload)" (click)="openSelectBitstreamsModal(itemRD.payload)"
class="btn btn-outline-dark border-0" type="button"> class="btn btn-outline-dark border-0" type="button">

View File

@@ -5190,8 +5190,16 @@
"access-control-item-header-toggle": "Item's Metadata", "access-control-item-header-toggle": "Item's Metadata",
"access-control-item-toggle.enable": "Enable option to perform changes on the item's metadata",
"access-control-item-toggle.disable": "Disable option to perform changes on the item's metadata",
"access-control-bitstream-header-toggle": "Bitstreams", "access-control-bitstream-header-toggle": "Bitstreams",
"access-control-bitstream-toggle.enable": "Enable option to perform changes on the bitstreams",
"access-control-bitstream-toggle.disable": "Disable option to perform changes on the bitstreams",
"access-control-mode": "Mode", "access-control-mode": "Mode",
"access-control-access-conditions": "Access conditions", "access-control-access-conditions": "Access conditions",
@@ -5208,12 +5216,16 @@
"access-control-bitstreams-selected": "bitstreams selected", "access-control-bitstreams-selected": "bitstreams selected",
"access-control-bitstreams-select": "Select bitstreams",
"access-control-cancel": "Cancel", "access-control-cancel": "Cancel",
"access-control-execute": "Execute", "access-control-execute": "Execute",
"access-control-add-more": "Add more", "access-control-add-more": "Add more",
"access-control-remove": "Remove access condition",
"access-control-select-bitstreams-modal.title": "Select bitstreams", "access-control-select-bitstreams-modal.title": "Select bitstreams",
"access-control-select-bitstreams-modal.no-items": "No items to show.", "access-control-select-bitstreams-modal.no-items": "No items to show.",

View File

@@ -8369,10 +8369,10 @@ ngx-sortablejs@^11.1.0:
dependencies: dependencies:
tslib "^2.0.0" tslib "^2.0.0"
ngx-ui-switch@^14.0.3: ngx-ui-switch@^14.1.0:
version "14.0.3" version "14.1.0"
resolved "https://registry.npmjs.org/ngx-ui-switch/-/ngx-ui-switch-14.0.3.tgz" resolved "https://registry.yarnpkg.com/ngx-ui-switch/-/ngx-ui-switch-14.1.0.tgz#32248361a684257c5ae64cfde61b95de920b901c"
integrity sha512-SZ8ZnTCuNJgNWuY3/mOG3TdsRUNPCX3vGdCKKx1ZHVMTUynerJQlTWck2JrYlnrexNnd7wy4P10jDvdtDwoYeg== integrity sha512-uGGLppBP1FXjyD+x7f8Pm6I3JQTMmsBqPtwERAX27jSZxDWFp/sewnl75fuDvu75qFofJd/BIOtV4xHxzgZOvw==
dependencies: dependencies:
tslib "^2.3.0" tslib "^2.3.0"