feat(web/m7-recurring-scans): admin Scan schedule section
Adds a "Scan schedule" section to the admin overview page between the existing Library Scan and Cover Art sections. Mode picker (Off / Every N hours / Daily / Weekly) with conditional interval / time / day inputs. Save button disabled until local state diverges from the server state. "Next scan: in N hours (timestamp)" inline indicator when mode != off. formatRelative is a static helper (recomputes on render); operator sees the configuration confirmation at a glance — not a countdown timer. admin.test.ts mock extended with createScanScheduleQuery returning mode='off' default. New test asserts the section renders. Existing assertions still pass.
This commit is contained in:
@@ -41,7 +41,21 @@ vi.mock('$lib/api/admin', async () => {
|
||||
deleteQuarantineFile: vi.fn().mockResolvedValue({}),
|
||||
deleteQuarantineViaLidarr: vi.fn().mockResolvedValue({}),
|
||||
triggerScan: vi.fn().mockResolvedValue({}),
|
||||
refetchMissingCovers: vi.fn().mockResolvedValue({ queued: 0 })
|
||||
refetchMissingCovers: vi.fn().mockResolvedValue({ queued: 0 }),
|
||||
createScanScheduleQuery: vi.fn(() =>
|
||||
readable({
|
||||
data: {
|
||||
mode: 'off',
|
||||
interval_hours: null,
|
||||
time_of_day: null,
|
||||
weekly_day: null,
|
||||
next_scheduled_at: null,
|
||||
},
|
||||
isPending: false,
|
||||
isError: false
|
||||
})
|
||||
),
|
||||
updateScanSchedule: vi.fn().mockResolvedValue({})
|
||||
};
|
||||
});
|
||||
|
||||
@@ -242,6 +256,14 @@ describe('admin Overview page', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('renders the scan-schedule section with mode=off default', () => {
|
||||
setupOverview();
|
||||
render(OverviewPage);
|
||||
expect(screen.getByText('Scan schedule')).toBeInTheDocument();
|
||||
const select = screen.getByLabelText('Mode') as HTMLSelectElement;
|
||||
expect(select.value).toBe('off');
|
||||
});
|
||||
|
||||
test('Library scan card shows Processing badge when library tally is populated and in-flight', async () => {
|
||||
const { readable } = await import('svelte/store');
|
||||
(createScanStatusQuery as ReturnType<typeof vi.fn>).mockReturnValueOnce(
|
||||
|
||||
Reference in New Issue
Block a user