97742: Feedback 2023-01-27 - Table roles and aria attributes + additional feedback changes

This commit is contained in:
Kristof De Langhe
2023-01-31 13:33:29 +01:00
parent 018c74def4
commit 47f05bf11d
10 changed files with 123 additions and 64 deletions

View File

@@ -1,5 +1,6 @@
<div class="flex-grow-1 ds-drop-list h-100" [class.disabled]="(draggingMdField$ | async) && (draggingMdField$ | async) !== mdField" cdkDropList (cdkDropListDropped)="drop($event)">
<ds-dso-edit-metadata-value *ngFor="let mdValue of form.fields[mdField]; let idx = index"
<div class="flex-grow-1 ds-drop-list h-100" [class.disabled]="(draggingMdField$ | async) && (draggingMdField$ | async) !== mdField" cdkDropList (cdkDropListDropped)="drop($event)" role="table">
<ds-dso-edit-metadata-value-headers role="presentation" [dsoType]="dsoType"></ds-dso-edit-metadata-value-headers>
<ds-dso-edit-metadata-value *ngFor="let mdValue of form.fields[mdField]; let idx = index" role="presentation"
[dso]="dso"
[mdValue]="mdValue"
[dsoType]="dsoType"

View File

@@ -0,0 +1,5 @@
<div role="row" class="visually-hidden">
<div role="columnheader">{{ dsoType + '.edit.metadata.headers.value' | translate }}</div>
<div role="columnheader">{{ dsoType + '.edit.metadata.headers.language' | translate }}</div>
<div role="columnheader">{{ dsoType + '.edit.metadata.headers.edit' | translate }}</div>
</div>

View File

@@ -0,0 +1,17 @@
import { Component, Input } from '@angular/core';
@Component({
selector: 'ds-dso-edit-metadata-value-headers',
styleUrls: ['./dso-edit-metadata-value-headers.component.scss', '../dso-edit-metadata-shared/dso-edit-metadata-cells.scss'],
templateUrl: './dso-edit-metadata-value-headers.component.html',
})
/**
* Component displaying invisible headers for a list of metadata values using table roles for accessibility
*/
export class DsoEditMetadataValueHeadersComponent {
/**
* Type of DSO we're displaying values for
* Determines i18n messages
*/
@Input() dsoType: string;
}

View File

