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

fix(platform): Update info bar table to reflect selected filters #12634

Merged
merged 10 commits into from
Nov 6, 2024
Merged
26 changes: 23 additions & 3 deletions libs/docs/platform/table/platform-table-docs.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -398,10 +398,30 @@ <h3>Tree initialization</h3>
>
</fdp-column>

<fdp-column name="description" key="description" label="Description" width="200px"></fdp-column>
<fdp-column
[filterable]="true"
name="description"
key="description"
label="Description"
width="200px"
></fdp-column>

<fdp-column name="price" key="price.value" label="Price" align="end" width="100px"></fdp-column>
<fdp-column
[filterable]="true"
name="price"
key="price.value"
label="Price"
align="end"
width="100px"
></fdp-column>

<fdp-column name="status" key="status" label="Status" align="center" width="150px"></fdp-column>
<fdp-column
[filterable]="true"
name="status"
key="status"
label="Status"
align="center"
width="150px"
></fdp-column>
</fdp-table>
</playground>
1 change: 1 addition & 0 deletions libs/i18n/src/lib/models/fd-language-key-identifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ export type FdLanguageKeyIdentifier =
| 'platformTable.deselectSingleRow'
| 'platformTable.selectSingleRow'
| 'platformTable.loadMore'
| 'platformTable.filteredBy'
| 'platformWizardGenerator.summarySectionEditStep'
| 'platformMessagePopover.allErrors'
| 'platformMessagePopover.defaultErrors.email'
Expand Down
2 changes: 2 additions & 0 deletions libs/i18n/src/lib/translations/translations.properties
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,8 @@ platformTable.deselectSingleRow = To deselect row, press SPACEBAR
platformTable.selectSingleRow = To select row, press SPACEBAR
#XBUT Label for the button, which loads additional rows
platformTable.loadMore = Load more
#XBUT Label for applied filter table toolbar
platformTable.filteredBy = Filtered by
#XBUT Label for the button, navigates to the edit section of the wizard
platformWizardGenerator.summarySectionEditStep = Edit
#XBUT Label for the button, which activates the list of all errors in message popover
Expand Down
3 changes: 2 additions & 1 deletion libs/i18n/src/lib/translations/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,8 @@ export default {
deselectAllCheckboxLabel: 'Deselect all',
deselectSingleRow: 'To deselect row, press SPACEBAR',
selectSingleRow: 'To select row, press SPACEBAR',
loadMore: 'Load more'
loadMore: 'Load more',
filteredBy: 'Filtered by'
},
platformWizardGenerator: {
summarySectionEditStep: 'Edit'
Expand Down
24 changes: 23 additions & 1 deletion libs/platform/table-helpers/services/table.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export class TableService {
}
}

/** Set new sort rules */
/** Set new filter rules */
setFilters(filterRules: CollectionFilter[] | undefined): void {
const prevState = this.getTableState();
const prevFilterRules = (prevState && prevState.filterBy) || [];
Expand Down Expand Up @@ -426,6 +426,8 @@ export class TableService {
* @param state Table state.
*/
buildFilterRulesMap(state = this.getTableState()): void {
const prevState = this.getTableState();
const evt = { current: state.filterBy, previous: prevState.filterBy };
this.filterRules$.set(
state.filterBy.reduce((hash, rule) => {
const key = rule.field;
Expand All @@ -436,6 +438,26 @@ export class TableService {
return hash;
}, new Map<string, CollectionFilter[]>())
);
this.stateChange$.next({ type: 'filter', state: evt });
}

/** Reset all filter rules */
resetFilters(): void {
const prevState = this.getTableState();
const prevFilterRules = (prevState && prevState.filterBy) || [];

const newFilterRules: CollectionFilter[] = [];
const state: TableState = { ...prevState, filterBy: newFilterRules };

if (!equal(prevFilterRules, state.filterBy)) {
this.setTableState(setCurrentPageToState(state, 1));
const evt = { current: state.filterBy, previous: prevFilterRules };

this.buildFilterRulesMap();
this.needFetch$.next();
this.stateChange$.next({ type: 'filter', state: evt });
this.filterChange$.next(evt);
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions libs/platform/table-helpers/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ export abstract class Table<T = any> implements PresetManagedComponent<PlatformT
/** Toolbar Column Settings button click event */
readonly openTableColumnSettings: EventEmitter<void> = new EventEmitter<void>();

/** Event fired when table state changes. */
readonly tableColumnFilterChange: EventEmitter<any> = new EventEmitter<void>();

/** Event fired when empty row added. */
readonly emptyRowAdded: EventEmitter<void>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
let-groupable="groupable"
let-columns="columns"
let-hasAnyActions="hasAnyActions"
let-appliedFilters="appliedFilters"
>
<fd-toolbar
fdType="transparent"
Expand Down Expand Up @@ -157,4 +158,33 @@
}
}
</fd-toolbar>
@if (appliedFilters().length) {
<fd-toolbar
fdType="info"
[active]="true"
[titleId]="tableToolbarTitleId"
[shouldOverflow]="shouldOverflow"
[headingLevel]="headingLevel"
>
<label fd-toolbar-label>
{{ 'platformTable.filteredBy' | fdTranslate }}:
@for (filter of appliedFilters(); track filter.columnName; let i = $index) {
{{ filter.columnName }} ({{ filter.params }})
@if (i < appliedFilters().length - 1) {
,
}
}
</label>
<fd-toolbar-spacer></fd-toolbar-spacer>
<button
fdCompact
(click)="_closeFilterToolbar()"
fd-button
fdType="transparent"
glyph="decline"
ariaLabel="Close Toolbar Button"
title="Close Toolbar Button"
></button>
</fd-toolbar>
}
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ import { AsyncPipe, NgTemplateOutlet } from '@angular/common';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { Nullable } from '@fundamental-ngx/cdk/utils';
import { ButtonComponent } from '@fundamental-ngx/core/button';
import { ContentDensityDirective } from '@fundamental-ngx/core/content-density';
import { HeadingLevel } from '@fundamental-ngx/core/shared';
import {
ToolbarComponent,
ToolbarItemDirective,
ToolbarLabelDirective,
ToolbarSeparatorComponent,
ToolbarSpacerDirective
} from '@fundamental-ngx/core/toolbar';
Expand All @@ -31,13 +33,19 @@ import { TABLE_TOOLBAR, TableToolbarInterface } from './table-toolbar';
import { TableToolbarActionsComponent } from './table-toolbar-actions.component';
import { TableToolbarLeftActionsComponent } from './table-toolbar-left-actions.component';

export interface TableAppliedFilter {
columnName: string;
params: string;
}

export interface ToolbarContext {
counter: Signal<number>;
sortable: Signal<boolean>;
filterable: Signal<boolean>;
groupable: Signal<boolean>;
columns: Signal<boolean>;
hasAnyActions: Signal<boolean>;
appliedFilters: Signal<TableAppliedFilter[]>;
}

export type EditMode = 'none' | 'inline';
Expand Down Expand Up @@ -89,7 +97,9 @@ export class TableToolbarTemplateDirective {
ButtonComponent,
AsyncPipe,
FdTranslatePipe,
TableToolbarTemplateDirective
TableToolbarTemplateDirective,
ToolbarLabelDirective,
ContentDensityDirective
]
})
export class TableToolbarComponent implements TableToolbarInterface {
Expand Down Expand Up @@ -168,7 +178,10 @@ export class TableToolbarComponent implements TableToolbarInterface {
private readonly _destroyRef = inject(DestroyRef);

/** @hidden */
constructor(private readonly _table: Table) {
constructor(
private _tableService: TableService,
private readonly _table: Table
) {
this._listenToTableEvents();
}

Expand Down Expand Up @@ -217,6 +230,11 @@ export class TableToolbarComponent implements TableToolbarInterface {
this._table.expandAll();
}

/** @hidden */
_closeFilterToolbar(): void {
this._tableService.resetFilters();
}

/** @hidden */
_collapseAll(): void {
this._table.collapseAll();
Expand Down
37 changes: 34 additions & 3 deletions libs/platform/table/table.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ import {
NoDataWrapperComponent,
PlatformTableColumnResizerComponent,
TABLE_TOOLBAR,
TableAppliedFilter,
TableToolbarInterface,
ToolbarContext
} from './components';
Expand Down Expand Up @@ -460,6 +461,7 @@ export class TableComponent<T = any>
this._semanticHighlightingKey = value;
this._setSemanticHighlighting();
}

get semanticHighlighting(): string {
if (!this._semanticHighlightingKey && this._forceSemanticHighlighting) {
return DEFAULT_HIGHLIGHTING_KEY;
Expand Down Expand Up @@ -810,6 +812,8 @@ export class TableComponent<T = any>
/** @hidden */
private readonly _isShownGroupSettingsInToolbar$ = signal(false);
/** @hidden */
private _appliedFilterNames = signal<TableAppliedFilter[]>([]);
/** @hidden */
private readonly _isShownColumnSettingsInToolbar$ = signal(false);
/**
* @hidden
Expand Down Expand Up @@ -873,7 +877,6 @@ export class TableComponent<T = any>
this._dndTableDirective?.setTable(this);
this._virtualScrollDirective?.setTable(this);
this._dataSourceDirective.setTable(this);

this._rowTrackBy = this._defaultTrackBy;
this._toolbarContext = {
counter: this._dataSourceDirective.totalItems$,
Expand All @@ -887,7 +890,8 @@ export class TableComponent<T = any>
this._isShownFilterSettingsInToolbar$() ||
this._isShownGroupSettingsInToolbar$() ||
this._isShownColumnSettingsInToolbar$()
)
),
appliedFilters: this._appliedFilterNames
};

this.tableColumnsStream = this._tableService.tableColumns$.asObservable();
Expand Down Expand Up @@ -1812,7 +1816,6 @@ export class TableComponent<T = any>
this._dataSourceDirective._tableDataSource.fetch(state);
})
);

this._subscriptions.add(
this._tableService.stateChange$.subscribe(({ type, state }) => {
switch (type) {
Expand All @@ -1824,6 +1827,8 @@ export class TableComponent<T = any>
break;
case 'filter':
this.filterChange.emit(new TableFilterChangeEvent(this, state.current, state.previous));
this.tableColumnFilterChange.emit();
this._setAppliedFilterNames(state.current);
break;
case 'freeze':
if (!this._lastFreezableColumnCalculation) {
Expand Down Expand Up @@ -1852,6 +1857,32 @@ export class TableComponent<T = any>
this._listenToTableRowStateChange();
}

/** @hidden */
private _setAppliedFilterNames(filters: CollectionFilter[]): void {
const formattedFilters = filters.map((f) => ({
columnName: this._formatColumnName(f.field),
params: this._formatParams(f.value)
}));

this._appliedFilterNames.set(formattedFilters);
}

// Helper function to format nested parameters
private _formatParams(value: any): string {
if (typeof value !== 'object' || value === null) {
return String(value); // Handle non-object values
}

return Object.entries(value)
.map(([key, val]) => `${key}: ${this._formatParams(val)}`) // Recursive call for nested objects
.join(', ');
}

/** @hidden */
private _formatColumnName(columnName: string): string {
return columnName.charAt(0).toUpperCase() + columnName.slice(1);
}

/** @hidden */
private _listenToTableRowStateChange(): void {
this._subscriptions.add(
Expand Down