Skip to content

feat(blog): post publish toggle + status filter on the posts list - #6360

Merged
aka-sacci-ccr merged 3 commits into
mainfrom
blogpost-publish-toggle
Aug 20, 2026
Merged

feat(blog): post publish toggle + status filter on the posts list#6360
aka-sacci-ccr merged 3 commits into
mainfrom
blogpost-publish-toggle

Conversation

@aka-sacci-ccr

@aka-sacci-ccr aka-sacci-ccr commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Integrates the blog app's new optional status field into the CMS. Only the publisheddraft transition is exposed — the other states (archived, generating, awaiting_review) are read, never written.

Editor (Settings tab, top-right). A Published switch, styled bg-success when on. Flipping it writes status: "published" | "draft" onto the post payload; the existing autosave persists it. No new save path, no new tool.

Posts list. Published / Draft join the existing filter dropdown as a third group next to Category and Author, with live counts like the other two. It resets alongside the other post filters on collection switch and on the "Manage posts" landing, and clearing selection behaves as before.

Assumption worth reviewing

An unset status reads as published, centralized in isPostPublished() (blog-data.ts) and used by both the editor switch and the list filter so the two can never disagree. The field is new and optional, so every post that predates it has no status — treating that as a draft would show the whole existing blog as unpublished.

This holds as long as the blog app filters with status !== "draft". If the app filters with status === "published", it needs the same undefined-is-published default, otherwise the site and the CMS disagree about legacy posts.

Everything that is not published (including generating / awaiting_review) groups under Draft in the filter and reads as off in the switch — flipping the switch overwrites such a state with an explicit draft/published.

emptyBlogPayload is untouched, so a new post has no status and therefore reads as published. Making new posts draft-by-default is a one-liner if preferred.

Known limitation

The filter dropdown is a single radio group by existing design ("one filter at a time"), so status does not stack with category/author — you can't ask for "drafts in Sustentabilidade". Making status an orthogonal second chip is a contained follow-up if that combination is wanted.

Testing

  • bun test apps/web/src/components/sandbox/content/blog/ — 125 pass, 0 fail. New unit tests cover isPostPublished (unset / empty / non-string / exact-match / case + whitespace sensitivity / the non-editable states) and listPostsWithMeta reporting published; the existing listPostsWithMeta assertion was updated for the new field.
  • bun --bun node_modules/typescript/bin/tsc --noEmit -p apps/web/tsconfig.json — exit 0
  • bun run lint — 18 warnings, 0 errors; identical to the count on a stashed tree, so nothing new
  • bun run fmt — clean

Not verified in a running browser: the exact rendering of the green switch and the dropdown group. Both are token-based (bg-success) and reuse the existing DropdownMenuRadioItem + OptionCount markup.

Affected areas

apps/web blog post editor and posts list only. i18n keys added to both en/sandbox.ts and pt-br/sandbox.ts.

🤖 Generated with Claude Code

Adds a status header row at the top of the post Settings tab: a badge
showing the current state plus a button that flips `status` between
"published" and "draft". The write goes through the existing autosave,
so no new save path.

An unset `status` reads as published — the field is new and optional, so
every pre-existing post would otherwise read as a draft. Statuses the
editor does not own (generating, awaiting_review) render verbatim
instead of being reported as drafts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the claude PR authored by a coding agent label Aug 20, 2026
decobot and others added 2 commits August 20, 2026 17:25
Label + badge + button said the same thing three times. Collapsed to the
Label + Switch pattern SeoFields already uses two fields below, dropping
PostStatusBadge and three of the four i18n keys with it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The switch now paints bg-success when checked, so "published" reads at a
glance instead of looking like every other toggle.

Adds Published/Draft to the posts list filter dropdown, alongside the
existing category and author groups (same one-filter-at-a-time radio, so
status does not stack with a category). Counts come from the same live
scan the other groups use, and the filter resets with them on collection
switch and on the "Manage posts" landing.

Both surfaces read isPostPublished() in blog-data, so the list and the
editor can't disagree about what "published" means: unset status is
published (the field postdates existing posts), everything else —
draft, generating, awaiting_review — is not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@aka-sacci-ccr aka-sacci-ccr changed the title feat(blog): publish/unpublish toggle in the post settings tab feat(blog): post publish toggle + status filter on the posts list Aug 20, 2026
@aka-sacci-ccr
aka-sacci-ccr merged commit 89a3709 into main Aug 20, 2026
33 checks passed
@aka-sacci-ccr
aka-sacci-ccr deleted the blogpost-publish-toggle branch August 20, 2026 20:49
decocms Bot pushed a commit that referenced this pull request Aug 20, 2026
PR: #6360 feat(blog): post publish toggle + status filter on the posts list
Bump type: minor

- decocms (apps/api/package.json): 4.250.0 -> 4.251.0
- @decocms/native (apps/native/package.json): 4.250.0 -> 4.251.0

Deploy-Scope: web
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude PR authored by a coding agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants