mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-03-26 10:03:12 -04:00
fixed custom format page filtering
This commit is contained in:
@@ -25,7 +25,8 @@ public sealed class CustomFormatScoreController : ControllerBase
|
||||
public async Task<IActionResult> GetCustomFormatScores(
|
||||
[FromQuery] int page = 1,
|
||||
[FromQuery] int pageSize = 50,
|
||||
[FromQuery] Guid? instanceId = null)
|
||||
[FromQuery] Guid? instanceId = null,
|
||||
[FromQuery] string? search = null)
|
||||
{
|
||||
if (page < 1) page = 1;
|
||||
if (pageSize < 1) pageSize = 50;
|
||||
@@ -40,6 +41,11 @@ public sealed class CustomFormatScoreController : ControllerBase
|
||||
query = query.Where(e => e.ArrInstanceId == instanceId.Value);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
query = query.Where(e => e.Title.Contains(search));
|
||||
}
|
||||
|
||||
int totalCount = await query.CountAsync();
|
||||
|
||||
var items = await query
|
||||
@@ -151,6 +157,29 @@ public sealed class CustomFormatScoreController : ControllerBase
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet("instances")]
|
||||
public async Task<IActionResult> GetInstances()
|
||||
{
|
||||
var instances = await _dataContext.CustomFormatScoreEntries
|
||||
.AsNoTracking()
|
||||
.Select(e => new { e.ArrInstanceId, e.ItemType })
|
||||
.Distinct()
|
||||
.Join(
|
||||
_dataContext.ArrInstances.AsNoTracking(),
|
||||
e => e.ArrInstanceId,
|
||||
a => a.Id,
|
||||
(e, a) => new
|
||||
{
|
||||
Id = e.ArrInstanceId,
|
||||
a.Name,
|
||||
e.ItemType,
|
||||
})
|
||||
.OrderBy(x => x.Name)
|
||||
.ToListAsync();
|
||||
|
||||
return Ok(new { Instances = instances });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets summary statistics for CF score tracking.
|
||||
/// </summary>
|
||||
|
||||
@@ -63,6 +63,12 @@ export interface CfScoreHistoryResponse {
|
||||
entries: CfScoreHistoryEntry[];
|
||||
}
|
||||
|
||||
export interface CfScoreInstance {
|
||||
id: string;
|
||||
name: string;
|
||||
itemType: string;
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CfScoreApi {
|
||||
private http = inject(HttpClient);
|
||||
@@ -77,12 +83,17 @@ export class CfScoreApi {
|
||||
});
|
||||
}
|
||||
|
||||
getScores(page = 1, pageSize = 50, search?: string): Observable<CfScoreEntriesResponse> {
|
||||
getScores(page = 1, pageSize = 50, search?: string, instanceId?: string): Observable<CfScoreEntriesResponse> {
|
||||
const params: Record<string, string | number> = { page, pageSize };
|
||||
if (search) params['search'] = search;
|
||||
if (instanceId) params['instanceId'] = instanceId;
|
||||
return this.http.get<CfScoreEntriesResponse>('/api/seeker/cf-scores', { params });
|
||||
}
|
||||
|
||||
getInstances(): Observable<{ instances: CfScoreInstance[] }> {
|
||||
return this.http.get<{ instances: CfScoreInstance[] }>('/api/seeker/cf-scores/instances');
|
||||
}
|
||||
|
||||
getItemHistory(instanceId: string, itemId: number, episodeId = 0): Observable<CfScoreHistoryResponse> {
|
||||
return this.http.get<CfScoreHistoryResponse>(
|
||||
`/api/seeker/cf-scores/${instanceId}/${itemId}/history`,
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
<!-- Toolbar -->
|
||||
<div class="toolbar">
|
||||
<div class="toolbar__filters">
|
||||
<app-select
|
||||
placeholder="All Instances"
|
||||
[options]="instanceOptions()"
|
||||
[value]="selectedInstanceId()"
|
||||
(valueChange)="onInstanceFilterChange($any($event))"
|
||||
/>
|
||||
<app-input
|
||||
placeholder="Search by title..."
|
||||
type="search"
|
||||
|
||||
@@ -4,8 +4,9 @@ import { NgIcon } from '@ng-icons/core';
|
||||
import { PageHeaderComponent } from '@layout/page-header/page-header.component';
|
||||
import {
|
||||
CardComponent, BadgeComponent, ButtonComponent, InputComponent,
|
||||
PaginatorComponent, EmptyStateComponent,
|
||||
PaginatorComponent, EmptyStateComponent, SelectComponent,
|
||||
} from '@ui';
|
||||
import type { SelectOption } from '@ui';
|
||||
import { AnimatedCounterComponent } from '@ui/animated-counter/animated-counter.component';
|
||||
import {
|
||||
CfScoreApi, CfScoreEntry, CfScoreStats, CfScoreHistoryEntry,
|
||||
@@ -25,6 +26,7 @@ const POLL_INTERVAL_MS = 10_000;
|
||||
BadgeComponent,
|
||||
ButtonComponent,
|
||||
InputComponent,
|
||||
SelectComponent,
|
||||
PaginatorComponent,
|
||||
EmptyStateComponent,
|
||||
AnimatedCounterComponent,
|
||||
@@ -46,12 +48,15 @@ export class CfScoresComponent implements OnInit, OnDestroy {
|
||||
readonly currentPage = signal(1);
|
||||
readonly pageSize = signal(50);
|
||||
readonly searchQuery = signal('');
|
||||
readonly selectedInstanceId = signal<string>('');
|
||||
readonly instanceOptions = signal<SelectOption[]>([]);
|
||||
|
||||
readonly expandedId = signal<string | null>(null);
|
||||
readonly historyEntries = signal<CfScoreHistoryEntry[]>([]);
|
||||
readonly historyLoading = signal(false);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadInstances();
|
||||
this.loadScores();
|
||||
this.loadStats();
|
||||
this.pollTimer = setInterval(() => {
|
||||
@@ -68,7 +73,7 @@ export class CfScoresComponent implements OnInit, OnDestroy {
|
||||
|
||||
loadScores(): void {
|
||||
this.loading.set(true);
|
||||
this.api.getScores(this.currentPage(), this.pageSize(), this.searchQuery() || undefined).subscribe({
|
||||
this.api.getScores(this.currentPage(), this.pageSize(), this.searchQuery() || undefined, this.selectedInstanceId() || undefined).subscribe({
|
||||
next: (result) => {
|
||||
this.items.set(result.items);
|
||||
this.totalRecords.set(result.totalCount);
|
||||
@@ -81,6 +86,26 @@ export class CfScoresComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
private loadInstances(): void {
|
||||
this.api.getInstances().subscribe({
|
||||
next: (result) => {
|
||||
this.instanceOptions.set([
|
||||
{ label: 'All Instances', value: '' },
|
||||
...result.instances.map(i => ({
|
||||
label: `${i.name} (${i.itemType})`,
|
||||
value: i.id,
|
||||
})),
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onInstanceFilterChange(value: string): void {
|
||||
this.selectedInstanceId.set(value);
|
||||
this.currentPage.set(1);
|
||||
this.loadScores();
|
||||
}
|
||||
|
||||
private loadStats(): void {
|
||||
this.api.getStats().subscribe({
|
||||
next: (stats) => this.stats.set(stats),
|
||||
|
||||
Reference in New Issue
Block a user