diff --git a/libs/portal-integration-angular/assets/i18n/de.json b/libs/portal-integration-angular/assets/i18n/de.json index 28e5d56f..248be0d9 100644 --- a/libs/portal-integration-angular/assets/i18n/de.json +++ b/libs/portal-integration-angular/assets/i18n/de.json @@ -1,7 +1,7 @@ { "OCX_CUSTOM_GROUP_COLUMN_SELECTOR": { "DROPDOWN_LABEL": "Spalten", - "OPEN_BUTTON_TITLE": "Dialog zur Auswahl einer benutzerdefinierten Gruppe öffnen", + "OPEN_BUTTON_DETAIL": "Dialog zur Auswahl einer benutzerdefinierten Gruppe öffnen", "ACTIVE_COLUMNS_LABEL": "Aktive Spalten", "INACTIVE_COLUMNS_LABEL": "Inaktive Spalten", "SAVE_BUTTON_LABEL": "Speichern", @@ -15,6 +15,17 @@ "NO": "Nein", "LEFT": "Links", "RIGHT": "Rechts" + }, + "ARIA_LABELS": { + "UP": "Spalte nach oben verschieben", + "TOP": "Spalte an den Anfang verschieben", + "DOWN": "Spalte nach unten verschieben", + "BOTTOM": "Spalte ans Ende verschieben", + "RIGHT": "Spalte als inaktiv setzen", + "ALL_RIGHT": "Alle Spalten als inaktiv setzen", + "LEFT": "Spalte als aktiv setzen", + "ALL_LEFT": "Alle Spalten als aktiv setzen", + "CLOSE": "Dialog schließen" } }, "OCX_SEARCH_CONFIG": { @@ -28,16 +39,18 @@ "TITLE": "Sortieren nach" }, "TOGGLE_BUTTON": { - "ASCENDING_TITLE": "Auftseigend", + "ASCENDING_TITLE": "Aufsteigend", "DESCENDING_TITLE": "Absteigend", "DEFAULT_TITLE": "Standard" - } + }, + "SORTING_BUTTON_ARIA_LABEL": "{{direction}} sortieren" }, "OCX_DATA_TABLE": { "EMPTY_RESULT": "Keine Daten gefunden.", "EMPTY_FILTER_MESSAGE": "Keine Filter gefunden.", "ACTIONS_COLUMN_NAME": "Aktionen", "FILTER_TITLE": "Filter", + "FILTER_ARIA_LABEL": "Filter {{column}}", "EDITED": "Bearbeitet", "SHOWING": "{{first}} - {{last}} von {{totalRecords}}", "SHOWING_WITH_TOTAL_ON_SERVER": "{{first}} - {{last}} von {{totalRecords}} ({{totalRecordsOnServer}})", @@ -46,6 +59,12 @@ "VIEW": "Anzeigen", "EDIT": "Bearbeiten", "DELETE": "Löschen" + }, + "TOGGLE_BUTTON": { + "ASCENDING_TITLE": "Aufsteigend", + "DESCENDING_TITLE": "Absteigend", + "DEFAULT_TITLE": "Standard", + "ARIA_LABEL": "{{column}} {{direction}} sortieren" } }, "OCX_DATA_LIST_GRID": { @@ -54,7 +73,8 @@ "VIEW": "Anzeigen", "EDIT": "Bearbeiten", "DELETE": "Löschen" - } + }, + "MORE_ACTIONS": "Weitere Aktionen" }, "OCX_DATA_LAYOUT_SELECTION": { "LAYOUT": { @@ -91,12 +111,12 @@ "TEXT": "Suchen", "DETAIL": "Suche starten" }, - "RESET_BUTTON_TEXT": "Zurücksetzen", - "SEARCH_BUTTON_TEXT": "Suchen", "EXPORT": "Alle Ereignisse exportieren" }, "OCX_PAGE_HEADER": { - "MORE_ACTIONS": "Weitere Aktionen" + "MORE_ACTIONS": "Weitere Aktionen", + "HOME_DEFAULT_ARIA_LABEL": "Zur Startseite navigieren", + "HOME_ARIA_LABEL": "Zu {{page}} navigieren" }, "OCX_HEADER": { "MENU_TOGGLE": "Menü" diff --git a/libs/portal-integration-angular/assets/i18n/en.json b/libs/portal-integration-angular/assets/i18n/en.json index 920444cc..bd151ad6 100644 --- a/libs/portal-integration-angular/assets/i18n/en.json +++ b/libs/portal-integration-angular/assets/i18n/en.json @@ -1,7 +1,7 @@ { "OCX_CUSTOM_GROUP_COLUMN_SELECTOR": { "DROPDOWN_LABEL": "Columns", - "OPEN_BUTTON_TITLE": "Open custom group selection dialog", + "OPEN_BUTTON_DETAIL": "Open custom group selection dialog", "ACTIVE_COLUMNS_LABEL": "Active columns", "INACTIVE_COLUMNS_LABEL": "Inactive columns", "SAVE_BUTTON_LABEL": "Save", @@ -15,6 +15,17 @@ "NO": "No", "LEFT": "Left", "RIGHT": "Right" + }, + "ARIA_LABELS": { + "UP": "Move column up", + "TOP": "Move column to the top", + "DOWN": "Move column down", + "BOTTOM": "Move column to the bottom", + "RIGHT": "Set column as inactive", + "ALL_RIGHT": "Set all columns as inactive", + "LEFT": "Set column as active", + "ALL_LEFT": "Set all columns as active", + "CLOSE": "Close dialog" } }, "OCX_SEARCH_CONFIG": { @@ -31,13 +42,15 @@ "ASCENDING_TITLE": "Ascending", "DESCENDING_TITLE": "Descending", "DEFAULT_TITLE": "Default" - } + }, + "SORTING_BUTTON_ARIA_LABEL": "Toggle sorting direction to {{direction}}" }, "OCX_DATA_TABLE": { "EMPTY_RESULT": "No data found.", "EMPTY_FILTER_MESSAGE": "No filters found.", "ACTIONS_COLUMN_NAME": "Actions", "FILTER_TITLE": "Filter", + "FILTER_ARIA_LABEL": "Filter {{column}}", "EDITED": "Edited", "SHOWING": "{{first}} - {{last}} of {{totalRecords}}", "SHOWING_WITH_TOTAL_ON_SERVER": "{{first}} - {{last}} of {{totalRecords}} ({{totalRecordsOnServer}})", @@ -46,7 +59,13 @@ "VIEW": "View", "EDIT": "Edit", "DELETE": "Delete" - } + }, + "TOGGLE_BUTTON": { + "ASCENDING_TITLE": "Ascending", + "DESCENDING_TITLE": "Descending", + "DEFAULT_TITLE": "Default", + "ARIA_LABEL": "Toggle {{column}} sorting direction to {{direction}}" + } }, "OCX_DATA_LIST_GRID": { "EMPTY_RESULT": "No data found.", @@ -54,7 +73,8 @@ "VIEW": "View", "EDIT": "Edit", "DELETE": "Delete" - } + }, + "MORE_ACTIONS": "More actions" }, "OCX_DATA_LAYOUT_SELECTION": { "LAYOUT": { @@ -94,7 +114,9 @@ "EXPORT": "Export all events" }, "OCX_PAGE_HEADER": { - "MORE_ACTIONS": "More actions" + "MORE_ACTIONS": "More actions", + "HOME_DEFAULT_ARIA_LABEL": "Go to home page", + "HOME_ARIA_LABEL": "Go to {{page}} home page" }, "OCX_HEADER": { "MENU_TOGGLE": "Menu" diff --git a/libs/portal-integration-angular/src/lib/core/components/custom-group-column-selector/custom-group-column-selector.component.html b/libs/portal-integration-angular/src/lib/core/components/custom-group-column-selector/custom-group-column-selector.component.html index 1d89b0e1..ec1d2884 100644 --- a/libs/portal-integration-angular/src/lib/core/components/custom-group-column-selector/custom-group-column-selector.component.html +++ b/libs/portal-integration-angular/src/lib/core/components/custom-group-column-selector/custom-group-column-selector.component.html @@ -2,12 +2,13 @@ id="customGroupColumnSelectorButton" type="button" (click)="onOpenCustomGroupColumnSelectionDialogClick()" - [title]="openButtonTitle || ('OCX_CUSTOM_GROUP_COLUMN_SELECTOR.OPEN_BUTTON_TITLE' | translate)" + [title]="openButtonTitle || ('OCX_CUSTOM_GROUP_COLUMN_SELECTOR.OPEN_BUTTON_DETAIL' | translate)" icon="pi pi-cog" styleClass="p-button" + [ariaLabel]="openButtonTitle || ('OCX_CUSTOM_GROUP_COLUMN_SELECTOR.OPEN_BUTTON_DETAIL' | translate)" > - + {{ dialogTitle || ('OCX_CUSTOM_GROUP_COLUMN_SELECTOR.DIALOG_TITLE' | translate) }}
{{ item.nameKey | translate }}
diff --git a/libs/portal-integration-angular/src/lib/core/components/data-list-grid-sorting/data-list-grid-sorting.component.html b/libs/portal-integration-angular/src/lib/core/components/data-list-grid-sorting/data-list-grid-sorting.component.html index 2e38b895..12c42477 100644 --- a/libs/portal-integration-angular/src/lib/core/components/data-list-grid-sorting/data-list-grid-sorting.component.html +++ b/libs/portal-integration-angular/src/lib/core/components/data-list-grid-sorting/data-list-grid-sorting.component.html @@ -19,5 +19,6 @@ styleClass="p-button-outlined" (onClick)="sortDirectionChanged()" [title]="(sortIconTitle() | translate)" + [ariaLabel]="('OCX_LIST_GRID_SORT.SORTING_BUTTON_ARIA_LABEL' | translate:{direction: (sortDirectionToTitle(nextSortDirection())) | translate})" > diff --git a/libs/portal-integration-angular/src/lib/core/components/data-list-grid-sorting/data-list-grid-sorting.component.ts b/libs/portal-integration-angular/src/lib/core/components/data-list-grid-sorting/data-list-grid-sorting.component.ts index 1ca7c68a..16ee27a9 100644 --- a/libs/portal-integration-angular/src/lib/core/components/data-list-grid-sorting/data-list-grid-sorting.component.ts +++ b/libs/portal-integration-angular/src/lib/core/components/data-list-grid-sorting/data-list-grid-sorting.component.ts @@ -45,11 +45,15 @@ export class DataListGridSortingComponent implements OnInit { this.sortChange.emit(event.value.columnId) } sortDirectionChanged(): void { - const newSortDirection = this.sortStates[(this.sortStates.indexOf(this.sortDirection) + 1) % this.sortStates.length] + const newSortDirection = this.nextSortDirection() this._sortDirection$.next(newSortDirection) this.sortDirectionChange.emit(newSortDirection) } + nextSortDirection() { + return this.sortStates[(this.sortStates.indexOf(this.sortDirection) + 1) % this.sortStates.length] + } + sortIcon() { switch (this.sortDirection) { case DataSortDirection.ASCENDING: @@ -62,7 +66,11 @@ export class DataListGridSortingComponent implements OnInit { } sortIconTitle() { - switch (this.sortDirection) { + return this.sortDirectionToTitle(this.sortDirection) + } + + sortDirectionToTitle(sortDirection: DataSortDirection) { + switch (sortDirection) { case DataSortDirection.ASCENDING: return 'OCX_LIST_GRID_SORT.TOGGLE_BUTTON.ASCENDING_TITLE' case DataSortDirection.DESCENDING: diff --git a/libs/portal-integration-angular/src/lib/core/components/data-list-grid/data-list-grid.component.html b/libs/portal-integration-angular/src/lib/core/components/data-list-grid/data-list-grid.component.html index 8a0fe6f7..ec90279a 100644 --- a/libs/portal-integration-angular/src/lib/core/components/data-list-grid/data-list-grid.component.html +++ b/libs/portal-integration-angular/src/lib/core/components/data-list-grid/data-list-grid.component.html @@ -58,6 +58,7 @@ pButton (click)="setSelectedItem(item); menu.toggle($event)" icon="pi pi-ellipsis-v" + [ariaLabel]="'OCX_DATA_LIST_GRID.MORE_ACTIONS' | translate" class="more-actions-menu-button menu-btn" > @@ -81,11 +82,10 @@
filter.columnId === columnId).map((filter) => filter.value) } - sortIconTitle() { - switch (this.sortDirection) { + sortIconTitle(sortColumn: string) { + return this.sortDirectionToTitle( + sortColumn !== this.sortDirection + ? DataSortDirection.NONE + : this.sortStates[this.sortStates.indexOf(this.sortDirection) % this.sortStates.length] + ) + } + + sortDirectionToTitle(sortDirection: DataSortDirection) { + switch (sortDirection) { case DataSortDirection.ASCENDING: - return 'OCX_LIST_GRID_SORT.TOGGLE_BUTTON.ASCENDING_TITLE' + return 'OCX_DATA_TABLE.TOGGLE_BUTTON.ASCENDING_TITLE' case DataSortDirection.DESCENDING: - return 'OCX_LIST_GRID_SORT.TOGGLE_BUTTON.DESCENDING_TITLE' + return 'OCX_DATA_TABLE.TOGGLE_BUTTON.DESCENDING_TITLE' default: - return 'OCX_LIST_GRID_SORT.TOGGLE_BUTTON.DEFAULT_TITLE' + return 'OCX_DATA_TABLE.TOGGLE_BUTTON.DEFAULT_TITLE' } } diff --git a/libs/portal-integration-angular/src/lib/core/components/data-view-controls/data-view-controls.component.html b/libs/portal-integration-angular/src/lib/core/components/data-view-controls/data-view-controls.component.html index b70d0f88..797784cf 100644 --- a/libs/portal-integration-angular/src/lib/core/components/data-view-controls/data-view-controls.component.html +++ b/libs/portal-integration-angular/src/lib/core/components/data-view-controls/data-view-controls.component.html @@ -27,7 +27,7 @@ type="button" (click)="toggleColumns()" pButton - [title]="translations?.toggleColumnButtonTooltip || ('OCX_CUSTOM_GROUP_COLUMN_SELECTOR.OPEN_BUTTON_TITLE' | translate)" + [title]="translations?.toggleColumnButtonTooltip || ('OCX_CUSTOM_GROUP_COLUMN_SELECTOR.OPEN_BUTTON_DETAIL' | translate)" icon="pi pi-cog" >
diff --git a/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.html b/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.html index bd778301..88c7a1a0 100644 --- a/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.html +++ b/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.html @@ -3,7 +3,8 @@
@@ -23,8 +24,8 @@
-

{{ header }}

-

{{ subheader }}

+

{{ header }}

+

{{ subheader }}

@@ -64,6 +65,7 @@

{{ subheader }}

class="more-actions-menu-button action-button ml-2" (click)="menu.toggle($event)" name="ocx-page-header-overflow-action-button" + [ariaLabel]="('OCX_PAGE_HEADER.MORE_ACTIONS' | translate)" >
diff --git a/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.scss b/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.scss index e3941bbc..27d1dee6 100644 --- a/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.scss +++ b/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.scss @@ -57,13 +57,13 @@ justify-content: center; flex-direction: column; } - h3 { + h1 { font-size: 1em; font-weight: 700; margin: 0px; padding: 0px; } - h4 { + h2 { font-size: 1em; font-weight: 400; margin: 0px; diff --git a/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.ts b/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.ts index 859d5ca4..4ad11e35 100644 --- a/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.ts +++ b/libs/portal-integration-angular/src/lib/core/components/page-header/page-header.component.ts @@ -53,6 +53,11 @@ export interface ObjectDetailItem { valuePipeArgs?: string } +export interface HomeItem { + menuItem: MenuItem + page?: string +} + @Component({ selector: 'ocx-page-header', templateUrl: './page-header.component.html', @@ -113,7 +118,7 @@ export class PageHeaderComponent implements OnInit, OnChanges { dd = new Date() breadcrumbs$!: Observable - home$!: Observable + home$!: Observable protected breadcrumbs: BreadcrumbService @@ -125,8 +130,16 @@ export class PageHeaderComponent implements OnInit, OnChanges { ) { this.breadcrumbs = breadcrumbs this.home$ = concat( - of({ icon: PrimeIcons.HOME, routerLink: '/' }), - this.appStateService.currentPortal$.pipe(map((portal) => ({ icon: PrimeIcons.HOME, routerLink: portal.baseUrl }))) + of({ menuItem: { icon: PrimeIcons.HOME, routerLink: '/' } }), + this.appStateService.currentPortal$.pipe( + map((portal) => ({ + menuItem: { + icon: PrimeIcons.HOME, + routerLink: portal.baseUrl, + }, + page: portal.portalName, + })) + ) ) } ngOnChanges(changes: SimpleChanges): void { diff --git a/libs/portal-integration-angular/testing/default-list-item.harness.ts b/libs/portal-integration-angular/testing/default-list-item.harness.ts index 3b5415ec..d4956af5 100644 --- a/libs/portal-integration-angular/testing/default-list-item.harness.ts +++ b/libs/portal-integration-angular/testing/default-list-item.harness.ts @@ -6,9 +6,9 @@ export class DefaultListItemHarness extends ComponentHarness { static hostSelector = '.data-list-items' getAllActionButtons = this.locatorForAll('button') - getViewButton = this.locatorForOptional(ButtonHarness.with({ id: 'viewListItemButton' })) - getEditButton = this.locatorForOptional(ButtonHarness.with({ id: 'editListItemButton' })) - getDeleteButton = this.locatorForOptional(ButtonHarness.with({ id: 'deleteListItemButton' })) + getViewButton = this.locatorForOptional(ButtonHarness.with({ class: 'viewListItemButton' })) + getEditButton = this.locatorForOptional(ButtonHarness.with({ class: 'editListItemButton' })) + getDeleteButton = this.locatorForOptional(ButtonHarness.with({ class: 'deleteListItemButton' })) private getAllDivs = this.locatorForAll(DivHarness) diff --git a/libs/portal-integration-angular/testing/primeng/p-multiSelect.harness.ts b/libs/portal-integration-angular/testing/primeng/p-multiSelect.harness.ts index 6d77133c..4ead5e87 100644 --- a/libs/portal-integration-angular/testing/primeng/p-multiSelect.harness.ts +++ b/libs/portal-integration-angular/testing/primeng/p-multiSelect.harness.ts @@ -3,21 +3,26 @@ import { PMultiSelectListItemHarness } from './p-multiSelectListItem.harness' export interface PMultiSelectHarnessFilters extends BaseHarnessFilters { id?: string + class?: string } export class PMultiSelectHarness extends ComponentHarness { static hostSelector = 'p-multiSelect' static with(options: PMultiSelectHarnessFilters): HarnessPredicate { - return new HarnessPredicate(PMultiSelectHarness, options).addOption('id', options.id, (harness, id) => - HarnessPredicate.stringMatches(harness.getId(), id) - ) + return new HarnessPredicate(PMultiSelectHarness, options) + .addOption('id', options.id, (harness, id) => HarnessPredicate.stringMatches(harness.getId(), id)) + .addOption('class', options.class, (harness, c) => HarnessPredicate.stringMatches(harness.getByClass(c), c)) } async getId(): Promise { return await (await this.host()).getAttribute('id') } + async getByClass(c: string): Promise { + return (await (await this.host()).hasClass(c)) ? c : '' + } + async getHarnessLoaderForPMultiSelectPanel(): Promise { const rootLocator = this.documentRootLocatorFactory() return rootLocator.harnessLoaderFor('.p-multiselect-panel') diff --git a/libs/portal-integration-angular/testing/table-header-column.harness.ts b/libs/portal-integration-angular/testing/table-header-column.harness.ts index 4ab4cf2f..c504a68b 100644 --- a/libs/portal-integration-angular/testing/table-header-column.harness.ts +++ b/libs/portal-integration-angular/testing/table-header-column.harness.ts @@ -7,13 +7,13 @@ export class TableHeaderColumnHarness extends ContentContainerComponentHarness { getSortButton = this.locatorFor( ButtonHarness.with({ - id: 'sortButton', + class: 'sortButton', }) ) getFilterMultiSelect = this.locatorFor( PMultiSelectHarness.with({ - id: 'filterMultiSelect', + class: 'filterMultiSelect', }) ) diff --git a/libs/portal-integration-angular/testing/table-row.harness.ts b/libs/portal-integration-angular/testing/table-row.harness.ts index 5cd137a2..e15e803d 100644 --- a/libs/portal-integration-angular/testing/table-row.harness.ts +++ b/libs/portal-integration-angular/testing/table-row.harness.ts @@ -5,9 +5,9 @@ export class TableRowHarness extends ContentContainerComponentHarness { static hostSelector = 'tbody > tr' getAllActionButtons = this.locatorForAll('button') - getViewButton = this.locatorForOptional(ButtonHarness.with({ id: 'viewTableRowButton' })) - getEditButton = this.locatorForOptional(ButtonHarness.with({ id: 'editTableRowButton' })) - getDeleteButton = this.locatorForOptional(ButtonHarness.with({ id: 'deleteTableRowButton' })) + getViewButton = this.locatorForOptional(ButtonHarness.with({ class: 'viewTableRowButton' })) + getEditButton = this.locatorForOptional(ButtonHarness.with({ class: 'editTableRowButton' })) + getDeleteButton = this.locatorForOptional(ButtonHarness.with({ class: 'deleteTableRowButton' })) async getData(): Promise { const tds = await this.locatorForAll('td')()