import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, EventEmitter, inject, OnInit, Output, QueryList, ViewChildren } from '@angular/core'; import {FormControl, FormGroup, ReactiveFormsModule} from "@angular/forms"; import {compare, SortableHeader, SortEvent} from "../../_single-module/table/_directives/sortable-header.directive"; import {KavitaMediaError} from "../_models/media-error"; import {EVENTS, MessageHubService} from "../../_services/message-hub.service"; import {takeUntilDestroyed} from "@angular/core/rxjs-interop"; import {BehaviorSubject, filter, Observable, shareReplay} from "rxjs"; import {ScrobblingService} from "../../_services/scrobbling.service"; import {ScrobbleError} from "../../_models/scrobbling/scrobble-error"; import {SeriesService} from "../../_services/series.service"; import {EditSeriesModalComponent} from "../../cards/_modals/edit-series-modal/edit-series-modal.component"; import {NgbModal} from "@ng-bootstrap/ng-bootstrap"; import {FilterPipe} from "../../_pipes/filter.pipe"; import {LoadingComponent} from "../../shared/loading/loading.component"; import {TranslocoModule} from "@jsverse/transloco"; import {DefaultDatePipe} from "../../_pipes/default-date.pipe"; import {DefaultValuePipe} from "../../_pipes/default-value.pipe"; import {TranslocoLocaleModule} from "@jsverse/transloco-locale"; import {UtcToLocalTimePipe} from "../../_pipes/utc-to-local-time.pipe"; @Component({ selector: 'app-manage-scrobble-errors', standalone: true, imports: [ReactiveFormsModule, FilterPipe, LoadingComponent, SortableHeader, TranslocoModule, DefaultDatePipe, DefaultValuePipe, TranslocoLocaleModule, UtcToLocalTimePipe], templateUrl: './manage-scrobble-errors.component.html', styleUrls: ['./manage-scrobble-errors.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ManageScrobbleErrorsComponent implements OnInit { @Output() scrobbleCount = new EventEmitter(); @ViewChildren(SortableHeader) headers!: QueryList>; private readonly scrobbleService = inject(ScrobblingService); private readonly messageHub = inject(MessageHubService); private readonly cdRef = inject(ChangeDetectorRef); private readonly destroyRef = inject(DestroyRef); private readonly seriesService = inject(SeriesService); private readonly modalService = inject(NgbModal); messageHubUpdate$ = this.messageHub.messages$.pipe(takeUntilDestroyed(this.destroyRef), filter(m => m.event === EVENTS.ScanSeries), shareReplay()); currentSort = new BehaviorSubject>({column: 'created', direction: 'asc'}); currentSort$: Observable> = this.currentSort.asObservable(); data: Array = []; isLoading = true; formGroup = new FormGroup({ filter: new FormControl('', []) }); constructor() {} ngOnInit() { this.loadData(); this.messageHubUpdate$.subscribe(_ => this.loadData()); this.currentSort$.subscribe(sortConfig => { this.data = (sortConfig.column) ? this.data.sort((a: ScrobbleError, b: ScrobbleError) => { if (sortConfig.column === '') return 0; const res = compare(a[sortConfig.column], b[sortConfig.column]); return sortConfig.direction === 'asc' ? res : -res; }) : this.data; this.cdRef.markForCheck(); }); } onSort(evt: any) { //SortEvent this.currentSort.next(evt); // Must clear out headers here this.headers.forEach((header) => { if (header.sortable !== evt.column) { header.direction = ''; } }); } loadData() { this.isLoading = true; this.cdRef.markForCheck(); this.scrobbleService.getScrobbleErrors().subscribe(d => { this.data = d; this.isLoading = false; this.scrobbleCount.emit(d.length); this.cdRef.detectChanges(); }); } clear() { this.scrobbleService.clearScrobbleErrors().subscribe(_ => this.loadData()); } filterList = (listItem: ScrobbleError) => { const query = (this.formGroup.get('filter')?.value || '').toLowerCase(); return listItem.comment.toLowerCase().indexOf(query) >= 0 || listItem.details.toLowerCase().indexOf(query) >= 0; } editSeries(seriesId: number) { this.seriesService.getSeries(seriesId).subscribe(series => { const modalRef = this.modalService.open(EditSeriesModalComponent, { size: 'xl' }); modalRef.componentInstance.series = series; }); } protected readonly filter = filter; }