Skip to content

fix(admin): only show Pending changes when a live revision exists - #3010

Open
eisenbruch wants to merge 1 commit into
emdash-cms:mainfrom
eisenbruch:fix/content-list-pending-changes-unpublished
Open

fix(admin): only show Pending changes when a live revision exists#3010
eisenbruch wants to merge 1 commit into
emdash-cms:mainfrom
eisenbruch:fix/content-list-pending-changes-unpublished

Conversation

@eisenbruch

@eisenbruch eisenbruch commented Sep 9, 2026

Copy link
Copy Markdown

What does this PR do?

The content list shows a Pending changes badge on entries that have never been published, so the same entry reads as both Scheduled and Pending changes at once. The editor disagrees with the list for that entry, and the list is the one that is wrong.

ContentListItem compares the revision pointers directly:

hasPendingChanges={!!item.draftRevisionId && item.draftRevisionId !== item.liveRevisionId}

A draft or scheduled entry has a draft revision and liveRevisionId === null, so the two "differ" and the badge renders — but there is no published version for the changes to be pending against. The editor goes through getContentPublishingState(), which checks isLive first and correctly reports scheduled or draft.

The fix uses getDraftStatus(), which already encodes the rule and already lives in lib/api:

if (!item.liveRevisionId) return "unpublished";
if (item.draftRevisionId && item.draftRevisionId !== item.liveRevisionId)
	return "published_with_changes";
return "published";

Two lines: the badge condition and the import. The two screens now agree.

Found on a site running 0.37: a scheduled entry with several revisions and live_revision_id null was listed with pending changes while its editor showed only "Scheduled". Every unpublished entry that had been edited at least once was affected.

Closes #

Type of change

  • Bug fix
  • Feature (requires maintainer-approved Discussion)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation (if applicable). Do not include messages.po changes except in translation PRs — a workflow extracts catalogs on merge to main.
  • I have added and reviewed the user-facing changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/...
  • I have included screenshots below if this PR changes the UI — described instead, see below

Notes on the checklist, so the ticks are honest:

  • No new strings, so nothing to wrap. No messages.po changes are included.
  • tests/components/ContentList.test.tsx is 70/70, and pnpm --filter @emdash-cms/admin typecheck passes. pnpm lint:json reports nothing for the touched file; the repository has pre-existing diagnostics elsewhere that this branch does not add to.
  • A few admin browser tests fail locally, but the set differs between runs (SeoPanel, SocialSettings, LoginPage, router and others) and never includes ContentList, so they look like local flakes rather than anything from this change.

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: Claude Opus 5 (Claude Code)

Screenshots / test output

No screenshot, deliberately. The only site I can reproduce this on is a private pre-launch client site, and a shot of the affected list is a shot of unpublished client content and headlines. Describing it instead:

The status cell of an unpublished-but-edited entry renders two badges side by side — the lifecycle badge (Scheduled, blue, calendar icon) immediately followed by the companion badge (Pending changes, amber, arrows icon). After the fix the companion badge is gone and the lifecycle badge is unchanged. A published entry with unpublished edits still shows both, which the pre-existing test covers.

If a maintainer wants a rendered before/after, the fastest reproduction is a demo entry: create any entry in a collection with drafts enabled, save it without publishing, and it will show Pending changes on main.

Test added for the case that was not covered:

✓ ContentList > status badges > shows the Pending changes companion badge when revisions differ
✓ ContentList > status badges > does not show pending badge when the entry has never been published
✓ ContentList > status badges > does not show pending badge when revisions match

Test Files  1 passed (1)
     Tests  70 passed (70)

The content list compared the draft and live revision pointers directly, so an
entry that had never been published - draft revision set, live revision null -
counted as a difference and rendered the badge. getDraftStatus() already
encodes the correct rule and is what the editor's publishing state derives
from, so the list now uses it and the two screens agree.
@changeset-bot

changeset-bot Bot commented Sep 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6c5b805

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 17 packages
Name Type
@emdash-cms/admin Patch
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/sandbox-workerd Patch
@emdash-cms/fixture-perf-site Patch
@emdash-cms/perf-demo-site Patch
@emdash-cms/cache-demo-site Patch
@emdash-cms/do-demo-site Patch
@emdash-cms/do-solo-demo-site Patch
@emdash-cms/auth Patch
@emdash-cms/blocks Patch
create-emdash Patch
@emdash-cms/gutenberg-to-portable-text Patch
@emdash-cms/x402 Patch
@emdash-cms/auth-atproto Patch
@emdash-cms/release-service Patch
@emdash-cms/plugin-embeds Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added area/admin size/S review/needs-review No maintainer or bot review yet labels Sep 9, 2026
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the right fix for the right problem, implemented in the way the codebase already uses elsewhere.

The bug is real: ContentListItem was computing hasPendingChanges by comparing the two revision pointers directly, so any entry with a draft revision and liveRevisionId === null (draft or scheduled, never published) got the “Pending changes” badge. The editor was already deriving the same boolean from getDraftStatus(item) === "published_with_changes", so the two screens disagreed.

The change:

  • swaps the list’s inline pointer comparison for the shared getDraftStatus() helper from lib/api, which returns "unpublished" when there is no live revision. This matches the editor’s derivation exactly.
  • adds a focused regression test for the never-published/scheduled case that would have failed before the fix.
  • includes a clear, user-facing changeset for @emdash-cms/admin.

What I checked:

  • Read the diff and the full changed files.
  • Verified getDraftStatus in packages/admin/src/lib/api/content.ts and its export from index.ts.
  • Traced the editor’s use of the same helper in ContentEditor.tsx (it already computes hasPendingChanges and isLive from getDraftStatus), confirming consistency.
  • Reviewed the changeset against .changeset/README.md — it leads with the observable behavior, names the affected surface, and explains the fix.
  • Confirmed no messages.po changes are included, no new logged-out queries, no SQL, no authorization, and no RTL/styling edits.

The test is a real behavior test (the badge text is absent/present), the helper is the same one the editor relies on, and the changeset is properly user-facing. No findings.

@eisenbruch

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Sep 9, 2026
@github-actions github-actions Bot added cla: signed review/approved Approved; no new commits since and removed cla: needed review/needs-review No maintainer or bot review yet labels Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant