Skip to content

A form can be deleted — and the Trash gives it back - #44

Merged
AllTerrainDeveloper merged 3 commits into
mainfrom
feature/delete-form
Aug 23, 2026
Merged

AllTerrainDeveloper merged 3 commits into
mainfrom
feature/delete-form

Conversation

@AllTerrainDeveloper

Copy link
Copy Markdown
Owner

Adds the missing way to delete a form, and makes the desktop's Trash a real safety net for it:

  • Delete UI — a Delete section in the builder's Settings pane (below Archive): danger button, confirmation stating exactly what happens, and the same landing as archiving (next form or empty state). Entries deliberately survive their form; deletion is wp_trash_post, not a hard delete.
  • Trashed forms actually disappear — the renderer and the submission pipeline only checked post type, so a "deleted" form kept rendering and accepting POSTs through any shortcode. Both public gates now treat trash as nonexistence.
  • Recycle Bin integration — forms opt into openstation_recycle_bin_capture_post_types (forms only; retention bulk-trashes entries and would bury the bin), and the capability map gains the edit_published_/delete_published_ primitives that WordPress's standard edit_post/delete_post meta caps resolve to on a trashed-from-published form — without them the bin silently hid trashed forms from administrators.
  • Live updates — after a delete resolves, the builder announces via OpenStation's new wp.os.announceContentChange() (Trash: localize config before the lazy payload harvest WordPress/openstation#656), so an open Trash window and the dock badge repaint immediately instead of on the 15–60 s Heartbeat cadence.

Verification: 732 PHPUnit + 372 vitest green, PHPCS clean; QA'd end to end on the 8889 site — delete from the builder, watch the open Trash list it as "now", restore it back to its pre-trash status.

🤖 Generated with Claude Code

https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp

AllTerrainDeveloper and others added 3 commits August 23, 2026 18:02
There was archiving, for a form whose moment has passed, and there was
no way at all to be rid of one that should never have existed. The
server has known how since the beginning -- DELETE /forms/{id} trashes
the form and fires alltfo_form_deleted -- but nothing in the builder
ever called it.

Now the Settings pane pairs the Archive section with a Delete one: a
danger button, a confirmation that says exactly what will happen, and
the same landing the archive uses -- the next form if there is one, the
empty state if not. The entries deliberately stay, because they are the
visitors' words rather than the form's, and the trash rather than a
hard delete means a wrong click is a support request, not a loss.

And the part nobody had noticed: a trashed form kept rendering. Both
public gates -- the renderer and the submission pipeline -- checked the
post type and never the status, so "deleted" meant "gone from the
lists" while every shortcode still showed the form and accepted its
answers. Both now treat trash as nonexistence, and three new tests hold
the door shut: silent render, refused POST, surviving entries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp
Deleting worked; changing your mind did not. Two bugs stood between a
trashed form and the desktop's Trash window, one in each plugin.

On this side: the form post type is headless, so OpenStation's bin does
not track it by itself — it is now opted in through
`openstation_recycle_bin_capture_post_types`. Forms only, deliberately:
retention trashes entries in bulk every day, and a bin full of expired
entries would bury the one form somebody actually wants back.

And the capability map was two primitives short. Our own REST asks
`alltfo_edit_forms` and never WordPress's `edit_post`, but everything
outside the plugin asks the standard question — and on a form trashed
from publish, `edit_post` resolves to `edit_published_alltfo_forms`,
which no role held. The bin dutifully hid every trashed form from the
administrator who had just trashed it. Both `_published_` primitives
are granted now, for forms and entries alike, and a test asks the
standard question so the next missing primitive cannot hide.

The builder's delete copy now tells the whole story too: the form
moves to the desktop's Trash, and it can be brought back from there.

(The other half — the bin's config never reaching its lazy-loaded
bundle — is fixed in the desktop-mode repo, branch
fix/lazy-window-config-priority.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp
Deleting a form updated the open Trash window a heartbeat late —
fifteen to sixty seconds, which reads as never. The shell cannot see a
mutation made through this plugin's own REST endpoints; the moment the
delete resolves, the builder now says so itself through the shell's
new `wp.os.announceContentChange()`, and the Trash window and its dock
badge repaint before the toast has faded.

(The announcer is OpenStation PR #656, which also carries the
lazy-config fix that made the Trash window list anything at all.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp
@AllTerrainDeveloper
AllTerrainDeveloper merged commit 3675e32 into main Aug 23, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant