mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merged PR 1843: feat(libs-shared-filter): show selected filter count on filter button
feat(libs-shared-filter): show selected filter count on filter button - Display the number of selected filters as a badge on the filter menu button when filters are active. - Add `.has-selected-filter` styling for visual emphasis when filters are selected. - Update FilterService to provide a computed `selectedFilterCount` property, counting non-default filter inputs. - Remove direct icon rendering from the button; icon is now handled by the button component. - Update tests to mock and assert the new selected filter count logic. Ref: #5070
This commit is contained in:
committed by
Lorenz Hilpert
parent
bd7faeb1b5
commit
bcd3c800b1
@@ -214,6 +214,37 @@ export class FilterService {
|
||||
return isEqual(currentInputState, defaultInputState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the number of filter inputs that are currently selected (i.e., not in their default state).
|
||||
*
|
||||
* - For checkbox inputs, increments the count if any values are selected.
|
||||
* - For date range inputs, increments the count if either start or stop is set.
|
||||
* - Inputs in their default state are not counted.
|
||||
*
|
||||
* @remarks
|
||||
* This property is a computed signal and updates automatically when the filter state changes.
|
||||
*
|
||||
* @returns The number of filter inputs that are currently selected and differ from their default state.
|
||||
*/
|
||||
selectedFilterCount = computed<number>(() => {
|
||||
const currentState = getState(this.#state);
|
||||
return currentState.inputs.reduce((count, input) => {
|
||||
if (this.isDefaultFilterInput(input)) {
|
||||
return count;
|
||||
}
|
||||
|
||||
if (input.type === InputType.Checkbox && input.selected?.length) {
|
||||
return count + 1;
|
||||
}
|
||||
|
||||
if (input.type === InputType.DateRange && (input.start || input.stop)) {
|
||||
return count + 1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}, 0);
|
||||
});
|
||||
|
||||
/**
|
||||
* Indicates whether the current state is empty.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
@let selected = selectedFilters();
|
||||
<button
|
||||
class="flex flex-row gap-2 items-center justify-center"
|
||||
[class.has-selected-filter]="selected > 0"
|
||||
uiIconButton
|
||||
cdkOverlayOrigin
|
||||
name="isaActionFilter"
|
||||
@@ -8,7 +11,9 @@
|
||||
[class.active]="isIconButtonActive()"
|
||||
data-what="filter-button"
|
||||
>
|
||||
<ng-icon name="isaActionFilter"></ng-icon>
|
||||
@if (selected > 0) {
|
||||
({{ selected }})
|
||||
}
|
||||
</button>
|
||||
|
||||
<ng-template
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.has-selected-filter {
|
||||
@apply w-full px-6;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ describe('FilterMenuButtonComponent', () => {
|
||||
mockProvider(FilterService, {
|
||||
isDefaultFilter: jest.fn().mockReturnValue(true),
|
||||
rollback: jest.fn(),
|
||||
selectedFilterCount: jest.fn().mockReturnValue(0),
|
||||
}),
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
|
||||
@@ -9,9 +9,7 @@ import {
|
||||
output,
|
||||
} from '@angular/core';
|
||||
import { IconButtonComponent } from '@isa/ui/buttons';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { FilterMenuComponent } from './filter-menu.component';
|
||||
import { isaActionFilter } from '@isa/icons';
|
||||
import { FilterService } from '../../core';
|
||||
|
||||
/**
|
||||
@@ -23,13 +21,7 @@ import { FilterService } from '../../core';
|
||||
templateUrl: './filter-menu-button.component.html',
|
||||
styleUrls: ['./filter-menu-button.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
IconButtonComponent,
|
||||
OverlayModule,
|
||||
NgIconComponent,
|
||||
FilterMenuComponent,
|
||||
],
|
||||
providers: [provideIcons({ isaActionFilter })],
|
||||
imports: [IconButtonComponent, OverlayModule, FilterMenuComponent],
|
||||
})
|
||||
export class FilterMenuButtonComponent {
|
||||
scrollStrategy = inject(Overlay).scrollStrategies.block();
|
||||
@@ -38,6 +30,8 @@ export class FilterMenuButtonComponent {
|
||||
|
||||
isIconButtonActive = computed(() => !this.#filter.isDefaultFilter());
|
||||
|
||||
selectedFilters = this.#filter.selectedFilterCount;
|
||||
|
||||
/**
|
||||
* Tracks the open state of the filter menu.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user