feat(tasks): All Tasks cross-project view + fix viewMode flash on project switch#423
Open
hudsonhrh wants to merge 1 commit into
Open
feat(tasks): All Tasks cross-project view + fix viewMode flash on project switch#423hudsonhrh wants to merge 1 commit into
hudsonhrh wants to merge 1 commit into
Conversation
Two related changes to the tasks page that landed together since they touch
the same code path.
1. Hoist viewMode state above TaskBoardProvider
TaskBoardProvider is keyed on selectedProject.id (intentional — resets per-
project optimistic state). TaskBoard owned useViewMode, so the view mode
state unmounted/remounted on every project switch, snapping from the 'board'
default back to the stored value a frame later. That's the board→list flash
when navigating between projects in list view.
Fix: TaskViewModeProvider sits at MainLayout level (sibling above the keyed
boundary). useViewMode is now a consumer; same public API, no flash.
2. All Tasks cross-project view
New top-of-sidebar entry — distinct from project rows: gradient accent,
stacked icon, task/project count subtitle. Clicking it sets the
ALL_PROJECTS_ID ('__all__') sentinel as the active selection.
AllTasksProvider (new) wraps the same TaskBoardContext that consumers
already use, so ListView/GanttView/TaskBoard render unchanged. It supplies:
- synthetic taskColumns: aggregateAllTasksColumns(projects) merges every
project's columns by status and decorates each task with projectId +
projectName for the chip
- isAllTasks: true (read in TaskColumn to hide Add Task)
- all mutators no-op + toast "Open a project to <action>" — the All Tasks
view is for browsing, not editing. Clicking a task card still navigates
into the project's detail modal where mutations work normally.
View-side adaptations are minimal: TaskCard + TaskRow render a project chip
when task.projectName is populated (only true in All-Tasks aggregation).
Files touched:
- new: views/allTasks.js (sentinel + aggregateAllTasksColumns + countAllTasks)
- new: AllTasksProvider.jsx
- views/useViewMode.js (split into provider + consumer)
- MainLayout.js (hoist provider, render AllTasksProvider on sentinel)
- ProjectSidebar.js (top-of-sidebar entry)
- TaskColumn.js (hide Add Task in all-tasks mode)
- TaskCard.js, TaskRow.jsx (project chip)
- TaskBoardContext.js (export the context for the alt provider)
- dataBaseContext.js (synthetic ALL_TASKS_PROJECT, preserve across refreshes)
Tested locally: yarn build clean; All Tasks renders aggregated tasks across
Test6's 3 projects; viewMode persists across project switches with no flash.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related fixes on the tasks page, bundled into one PR because they touch the same code path:
Flash fix — viewMode (board/list/gantt) no longer resets to 'board' for a frame when you switch projects in List or Gantt view. The view state is now hoisted above the keyed
TaskBoardProviderboundary instead of being reset on every project remount.All Tasks view — new top-of-sidebar entry that aggregates every project's tasks into one cross-project view. Distinct accent treatment so it doesn't blend into the project list. Read-only for now (Add Task hidden, mutations toast "Open a project to make changes" — clicking a task navigates into the project's detail modal where everything works normally).
Screenshot
(See
/tmp/poa-screenshots/all-tasks-final.pnglocally — header shows ""All Tasks 28 tasks across 3 projects"", sidebar shows the accent-tinted ""All Tasks · 28 tasks · 3 projects"" entry at the top, list view aggregates across projects with a project chip on each row.)Flash fix
Root cause:
MainLayout.jsmounts<TaskBoardProvider key={selectedProject.id}>so each project gets a fresh TaskBoardContext (intentional — optimistic state must reset per project).TaskBoardlives inside that subtree and owneduseViewMode. On every project switch,useViewMode's state reset to the'board'default, then a useEffect read localStorage and switched to the user's stored mode → that's the visible flash.Fix:
views/useViewMode.jssplit into aTaskViewModeProvider(lives at the MainLayout level, sibling above the keyed boundary) and a thinuseViewModeconsumer. Same public API; viewMode now persists across project switches.All Tasks view design
Sidebar entry — distinct but consistent:
?projectId=__all__(ALL_PROJECTS_ID sentinel — cannot collide with real on-chain project ids which are 0x-prefixed)Data layer:
AllTasksProvider(new) wraps the sameTaskBoardContextthatListView/GanttView/TaskBoardDesktopalready consume, so the existing views render unchangedaggregateAllTasksColumns(projects)merges same-status columns across every project and decorates each task withprojectId+projectNamefor the chipaddTask,moveTask,editTask,deleteTask,applyForTask,approveApplication,assignTask,rejectTask) are no-op + toast; the All Tasks view is a browser, not an editorTaskColumnreadsisAllTasksfrom context and hides the Add Task button accordinglyTaskCardandTaskRowrender a project chip whentask.projectNameis populated (only true in this aggregation)Mobile project picker doesn't include All Tasks yet — desktop-only for v1.
Test plan
yarn buildclean🤖 Generated with Claude Code