Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: basic search to simple search with aria labels improvements #146

18 changes: 16 additions & 2 deletions libs/portal-integration-angular/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,27 @@
},
"OCX_SEARCH_HEADER": {
"TOGGLE_BUTTON": {
"BASIC": "Basis",
"ADVANCED": "Erweitert"
"SIMPLE": {
"TEXT": "Einfach",
"ARIA_LABEL": "Zu einfachen Suchkriterien wechseln"
},
"ADVANCED": {
"TEXT": "Erweitert",
"ARIA_LABEL": "Zu erweiterten Suchkriterien wechseln"
}
},
"OCX_SEARCH_CONFIG": {
"DROPDOWN_DEFAULT": "Gespeicherte Suchvorlage auswählen"
},
"HEADLINE": "Suche",
"RESET_BUTTON": {
"TEXT": "Zurücksetzen",
"ARIA_LABEL": "Suchkriterien zurücksetzen"
},
"SEARCH_BUTTON": {
"TEXT": "Suchen",
"ARIA_LABEL": "Suchen"
},
"RESET_BUTTON_TEXT": "Zurücksetzen",
"SEARCH_BUTTON_TEXT": "Suchen",
"EXPORT": "Alle Ereignisse exportieren"
Expand Down
20 changes: 16 additions & 4 deletions libs/portal-integration-angular/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,27 @@
},
"OCX_SEARCH_HEADER": {
"TOGGLE_BUTTON": {
"BASIC": "Basic",
"ADVANCED": "Advanced"
"SIMPLE": {
"TEXT": "Simple",
"ARIA_LABEL": "Switch to simple search criteria"
},
"ADVANCED": {
"TEXT": "Advanced",
"ARIA_LABEL": "Switch to advanced search criteria"
}
},
"OCX_SEARCH_CONFIG": {
"DROPDOWN_DEFAULT": "Pick predefined template"
},
"HEADLINE": "Search",
"RESET_BUTTON_TEXT": "Reset",
"SEARCH_BUTTON_TEXT": "Search",
"RESET_BUTTON": {
"TEXT": "Reset",
"ARIA_LABEL": "Reset search criteria"
},
"SEARCH_BUTTON": {
"TEXT": "Search",
"ARIA_LABEL": "Search"
},
"EXPORT": "Export all events"
},
"OCX_PAGE_HEADER": {
Expand Down
2 changes: 1 addition & 1 deletion libs/portal-integration-angular/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export * from './lib/core/directives/autofocus.directive'
export * from './lib/core/directives/if-breakpoint.directive'
export * from './lib/core/directives/if-permission.directive'
export * from './lib/core/directives/advanced.directive'
export * from './lib/core/directives/basic.directive'
export * from './lib/core/directives/simple.directive'
export * from './lib/core/directives/patch-form-group-values.driective'
export * from './lib/core/directives/set-input-value.directive'
export * from './lib/core/directives/loading-indicator.directive'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ <h4>{{ subheader }}</h4>
[title]="(action.titleKey ? (action.titleKey | translate) : action.title) || (action.labelKey ? (action.labelKey | translate) : action.label)"
[disabled]="action.disabled ? action.disabled : false"
[attr.name]="action.icon ? 'ocx-page-header-inline-action-icon-button' : 'ocx-page-header-inline-action-button'"
[ariaLabel]="action.ariaLabel ? (action.ariaLabel | translate) : (action.titleKey ? (action.titleKey | translate) : action.title) || (action.labelKey ? (action.labelKey | translate) : action.label)"
></p-button>
</ng-container>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface Action {
// Note: This currently doesn't work with dynamic values, since a passed in Action is just a copy of the original object.
// As a workaround, you can manually update/replace the passed in Action if you wish to update a showCondition
showCondition?: boolean
ariaLabel?: string
}

export interface ObjectDetailItem {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('SearchConfigComponent', () => {
const searchConfigs: SearchConfig[] = [
{
id: '01',
name: 'Basic search config',
name: 'Simple search config',
version: 1,
readonly: true,
isAdvanced: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default {
MenuModule,
BreadcrumbModule,
SkeletonModule,
StorybookTranslateModule
StorybookTranslateModule,
],
providers: [],
}),
Expand Down Expand Up @@ -117,7 +117,7 @@ const TemplateWithProjectionAndExtraToolbar: StoryFn<SearchCriteriaComponent> =
</ocx-search-criteria>`,
})

export const Basic = {
export const Simple = {
render: Template,

args: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,18 @@ export class SearchCriteriaComponent extends PageHeaderComponent implements OnIn
}

/** Event emitted when the search button has been pressed. */
@Output() readonly search: EventEmitter<'basic' | 'advanced'> = new EventEmitter<'basic' | 'advanced'>()
@Output() readonly search: EventEmitter<'simple' | 'advanced'> = new EventEmitter<'simple' | 'advanced'>()
markuczy marked this conversation as resolved.
Show resolved Hide resolved

/** Event emitted when the reset button has been pressed. */
// eslint-disable-next-line @angular-eslint/no-output-native
@Output() readonly reset: EventEmitter<'basic' | 'advanced'> = new EventEmitter<'basic' | 'advanced'>()
@Output() readonly reset: EventEmitter<'simple' | 'advanced'> = new EventEmitter<'simple' | 'advanced'>()

/** Event emitted when the adnvanced view has been toggled. */
@Output() readonly advancedViewToggle = new EventEmitter()

protected advancedSearchActive = false

// in BASIC mode ... enable switching to ADVANCED
// in SIMPLE mode ... enable switching to ADVANCED
private enableAdvancedSearch: Action = {
label: 'Advanced',
title: 'Switch to Advanced Search',
Expand All @@ -60,10 +60,10 @@ export class SearchCriteriaComponent extends PageHeaderComponent implements OnIn
this.activateAdvancedSearch(true)
},
}
// in ADVANCED mode ... enable switching to BASIC
private enableBasicSearch: Action = {
label: 'Basic',
title: 'Switch to Basic Search',
// in ADVANCED mode ... enable switching to SIMPLE
private enableSimpleSearch: Action = {
label: 'Simple',
title: 'Switch to Simple Search',
show: 'always',
actionCallback: () => {
this.activateAdvancedSearch(false)
Expand All @@ -75,7 +75,7 @@ export class SearchCriteriaComponent extends PageHeaderComponent implements OnIn
translateService: TranslateService,
appStateService: AppStateService,
userService: UserService,
@Inject(PortalSearchPage) @Optional() private searchPage?: PortalSearchPage<unknown>,
@Inject(PortalSearchPage) @Optional() private searchPage?: PortalSearchPage<unknown>
) {
super(breadcrumbs, translateService, appStateService, userService)
}
Expand All @@ -95,28 +95,28 @@ export class SearchCriteriaComponent extends PageHeaderComponent implements OnIn
this.advancedViewToggle.emit()
}
protected emitSearchEvent() {
this.search.emit(this.advancedSearchActive ? 'advanced' : 'basic')
this.search.emit(this.advancedSearchActive ? 'advanced' : 'simple')
if (this.searchPage) {
this.searchPage.onSearch(this.advancedSearchActive ? 'advanced' : 'basic')
this.searchPage.onSearch(this.advancedSearchActive ? 'advanced' : 'simple')
}
}
protected emitResetEvent() {
this.reset.emit(this.advancedSearchActive ? 'advanced' : 'basic')
this.reset.emit(this.advancedSearchActive ? 'advanced' : 'simple')
if (this.searchPage) {
this.searchPage.onReset(this.advancedSearchActive ? 'advanced' : 'basic')
this.searchPage.onReset(this.advancedSearchActive ? 'advanced' : 'simple')
}
}

public activateAdvancedSearch(advanced: boolean) {
this.advancedSearchActive = advanced
const actions = [...(this.actions || [])]
const index = actions.findIndex(
(a) => (advanced && a === this.enableAdvancedSearch) || (!advanced && a === this.enableBasicSearch)
(a) => (advanced && a === this.enableAdvancedSearch) || (!advanced && a === this.enableSimpleSearch)
)
if (index >= 0) {
actions[index] = advanced ? this.enableBasicSearch : this.enableAdvancedSearch
actions[index] = advanced ? this.enableSimpleSearch : this.enableAdvancedSearch
} else {
actions.push(advanced ? this.enableBasicSearch : this.enableAdvancedSearch)
actions.push(advanced ? this.enableSimpleSearch : this.enableAdvancedSearch)
}
this.actions = actions
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ export abstract class PortalSearchPage<T> {
searchInProgress = false
public results: T[] = []

abstract search(mode: 'basic' | 'advanced'): T[] | Observable<T[]>
abstract reset(mode: 'basic' | 'advanced'): void
abstract search(mode: 'simple' | 'advanced'): T[] | Observable<T[]>
abstract reset(mode: 'simple' | 'advanced'): void

onSearch(mode: 'basic' | 'advanced') {
onSearch(mode: 'simple' | 'advanced') {
this.searchInProgress = true
const resultIntermediate = this.search(mode)
if (isObservable(resultIntermediate)) {
Expand All @@ -31,7 +31,7 @@ export abstract class PortalSearchPage<T> {
}
}

onReset(mode: 'basic' | 'advanced') {
onReset(mode: 'simple' | 'advanced') {
this.results = []
this.reset(mode)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@
id="resetButton"
*ngIf="resetted.observed"
(onClick)="onResetClicked()"
label="{{ 'OCX_SEARCH_HEADER.RESET_BUTTON_TEXT' | translate }}"
label="{{ 'OCX_SEARCH_HEADER.RESET_BUTTON.TEXT' | translate }}"
icon="pi pi-eraser"
[attr.aria-label]="'OCX_SEARCH_HEADER.RESET_BUTTON_TEXT' | translate"
title="{{ 'OCX_SEARCH_HEADER.RESET_BUTTON_TEXT' | translate }}"
[ariaLabel]="'OCX_SEARCH_HEADER.RESET_BUTTON.ARIA_LABEL' | translate"
title="{{ 'OCX_SEARCH_HEADER.RESET_BUTTON.TEXT' | translate }}"
>
</p-button>

<p-button
id="searchButton"
(onClick)="onSearchClicked()"
label="{{ 'OCX_SEARCH_HEADER.SEARCH_BUTTON_TEXT' | translate }}"
label="{{ 'OCX_SEARCH_HEADER.SEARCH_BUTTON.TEXT' | translate }}"
icon="pi pi-search"
[attr.aria-label]="'OCX_SEARCH_HEADER.SEARCH_BUTTON_TEXT' | translate"
title="{{ 'OCX_SEARCH_HEADER.SEARCH_BUTTON_TEXT' | translate }}"
[ariaLabel]="'OCX_SEARCH_HEADER.SEARCH_BUTTON.ARIA_LABEL' | translate"
title="{{ 'OCX_SEARCH_HEADER.SEARCH_BUTTON.TEXT' | translate }}"
>
</p-button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { SearchConfig } from '../../../model/search-config'
export class SearchHeaderComponent implements AfterViewInit {
@Input() searchConfigs: SearchConfig[] | undefined
@Input() headline = ''
@Input() viewMode: 'basic' | 'advanced' = 'basic'
@Input() viewMode: 'simple' | 'advanced' = 'simple'
@Input() manualBreadcrumbs = false
_actions: Action[] = []
@Input()
Expand Down Expand Up @@ -59,7 +59,7 @@ export class SearchHeaderComponent implements AfterViewInit {
}

toggleViewMode() {
this.viewMode = this.viewMode === 'basic' ? 'advanced' : 'basic'
this.viewMode = this.viewMode === 'simple' ? 'advanced' : 'simple'
this.viewModeChanged?.emit(this.viewMode)
this.updateHeaderActions()
setTimeout(() => this.addKeyUpEventListener())
Expand All @@ -77,13 +77,17 @@ export class SearchHeaderComponent implements AfterViewInit {
const headerActions: Action[] = []
if (this.hasAdvanced) {
headerActions.push({
id: 'basicAdvancedButton',
id: 'simpleAdvancedButton',
labelKey:
this.viewMode === 'basic'
? 'OCX_SEARCH_HEADER.TOGGLE_BUTTON.ADVANCED'
: 'OCX_SEARCH_HEADER.TOGGLE_BUTTON.BASIC',
this.viewMode === 'simple'
? 'OCX_SEARCH_HEADER.TOGGLE_BUTTON.ADVANCED.TEXT'
: 'OCX_SEARCH_HEADER.TOGGLE_BUTTON.SIMPLE.TEXT',
actionCallback: () => this.toggleViewMode(),
show: 'always',
ariaLabel:
this.viewMode === 'simple'
? 'OCX_SEARCH_HEADER.TOGGLE_BUTTON.ADVANCED.ARIA_LABEL'
: 'OCX_SEARCH_HEADER.TOGGLE_BUTTON.SIMPLE.ARIA_LABEL',
})
}
this.headerActions = headerActions.concat(this.actions)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { Directive, DoCheck, Optional, TemplateRef, ViewContainerRef } from '@angular/core'
import { SearchHeaderComponent } from '../components/search-header/search-header.component'

@Directive({ selector: '[ocxBasic]' })
export class BasicDirective implements DoCheck {
@Directive({ selector: '[ocxSimple]' })
export class SimpleDirective implements DoCheck {
constructor(
private viewContainer: ViewContainerRef,
@Optional() private templateRef?: TemplateRef<any>,
@Optional() private searchHeader?: SearchHeaderComponent
) {
if (!searchHeader) {
throw 'Basic directive can only be used inside search header component'
throw 'Simple directive can only be used inside search header component'
}
}
ngDoCheck(): void {
if (this.searchHeader?.viewMode === 'basic') {
if (this.searchHeader?.viewMode === 'simple') {
if (this.templateRef && !this.viewContainer.length) {
this.viewContainer.createEmbeddedView(this.templateRef)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import { ColumnGroupSelectionComponent } from './components/column-group-selecti
import { CustomGroupColumnSelectorComponent } from './components/custom-group-column-selector/custom-group-column-selector.component'
import { SearchHeaderComponent } from './components/search-header/search-header.component'
import { AdvancedDirective } from './directives/advanced.directive'
import { BasicDirective } from './directives/basic.directive'
import { SimpleDirective } from './directives/simple.directive'
import { DataListGridSortingComponent } from './components/data-list-grid-sorting/data-list-grid-sorting.component'
import { RelativeDatePipe } from './pipes/relative-date.pipe'
import { PatchFormGroupValuesDirective } from './directives/patch-form-group-values.driective'
Expand Down Expand Up @@ -154,7 +154,7 @@ export class PortalMissingTranslationHandler implements MissingTranslationHandle
LoadingIndicatorComponent,
LoadingIndicatorDirective,
AdvancedDirective,
BasicDirective,
SimpleDirective,
DataListGridSortingComponent,
RelativeDatePipe,
PatchFormGroupValuesDirective,
Expand Down Expand Up @@ -226,7 +226,7 @@ export class PortalMissingTranslationHandler implements MissingTranslationHandle
LoadingIndicatorComponent,
LoadingIndicatorDirective,
AdvancedDirective,
BasicDirective,
SimpleDirective,
RelativeDatePipe,
PatchFormGroupValuesDirective,
SetInputValueDirective,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ describe('PortalDialogService', () => {
let fixture: ComponentFixture<BaseTestComponent>

const translations = {
TITLE_TRANSLATE: 'basicTitle',
TITLE_TRANSLATE: 'simpleTitle',
TITLE_TRANSLATE_PARAM: 'translatedTitle {{val}}',
MESSAGE: 'myMessage',
MESSAGE_PARAM: 'myMessage {{val}}',
Expand Down
12 changes: 6 additions & 6 deletions libs/portal-integration-angular/testing/search-header.harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export class SearchHeaderHarness extends ContentContainerComponentHarness {
})
)

getBasicAdvancedButton = this.locatorForOptional(
getSimpleAdvancedButton = this.locatorForOptional(
ButtonHarness.with({
id: 'basicAdvancedButton',
id: 'simpleAdvancedButton',
})
)

Expand All @@ -34,11 +34,11 @@ export class SearchHeaderHarness extends ContentContainerComponentHarness {
await (await this.getResetButton()).click()
}

async toggleBasicAdvanced() {
if (await this.getBasicAdvancedButton()) {
await (await this.getBasicAdvancedButton())?.click()
async toggleSimpleAdvanced() {
if (await this.getSimpleAdvancedButton()) {
await (await this.getSimpleAdvancedButton())?.click()
} else {
console.warn('No BasicAdvancedButton is being displayed to toggle, because no advanced form field is defined.')
console.warn('No SimpleAdvancedButton is being displayed to toggle, because no advanced form field is defined.')
}
}
}
Loading