@@ -1,7 +1,7 @@
<div class="d-flex flex-row ds-value-row" *ngVar="mdValue.newValue.isVirtual as isVirtual"
<div class="d-flex flex-row ds-value-row" *ngVar="mdValue.newValue.isVirtual as isVirtual" role="row"
cdkDrag (cdkDragStarted)="dragging.emit(true)" (cdkDragEnded)="dragging.emit(false)"
[ngClass]="{ 'ds-warning': mdValue.reordered || mdValue.change === DsoEditMetadataChangeTypeEnum.UPDATE, 'ds-danger': mdValue.change === DsoEditMetadataChangeTypeEnum.REMOVE, 'ds-success': mdValue.change === DsoEditMetadataChangeTypeEnum.ADD, 'h-100': isOnlyValue }">
<div class="flex-grow-1 ds-flex-cell ds-value-cell d-flex align-items-center" *ngVar="(mdRepresentation$ | async) as mdRepresentation">
<div class="flex-grow-1 ds-flex-cell ds-value-cell d-flex align-items-center" *ngVar="(mdRepresentation$ | async) as mdRepresentation" role="cell">
<div class="dont-break-out preserve-line-breaks" *ngIf="!mdValue.editing && !mdRepresentation">{{ mdValue.newValue.value }}</div>
<textarea class="form-control" rows="5" *ngIf="mdValue.editing && !mdRepresentation" [(ngModel)]="mdValue.newValue.value"
[dsDebounce]="300" (onDebounce)="confirm.emit(false)"></textarea>
@@ -10,33 +10,45 @@
<ds-type-badge [object]="mdRepresentation"></ds-type-badge>
</div>
</div>
<div class="ds-flex-cell ds-lang-cell">
<div class="ds-flex-cell ds-lang-cell" role="cell">
<div class="dont-break-out preserve-line-breaks" *ngIf="!mdValue.editing">{{ mdValue.newValue.language }}</div>
<input class="form-control" type="text" *ngIf="mdValue.editing" [(ngModel)]="mdValue.newValue.language"
[dsDebounce]="300" (onDebounce)="confirm.emit(false)" />
</div>
<div class="text-center ds-flex-cell ds-edit-cell">
<div class="btn-group edit-field">
<div class="btn-group" [ngbTooltip]="isVirtual ? (dsoType + '.edit.metadata.edit.buttons.virtual' | translate) : null">
<button class="btn btn-outline-primary btn-sm ng-star-inserted" id="metadata-edit-btn" ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.edit' | translate }}" *ngIf="!mdValue.editing"
<div class="text-center ds-flex-cell ds-edit-cell" role="cell">
<div class="btn-group">
<div class="edit-field">
<div class="btn-group edit-buttons" [ngbTooltip]="isVirtual ? (dsoType + '.edit.metadata.edit.buttons.virtual' | translate) : null">
<button class="btn btn-outline-primary btn-sm ng-star-inserted" id="metadata-edit-btn" *ngIf="!mdValue.editing"
[title]="dsoType + '.edit.metadata.edit.buttons.edit' | translate"
ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.edit' | translate }}"
[disabled]="isVirtual || mdValue.change === DsoEditMetadataChangeTypeEnum.REMOVE || (saving$ | async)" (click)="edit.emit()">
<i class="fas fa-edit fa-fw"></i>
</button>
<button class="btn btn-outline-success btn-sm ng-star-inserted" id="metadata-confirm-btn" ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.confirm' | translate }}" *ngIf="mdValue.editing"
<button class="btn btn-outline-success btn-sm ng-star-inserted" id="metadata-confirm-btn" *ngIf="mdValue.editing"
[title]="dsoType + '.edit.metadata.edit.buttons.confirm' | translate"
ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.confirm' | translate }}"
[disabled]="isVirtual || (saving$ | async)" (click)="confirm.emit(true)">
<i class="fas fa-check fa-fw"></i>
</button>
<button class="btn btn-outline-danger btn-sm" id="metadata-remove-btn" ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.remove' | translate }}"
<button class="btn btn-outline-danger btn-sm" id="metadata-remove-btn"
[title]="dsoType + '.edit.metadata.edit.buttons.remove' | translate"
ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.remove' | translate }}"
[disabled]="isVirtual || (mdValue.change && mdValue.change !== DsoEditMetadataChangeTypeEnum.ADD) || mdValue.editing || (saving$ | async)" (click)="remove.emit()">
<i class="fas fa-trash-alt fa-fw"></i>
</button>
<button class="btn btn-outline-warning btn-sm" id="metadata-undo-btn" ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.undo' | translate }}"
<button class="btn btn-outline-warning btn-sm" id="metadata-undo-btn"
[title]="dsoType + '.edit.metadata.edit.buttons.undo' | translate"
ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.undo' | translate }}"
[disabled]="isVirtual || (!mdValue.change && mdValue.reordered) || (!mdValue.change && !mdValue.editing) || (saving$ | async)" (click)="undo.emit()">
<i class="fas fa-undo-alt fa-fw"></i>
</button>
</div>
<button class="btn btn-outline-secondary ds-drag-handle btn-sm" id="metadata-drag-btn" *ngVar="(isOnlyValue || (saving$ | async)) as disabled" cdkDragHandle [cdkDragHandleDisabled]="disabled"
[ngClass]="{'disabled': disabled}" ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.drag' | translate }}" [disabled]="disabled">
</div>
<button class="btn btn-outline-secondary ds-drag-handle btn-sm" id="metadata-drag-btn" *ngVar="(isOnlyValue || (saving$ | async)) as disabled"
cdkDragHandle [cdkDragHandleDisabled]="disabled" [ngClass]="{'disabled': disabled}" [disabled]="disabled"
[title]="dsoType + '.edit.metadata.edit.buttons.drag' | translate"
ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.drag' | translate }}">
<i class="fas fa-grip-vertical fa-fw"></i>
</button>
</div>

