From 9796969e801e95d6a0f944ab33cb59b6e2260f7f Mon Sep 17 00:00:00 2001 From: Bernt Popp Date: Mon, 9 Feb 2026 14:36:25 +0100 Subject: [PATCH] fix: address Copilot review comments from PR #180 - useToast: replace unsafe `as string` casts with typeof guards, skip __handled401 errors to prevent duplicate toasts - ReloadPrompt: clean up setInterval on unmount, add network/installing guards and try/catch per vite-plugin-pwa best practices - axios: replace never-resolving promise with marked rejection so .finally() cleanup blocks still run - vite proxy: only set Host:localhost header when using default Traefik target, skip when VITE_API_URL overrides it - annotation_dates: fetch job history once instead of 3x, sort by completed_at desc instead of submitted_at --- api/endpoints/admin_endpoints.R | 38 +++++++++++++++++------------ app/src/components/ReloadPrompt.vue | 27 +++++++++++++++++--- app/src/composables/useToast.ts | 35 ++++++++++++++++++++------ app/src/plugins/axios.ts | 7 ++++-- app/vite.config.ts | 7 +++--- 5 files changed, 83 insertions(+), 31 deletions(-) diff --git a/api/endpoints/admin_endpoints.R b/api/endpoints/admin_endpoints.R index dc43600e..19ca4b65 100644 --- a/api/endpoints/admin_endpoints.R +++ b/api/endpoints/admin_endpoints.R @@ -686,22 +686,28 @@ function() { function() { data_dir <- "data/" + # Fetch job history once for all lookups + history <- tryCatch(get_job_history(100), error = function(e) { + data.frame( + operation = character(0), + status = character(0), + completed_at = character(0), + stringsAsFactors = FALSE + ) + }) + # Helper: get most recent completed_at for matching operations - get_last_successful_run <- function(operations) { - history <- tryCatch(get_job_history(100), error = function(e) { - data.frame( - operation = character(0), - status = character(0), - completed_at = character(0) - ) - }) - if (nrow(history) == 0) return(NA) - matches <- history[ - history$operation %in% operations & history$status == "completed", + get_last_successful_run <- function(operations, hist) { + if (nrow(hist) == 0) return(NA) + matches <- hist[ + hist$operation %in% operations & hist$status == "completed", ] if (nrow(matches) == 0) return(NA) - # get_job_history returns newest first - matches$completed_at[1] + # Sort by completed_at descending to get most recently finished job + valid <- matches[!is.na(matches$completed_at), ] + if (nrow(valid) == 0) return(NA) + sorted <- valid[order(valid$completed_at, decreasing = TRUE), ] + sorted$completed_at[1] } # Helper to get most recent file date matching a pattern @@ -724,11 +730,11 @@ function() { } # Prefer job history timestamps; fall back to file metadata - omim_job <- get_last_successful_run("omim_update") + omim_job <- get_last_successful_run("omim_update", history) ontology_job <- get_last_successful_run( - c("ontology_update", "force_apply_ontology") + c("ontology_update", "force_apply_ontology"), history ) - hgnc_job <- get_last_successful_run("hgnc_update") + hgnc_job <- get_last_successful_run("hgnc_update", history) null_coalesce <- function(a, b) if (!is.na(a)) a else b diff --git a/app/src/components/ReloadPrompt.vue b/app/src/components/ReloadPrompt.vue index badc9dc0..eca3a1aa 100644 --- a/app/src/components/ReloadPrompt.vue +++ b/app/src/components/ReloadPrompt.vue @@ -9,15 +9,30 @@