PUT /panels/ carries a version and refuses a stale one with 409

The Panels dialog re-reads the list on 409. A panels.json without a
version reads as 0.
This commit is contained in:
2026-10-15 10:07:50 +02:00
parent 589ddecbb1
commit 43498037be
10 changed files with 108 additions and 10 deletions
@@ -107,9 +107,17 @@ export function PanelsDialog() {
const host = config?.frontend_host ?? ""
const write = (next: PanelsConfig) =>
save.mutate(next, {
onError: (error) => handleError.call(showErrorToast, error as ApiError),
})
save.mutate(
{ ...next, version: config?.version },
{
onError: (error) =>
(error as ApiError).status === 409
? showErrorToast(
"Someone else changed the panels first. Their version is shown now, so make the change again.",
)
: handleError.call(showErrorToast, error as ApiError),
},
)
const replace = (id: string, panel: PanelDef) =>
write({ panels: panels.map((p) => (p.id === id ? panel : p)) })
+12 -1
View File
@@ -1,6 +1,7 @@
import { useMutation, useQueryClient } from "@tanstack/react-query"
import {
ApiError,
type DashboardDef_Input,
DashboardsService,
MessagesService,
@@ -55,7 +56,13 @@ export const panelQueryOptions = (id: string) => ({
queryFn: () => PanelsService.readPanel({ panelId: id }),
})
/** Replace the panels. Superuser-only on the server. */
/**
* Replace the panels, carrying the version they were read at. Superuser-only
* on the server.
*
* A 409 means someone else saved first, so the list is read again and the
* next change is based on theirs.
*/
export function useSavePanels() {
const queryClient = useQueryClient()
return useMutation({
@@ -65,6 +72,10 @@ export function useSavePanels() {
queryClient.setQueryData(panelKeys.all, saved)
queryClient.invalidateQueries({ queryKey: panelKeys.all })
},
onError: (error) => {
if (error instanceof ApiError && error.status === 409)
queryClient.invalidateQueries({ queryKey: panelKeys.all })
},
})
}