fix: a button that starts work sends one request and shows the run it started #73
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/double-submit"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Clicking "Free 231 GiB" in the prune dialog gave no feedback beyond a background activity appearing in Activity, and the button could be spammed. The backend was already safe: prune holds the
storagelock withonSelfConflict: drop, so duplicates became 409s orskippedrows. The frontend was not, and an audit found the same pattern in about 20 places.Why the prune dialog showed nothing
It subscribed to
core:task:<id>, which is a retained topic, but read onlyonData. The run has usually reportedrunningbefore the subscription connects, so that news arrives only in the snapshot, which was dropped. The form, with its button live, stayed up until the sweep ended. Each extra click also leaked a subscription. The dialog then followed theskippedduplicate, which it rendered as running forever.Commits
fix(docker): prune dialog. Adds a busy flag, held until the snapshot lands. The dialog adopts the snapshot and folds progress and step deltas into the run. It stops the previous subscription before opening another.skippedandinterruptednow count as terminal. The reducer lives inrun_model.ts, with tests, so the other pages that follow a single run can share it.fix(shell): generic actions and forms. Handlers set busy but never checked it, and a disabled button lands a frame after a fast double click. Where the server queues rather than drops, this did double work: filebrowser copy/move/delete arewaitactions, so a second Retry on RunPage queued them again, and minecraft'sdiscard-latestpopped two edits.ConfirmDialogholds itself busy while an asynconconfirmis in flight, on click and on Enter. This covers callers that pass nobusy.ActionsBlock,FormBlock, RunPage retry/cancel, schedules, Activity's run button and the module-storage clear all return early while a request is in flight.ActionsBlockstops its previous progress subscription before opening a new one. For a plain POST that succeeds, it says "done" instead of showing nothing.fix(docker): the other pages.Verification
deno fmt --check,deno lint,deno task check: clean.check:svelte: 0 errors, no new warnings in the touched files.deno task test: 1019 passed, 0 failed.1c76917(#66's head). A test-merge onto currentmainis clean, but the suite has not been re-run on the merged tree.OPSDECK_FAKE_DATA=1:ActionsBlock's "done" label,FormBlock, and volume import.Not in here
The truncate route ignores
?wait=1, whichStoragePagesends, so the page reloads the log size from before the truncate. That is a backend change.Downstream
The same guards went into module_filebrowser, module_minecraft and module_healthchecks. In filebrowser, the create/rename prompt's Cancel was a submit button (
Buttonhas notype), so Create fired twice per click, and Cancel with a name typed created the item.🤖 Generated with Claude Code
Reviewed the three commits against
1c76917. I found no blocking bugs. Every busy flag resets on success, error and throw. ConfirmDialog's newpendingresets before it rethrows, so callers that pass their ownbusyare unaffected. Each follow closes its previous subscription before it opens a new one.Nits, none blocking:
VolumePage.svelte:119-134:uploadingis now reset only on error or a null snapshot. When the run is adopted it staystrue. Nobody can see that today, because a setimportRunreplaces the DropZone for the life of the page. But if anyone later clearsimportRunto allow a second import, the zone will come back disabled. A comment there, or a reset inadopt, would keep that from surprising someone.ActionsBlock.svelte:190:doneTimeris not cleared on unmount. It is harmless in Svelte 5.$effect(() => () => clearTimeout(doneTimer))would tidy it up.As the description says, the suite has not been run on the tree merged with current
main. Please run it before merging.Ran the full suite on this branch merged with current
main(323e746), as the approval asked. The merge was clean.deno task test: 1051 passed, 0 failed, 1 ignoreddeno task check,deno lintanddeno fmt --check: cleancheck:svelte: 0 errorsThe two nits (
uploadinginVolumePageanddoneTimerinActionsBlock) are non-blocking and not addressed here. The re-request for review on this PR was a mistake on my side, so I'm merging on the existing approval.