Skip to content

feat(desktop): show the empty state on an empty workspace's Issues board - #3659

Merged
luke-agent[bot] merged 1 commit into
mainfrom
luke/issues-empty-board-state
Oct 18, 2026
Merged

luke-agent[bot] merged 1 commit into
mainfrom
luke/issues-empty-board-state

Conversation

@dastratakos

@dastratakos dastratakos commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Item "Empty board shows EmptyState" of the Improve Issues board plan. The developer settled the plan's open question: a workspace with no issues shows the app's empty state on the board too, instead of five empty columns.

Summary

  • issues-page.tsx: listState now gives COLLECTION_STATE.EMPTY to an empty workspace in both layouts, not only the List. CollectionPage then draws the same EmptyState ("No issues yet", ListTodoIcon) on the board. The board's reading blocks (IssueBoardSkeleton) are unchanged. A workspace with issues still stands all five columns, empty ones included.
  • The empty state's way on: a New issue button through EmptyState's action slot. It is wired to the toolbar's own onCompose, so it opens the same card (on Backlog). It is disabled whenever the toolbar's New issue is: no workspace listed, or the card already open. It matches the Inbox's NeedsYouEmpty, a label alone with no glyph. Factory and Automations have no action in their empty states. "New issue" is now one constant used by both buttons.
  • @luke/ui EmptyStateAction gains an optional disabled, passed to its Button. Without it, the empty state's button would vanish and reappear behind the card each time the card opened.
  • @luke/ui CollectionPage (CSS only): the notice wrapping an empty or failed state no longer adds its own 2:3 spacers around an EmptyState. The EmptyState already does that split itself, so the two stacked. That left the state a sixth of the room (about 115px on an 800px window) and clipped anything past the icon and line: this New issue, and a centred ErrorState's Retry. The rule is scoped to :has(> .luke-empty-state). With the spacers gone, a line-only state sits about 20px higher than before, at the 2:3 point of the whole room.

Shared component change

Two @luke/ui components owned by @charleslpan change.

  • EmptyStateAction.disabled (optional): passed straight to the action's Button. Every existing caller (NotFound, the Inbox's NeedsYouEmpty, ErrorState's Retry) leaves it out, so their buttons are unchanged.
  • CollectionPage's notice spacers: .luke-collection-page-notice stands its content at the room's 2:3 point with ::before/::after. EmptyState, and a centred ErrorState, which is drawn as one, already does the same split inside a flex: 1 1 0 box. Inside the notice, the two splits stacked: the state got a sixth of the room and scrolled what didn't fit. On main that already hides Factory's Retry when its tasks could not be read (shots below), and it would have hidden this New issue. The new rule drops the notice's spacers only where its direct child is .luke-empty-state. Its callers:
    • Factory (empty and failed): the line-only empty state sits 2px higher, and the failed state's Retry now shows. See the pair below.
    • Issues (empty and failed): this PR's change. The failed state's Retry now shows too.
    • Web admin (AdminPage, the accounts table, a day): these pass plain text, not an EmptyState, so :has(> .luke-empty-state) does not match and nothing moves.
    • Automations, the Inbox and Home do not draw on CollectionPage, so nothing changes there.
Before (main) After
Factory, nothing at work
Factory, tasks could not be read

Screenshots

These come from a throwaway, uncommitted jsdom test that rendered the real IssuesPage with an empty workspace. Headless Chromium then painted them at 1280×800 in .desktop-shell > main.desktop-main, with the sidebar folded, using the desktop stylesheet built from main (before) and from this branch (after). This is the same method as #3559 and #3642.

Before After
Board, empty workspace
List, empty workspace
Board, empty workspace, light
List, empty workspace, light

After filing the first issue, the board stands its five columns again:

Evidence

  • pnpm check:affected: typecheck, lint and knip pass, and the desktop and ui suites pass. discarded-effect ran out of memory inside turbo's parallel group in this sandbox. Run alone, it passes ("No discarded Effect, Stream, or Layer in 2342 files"). The first run's one desktop failure was app-menu.test.ts, because the sandbox lacked Electron's binary. It passes once the binary is installed.
  • issues-page.test.ts: the test "a workspace with no issue yet still stands the board's columns, each saying it holds none" is replaced by "a workspace with no issue yet says so on the board and in the list, its New issue opening the card, and the first issue filed stands the board's columns". The new test fails on main ("the empty state offers New issue"). The column-+ test now stands one issue first, since an empty workspace no longer draws column heads.
  • empty-state.test.ts: new test "a way on unavailable for now still stands, and a press does nothing". It fails without the disabled field.
  • Test count: +1. The issues-page test was replaced one for one, and empty-state gains one.

Invariants

  • ./scripts/check.sh green. (CI)
  • JSON Schema goldens unchanged.
  • Every behavior change has, in this PR, the test that fails without it; no change-detector test added.
  • Gateway envelope goldens unchanged.
  • No new as type assertion outside the allowlisted files.
  • No Effect.runPromise/runSync/runFork outside the runtime edges.
  • No new setTimeout/setInterval/new Promise/AbortController/fs.watch.
  • No Effect, Stream, or Layer written as a statement and dropped.
  • Test count delta listed above (+1).
  • No hand-rolled file replaced.
  • No CLAUDE.md/AGENTS.md sentence names a changed part.
  • PRIVACY.md unchanged.
  • Package deps unchanged.
  • Barrel/door rule unaffected.

Notes

  • No hosted-service change, so no run.sh --preview run is needed.
  • Blockers or follow-up verification: None

Made with Luke

An empty workspace's board stood five empty columns; it now shows the
same "No issues yet" empty state as the List, with New issue as its one
way on, unavailable when the toolbar's is.

EmptyState's action gains `disabled`, and CollectionPage hands an empty
or failed state the whole room, where its notice's spacers left it a
sixth and clipped the button under the line.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
@vercel

vercel Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
luke-web Ready Ready Preview Oct 18, 2026 6:57pm UTC

Request Review

luke-agent Bot added a commit that referenced this pull request Oct 18, 2026
Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>

@devin-ai-integration devin-ai-integration 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.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

luke-agent Bot added a commit that referenced this pull request Oct 18, 2026
Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
@luke-agent
luke-agent Bot requested a review from charleslpan October 18, 2026 18:58
@luke-agent
luke-agent Bot added this pull request to the merge queue Oct 18, 2026
Merged via the queue into main with commit 81c6d43 Oct 18, 2026
11 checks passed
@luke-agent
luke-agent Bot deleted the luke/issues-empty-board-state branch October 18, 2026 19:14

This branch was successfully deployed

1 active deployment
Preview — 23f837f0 Deployed Oct 18, 2026 by vercel[bot]
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