fix(frontend): confirm modal, settings display, race guard, and test coverage

- S1: Replace window.confirm() with AppConfirmModal for delete actions
- S4: Add formatHours helper to avoid ugly decimals in settings hints
- W5: Add generation counter to SettingsAdminPanel to prevent stale
  async results when section changes rapidly
- S7: Remove unused ApiRequestError import from useScholarBulkActions
- S2: Add error-path tests for bulk delete/toggle network failures
- S3: Add CSRF boundary tests for bulk-delete and bulk-toggle endpoints
This commit is contained in:
Justin Visser 2026-03-07 18:00:59 +01:00
parent f8e3098fc3
commit f501ea4f94
8 changed files with 181 additions and 33 deletions

View file

@ -25,7 +25,10 @@ const integrityRef = ref<InstanceType<typeof AdminIntegritySection> | null>(null
const repairsRef = ref<InstanceType<typeof AdminRepairsSection> | null>(null);
const pdfQueueRef = ref<InstanceType<typeof AdminPdfQueueSection> | null>(null);
let loadGeneration = 0;
async function loadSection(): Promise<void> {
const gen = ++loadGeneration;
clearAlerts();
try {
if (props.section === SECTION_USERS && usersRef.value) {
@ -34,11 +37,13 @@ async function loadSection(): Promise<void> {
await integrityRef.value.load();
} else if (props.section === SECTION_REPAIRS) {
await usersRef.value?.load();
if (gen !== loadGeneration) return;
await repairsRef.value?.load();
} else if (props.section === SECTION_PDF && pdfQueueRef.value) {
await pdfQueueRef.value.load();
}
} catch (error) {
if (gen !== loadGeneration) return;
assignError(error, "Unable to load admin data.");
}
}