add single filters
This commit is contained in:
parent
0157507f66
commit
c11f73ba9e
@ -7,11 +7,13 @@ import { INestedFilter } from './models/nested-filter.model';
|
||||
import { get, shareDistinctLast, shareLast } from '../utils';
|
||||
import { NestedFilter } from './models/nested-filter';
|
||||
import { Filter } from './models/filter';
|
||||
import { IFilter } from './models/filter.model';
|
||||
|
||||
@Injectable()
|
||||
export class FilterService {
|
||||
readonly showResetFilters$: Observable<boolean>;
|
||||
readonly filterGroups$: Observable<IFilterGroup[]>;
|
||||
readonly #singleFilters = new Map<string, BehaviorSubject<IFilter | undefined>>();
|
||||
private readonly _filterGroups$ = new BehaviorSubject<IFilterGroup[]>([]);
|
||||
private readonly _refresh$ = new Subject();
|
||||
|
||||
@ -29,6 +31,10 @@ export class FilterService {
|
||||
return toFlatFilters(this.filterGroups, filters => filters.filter(f => f.checked));
|
||||
}
|
||||
|
||||
get singleFilters() {
|
||||
return Array.from(this.#singleFilters.values());
|
||||
}
|
||||
|
||||
private get _showResetFilters$(): Observable<boolean> {
|
||||
return this.filterGroups$.pipe(
|
||||
map(value => toFlatFilters(value)),
|
||||
@ -92,6 +98,23 @@ export class FilterService {
|
||||
);
|
||||
}
|
||||
|
||||
addSingleFilter(filter: IFilter) {
|
||||
if (!this.#singleFilters.has(filter.id)) {
|
||||
return this.#singleFilters.set(filter.id, new BehaviorSubject<IFilter | undefined>(filter));
|
||||
}
|
||||
|
||||
return this.#singleFilters.get(filter.id)?.next(filter);
|
||||
}
|
||||
|
||||
getSingleFilter(filterId: string) {
|
||||
if (!this.#singleFilters.has(filterId)) {
|
||||
this.#singleFilters.set(filterId, new BehaviorSubject<IFilter | undefined>(undefined));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
return this.#singleFilters.get(filterId)!.asObservable();
|
||||
}
|
||||
|
||||
getGroup(slug: string): IFilterGroup | undefined {
|
||||
return this.filterGroups.find(group => group.slug === slug);
|
||||
}
|
||||
@ -131,6 +154,30 @@ export class FilterService {
|
||||
});
|
||||
});
|
||||
|
||||
this.resetSingleFilters();
|
||||
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
resetSingleFilters() {
|
||||
this.#singleFilters.forEach(filter$ => {
|
||||
const filter = filter$.value;
|
||||
if (filter) {
|
||||
filter$.next({ ...filter$.value, checked: !filter$.value?.checked });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toggleSingleFilter(filterId: string) {
|
||||
const filter$ = this.#singleFilters.get(filterId);
|
||||
if (!filter$) {
|
||||
return;
|
||||
}
|
||||
|
||||
const filter = filter$.value;
|
||||
if (filter) {
|
||||
filter.checked = !filter.checked;
|
||||
this.addSingleFilter(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,10 +9,11 @@ import { QuickFiltersComponent } from './quick-filters/quick-filters.component';
|
||||
import { IqserIconsModule } from '../icons';
|
||||
import { IqserInputsModule } from '../inputs';
|
||||
import { IqserHelpModeModule } from '../help-mode';
|
||||
import { SingleFilterComponent } from './single-filter/single-filter.component';
|
||||
|
||||
const matModules = [MatCheckboxModule, MatMenuModule];
|
||||
const modules = [TranslateModule, IqserButtonsModule, IqserIconsModule, IqserInputsModule, IqserHelpModeModule];
|
||||
const components = [QuickFiltersComponent, PopupFilterComponent];
|
||||
const components = [QuickFiltersComponent, PopupFilterComponent, SingleFilterComponent];
|
||||
|
||||
@NgModule({
|
||||
declarations: [...components],
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
<mat-checkbox (click)="checkboxClicked($event)" [checked]="filter.checked" class="filter-menu-checkbox">
|
||||
{{ filter.label }}
|
||||
</mat-checkbox>
|
||||
@ -0,0 +1,8 @@
|
||||
::ng-deep .filter-menu-checkbox {
|
||||
width: 100%;
|
||||
|
||||
label {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
19
src/lib/filtering/single-filter/single-filter.component.ts
Normal file
19
src/lib/filtering/single-filter/single-filter.component.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { FilterService } from '../filter.service';
|
||||
import { IFilter } from '../models/filter.model';
|
||||
|
||||
@Component({
|
||||
selector: 'iqser-single-filter',
|
||||
templateUrl: './single-filter.component.html',
|
||||
styleUrls: ['./single-filter.component.scss'],
|
||||
})
|
||||
export class SingleFilterComponent {
|
||||
@Input() filter!: IFilter;
|
||||
|
||||
constructor(readonly filterService: FilterService) {}
|
||||
|
||||
checkboxClicked($event: MouseEvent) {
|
||||
$event.preventDefault();
|
||||
this.filterService.toggleSingleFilter(this.filter.id);
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,15 @@
|
||||
<ng-container *ngIf="searchPosition === searchPositions.beforeFilters" [ngTemplateOutlet]="searchBar"></ng-container>
|
||||
|
||||
<ng-container *ngFor="let config of filters; trackBy: trackByLabel">
|
||||
<iqser-popup-filter *ngIf="!config.hide" [primaryFiltersSlug]="config.slug" [iqserHelpMode]="filterHelpModeKey"></iqser-popup-filter>
|
||||
<iqser-popup-filter
|
||||
*ngIf="!config.hide"
|
||||
[iqserHelpMode]="filterHelpModeKey"
|
||||
[primaryFiltersSlug]="config.slug"
|
||||
></iqser-popup-filter>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngFor="let filter$ of filterService.singleFilters">
|
||||
<iqser-single-filter *ngIf="filter$ | async as filter" [filter]="filter"></iqser-single-filter>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="searchPosition === searchPositions.afterFilters" [ngTemplateOutlet]="searchBar"></ng-container>
|
||||
@ -15,9 +23,9 @@
|
||||
<div
|
||||
(click)="resetFilters()"
|
||||
*ngIf="showResetFilters$ | async"
|
||||
[iqserHelpMode]="resetFiltersHelpModeKey"
|
||||
class="reset-filters"
|
||||
translate="reset-filters"
|
||||
[iqserHelpMode]="resetFiltersHelpModeKey"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
@ -30,9 +38,9 @@
|
||||
*ngIf="!config.hide"
|
||||
[icon]="config.icon"
|
||||
[id]="config.label.replace('.', '-')"
|
||||
[iqserHelpMode]="config.helpModeKey"
|
||||
[label]="config.label | translate"
|
||||
[type]="config.type"
|
||||
[iqserHelpMode]="config.helpModeKey"
|
||||
></iqser-icon-button>
|
||||
</ng-container>
|
||||
|
||||
@ -43,9 +51,9 @@
|
||||
*ngIf="!config.hide"
|
||||
[disabled]="config.disabled$ && (config.disabled$ | async)"
|
||||
[icon]="config.icon"
|
||||
[iqserHelpMode]="config.helpModeKey"
|
||||
[tooltip]="config.label"
|
||||
tooltipPosition="below"
|
||||
[iqserHelpMode]="config.helpModeKey"
|
||||
></iqser-circle-button>
|
||||
</ng-container>
|
||||
|
||||
@ -58,8 +66,8 @@
|
||||
[class.ml-6]="actionConfigs"
|
||||
[tooltip]="'common.close' | translate"
|
||||
icon="iqser:close"
|
||||
tooltipPosition="below"
|
||||
iqserHelpMode="edit_dossier_in_dossier"
|
||||
tooltipPosition="below"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -45,6 +45,14 @@ export class PageHeaderComponent<T extends IListable> {
|
||||
);
|
||||
}
|
||||
|
||||
get filterHelpModeKey() {
|
||||
return this.helpModeKey ? `filter_${this.helpModeKey}_list` : '';
|
||||
}
|
||||
|
||||
get resetFiltersHelpModeKey() {
|
||||
return this.helpModeKey === 'dossier' ? 'reset_filters' : 'delete_document_filter';
|
||||
}
|
||||
|
||||
resetFilters(): void {
|
||||
this.filterService.reset();
|
||||
this.searchService.reset();
|
||||
@ -53,12 +61,4 @@ export class PageHeaderComponent<T extends IListable> {
|
||||
trackByLabel<K extends { label?: string }>(index: number, item: K): string | undefined {
|
||||
return item.label;
|
||||
}
|
||||
|
||||
get filterHelpModeKey() {
|
||||
return !!this.helpModeKey ? `filter_${this.helpModeKey}_list` : '';
|
||||
}
|
||||
|
||||
get resetFiltersHelpModeKey() {
|
||||
return this.helpModeKey === 'dossier' ? 'reset_filters' : `delete_document_filter`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,3 +68,19 @@ export function hasFormChanged(form: FormGroup, initialFormValue): boolean {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const HOURS_IN_A_DAY = 24;
|
||||
const MINUTES_IN_AN_HOUR = 60;
|
||||
|
||||
export function getLeftDateTime(ISOString: string) {
|
||||
const date = moment(ISOString);
|
||||
const now = new Date(Date.now());
|
||||
|
||||
const daysLeft = date.diff(now, 'days');
|
||||
const hoursFromNow = date.diff(now, 'hours');
|
||||
const hoursLeft = hoursFromNow - HOURS_IN_A_DAY * daysLeft;
|
||||
const minutesFromNow = date.diff(now, 'minutes');
|
||||
const minutesLeft = minutesFromNow - HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR * daysLeft;
|
||||
|
||||
return { daysLeft, hoursLeft, minutesLeft };
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user