Skip to content

Commit 47f05bf

Browse files
97742: Feedback 2023-01-27 - Table roles and aria attributes + additional feedback changes
1 parent 018c74d commit 47f05bf

10 files changed

Lines changed: 122 additions & 63 deletions

src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-field-values/dso-edit-metadata-field-values.component.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
<div class="flex-grow-1 ds-drop-list h-100" [class.disabled]="(draggingMdField$ | async) && (draggingMdField$ | async) !== mdField" cdkDropList (cdkDropListDropped)="drop($event)">
2-
<ds-dso-edit-metadata-value *ngFor="let mdValue of form.fields[mdField]; let idx = index"
1+
<div class="flex-grow-1 ds-drop-list h-100" [class.disabled]="(draggingMdField$ | async) && (draggingMdField$ | async) !== mdField" cdkDropList (cdkDropListDropped)="drop($event)" role="table">
2+
<ds-dso-edit-metadata-value-headers role="presentation" [dsoType]="dsoType"></ds-dso-edit-metadata-value-headers>
3+
<ds-dso-edit-metadata-value *ngFor="let mdValue of form.fields[mdField]; let idx = index" role="presentation"
34
[dso]="dso"
45
[mdValue]="mdValue"
56
[dsoType]="dsoType"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div role="row" class="visually-hidden">
2+
<div role="columnheader">{{ dsoType + '.edit.metadata.headers.value' | translate }}</div>
3+
<div role="columnheader">{{ dsoType + '.edit.metadata.headers.language' | translate }}</div>
4+
<div role="columnheader">{{ dsoType + '.edit.metadata.headers.edit' | translate }}</div>
5+
</div>

src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value-headers/dso-edit-metadata-value-headers.component.scss

Whitespace-only changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Component, Input } from '@angular/core';
2+
3+
@Component({
4+
selector: 'ds-dso-edit-metadata-value-headers',
5+
styleUrls: ['./dso-edit-metadata-value-headers.component.scss', '../dso-edit-metadata-shared/dso-edit-metadata-cells.scss'],
6+
templateUrl: './dso-edit-metadata-value-headers.component.html',
7+
})
8+
/**
9+
* Component displaying invisible headers for a list of metadata values using table roles for accessibility
10+
*/
11+
export class DsoEditMetadataValueHeadersComponent {
12+
/**
13+
* Type of DSO we're displaying values for
14+
* Determines i18n messages
15+
*/
16+
@Input() dsoType: string;
17+
}

