Skip to content

Commit

Permalink
feat: filter view further improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
markuczy committed Nov 5, 2024
1 parent c784eb0 commit 18b0127
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 48 deletions.
8 changes: 6 additions & 2 deletions libs/angular-accelerator/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,12 @@
},
"TABLE": {
"COLUMN_NAME": "Spaltenname",
"VALUE": "Filterwert"
}
"VALUE": "Filterwert",
"ACTIONS": "Aktionen",
"REMOVE_FILTER_TITLE": "Filter löschen",
"REMOVE_FILTER_ARIA_LABEL": "Filter löschen"
},
"PANEL_TITLE": "Filter"
},
"OCX_SEARCH_HEADER": {
"TOGGLE_BUTTON": {
Expand Down
8 changes: 6 additions & 2 deletions libs/angular-accelerator/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,12 @@
},
"TABLE": {
"COLUMN_NAME": "Column name",
"VALUE": "Filter value"
}
"VALUE": "Filter value",
"ACTIONS": "Actions",
"REMOVE_FILTER_TITLE": "Remove filter",
"REMOVE_FILTER_ARIA_LABEL": "Remove filter"
},
"PANEL_TITLE": "Filters"
},
"OCX_SEARCH_HEADER": {
"TOGGLE_BUTTON": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@
(selectionChange)="onSelectionChange($event)"
[selection]="(selectedRows$ | async) ?? []"
[scrollable]="true"
scrollHeight="flex"
[style]="tableStyle"
paginatorDropdownAppendTo="body"
>
<ng-template pTemplate="header">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ export class DataTableComponent extends DataSortBase implements OnInit, AfterCon
@Input() allowSelectAll = true
@Input() paginator = true
@Input() page = 0
@Input() tableStyle: { [klass: string]: any } | undefined
@Input()
get totalRecordsOnServer(): number | undefined {
return this.params['totalRecordsOnServer'] ? Number(this.params['totalRecordsOnServer']) : undefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<ng-container *ngIf="showChips; else noChipsContent">
<ng-container *ocxIfBreakpoint="'desktop'; elseTemplate: noChipsContent">
<p-button
id="resetFiltersButton"
id="ocxFilterViewReset"
(onClick)="onResetFilersClick()"
icon="pi pi-eraser"
pTooltip="{{ 'OCX_FILTER_VIEW.RESET_FILTERS_BUTTON.DETAIL' | translate }}"
Expand All @@ -14,7 +14,7 @@
<ng-container *ngIf="_fitlerViewNoSelection; else defaultNoFilters" [ngTemplateOutlet]="_fitlerViewNoSelection">
</ng-container>
<ng-template #defaultNoFilters>
<span id="noFiltersMessage">{{ 'OCX_FILTER_VIEW.NO_FILTERS' | translate }}</span>
<span id="ocxFilterViewNoFilters">{{ 'OCX_FILTER_VIEW.NO_FILTERS' | translate }}</span>
</ng-template>
</ng-container>
<ng-container *ngIf="(chipTemplates$ | async) ?? {} as templates">
Expand Down Expand Up @@ -78,7 +78,7 @@
</ng-container>
<ng-template #noChipsContent>
<p-button
id="manageFiltersButton"
id="ocxFilterViewManage"
(onClick)="showPanel($event)"
icon="pi pi-sliders-h"
label="{{ 'OCX_FILTER_VIEW.MANAGE_FILTERS_BUTTON.LABEL' | translate }}"
Expand All @@ -92,16 +92,28 @@
</ng-template>

<ng-template #filterTablePanel>
<p-overlayPanel *ngIf="tableTemplates$ | async as templates" #op [showCloseIcon]="true">
<p-overlayPanel *ngIf="tableTemplates$ | async as templates" #op [showCloseIcon]="true" [style]="panelStyle">
<ng-template pTemplate="content">
<div class="flex justify-content-between align-items-center mb-2">
<span class="text-2xl font-medium">Filters</span>
<div>
<p-button
id="ocxFilterViewOverlayReset"
(onClick)="onResetFilersClick()"
icon="pi pi-eraser"
pTooltip="{{ 'OCX_FILTER_VIEW.RESET_FILTERS_BUTTON.DETAIL' | translate }}"
tooltipPosition="top"
tooltipEvent="hover"
[ariaLabel]="'OCX_FILTER_VIEW.RESET_FILTERS_BUTTON.ARIA_LABEL' | translate"
></p-button>
</div>
</div>
<ocx-data-table
[rows]="(columnFilterDataRows$ | async) ?? []"
[columns]="columnFilterTableColumns"
[emptyResultsMessage]="'OCX_FILTER_VIEW.NO_FILTERS' | translate"
[actionColumnPosition]="'right'"
[paginator]="paginator"
[pageSize]="pageSize"
[pageSizes]="pageSizes"
[paginator]="false"
[tableStyle]="tableStyle"
>
<ng-template pTemplate="columnIdCell" let-rowObject="rowObject" let-column="column">
<ng-container
Expand All @@ -125,6 +137,18 @@
>
</ng-container>
</ng-template>
<ng-template pTemplate="actionsIdCell" let-rowObject="rowObject" let-column="column">
<div>
<button
pButton
class="p-button-rounded p-button-danger p-button-text"
title="{{ 'OCX_FILTER_VIEW.TABLE.REMOVE_FILTER_TITLE' | translate }}"
[attr.aria-label]="'OCX_FILTER_VIEW.TABLE.REMOVE_FILTER_ARIA_LABEL' | translate"
icon="pi pi-trash"
(click)="onFilterDelete(rowObject)"
></button>
</div>
</ng-template>
</ocx-data-table>
</ng-template>
</p-overlayPanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ describe('FilterViewComponent', () => {
})
})

describe('data table', () => {
describe('overlay', () => {
it('should show data table with column filters', async () => {
const datePipe = new DatePipe('en')
let dataTable = await filterView.getDataTable()
Expand All @@ -310,16 +310,58 @@ describe('FilterViewComponent', () => {
expect(dataTable).toBeTruthy()
const headers = await dataTable?.getHeaderColumns()
expect(headers).toBeTruthy()
expect(headers?.length).toBe(2)
expect(headers?.length).toBe(3)
expect(await headers![0].getText()).toBe('Column name')
expect(await headers![1].getText()).toBe('Filter value')
expect(await headers![2].getText()).toBe('Actions')

const rows = await dataTable?.getRows()
expect(rows?.length).toBe(4)
expect(await rows![0].getData()).toEqual(['Name', 'name-filter'])
expect(await rows![1].getData()).toEqual(['Start date', datePipe.transform(deafultDate, 'medium')])
expect(await rows![2].getData()).toEqual(['Status', 'My status'])
expect(await rows![3].getData()).toEqual(['Test number', 'Yes'])
expect(await rows![0].getData()).toEqual(['Name', 'name-filter', ''])
expect(await rows![1].getData()).toEqual(['Start date', datePipe.transform(deafultDate, 'medium'), ''])
expect(await rows![2].getData()).toEqual(['Status', 'My status', ''])
expect(await rows![3].getData()).toEqual(['Test number', 'Yes', ''])
})

it('should show reset all filters button above the table', async () => {
const filtersButton = await filterView.getFiltersButton()
await filtersButton?.click()
fixture.detectChanges()

const resetButton = await filterView.getOverlayResetFiltersButton()
expect(resetButton).toBeTruthy()
const dataTable = await filterView.getDataTable()
expect((await dataTable?.getRows())?.length).toBe(4)

await resetButton?.click()
const rows = await dataTable?.getRows()
expect(rows?.length).toBe(1)
expect(await rows![0].getData()).toEqual(['No filters selected'])
})

it('should show remove filter in action column', async () => {
const filteredEmitterSpy = jest.spyOn(component.filtered, 'emit')
const componentStateEmitterSpy = jest.spyOn(component.componentStateChanged, 'emit')

const filtersButton = await filterView.getFiltersButton()
await filtersButton?.click()
fixture.detectChanges()

const dataTable = await filterView.getDataTable()
let rows = await dataTable?.getRows()
expect(rows?.length).toBe(4)
const buttons = await rows![0].getAllActionButtons()
expect(buttons.length).toBe(1)
await buttons[0].click()

rows = await dataTable?.getRows()
expect(rows?.length).toBe(3)
expect(component.filters.length).toBe(3)
const expectedFilters = mockFilters.filter((f) => f.columnId !== 'name')
expect(filteredEmitterSpy).toHaveBeenCalledWith(expectedFilters)
expect(componentStateEmitterSpy).toHaveBeenCalledWith({
filters: expectedFilters,
})
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ export class FilterViewComponent implements OnInit {
@Input() selectDisplayedChips: (filters: ColumnFilterData[]) => ColumnFilterData[] = (filters) =>
limit(filters, 3, { reverse: true })
@Input() chipStyleClass: string = ''
@Input() pageSize: number | undefined
@Input() pageSizes: number[] = [5, 10, 25]
@Input() paginator: boolean = true
@Input() tableStyle: { [klass: string]: any } = { 'max-height': '50vh' }
@Input() panelStyle: { [klass: string]: any } = { 'max-width': '90%' }

@Output() filtered: EventEmitter<Filter[]> = new EventEmitter()
@Output() componentStateChanged: EventEmitter<FilterViewComponentState> = new EventEmitter()
Expand All @@ -84,6 +83,11 @@ export class FilterViewComponent implements OnInit {
filterable: true,
},
{ id: 'value', columnType: ColumnType.STRING, nameKey: 'OCX_FILTER_VIEW.TABLE.VALUE' },
{
id: 'actions',
columnType: ColumnType.STRING,
nameKey: 'OCX_FILTER_VIEW.TABLE.ACTIONS',
},
]

@ViewChild(OverlayPanel) panel!: OverlayPanel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
[showChips]="showFilterViewChips"
[selectDisplayedChips]="selectDisplayedChips"
[chipStyleClass]="filterViewChipStyleClass"
[pageSize]="filterViewPageSize"
[pageSizes]="filterViewPageSizes"
[paginator]="filterViewPaginator"
[tableStyle]="filterViewTableStyle"
(filtered)="filtering($event)"
(componentStateChanged)="filterViewComponentState$.next($event)"
></ocx-filter-view>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,10 @@ import { SlotService } from '@onecx/angular-remote-components'
import { of } from 'rxjs'
import { ColumnFilterData, FilterType } from '../../model/filter.model'
import { FilterViewComponent } from '../filter-view/filter-view.component'
import { limit } from '../../utils/filter.utils'

type InteractiveDataViewInputTypes = Pick<
InteractiveDataViewComponent,
| 'data'
| 'columns'
| 'emptyResultsMessage'
| 'disableFilterView'
| 'showFilterViewChips'
| 'selectDisplayedChips'
| 'filterViewPageSize'
| 'filterViewPageSizes'
'data' | 'columns' | 'emptyResultsMessage' | 'disableFilterView' | 'showFilterViewChips'
>
const InteractiveDataViewComponentSBConfig: Meta<InteractiveDataViewComponent> = {
title: 'InteractiveDataViewComponent',
Expand Down Expand Up @@ -184,9 +176,6 @@ const defaultComponentArgs: InteractiveDataViewInputTypes = {
emptyResultsMessage: 'No results',
disableFilterView: true,
showFilterViewChips: false,
selectDisplayedChips: (columnFilterData) => limit(columnFilterData, 1, { reverse: true }),
filterViewPageSize: undefined,
filterViewPageSizes: [5, 10, 25],
}

export const WithMockData = {
Expand Down Expand Up @@ -566,14 +555,14 @@ export const WithFilterViewCustomChipSelection = {
},
}

export const WithFilterViewCustomTable = {
export const WithFilterViewCustomStyles = {
render: Template,
args: {
...defaultComponentArgs,
disableFilterView: false,
showFilterViewChips: false,
filterViewPageSize: 2,
filterViewPageSizes: [2, 4, 6],
filterViewTableStyle: { 'max-height': '30vh' },
filterViewPanelStyle: { 'max-width': '80%' },
},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,8 @@ export class InteractiveDataViewComponent implements OnInit, AfterContentInit {
@Input() disableFilterView = true
@Input() showFilterViewChips = false
@Input() filterViewChipStyleClass: string = ''
@Input() filterViewPageSize: number | undefined
@Input() filterViewPageSizes: number[] = [5, 10, 25]
@Input() filterViewPaginator: boolean = true
@Input() filterViewTableStyle: { [klass: string]: any } = { 'max-height': '50vh' }
@Input() filterViewPanelStyle: { [klass: string]: any } = { 'max-width': '90%' }
@Input() selectDisplayedChips: (filters: ColumnFilterData[]) => ColumnFilterData[] = (filters) =>
limit(filters, 3, { reverse: true })
@Input() page = 0
Expand Down
9 changes: 6 additions & 3 deletions libs/angular-accelerator/testing/filter-view.harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ export class FilterViewHarness extends ContentContainerComponentHarness {
static hostSelector = 'ocx-filter-view'

getDataTable = this.documentRootLocatorFactory().locatorForOptional(DataTableHarness)
getFiltersButton = this.locatorForOptional(PButtonHarness.with({ id: 'manageFiltersButton' }))
getChipsResetFiltersButton = this.locatorForOptional(PButtonHarness.with({ id: 'resetFiltersButton' }))
getOverlayResetFiltersButton = this.documentRootLocatorFactory().locatorForOptional(
PButtonHarness.with({ id: 'ocxFilterViewOverlayReset' })
)
getFiltersButton = this.locatorForOptional(PButtonHarness.with({ id: 'ocxFilterViewManage' }))
getChipsResetFiltersButton = this.locatorForOptional(PButtonHarness.with({ id: 'ocxFilterViewReset' }))
getChips = this.locatorForAll(PChipHarness)
getNoFiltersMessage = this.locatorForOptional(SpanHarness.with({ id: 'noFiltersMessage' }))
getNoFiltersMessage = this.locatorForOptional(SpanHarness.with({ id: 'ocxFilterViewNoFilters' }))
}
8 changes: 6 additions & 2 deletions libs/portal-integration-angular/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,12 @@
},
"TABLE": {
"COLUMN_NAME": "Spaltenname",
"VALUE": "Filterwert"
}
"VALUE": "Filterwert",
"ACTIONS": "Aktionen",
"REMOVE_FILTER_TITLE": "Filter löschen",
"REMOVE_FILTER_ARIA_LABEL": "Filter löschen"
},
"PANEL_TITLE": "Filter"
},
"OCX_SEARCH_HEADER": {
"TOGGLE_BUTTON": {
Expand Down
7 changes: 6 additions & 1 deletion libs/portal-integration-angular/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,12 @@
},
"TABLE": {
"COLUMN_NAME": "Column name",
"VALUE": "Filter value"
"VALUE": "Filter value",
"ACTIONS": "Actions",
"REMOVE_FILTER_TITLE": "Remove filter",
"REMOVE_FILTER_ARIA_LABEL": "Remove filter"
},
"PANEL_TITLE": "Filters"
}
},
"OCX_SEARCH_HEADER": {
Expand Down

0 comments on commit 18b0127

Please sign in to comment.