Skip to content

[5/7] Open tasks in a modal over the board - #276

Open
alex-clickhouse wants to merge 3 commits into
alex-clickhouse/task-board-uifrom
alex-clickhouse/task-detail-modal
Open

[5/7] Open tasks in a modal over the board#276
alex-clickhouse wants to merge 3 commits into
alex-clickhouse/task-board-uifrom
alex-clickhouse/task-detail-modal

Conversation

@alex-clickhouse

Copy link
Copy Markdown
Collaborator

Stacked on #275#274#273#272main.

Clicking a board card navigated to the full task page — tearing down the board and losing its scroll position for what is usually a glance at the description.

Background-location routing

/tasks/:taskId now renders either way, depending on how it was reached:

  • From the board — the navigation carries a background location in history state, so App renders the board's route tree and overlays the task as a dialog.
  • Cold load, refresh, or a shared link — no such state, so it renders the ordinary full page.

Same URL either way. Links stay shareable, Back still means back, and the board survives underneath. First use of location.state in the app; the pattern is confined to App.tsx and TasksPage.openTask.

The modal's close does navigate(-1) rather than navigate('/tasks'), so returning restores the board with its scroll intact.

Shared editor

TaskDetailBody now holds the metadata row, edit/preview toggle, markdown body, and save — used by both the page and the modal so they can't drift. Only the surrounding chrome differs.

One behaviour change fell out of the extraction, and it's a fix: content no longer resyncs from the store while edits are unsaved. Previously a task_updated broadcast landing mid-typing would replace the textarea contents. That was unreachable before #275 (nothing broadcast); with live updates in, it's a real way to lose work.

Also

  • Page-scoped shortcuts (b/l view, n new, / focus search), bound only while /tasks is mounted — the ChatPage pattern. Card movement is left to dnd-kit's own keyboard handling rather than reimplemented on top of it.
  • A Tasks section in ShortcutsModal, whose own comment says the list is manual and must be kept in sync with the handlers.
  • Deletes components/Tasks/TaskList.tsx — 89 lines, zero importers, dead since the page was rewritten.

Testing

  • npm test — 46 passed
  • npx tsc -b — clean
  • npm run build — clean
  • npx eslint . — 148 problems vs 152 on main; net −4

No new specs here: the routing behaviour is a <Routes location=…> swap that's better checked by clicking than by mocking a router, and TaskDetailBody is a move rather than new logic. The unsaved-edits guard is the one thing here I'd want a spec for — flagging it rather than quietly skipping it.

Still pending across the stack: the live drag pass, which needs #272's API deployed (nerve restart on the instance).

🤖 Generated with Claude Code

@alex-clickhouse
alex-clickhouse force-pushed the alex-clickhouse/task-detail-modal branch from 4569a58 to 6c8449b Compare August 5, 2026 10:31
@alex-clickhouse
alex-clickhouse requested a review from Copilot August 5, 2026 10:38
@alex-clickhouse alex-clickhouse changed the title Open tasks in a modal over the board [5/6] Open tasks in a modal over the board Aug 5, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces background-location routing so opening a task from the Tasks board overlays task details in a modal without unmounting the board (preserving scroll/position and keeping /tasks/:taskId shareable), and adds Tasks-scoped keyboard shortcuts plus a ShortcutsModal section. It also removes a dead TaskList component and adds new task detail modal/body components.

Changes:

  • Implement background-location routing in App.tsx and navigate-to-task with state.background from TasksPage.
  • Add TaskDetailModal (modal overlay) and TaskDetailBody (extracted detail/editor UI) components.
  • Add Tasks page-scoped keyboard shortcuts and document them in ShortcutsModal; extend shortcut section typing; delete unused TaskList.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
web/src/utils/keyboard.ts Extends ShortcutDef.section to include a new tasks section.
web/src/pages/TasksPage.tsx Adds tasks-scoped shortcuts and navigates to task detail with background state for modal routing.
web/src/components/Tasks/TaskList.tsx Deletes a dead/unused legacy tasks list component.
web/src/components/Tasks/TaskDetailModal.tsx Adds the modal-rendered task detail route for board overlay behavior.
web/src/components/Tasks/TaskDetailBody.tsx Adds the extracted task detail editor/body intended to be shared between modal and full page.
web/src/components/ShortcutsModal.tsx Documents Tasks shortcuts in the shortcuts modal.
web/src/App.tsx Implements background-location routing and conditional modal route overlay for /tasks/:taskId.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread web/src/pages/TasksPage.tsx Outdated
Comment thread web/src/components/ShortcutsModal.tsx
Comment thread web/src/components/ShortcutsModal.tsx
Comment thread web/src/components/Tasks/TaskDetailBody.tsx
Comment thread web/src/components/Tasks/TaskDetailBody.tsx Outdated
@alex-clickhouse alex-clickhouse changed the title [5/6] Open tasks in a modal over the board [5/7] Open tasks in a modal over the board Aug 5, 2026
@alex-clickhouse
alex-clickhouse force-pushed the alex-clickhouse/task-detail-modal branch from 32d204d to 89d6161 Compare August 5, 2026 12:07
@alex-clickhouse
alex-clickhouse marked this pull request as ready for review August 5, 2026 12:26
alex-clickhouse and others added 3 commits August 6, 2026 18:54
Clicking a board card navigated to the full task page, tearing down the
board and losing its scroll position — for what is usually a glance at
the description.

/tasks/:taskId now renders either way depending on how it was reached.
Entered from the board it carries a `background` location in history
state, so App renders the board's route tree and overlays the task as a
dialog; a cold load, a refresh, or a shared link has no such state and
gets the ordinary full page. The URL is the same either way, so links
stay shareable and Back still means back. First use of location.state in
the app.

The editor itself moves into TaskDetailBody, shared by the page and the
modal so the two can't drift — only the surrounding chrome differs. One
behaviour change fell out of the extraction: content no longer resyncs
from the store while edits are unsaved, because a task_updated broadcast
arriving mid-typing would otherwise discard what you were writing.

Also adds page-scoped shortcuts (b/l to switch view, n for new, / to
focus search) and the Tasks section in ShortcutsModal — whose comment
says the list is manual and must be kept in sync. Card-level movement is
left to dnd-kit's own keyboard handling rather than reimplemented.

Deletes components/Tasks/TaskList.tsx: 89 lines, zero importers, dead
since the page was rewritten.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
At 620px the markdown body wrapped prose into a column too narrow to read
comfortably, let alone edit — the dialog was sized like a form when it
holds a document.

Adds a `wide` size to Modal (min(1100px, 94vw)) rather than a one-off
override, since any future document-shaped dialog wants the same thing,
and takes the task modal to 85vh so the editor has vertical room too.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ialog

Five review findings on the task modal.

TaskDetailBody said it was shared by the full page and the modal, and it was
not — TaskDetailPage still hand-rolled its own copy of the same editor, so
the claim was false and the two had already drifted: the status-history
button lands on the body only, leaving the full page quietly missing a
shipped feature. The page now renders TaskDetailBody and keeps just the
chrome the modal has no use for, a back button and a heading. That is a
visible change to the full page — the textarea and preview take the body's
metrics, and the meta row, edit/preview toggle and Save move out of the page
header into the body's single row.

Page shortcuts kept firing while a dialog was open. /tasks stays mounted
behind the task modal by design, so its document listener stayed live: `n`
opened a second dialog on top of the first, and `/` moved focus out of an
aria-modal dialog into a search box behind the backdrop, where typing edits
something the user cannot see. Gating on the URL would only cover the task
modal, and the same leak reproduces under the shortcuts dialog with no
background routing at all, so the gate is "is any dialog open" — the modal
stack Modal already keeps, moved to its own module so a page can read it
without turning Modal.tsx into a mixed component/util file.

The shortcuts list rendered ArrowUp for a binding that is all four arrows,
and its file comment still claimed the only handlers were in App.tsx and
ChatPage.tsx.

The dirty guard gets the unit test it warrants now that two surfaces depend
on it, and an honest comment: it is defensive, not a fix for something
reachable today, because a task_updated broadcast carries the tasks row and
that table has no content column.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@alex-clickhouse
alex-clickhouse force-pushed the alex-clickhouse/task-detail-modal branch from 89d6161 to 7384d6d Compare August 6, 2026 17:00
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.

2 participants