View File

@@ -7,7 +7,7 @@
cursor: grab;
}
::ng-deep .tooltip-inner {
::ng-deep .edit-field>ngb-tooltip-window .tooltip-inner {
min-width: var(--ds-dso-edit-virtual-tooltip-min-width);
}

View File

@@ -1,33 +1,40 @@
<div class="item-metadata" *ngIf="form">
<div class="button-row top d-flex my-2 space-children-mr ml-gap">
<button class="mr-auto btn btn-success" id="dso-add-btn" [disabled]="form.newValue || (saving$ | async)"
[title]="dsoType + '.edit.metadata.add-button' | translate"
(click)="add()"><i class="fas fa-plus"></i>
<span class="d-none d-sm-inline">&nbsp;{{ dsoType + '.edit.metadata.add-button' | translate }}</span>
</button>
<button class="btn btn-warning ml-1" id="dso-reinstate-btn" *ngIf="isReinstatable" [disabled]="(saving$ | async)"
[title]="dsoType + '.edit.metadata.reinstate-button' | translate"
(click)="reinstate()"><i class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">&nbsp;{{ dsoType + '.edit.metadata.reinstate-button' | translate }}</span>
</button>
<button class="btn btn-primary ml-1" id="dso-save-btn" [disabled]="!hasChanges || (saving$ | async)"
[title]="dsoType + '.edit.metadata.save-button' | translate"
(click)="submit()"><i class="fas fa-save"></i>
<span class="d-none d-sm-inline">&nbsp;{{ dsoType + '.edit.metadata.save-button' | translate }}</span>
</button>
<button class="btn btn-danger ml-1" id="dso-discard-btn" *ngIf="!isReinstatable"
[title]="dsoType + '.edit.metadata.discard-button' | translate"
[disabled]="!hasChanges || (saving$ | async)"
(click)="discard()"><i class="fas fa-times"></i>
<span class="d-none d-sm-inline">&nbsp;{{ dsoType + '.edit.metadata.discard-button' | translate }}</span>
</button>
</div>
<div role="table" [attr.aria-label]="'item.edit.head' | translate">
<ds-dso-edit-metadata-headers [dsoType]="dsoType"></ds-dso-edit-metadata-headers>
<div class="d-flex flex-row ds-field-row" *ngIf="form.newValue">
<div class="lbl-cell ds-success">
<div class="d-flex flex-row ds-field-row" role="row" *ngIf="form.newValue">
<div class="lbl-cell ds-success" role="rowheader">
<ds-metadata-field-selector [dsoType]="dsoType"
[(mdField)]="newMdField"
[autofocus]="true">
</ds-metadata-field-selector>
</div>
<div class="flex-grow-1 ds-drop-list">
<div class="flex-grow-1 ds-drop-list" role="cell">
<div role="table">
<ds-dso-edit-metadata-value-headers role="presentation" [dsoType]="dsoType"></ds-dso-edit-metadata-value-headers>
<ds-dso-edit-metadata-value [dso]="dso"
[mdValue]="form.newValue"
[dsoType]="dsoType"
@@ -39,15 +46,16 @@
</ds-dso-edit-metadata-value>
</div>
</div>
<div class="d-flex flex-row ds-field-row" *ngFor="let mdField of form.fieldKeys">
<div class="lbl-cell">
</div>
<div class="d-flex flex-row ds-field-row" role="row" *ngFor="let mdField of form.fieldKeys">
<div class="lbl-cell" role="rowheader">
<span class="dont-break-out preserve-line-breaks">{{ mdField }}</span>
<div class="btn btn-warning reset-order-button mt-2 w-100" *ngIf="form.hasOrderChanges(mdField)"
(click)="form.resetOrder(mdField); onValueSaved()">
{{ dsoType + '.edit.metadata.reset-order-button' | translate }}
</div>
</div>
<ds-dso-edit-metadata-field-values class="flex-grow-1"
<ds-dso-edit-metadata-field-values class="flex-grow-1" role="cell"
[dso]="dso"
[form]="form"
[dsoType]="dsoType"
@@ -57,6 +65,7 @@
(valueSaved)="onValueSaved()">
</ds-dso-edit-metadata-field-values>
</div>
</div>
<div *ngIf="isEmpty && !form.newValue">
<ds-alert [content]="dsoType + '.edit.metadata.empty'" [type]="AlertTypeEnum.Info"></ds-alert>
@@ -64,12 +73,15 @@
<div class="button-row bottom d-inline-block w-100">
<div class="mt-2 float-right space-children-mr ml-gap">
<button class="btn btn-warning" *ngIf="isReinstatable" [disabled]="(saving$ | async)"
[title]="dsoType + '.edit.metadata.reinstate-button' | translate"
(click)="reinstate()"><i class="fas fa-undo-alt"></i> {{ dsoType + '.edit.metadata.reinstate-button' | translate }}
</button>
<button class="btn btn-primary" [disabled]="!hasChanges || (saving$ | async)"
[title]="dsoType + '.edit.metadata.save-button' | translate"
(click)="submit()"><i class="fas fa-save"></i> {{ dsoType + '.edit.metadata.save-button' | translate }}
</button>
<button class="btn btn-danger" *ngIf="!isReinstatable"
[title]="dsoType + '.edit.metadata.discard-button' | translate"
[disabled]="!hasChanges || (saving$ | async)"
(click)="discard()"><i class="fas fa-times"></i> {{ dsoType + '.edit.metadata.discard-button' | translate }}
</button>

View File

@@ -5,6 +5,7 @@ import { MetadataFieldSelectorComponent } from './dso-edit-metadata/metadata-fie
import { DsoEditMetadataFieldValuesComponent } from './dso-edit-metadata/dso-edit-metadata-field-values/dso-edit-metadata-field-values.component';
import { DsoEditMetadataValueComponent } from './dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component';
import { DsoEditMetadataHeadersComponent } from './dso-edit-metadata/dso-edit-metadata-headers/dso-edit-metadata-headers.component';
import { DsoEditMetadataValueHeadersComponent } from './dso-edit-metadata/dso-edit-metadata-value-headers/dso-edit-metadata-value-headers.component';
@NgModule({
imports: [
@@ -16,6 +17,7 @@ import { DsoEditMetadataHeadersComponent } from './dso-edit-metadata/dso-edit-me
DsoEditMetadataFieldValuesComponent,
DsoEditMetadataValueComponent,
DsoEditMetadataHeadersComponent,
DsoEditMetadataValueHeadersComponent,
],
exports: [
DsoEditMetadataComponent,

View File

@@ -2288,8 +2288,6 @@
"itemtemplate.edit.metadata.edit.buttons.unedit": "Stop editing",
"itemtemplate.edit.metadata.edit.buttons.virtual": "This is a virtual metadata value, i.e. a value inherited from a related entity. It cant be modified directly. Add or remove the corresponding relationship in the \"Relationships\" tab",
"itemtemplate.edit.metadata.empty": "The item template currently doesn't contain any metadata. Click Add to start adding a metadata value.",
"itemtemplate.edit.metadata.headers.edit": "Edit",

View File

@@ -92,3 +92,15 @@ ngb-modal-backdrop {
hyphens: auto;
}
.visually-hidden {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0, 0, 0, 0) !important;
white-space: nowrap !important;
border: 0 !important;
}