Refactored to make the FilterSettings genetic and type safe. Now I need to refactor the metadata component to respect the generics.
This commit is contained in:
parent
2654ea2965
commit
a4c31debd0
20 changed files with 117 additions and 65 deletions
|
|
@ -23,7 +23,7 @@ export enum SortField {
|
|||
Random = 9
|
||||
}
|
||||
|
||||
export const allSortFields = Object.keys(SortField)
|
||||
export const allSeriesSortFields = Object.keys(SortField)
|
||||
.filter(key => !isNaN(Number(key)) && parseInt(key, 10) >= 0)
|
||||
.map(key => parseInt(key, 10)) as SortField[];
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ const enumArray = Object.keys(FilterField)
|
|||
|
||||
enumArray.sort((a, b) => a.value.localeCompare(b.value));
|
||||
|
||||
export const allFields = enumArray
|
||||
export const allSeriesFilterFields = enumArray
|
||||
.map(key => parseInt(key.key, 10))as FilterField[];
|
||||
|
||||
export const allPeople = [
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ import {FilterStatement} from "./filter-statement";
|
|||
import {FilterCombination} from "./filter-combination";
|
||||
import {SortOptions} from "./sort-options";
|
||||
|
||||
export interface FilterV2<T> {
|
||||
export interface FilterV2<TFilter, TSort extends number = number> {
|
||||
name?: string;
|
||||
statements: Array<FilterStatement<T>>;
|
||||
statements: Array<FilterStatement<TFilter>>;
|
||||
combination: FilterCombination;
|
||||
sortOptions?: SortOptions;
|
||||
sortOptions?: SortOptions<TSort>;
|
||||
limitTo: number;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,3 +3,9 @@ export enum PersonFilterField {
|
|||
Role = 1,
|
||||
Name = 2
|
||||
}
|
||||
|
||||
|
||||
export const allPersonFilterFields = Object.keys(PersonFilterField)
|
||||
.filter(key => !isNaN(Number(key)) && parseInt(key, 10) >= 0)
|
||||
.map(key => parseInt(key, 10)) as PersonFilterField[];
|
||||
|
||||
|
|
|
|||
|
|
@ -3,3 +3,7 @@ export enum PersonSortField {
|
|||
SeriesCount = 2,
|
||||
ChapterCount = 3
|
||||
}
|
||||
|
||||
export const allPersonSortFields = Object.keys(PersonSortField)
|
||||
.filter(key => !isNaN(Number(key)) && parseInt(key, 10) >= 0)
|
||||
.map(key => parseInt(key, 10)) as PersonSortField[];
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import {SortField} from "../series-filter";
|
||||
import {PersonSortField} from "./person-sort-field";
|
||||
|
||||
/**
|
||||
* Series-based Sort options
|
||||
*/
|
||||
export interface SortOptions {
|
||||
sortField: SortField;
|
||||
export interface SortOptions<TSort extends number = number> {
|
||||
sortField: TSort;
|
||||
isAscending: boolean;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,5 +25,4 @@ export class FilterService {
|
|||
renameSmartFilter(filter: SmartFilter) {
|
||||
return this.httpClient.post(this.baseUrl + `filter/rename?filterId=${filter.id}&name=${filter.name.trim()}`, {});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,5 +227,4 @@ export class SeriesService {
|
|||
updateDontMatch(seriesId: number, dontMatch: boolean) {
|
||||
return this.httpClient.post<string>(this.baseUrl + `series/dont-match?seriesId=${seriesId}&dontMatch=${dontMatch}`, {}, TextResonse);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,13 +11,12 @@ import {Title} from '@angular/platform-browser';
|
|||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {debounceTime, take} from 'rxjs/operators';
|
||||
import {BulkSelectionService} from 'src/app/cards/bulk-selection.service';
|
||||
import {FilterSettings} from 'src/app/metadata-filter/filter-settings';
|
||||
import {FilterUtilitiesService} from 'src/app/shared/_services/filter-utilities.service';
|
||||
import {UtilityService} from 'src/app/shared/_services/utility.service';
|
||||
import {JumpKey} from 'src/app/_models/jumpbar/jump-key';
|
||||
import {Pagination} from 'src/app/_models/pagination';
|
||||
import {Series} from 'src/app/_models/series';
|
||||
import {FilterEvent} from 'src/app/_models/metadata/series-filter';
|
||||
import {FilterEvent, SortField} from 'src/app/_models/metadata/series-filter';
|
||||
import {Action, ActionItem} from 'src/app/_services/action-factory.service';
|
||||
import {ActionService} from 'src/app/_services/action.service';
|
||||
import {JumpbarService} from 'src/app/_services/jumpbar.service';
|
||||
|
|
@ -38,6 +37,7 @@ import {BrowseTitlePipe} from "../../../_pipes/browse-title.pipe";
|
|||
import {MetadataService} from "../../../_services/metadata.service";
|
||||
import {Observable} from "rxjs";
|
||||
import {FilterField} from "../../../_models/metadata/v2/filter-field";
|
||||
import {SeriesFilterSettings} from "../../../metadata-filter/filter-settings";
|
||||
|
||||
|
||||
@Component({
|
||||
|
|
@ -68,8 +68,8 @@ export class AllSeriesComponent implements OnInit {
|
|||
series: Series[] = [];
|
||||
loadingSeries = false;
|
||||
pagination: Pagination = new Pagination();
|
||||
filter: FilterV2<FilterField> | undefined = undefined;
|
||||
filterSettings: FilterSettings<FilterField> = new FilterSettings();
|
||||
filter: FilterV2<FilterField, SortField> | undefined = undefined;
|
||||
filterSettings: SeriesFilterSettings = new SeriesFilterSettings();
|
||||
filterOpen: EventEmitter<boolean> = new EventEmitter();
|
||||
filterActiveCheck!: FilterV2<FilterField>;
|
||||
filterActive: boolean = false;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import {ActivatedRoute, Router} from '@angular/router';
|
|||
import {ToastrService} from 'ngx-toastr';
|
||||
import {take} from 'rxjs';
|
||||
import {BulkSelectionService} from 'src/app/cards/bulk-selection.service';
|
||||
import {FilterSettings} from 'src/app/metadata-filter/filter-settings';
|
||||
import {ConfirmService} from 'src/app/shared/confirm.service';
|
||||
import {DownloadService} from 'src/app/shared/_services/download.service';
|
||||
import {FilterUtilitiesService} from 'src/app/shared/_services/filter-utilities.service';
|
||||
|
|
@ -28,6 +27,7 @@ import {FilterV2} from "../../../_models/metadata/v2/filter-v2";
|
|||
import {Title} from "@angular/platform-browser";
|
||||
import {WikiLink} from "../../../_models/wiki";
|
||||
import {FilterField} from "../../../_models/metadata/v2/filter-field";
|
||||
import {SeriesFilterSettings} from "../../../metadata-filter/filter-settings";
|
||||
|
||||
@Component({
|
||||
selector: 'app-bookmarks',
|
||||
|
|
@ -65,7 +65,7 @@ export class BookmarksComponent implements OnInit {
|
|||
|
||||
pagination: Pagination = new Pagination();
|
||||
filter: FilterV2<FilterField> | undefined = undefined;
|
||||
filterSettings: FilterSettings<FilterField> = new FilterSettings();
|
||||
filterSettings: SeriesFilterSettings = new SeriesFilterSettings();
|
||||
filterOpen: EventEmitter<boolean> = new EventEmitter();
|
||||
filterActive: boolean = false;
|
||||
filterActiveCheck!: FilterV2<FilterField>;
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ import {debounceTime, tap} from "rxjs/operators";
|
|||
import {SortButtonComponent} from "../../_single-module/sort-button/sort-button.component";
|
||||
import {PersonSortField} from "../../_models/metadata/v2/person-sort-field";
|
||||
import {PersonSortOptions} from "../../_models/metadata/v2/sort-options";
|
||||
import {FilterSettings} from "../../metadata-filter/filter-settings";
|
||||
import {PersonFilterField} from "../../_models/metadata/v2/person-filter-field";
|
||||
import {FilterUtilitiesService} from "../../shared/_services/filter-utilities.service";
|
||||
import {FilterV2} from "../../_models/metadata/v2/filter-v2";
|
||||
import {PersonFilterSettings} from "../../metadata-filter/filter-settings";
|
||||
|
||||
|
||||
@Component({
|
||||
|
|
@ -83,7 +83,7 @@ export class BrowseAuthorsComponent implements OnInit {
|
|||
query: new FormControl('', []),
|
||||
});
|
||||
isAscending: boolean = true;
|
||||
filterSettings: FilterSettings<PersonFilterField> = new FilterSettings<PersonFilterField>();
|
||||
filterSettings: PersonFilterSettings = new PersonFilterSettings();
|
||||
filterActive: boolean = false;
|
||||
filterOpen: EventEmitter<boolean> = new EventEmitter();
|
||||
filter: FilterV2<PersonFilterField> | undefined = undefined;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import {
|
|||
} from '@angular/core';
|
||||
import {NavigationStart, Router} from '@angular/router';
|
||||
import {VirtualScrollerComponent, VirtualScrollerModule} from '@iharbeck/ngx-virtual-scroller';
|
||||
import {FilterSettings} from 'src/app/metadata-filter/filter-settings';
|
||||
import {FilterUtilitiesService} from 'src/app/shared/_services/filter-utilities.service';
|
||||
import {Breakpoint, UtilityService} from 'src/app/shared/_services/utility.service';
|
||||
import {JumpKey} from 'src/app/_models/jumpbar/jump-key';
|
||||
|
|
@ -39,6 +38,7 @@ import {filter, map} from "rxjs/operators";
|
|||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
import {tap} from "rxjs";
|
||||
import {FilterV2} from "../../_models/metadata/v2/filter-v2";
|
||||
import {FilterSettingsBase, SeriesFilterSettings} from "../../metadata-filter/filter-settings";
|
||||
|
||||
|
||||
const ANIMATION_TIME_MS = 0;
|
||||
|
|
@ -49,7 +49,7 @@ const ANIMATION_TIME_MS = 0;
|
|||
* How to use:
|
||||
* - For filtering:
|
||||
* - pass a filterSettings which will bootstrap the filtering bar
|
||||
* - pass a jumpbar method binding to calc the count for the entity
|
||||
* - pass a jumpbar method binding to calc the count for the entity (not implemented yet)
|
||||
* - For card layout
|
||||
* - Pass an identity function for trackby
|
||||
* - Pass a pagination object for the total count
|
||||
|
|
@ -84,7 +84,7 @@ export class CardDetailLayoutComponent implements OnInit, OnChanges {
|
|||
*/
|
||||
@Input() parentScroll!: Element | Window;
|
||||
|
||||
// Filter Code
|
||||
// We need to pass filterOpen from the grandfather to the metadata filter due to the filter button being in a separate component
|
||||
@Input() filterOpen!: EventEmitter<boolean>;
|
||||
/**
|
||||
* Should filtering be shown on the page
|
||||
|
|
@ -98,7 +98,7 @@ export class CardDetailLayoutComponent implements OnInit, OnChanges {
|
|||
* A trackBy to help with rendering. This is required as without it there are issues when scrolling
|
||||
*/
|
||||
@Input({required: true}) trackByIdentity!: TrackByFunction<any>;
|
||||
@Input() filterSettings!: FilterSettings<number>;
|
||||
@Input() filterSettings!: FilterSettingsBase;
|
||||
@Input() refresh!: EventEmitter<void>;
|
||||
/**
|
||||
* Pass the filter object optionally. If not passed, will create a SeriesFilter by default
|
||||
|
|
@ -150,7 +150,7 @@ export class CardDetailLayoutComponent implements OnInit, OnChanges {
|
|||
// }
|
||||
|
||||
if (this.filterSettings === undefined) {
|
||||
this.filterSettings = new FilterSettings();
|
||||
this.filterSettings = new SeriesFilterSettings();
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import {ToastrService} from 'ngx-toastr';
|
|||
import {debounceTime, take} from 'rxjs/operators';
|
||||
import {BulkSelectionService} from 'src/app/cards/bulk-selection.service';
|
||||
import {EditCollectionTagsComponent} from 'src/app/cards/_modals/edit-collection-tags/edit-collection-tags.component';
|
||||
import {FilterSettings} from 'src/app/metadata-filter/filter-settings';
|
||||
import {FilterUtilitiesService} from 'src/app/shared/_services/filter-utilities.service';
|
||||
import {Breakpoint, UtilityService} from 'src/app/shared/_services/utility.service';
|
||||
import {UserCollection} from 'src/app/_models/collection-tag';
|
||||
|
|
@ -63,6 +62,7 @@ import {DefaultModalOptions} from "../../../_models/default-modal-options";
|
|||
import {ScrobbleProviderNamePipe} from "../../../_pipes/scrobble-provider-name.pipe";
|
||||
import {PromotedIconComponent} from "../../../shared/_components/promoted-icon/promoted-icon.component";
|
||||
import {FilterStatement} from "../../../_models/metadata/v2/filter-statement";
|
||||
import {SeriesFilterSettings} from "../../../metadata-filter/filter-settings";
|
||||
|
||||
@Component({
|
||||
selector: 'app-collection-detail',
|
||||
|
|
@ -111,7 +111,7 @@ export class CollectionDetailComponent implements OnInit, AfterContentChecked {
|
|||
pagination: Pagination = new Pagination();
|
||||
collectionTagActions: ActionItem<UserCollection>[] = [];
|
||||
filter: FilterV2<FilterField> | undefined = undefined;
|
||||
filterSettings: FilterSettings<FilterField> = new FilterSettings();
|
||||
filterSettings: SeriesFilterSettings = new SeriesFilterSettings();
|
||||
summary: string = '';
|
||||
user!: User;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import {EVENTS, MessageHubService} from '../_services/message-hub.service';
|
|||
import {SeriesService} from '../_services/series.service';
|
||||
import {NavService} from '../_services/nav.service';
|
||||
import {FilterUtilitiesService} from '../shared/_services/filter-utilities.service';
|
||||
import {FilterSettings} from '../metadata-filter/filter-settings';
|
||||
import {JumpKey} from '../_models/jumpbar/jump-key';
|
||||
import {SeriesRemovedEvent} from '../_models/events/series-removed-event';
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
|
|
@ -43,6 +42,7 @@ import {FilterField} from "../_models/metadata/v2/filter-field";
|
|||
import {CardActionablesComponent} from "../_single-module/card-actionables/card-actionables.component";
|
||||
import {LoadingComponent} from "../shared/loading/loading.component";
|
||||
import {debounceTime, ReplaySubject, tap} from "rxjs";
|
||||
import {SeriesFilterSettings} from "../metadata-filter/filter-settings";
|
||||
|
||||
@Component({
|
||||
selector: 'app-library-detail',
|
||||
|
|
@ -76,7 +76,7 @@ export class LibraryDetailComponent implements OnInit {
|
|||
pagination: Pagination = {currentPage: 0, totalPages: 0, totalItems: 0, itemsPerPage: 0};
|
||||
actions: ActionItem<Library>[] = [];
|
||||
filter: FilterV2<FilterField> | undefined = undefined;
|
||||
filterSettings: FilterSettings<FilterField> = new FilterSettings();
|
||||
filterSettings: SeriesFilterSettings = new SeriesFilterSettings();
|
||||
filterOpen: EventEmitter<boolean> = new EventEmitter();
|
||||
filterActive: boolean = false;
|
||||
filterActiveCheck!: FilterV2<FilterField>;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import {FormControl, FormGroup, FormsModule, ReactiveFormsModule} from "@angular
|
|||
import {NgbTooltip} from "@ng-bootstrap/ng-bootstrap";
|
||||
import {FilterCombination} from "../../../_models/metadata/v2/filter-combination";
|
||||
import {FilterUtilitiesService} from "../../../shared/_services/filter-utilities.service";
|
||||
import {allFields} from "../../../_models/metadata/v2/filter-field";
|
||||
import {allSeriesFilterFields} from "../../../_models/metadata/v2/filter-field";
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
import {distinctUntilChanged, tap} from "rxjs/operators";
|
||||
import {translate, TranslocoDirective} from "@jsverse/transloco";
|
||||
|
|
@ -43,7 +43,7 @@ export class MetadataBuilderComponent implements OnInit {
|
|||
* The number of statements that can be. 0 means unlimited. -1 means none.
|
||||
*/
|
||||
@Input() statementLimit = 0;
|
||||
@Input() availableFilterFields = allFields;
|
||||
@Input() availableFilterFields = allSeriesFilterFields;
|
||||
@Output() update: EventEmitter<FilterV2<number>> = new EventEmitter<FilterV2<number>>();
|
||||
@Output() apply: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {FilterStatement} from '../../../_models/metadata/v2/filter-statement';
|
|||
import {BehaviorSubject, distinctUntilChanged, filter, Observable, of, startWith, switchMap, tap} from 'rxjs';
|
||||
import {MetadataService} from 'src/app/_services/metadata.service';
|
||||
import {FilterComparison} from 'src/app/_models/metadata/v2/filter-comparison';
|
||||
import {allFields, FilterField} from 'src/app/_models/metadata/v2/filter-field';
|
||||
import {allSeriesFilterFields, FilterField} from 'src/app/_models/metadata/v2/filter-field';
|
||||
import {AsyncPipe} from "@angular/common";
|
||||
import {FilterFieldPipe} from "../../../_pipes/filter-field.pipe";
|
||||
import {FilterComparisonPipe} from "../../../_pipes/filter-comparison.pipe";
|
||||
|
|
@ -148,7 +148,7 @@ export class MetadataFilterRowComponent implements OnInit {
|
|||
* Slightly misleading as this is the initial state and will be updated on the filterStatement event emitter
|
||||
*/
|
||||
@Input() preset!: FilterStatement<number>;
|
||||
@Input() availableFields: Array<FilterField> = allFields;
|
||||
@Input() availableFields: Array<FilterField> = allSeriesFilterFields;
|
||||
@Output() filterStatement = new EventEmitter<FilterStatement<number>>();
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,31 @@
|
|||
import {FilterV2} from "../_models/metadata/v2/filter-v2";
|
||||
import {SortField} from "../_models/metadata/series-filter";
|
||||
import {PersonSortField} from "../_models/metadata/v2/person-sort-field";
|
||||
import {PersonFilterField} from "../_models/metadata/v2/person-filter-field";
|
||||
import {FilterField} from "../_models/metadata/v2/filter-field";
|
||||
|
||||
export class FilterSettings<T> {
|
||||
presetsV2: FilterV2<T> | undefined;
|
||||
export class FilterSettingsBase<TFilter extends number = number, TSort extends number = number> {
|
||||
presetsV2: FilterV2<TFilter, TSort> | undefined;
|
||||
sortDisabled = false;
|
||||
/**
|
||||
* The number of statements that can be on the filter. Set to 1 to disable adding more.
|
||||
*/
|
||||
statementLimit: number = 0;
|
||||
saveDisabled: boolean = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter Settings for Series entity
|
||||
*/
|
||||
export class SeriesFilterSettings extends FilterSettingsBase<FilterField, SortField> {
|
||||
type = 'sortField';
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter Settings for People entity
|
||||
*/
|
||||
export class PersonFilterSettings extends FilterSettingsBase<PersonFilterField, PersonSortField> {
|
||||
type = 'personSortField';
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ import {
|
|||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
computed,
|
||||
ContentChild,
|
||||
DestroyRef,
|
||||
EventEmitter,
|
||||
inject,
|
||||
input,
|
||||
Input,
|
||||
OnInit,
|
||||
Output
|
||||
|
|
@ -14,9 +16,8 @@ import {FormControl, FormGroup, FormsModule, ReactiveFormsModule} from '@angular
|
|||
import {NgbCollapse} from '@ng-bootstrap/ng-bootstrap';
|
||||
import {Breakpoint, UtilityService} from '../shared/_services/utility.service';
|
||||
import {Library} from '../_models/library/library';
|
||||
import {allSortFields, FilterEvent, FilterItem, SortField} from '../_models/metadata/series-filter';
|
||||
import {allSeriesSortFields, FilterEvent, FilterItem} from '../_models/metadata/series-filter';
|
||||
import {ToggleService} from '../_services/toggle.service';
|
||||
import {FilterSettings} from './filter-settings';
|
||||
import {FilterV2} from '../_models/metadata/v2/filter-v2';
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
import {DrawerComponent} from '../shared/drawer/drawer.component';
|
||||
|
|
@ -24,11 +25,15 @@ import {AsyncPipe, NgClass, NgTemplateOutlet} from '@angular/common';
|
|||
import {translate, TranslocoModule, TranslocoService} from "@jsverse/transloco";
|
||||
import {SortFieldPipe} from "../_pipes/sort-field.pipe";
|
||||
import {MetadataBuilderComponent} from "./_components/metadata-builder/metadata-builder.component";
|
||||
import {allFields, FilterField} from "../_models/metadata/v2/filter-field";
|
||||
import {allSeriesFilterFields, FilterField} from "../_models/metadata/v2/filter-field";
|
||||
import {FilterService} from "../_services/filter.service";
|
||||
import {ToastrService} from "ngx-toastr";
|
||||
import {animate, style, transition, trigger} from "@angular/animations";
|
||||
import {SortButtonComponent} from "../_single-module/sort-button/sort-button.component";
|
||||
import {FilterUtilitiesService} from "../shared/_services/filter-utilities.service";
|
||||
import {FilterSettingsBase} from "./filter-settings";
|
||||
import {allPersonSortFields} from "../_models/metadata/v2/person-sort-field";
|
||||
import {allPersonFilterFields} from "../_models/metadata/v2/person-filter-field";
|
||||
|
||||
@Component({
|
||||
selector: 'app-metadata-filter',
|
||||
|
|
@ -51,10 +56,11 @@ import {SortButtonComponent} from "../_single-module/sort-button/sort-button.com
|
|||
ReactiveFormsModule, FormsModule, AsyncPipe, TranslocoModule,
|
||||
MetadataBuilderComponent, NgClass, SortButtonComponent]
|
||||
})
|
||||
export class MetadataFilterComponent implements OnInit {
|
||||
protected readonly allFilterFields = allFields;
|
||||
export class MetadataFilterComponent<TFilter extends number = number, TSort extends number = number> implements OnInit {
|
||||
protected readonly allFilterFields = allSeriesFilterFields;
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly filterUtilityService = inject(FilterUtilitiesService);
|
||||
public readonly utilityService = inject(UtilityService);
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
private readonly toastr = inject(ToastrService);
|
||||
|
|
@ -63,7 +69,7 @@ export class MetadataFilterComponent implements OnInit {
|
|||
protected readonly translocoService = inject(TranslocoService);
|
||||
private readonly sortFieldPipe = new SortFieldPipe(this.translocoService);
|
||||
|
||||
protected readonly allSortFields = allSortFields.map(f => {
|
||||
protected readonly allSortFields = allSeriesSortFields.map(f => {
|
||||
return {title: this.sortFieldPipe.transform(f), value: f};
|
||||
}).sort((a, b) => a.title.localeCompare(b.title));
|
||||
|
||||
|
|
@ -76,7 +82,23 @@ export class MetadataFilterComponent implements OnInit {
|
|||
* Should filtering be shown on the page
|
||||
*/
|
||||
@Input() filteringDisabled: boolean = false;
|
||||
@Input({required: true}) filterSettings!: FilterSettings<FilterField>;
|
||||
//@Input({required: true}) filterSettings!: FilterSettings<T>;
|
||||
|
||||
@Input({required: true}) filterSettings!: FilterSettingsBase<TFilter, TSort>;
|
||||
/**
|
||||
* Entity type derives the Sort and Filter fields
|
||||
*/
|
||||
entityType = input<'series' | 'person'>('series');
|
||||
|
||||
sortFieldOptions = computed(() => {
|
||||
if (this.entityType() === 'series') return allSeriesSortFields;
|
||||
return allPersonSortFields;
|
||||
});
|
||||
filterFieldOptions = computed(() => {
|
||||
if (this.entityType() === 'series') return allSeriesFilterFields;
|
||||
return allPersonFilterFields;
|
||||
});
|
||||
|
||||
@Output() applyFilter: EventEmitter<FilterEvent> = new EventEmitter();
|
||||
@ContentChild('[ngbCollapse]') collapse!: NgbCollapse;
|
||||
|
||||
|
|
@ -100,7 +122,7 @@ export class MetadataFilterComponent implements OnInit {
|
|||
|
||||
ngOnInit(): void {
|
||||
if (this.filterSettings === undefined) {
|
||||
this.filterSettings = new FilterSettings();
|
||||
this.filterSettings = new FilterSettingsBase<TFilter, TSort>();
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
|
|
@ -159,8 +181,10 @@ export class MetadataFilterComponent implements OnInit {
|
|||
|
||||
this.filterV2 = this.deepClone(this.filterSettings.presetsV2);
|
||||
|
||||
const defaultSortField = this.sortFieldOptions()[0];
|
||||
|
||||
this.sortGroup = new FormGroup({
|
||||
sortField: new FormControl({value: this.filterV2?.sortOptions?.sortField || SortField.SortName, disabled: this.filterSettings.sortDisabled}, []),
|
||||
sortField: new FormControl({value: this.filterV2?.sortOptions?.sortField || defaultSortField, disabled: this.filterSettings.sortDisabled}, []),
|
||||
limitTo: new FormControl(this.filterV2?.limitTo || 0, []),
|
||||
name: new FormControl(this.filterV2?.name || '', [])
|
||||
});
|
||||
|
|
@ -192,9 +216,11 @@ export class MetadataFilterComponent implements OnInit {
|
|||
this.isAscendingSort = isAscending;
|
||||
|
||||
if (this.filterV2?.sortOptions === null) {
|
||||
const defaultSortField = this.sortFieldOptions()[0];
|
||||
|
||||
this.filterV2.sortOptions = {
|
||||
isAscending: this.isAscendingSort,
|
||||
sortField: SortField.SortName
|
||||
sortField: defaultSortField
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,5 +262,6 @@ export class MetadataFilterComponent implements OnInit {
|
|||
this.toggleService.set(!this.filteringCollapsed);
|
||||
}
|
||||
|
||||
|
||||
protected readonly Breakpoint = Breakpoint;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import {TextResonse} from "../../_types/text-response";
|
|||
import {environment} from "../../../environments/environment";
|
||||
import {map, tap} from "rxjs/operators";
|
||||
import {Observable, of, switchMap} from "rxjs";
|
||||
import {Location} from "@angular/common";
|
||||
import {PersonFilterField} from "../../_models/metadata/v2/person-filter-field";
|
||||
|
||||
|
||||
|
|
@ -21,12 +20,11 @@ import {PersonFilterField} from "../../_models/metadata/v2/person-filter-field";
|
|||
})
|
||||
export class FilterUtilitiesService {
|
||||
|
||||
private readonly location = inject(Location);
|
||||
private readonly router = inject(Router);
|
||||
private readonly metadataService = inject(MetadataService);
|
||||
private readonly http = inject(HttpClient);
|
||||
|
||||
private apiUrl = environment.apiUrl;
|
||||
private readonly apiUrl = environment.apiUrl;
|
||||
|
||||
encodeFilter(filter: FilterV2<number> | undefined) {
|
||||
return this.http.post<string>(this.apiUrl + 'filter/encode', filter, TextResonse);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import {Title} from '@angular/platform-browser';
|
|||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {debounceTime, take} from 'rxjs';
|
||||
import {BulkSelectionService} from 'src/app/cards/bulk-selection.service';
|
||||
import {FilterSettings} from 'src/app/metadata-filter/filter-settings';
|
||||
import {FilterUtilitiesService} from 'src/app/shared/_services/filter-utilities.service';
|
||||
import {UtilityService} from 'src/app/shared/_services/utility.service';
|
||||
import {SeriesRemovedEvent} from 'src/app/_models/events/series-removed-event';
|
||||
|
|
@ -41,6 +40,7 @@ import {
|
|||
import {translate, TranslocoDirective} from "@jsverse/transloco";
|
||||
import {FilterV2} from "../../../_models/metadata/v2/filter-v2";
|
||||
import {FilterField} from "../../../_models/metadata/v2/filter-field";
|
||||
import {SeriesFilterSettings} from "../../../metadata-filter/filter-settings";
|
||||
|
||||
|
||||
@Component({
|
||||
|
|
@ -60,7 +60,7 @@ export class WantToReadComponent implements OnInit, AfterContentChecked {
|
|||
series: Array<Series> = [];
|
||||
pagination: Pagination = new Pagination();
|
||||
filter: FilterV2<FilterField> | undefined = undefined;
|
||||
filterSettings: FilterSettings<FilterField> = new FilterSettings();
|
||||
filterSettings: SeriesFilterSettings = new SeriesFilterSettings();
|
||||
refresh: EventEmitter<void> = new EventEmitter();
|
||||
|
||||
filterActiveCheck!: FilterV2<FilterField>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue