mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-10-28 10:48:49 -04:00
fixed overlapping seeker cycle resets losing progress state
This commit is contained in:
1 parent
fbee512835
commit
676679befc
3 files changed
+45
-6
No files matched your search
+2
-2
@@ -112,8 +112,8 @@
|
||||
class="instance-card__reset"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
[disabled]="inst.cycleItemsSearched === 0 || resettingId() === inst.instanceId"
|
||||
[loading]="resettingId() === inst.instanceId"
|
||||
[disabled]="inst.cycleItemsSearched === 0 || resettingIds().has(inst.instanceId)"
|
||||
[loading]="resettingIds().has(inst.instanceId)"
|
||||
(clicked)="resetCycle(inst)"
|
||||
>
|
||||
Reset cycle
|
||||
|
||||
+31
@@ -572,6 +572,37 @@ describe('SearchesTabComponent', () => {
|
||||
expect(resetButton(fixture, 'Zulu').disabled).toBe(false);
|
||||
});
|
||||
|
||||
it('keeps a reset in progress when another instance finishes meanwhile', async () => {
|
||||
const { fixture, component, confirm, resetCycle } = setup();
|
||||
const zulu = new Subject<null>();
|
||||
const beta = new Subject<null>();
|
||||
resetCycle.mockImplementation((id: string) => (id === 'radarr-zulu' ? zulu : beta));
|
||||
|
||||
const zuluAccepted = component.resetCycle(RADARR_ZULU);
|
||||
confirm.accept();
|
||||
await zuluAccepted;
|
||||
fixture.detectChanges();
|
||||
const betaAccepted = component.resetCycle(SONARR_BETA);
|
||||
confirm.accept();
|
||||
await betaAccepted;
|
||||
fixture.detectChanges();
|
||||
|
||||
beta.next(null);
|
||||
beta.complete();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(resetButton(fixture, 'Beta').disabled).toBe(false);
|
||||
expect(resetButton(fixture, 'Zulu').disabled).toBe(true);
|
||||
expect(resetButton(fixture, 'Zulu').classList).toContain('btn--loading');
|
||||
|
||||
zulu.next(null);
|
||||
zulu.complete();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(resetButton(fixture, 'Zulu').disabled).toBe(false);
|
||||
expect(resetButton(fixture, 'Zulu').classList).not.toContain('btn--loading');
|
||||
});
|
||||
|
||||
it('re-enables the button when the reset fails', async () => {
|
||||
const { fixture, component, confirm, resetCycle } = setup();
|
||||
const inFlight = new Subject<null>();
|
||||
|
||||
@@ -115,7 +115,7 @@ export class SearchesTabComponent {
|
||||
);
|
||||
|
||||
readonly selectedInstanceId = signal<string>('');
|
||||
readonly resettingId = signal<string | null>(null);
|
||||
readonly resettingIds = signal<ReadonlySet<string>>(new Set());
|
||||
readonly instanceOptions = computed<SelectOption[]>(() => {
|
||||
return [
|
||||
{ label: 'All Instances', value: '' },
|
||||
@@ -323,6 +323,14 @@ export class SearchesTabComponent {
|
||||
this.eventsResource.reload();
|
||||
}
|
||||
|
||||
private finishReset(instanceId: string): void {
|
||||
this.resettingIds.update((ids) => {
|
||||
const next = new Set(ids);
|
||||
next.delete(instanceId);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
|
||||
async resetCycle(inst: InstanceSearchStat): Promise<void> {
|
||||
const confirmed = await this.confirmService.confirm({
|
||||
title: 'Reset Cycle',
|
||||
@@ -334,15 +342,15 @@ export class SearchesTabComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
this.resettingId.set(inst.instanceId);
|
||||
this.resettingIds.update((ids) => new Set(ids).add(inst.instanceId));
|
||||
this.api.resetCycle(inst.instanceId).subscribe({
|
||||
next: () => {
|
||||
this.resettingId.set(null);
|
||||
this.finishReset(inst.instanceId);
|
||||
this.toast.success(`Cycle reset for ${inst.instanceName}`);
|
||||
this.summaryResource.reload();
|
||||
},
|
||||
error: (err: ApiError) => {
|
||||
this.resettingId.set(null);
|
||||
this.finishReset(inst.instanceId);
|
||||
this.toast.error(err.message);
|
||||
},
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user