src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
<div class="d-flex flex-row ds-value-row" *ngVar="mdValue.newValue.isVirtual as isVirtual"
1+
<div class="d-flex flex-row ds-value-row" *ngVar="mdValue.newValue.isVirtual as isVirtual" role="row"
22
cdkDrag (cdkDragStarted)="dragging.emit(true)" (cdkDragEnded)="dragging.emit(false)"
33
[ngClass]="{ 'ds-warning': mdValue.reordered || mdValue.change === DsoEditMetadataChangeTypeEnum.UPDATE, 'ds-danger': mdValue.change === DsoEditMetadataChangeTypeEnum.REMOVE, 'ds-success': mdValue.change === DsoEditMetadataChangeTypeEnum.ADD, 'h-100': isOnlyValue }">
4-
<div class="flex-grow-1 ds-flex-cell ds-value-cell d-flex align-items-center" *ngVar="(mdRepresentation$ | async) as mdRepresentation">
4+
<div class="flex-grow-1 ds-flex-cell ds-value-cell d-flex align-items-center" *ngVar="(mdRepresentation$ | async) as mdRepresentation" role="cell">
55
<div class="dont-break-out preserve-line-breaks" *ngIf="!mdValue.editing && !mdRepresentation">{{ mdValue.newValue.value }}</div>
66
<textarea class="form-control" rows="5" *ngIf="mdValue.editing && !mdRepresentation" [(ngModel)]="mdValue.newValue.value"
77
[dsDebounce]="300" (onDebounce)="confirm.emit(false)"></textarea>
@@ -10,33 +10,45 @@
1010
<ds-type-badge [object]="mdRepresentation"></ds-type-badge>
1111
</div>
1212
</div>
13-
<div class="ds-flex-cell ds-lang-cell">
13+
<div class="ds-flex-cell ds-lang-cell" role="cell">
1414
<div class="dont-break-out preserve-line-breaks" *ngIf="!mdValue.editing">{{ mdValue.newValue.language }}</div>
1515
<input class="form-control" type="text" *ngIf="mdValue.editing" [(ngModel)]="mdValue.newValue.language"
1616
[dsDebounce]="300" (onDebounce)="confirm.emit(false)" />
1717
</div>
18-
<div class="text-center ds-flex-cell ds-edit-cell">
19-
<div class="btn-group edit-field">
20-
<div class="btn-group" [ngbTooltip]="isVirtual ? (dsoType + '.edit.metadata.edit.buttons.virtual' | translate) : null">
21-
<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"
22-
[disabled]="isVirtual || mdValue.change === DsoEditMetadataChangeTypeEnum.REMOVE || (saving$ | async)" (click)="edit.emit()">
23-
<i class="fas fa-edit fa-fw"></i>
24-
</button>
25-
<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"
26-
[disabled]="isVirtual || (saving$ | async)" (click)="confirm.emit(true)">
27-
<i class="fas fa-check fa-fw"></i>
28-
</button>
29-
<button class="btn btn-outline-danger btn-sm" id="metadata-remove-btn" ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.remove' | translate }}"
30-
[disabled]="isVirtual || (mdValue.change && mdValue.change !== DsoEditMetadataChangeTypeEnum.ADD) || mdValue.editing || (saving$ | async)" (click)="remove.emit()">
31-
<i class="fas fa-trash-alt fa-fw"></i>
32-
</button>
33-
<button class="btn btn-outline-warning btn-sm" id="metadata-undo-btn" ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.undo' | translate }}"
34-
[disabled]="isVirtual || (!mdValue.change && mdValue.reordered) || (!mdValue.change && !mdValue.editing) || (saving$ | async)" (click)="undo.emit()">
35-
<i class="fas fa-undo-alt fa-fw"></i>
36-
</button>
18+
<div class="text-center ds-flex-cell ds-edit-cell" role="cell">
19+
<div class="btn-group">
20+
<div class="edit-field">
21+
<div class="btn-group edit-buttons" [ngbTooltip]="isVirtual ? (dsoType + '.edit.metadata.edit.buttons.virtual' | translate) : null">
22+
<button class="btn btn-outline-primary btn-sm ng-star-inserted" id="metadata-edit-btn" *ngIf="!mdValue.editing"
23+
[title]="dsoType + '.edit.metadata.edit.buttons.edit' | translate"
24+
ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.edit' | translate }}"
25+
[disabled]="isVirtual || mdValue.change === DsoEditMetadataChangeTypeEnum.REMOVE || (saving$ | async)" (click)="edit.emit()">
26+
<i class="fas fa-edit fa-fw"></i>
27+
</button>
28+
<button class="btn btn-outline-success btn-sm ng-star-inserted" id="metadata-confirm-btn" *ngIf="mdValue.editing"
29+
[title]="dsoType + '.edit.metadata.edit.buttons.confirm' | translate"
30+
ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.confirm' | translate }}"
31+
[disabled]="isVirtual || (saving$ | async)" (click)="confirm.emit(true)">
32+
<i class="fas fa-check fa-fw"></i>
33+
</button>
34+
<button class="btn btn-outline-danger btn-sm" id="metadata-remove-btn"
35+
[title]="dsoType + '.edit.metadata.edit.buttons.remove' | translate"
36+
ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.remove' | translate }}"
37+
[disabled]="isVirtual || (mdValue.change && mdValue.change !== DsoEditMetadataChangeTypeEnum.ADD) || mdValue.editing || (saving$ | async)" (click)="remove.emit()">
38+
<i class="fas fa-trash-alt fa-fw"></i>
39+
</button>
40+
<button class="btn btn-outline-warning btn-sm" id="metadata-undo-btn"
41+
[title]="dsoType + '.edit.metadata.edit.buttons.undo' | translate"
42+
ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.undo' | translate }}"
43+
[disabled]="isVirtual || (!mdValue.change && mdValue.reordered) || (!mdValue.change && !mdValue.editing) || (saving$ | async)" (click)="undo.emit()">
44+
<i class="fas fa-undo-alt fa-fw"></i>
45+
</button>
46+
</div>
3747
</div>
38-
<button class="btn btn-outline-secondary ds-drag-handle btn-sm" id="metadata-drag-btn" *ngVar="(isOnlyValue || (saving$ | async)) as disabled" cdkDragHandle [cdkDragHandleDisabled]="disabled"
39-
[ngClass]="{'disabled': disabled}" ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.drag' | translate }}" [disabled]="disabled">
48+
<button class="btn btn-outline-secondary ds-drag-handle btn-sm" id="metadata-drag-btn" *ngVar="(isOnlyValue || (saving$ | async)) as disabled"
49+
cdkDragHandle [cdkDragHandleDisabled]="disabled" [ngClass]="{'disabled': disabled}" [disabled]="disabled"
50+
[title]="dsoType + '.edit.metadata.edit.buttons.drag' | translate"
51+
ngbTooltip="{{ dsoType + '.edit.metadata.edit.buttons.drag' | translate }}">
4052
<i class="fas fa-grip-vertical fa-fw"></i>
4153
</button>
4254
</div>

src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
cursor: grab;
88
}
99

10-
::ng-deep .tooltip-inner {
10+
::ng-deep .edit-field>ngb-tooltip-window .tooltip-inner {
1111
min-width: var(--ds-dso-edit-virtual-tooltip-min-width);
1212
}
1313

src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,70 @@
11
<div class="item-metadata" *ngIf="form">
22
<div class="button-row top d-flex my-2 space-children-mr ml-gap">
33
<button class="mr-auto btn btn-success" id="dso-add-btn" [disabled]="form.newValue || (saving$ | async)"
4+
[title]="dsoType + '.edit.metadata.add-button' | translate"
45
(click)="add()"><i class="fas fa-plus"></i>
56
<span class="d-none d-sm-inline">&nbsp;{{ dsoType + '.edit.metadata.add-button' | translate }}</span>
67
</button>
78
<button class="btn btn-warning ml-1" id="dso-reinstate-btn" *ngIf="isReinstatable" [disabled]="(saving$ | async)"
9+
[title]="dsoType + '.edit.metadata.reinstate-button' | translate"
810
(click)="reinstate()"><i class="fas fa-undo-alt"></i>
911
<span class="d-none d-sm-inline">&nbsp;{{ dsoType + '.edit.metadata.reinstate-button' | translate }}</span>
1012
</button>
1113
<button class="btn btn-primary ml-1" id="dso-save-btn" [disabled]="!hasChanges || (saving$ | async)"
14+
[title]="dsoType + '.edit.metadata.save-button' | translate"
1215
(click)="submit()"><i class="fas fa-save"></i>
1316
<span class="d-none d-sm-inline">&nbsp;{{ dsoType + '.edit.metadata.save-button' | translate }}</span>
1417
</button>
1518
<button class="btn btn-danger ml-1" id="dso-discard-btn" *ngIf="!isReinstatable"
19+
[title]="dsoType + '.edit.metadata.discard-button' | translate"
1620
[disabled]="!hasChanges || (saving$ | async)"
1721
(click)="discard()"><i class="fas fa-times"></i>
1822
<span class="d-none d-sm-inline">&nbsp;{{ dsoType + '.edit.metadata.discard-button' | translate }}</span>
1923
</button>
2024
</div>
2125

22-
<ds-dso-edit-metadata-headers [dsoType]="dsoType"></ds-dso-edit-metadata-headers>
23-
<div class="d-flex flex-row ds-field-row" *ngIf="form.newValue">
24-
<div class="lbl-cell ds-success">
25-
<ds-metadata-field-selector [dsoType]="dsoType"
26-
[(mdField)]="newMdField"
27-
[autofocus]="true">
28-
</ds-metadata-field-selector>
29-
</div>
30-
<div class="flex-grow-1 ds-drop-list">
31-
<ds-dso-edit-metadata-value [dso]="dso"
32-
[mdValue]="form.newValue"
33-
[dsoType]="dsoType"
34-
[saving$]="savingOrLoadingFieldValidation$"
35-
[isOnlyValue]="true"
36-
(confirm)="confirmNewValue($event)"
37-
(remove)="form.newValue = undefined"
38-
(undo)="form.newValue = undefined">
39-
</ds-dso-edit-metadata-value>
26+
<div role="table" [attr.aria-label]="'item.edit.head' | translate">
27+
<ds-dso-edit-metadata-headers [dsoType]="dsoType"></ds-dso-edit-metadata-headers>
28+
<div class="d-flex flex-row ds-field-row" role="row" *ngIf="form.newValue">
29+
<div class="lbl-cell ds-success" role="rowheader">
30+
<ds-metadata-field-selector [dsoType]="dsoType"
31+
[(mdField)]="newMdField"
32+
[autofocus]="true">
33+
</ds-metadata-field-selector>
34+
</div>
35+
<div class="flex-grow-1 ds-drop-list" role="cell">
36+
<div role="table">
37+
<ds-dso-edit-metadata-value-headers role="presentation" [dsoType]="dsoType"></ds-dso-edit-metadata-value-headers>
38+
<ds-dso-edit-metadata-value [dso]="dso"
39+
[mdValue]="form.newValue"
40+
[dsoType]="dsoType"
41+
[saving$]="savingOrLoadingFieldValidation$"
42+
[isOnlyValue]="true"
43+
(confirm)="confirmNewValue($event)"
44+
(remove)="form.newValue = undefined"
45+
(undo)="form.newValue = undefined">
46+
</ds-dso-edit-metadata-value>
47+
</div>
48+
</div>
4049
</div>
41-
</div>
42-
<div class="d-flex flex-row ds-field-row" *ngFor="let mdField of form.fieldKeys">
43-
<div class="lbl-cell">
44-
<span class="dont-break-out preserve-line-breaks">{{ mdField }}</span>
45-
<div class="btn btn-warning reset-order-button mt-2 w-100" *ngIf="form.hasOrderChanges(mdField)"
46-
(click)="form.resetOrder(mdField); onValueSaved()">
47-
{{ dsoType + '.edit.metadata.reset-order-button' | translate }}
50+
<div class="d-flex flex-row ds-field-row" role="row" *ngFor="let mdField of form.fieldKeys">
51+
<div class="lbl-cell" role="rowheader">
52+
<span class="dont-break-out preserve-line-breaks">{{ mdField }}</span>
53+
<div class="btn btn-warning reset-order-button mt-2 w-100" *ngIf="form.hasOrderChanges(mdField)"
54+
(click)="form.resetOrder(mdField); onValueSaved()">
55+
{{ dsoType + '.edit.metadata.reset-order-button' | translate }}
56+
</div>
4857
</div>
58+
<ds-dso-edit-metadata-field-values class="flex-grow-1" role="cell"
59+
[dso]="dso"
60+
[form]="form"
61+
[dsoType]="dsoType"
62+
[saving$]="saving$"
63+
[draggingMdField$]="draggingMdField$"
64+
[mdField]="mdField"
65+
(valueSaved)="onValueSaved()">
66+
</ds-dso-edit-metadata-field-values>
4967
</div>
50-
<ds-dso-edit-metadata-field-values class="flex-grow-1"
51-
[dso]="dso"
52-
[form]="form"
53-
[dsoType]="dsoType"
54-
[saving$]="saving$"
55-
[draggingMdField$]="draggingMdField$"
56-
[mdField]="mdField"
57-
(valueSaved)="onValueSaved()">
58-
</ds-dso-edit-metadata-field-values>
5968
</div>
6069

6170
<div *ngIf="isEmpty && !form.newValue">
@@ -64,12 +73,15 @@
6473
<div class="button-row bottom d-inline-block w-100">
6574
<div class="mt-2 float-right space-children-mr ml-gap">
6675
<button class="btn btn-warning" *ngIf="isReinstatable" [disabled]="(saving$ | async)"
76+
[title]="dsoType + '.edit.metadata.reinstate-button' | translate"
6777
(click)="reinstate()"><i class="fas fa-undo-alt"></i> {{ dsoType + '.edit.metadata.reinstate-button' | translate }}
6878
</button>
6979
<button class="btn btn-primary" [disabled]="!hasChanges || (saving$ | async)"
80+
[title]="dsoType + '.edit.metadata.save-button' | translate"
7081
(click)="submit()"><i class="fas fa-save"></i> {{ dsoType + '.edit.metadata.save-button' | translate }}
7182
</button>
7283
<button class="btn btn-danger" *ngIf="!isReinstatable"
84+
[title]="dsoType + '.edit.metadata.discard-button' | translate"
7385
[disabled]="!hasChanges || (saving$ | async)"
7486
(click)="discard()"><i class="fas fa-times"></i> {{ dsoType + '.edit.metadata.discard-button' | translate }}
7587
</button>

src/app/dso-shared/dso-shared.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { MetadataFieldSelectorComponent } from './dso-edit-metadata/metadata-fie
55
import { DsoEditMetadataFieldValuesComponent } from './dso-edit-metadata/dso-edit-metadata-field-values/dso-edit-metadata-field-values.component';
66
import { DsoEditMetadataValueComponent } from './dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component';
77
import { DsoEditMetadataHeadersComponent } from './dso-edit-metadata/dso-edit-metadata-headers/dso-edit-metadata-headers.component';
8+
import { DsoEditMetadataValueHeadersComponent } from './dso-edit-metadata/dso-edit-metadata-value-headers/dso-edit-metadata-value-headers.component';
89

910
@NgModule({
1011
imports: [
@@ -16,6 +17,7 @@ import { DsoEditMetadataHeadersComponent } from './dso-edit-metadata/dso-edit-me
1617
DsoEditMetadataFieldValuesComponent,
1718
DsoEditMetadataValueComponent,
1819
DsoEditMetadataHeadersComponent,
20+
DsoEditMetadataValueHeadersComponent,
1921
],
2022
exports: [
2123
DsoEditMetadataComponent,

src/assets/i18n/en.json5

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2288,8 +2288,6 @@
22882288

22892289
"itemtemplate.edit.metadata.edit.buttons.unedit": "Stop editing",
22902290

2291-
"itemtemplate.edit.metadata.edit.buttons.virtual": "This is a virtual metadata value, i.e. a value inherited from a related entity. It can’t be modified directly. Add or remove the corresponding relationship in the \"Relationships\" tab",
2292-
22932291
"itemtemplate.edit.metadata.empty": "The item template currently doesn't contain any metadata. Click Add to start adding a metadata value.",
22942292

22952293
"itemtemplate.edit.metadata.headers.edit": "Edit",

src/styles/_global-styles.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,15 @@ ngb-modal-backdrop {
9292
hyphens: auto;
9393

9494
}
95+
96+
.visually-hidden {
97+
position: absolute !important;
98+
width: 1px !important;
99+
height: 1px !important;
100+
padding: 0 !important;
101+
margin: -1px !important;
102+
overflow: hidden !important;
103+
clip: rect(0, 0, 0, 0) !important;
104+
white-space: nowrap !important;
105+
border: 0 !important;
106+
}

0 commit comments

Comments
 (0)