* [170c9578] Frontend: Panel consistency & UX wave (forms audit, command palette, kanban merge, responsiveness) (#688) * [f1957610] Stream1-A: Project form sync (#667) * [f1957610] feat(panel): expose codegen_command in create-project dialog Add the Codegen Command input to create-project-dialog.tsx, mirroring the field already present in edit-project-dialog.tsx. All other fields named in this task (git_provider, github_installation_id, environments, protected_branches, video_engine_enabled, monthly_budget_usd with gt=0 client validation, sandbox_extensions) were already implemented on this branch's base by prior work, and the ProjectCreate/ProjectUpdate types in types/index.ts already match the backend ProjectCreateRequest/ProjectUpdateRequest schemas exactly -- no further changes were needed there. * [f1957610] docs(forms): add project-fields-audit reference for future field consistency Create a living audit of which project configuration fields are exposed in the create vs. edit dialogs, mapping to the backend ProjectCreateRequest/ProjectUpdateRequest schemas. This serves as a future reference to prevent field-sync gaps and documents the intentional asymmetry (create focuses on git setup, edit adds autonomy/maintenance toggles). Includes a checklist for adding new project fields in the future. --------- Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech> Co-authored-by: Frontend Documenter <fe-doc@roboco.tech> * [515697f4] feat(panel): settings save feedback + forms-audit.md living reference (#669) Add per-toggle confirmation toasts to the four Settings-page prefs (notifications, sound, auto refresh, refresh interval) so an immediate write is never indistinguishable from a silent failure. These prefs stay on the already-shipped client-persisted useUIStore pattern (CHANGELOG.md "Settings preferences persist as real client prefs instead of 422-ing as theater") rather than settingsApi, since the backend _VALIDATORS allowlist deliberately excludes them and the parent task scoped this stream as needing no backend schema changes. Check in docs/forms-audit.md: a living form x field x verdict table covering Stream1-A (project dialogs), Stream1-B (task dialogs), and this settings work, with a header note that future backend schema changes require a row update. Fixes the project-slug help text (now correctly says letters/numbers/hyphens, not just hyphens). Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech> * [80a215a4] Stream2-A: Command palette component (#670) * [80a215a4] feat(panel): Cmd+K command palette component Radix Dialog + combobox pattern searching tasks/agents/projects/pages, localStorage recents under roboco-cmd-recents, keyboard nav (arrows/ Enter/Escape), mounted globally in the dashboard layout. * [80a215a4] fix(panel): restore fields dropped from ui-store.ts by prior merge Stream1-C's merge stripped notificationsEnabled, soundEnabled, autoRefresh, refreshIntervalSeconds, a2aContextOpen, quickActionIds, productsView, and projectsView from the shared UI store, breaking typecheck for settings/quick-actions/products/projects/a2a/notification consumers repo-wide. Restored per already-committed tests + consumers. * [80a215a4] docs(panel): add command palette reference guide Documents the global Cmd+K search feature: usage (keyboard shortcuts, search categories, recents), architecture (CommandPalette component, useCommandPalette hook, fuzzy-match and recents helpers), data flow, and verification against live API data. --------- Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech> Co-authored-by: Frontend Documenter <fe-doc@roboco.tech> * [cdc371d1] Stream4-A: Responsiveness audit and fix — wide-content pages (#671) * [cdc371d1] fix(panel): bump Button sm size to 36px touch-target floor Button's size="sm" variant was h-8 (32px), used as literal row-action buttons on the overview page's CEO Approval/PR Review queues and other controls across settings/metrics/agents/a2a. Bump to h-9 (36px) to meet the touch-target floor everywhere at once, keeping the smaller horizontal padding/gap intact for visual density. * [cdc371d1] fix(panel): make AlertDialog scroll its body at short viewport heights AlertDialogContent lacked the max-h-[85vh]/overflow-y-auto that the sibling DialogContent already has, and AlertDialogFooter lacked DialogFooter's sticky bottom-0 pinning. A tall description at a short viewport height (mobile landscape) could clip the action buttons off screen with no way to reach them. Affects the settings page's GitHubAppCredentialsCard/FeatureFlagsCard confirm dialogs (and every other AlertDialog app-wide). Ports DialogContent's already-solved scroll pattern onto AlertDialogContent/Footer. * [cdc371d1] fix(panel): wrap Scorecards Members table in ResponsiveTable metrics/scorecards-tab.tsx's 9-column Members table was a bare <Table> with no mobile-card fallback, unlike its sibling tables in the same file (Rework, SpawnWaste) and sessions-table.tsx, which already use the established ResponsiveTable wrapper. Add a MemberCard component and wrap the table so it stacks as cards below md instead of forcing a cramped in-card horizontal scroll on a 375px viewport. --------- Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech> * [b25fca69] Stream2-B: Header integration for command palette (#675) * [b25fca69] Wire header search into Stream2-A command palette: click trigger via useUIStore.setCommandPaletteOpen, remove disabled input and Coming Soon tooltip remnants * [b25fca69] Wire header search into Stream2-A command palette: click trigger via useUIStore.setCommandPaletteOpen, remove disabled input and Coming Soon tooltip remnants --------- Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech> * [e4ce5b9a] Stream3-A: Tasks page List|Kanban tabs + kanban embed (#674) * [e4ce5b9a] feat(tasks): add List|Kanban tabs to tasks page sharing URL filter state Add top-level List|Kanban Tabs above the tasks page filter bar. List tab renders the existing TaskFilters+TaskTable unchanged; Kanban tab embeds the existing DevKanban/QaKanban/PrReviewKanban/PmKanban views via nested sub-tabs (dev/qa/pr-review/pm), mirroring the standalone /kanban page's own tab styling (tooltip-wrapped triggers, pickTab helper). Both tabs read/write `tab`/`view` query params through the page's existing updateParams pattern, so all filters persist across tab switches. The four kanban view wrappers gain an optional controlled team/onTeamChange pair so the team filter is shared bidirectionally with the List tab's team filter, while staying backward compatible (uncontrolled, initialTeam-only) for the standalone /kanban route. KanbanBoard's dnd-kit drag-and-drop and mobile single-column navigation are untouched. * [e4ce5b9a] docs(tasks): add tasks-page-tabs.md documenting List|Kanban tab structure and shared filter state --------- Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech> Co-authored-by: Frontend Documenter <fe-doc@roboco.tech> * [18c52802] feat(panel): redirect /kanban to Tasks kanban tab, remove sidebar entry, swap bottom tab bar to Agents (#679) Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech> * Stream4-B: Responsiveness fixes — remaining dashboard pages (#676) * [fee25542] fix(a11y): bump sub-36px icon-sm touch targets to 36px on remaining pages Both kb-search-bar.tsx (Knowledge Base search clear button) and self-hosted-section.tsx (Settings token show/hide button) used Button size="icon-sm" (32px) for an absolutely-positioned input adornment, below the 36px minimum touch-target size. Bumped both to size="icon" (36px, matching the 36px input height) and adjusted the absolute-position offset so the button still sits fully inside each input's existing right padding reservation. Audited every remaining dashboard page (everything Stream4-A's wide-content/table fixes didn't already cover): no un-wrapped wide tables remain (every <Table> already rides ResponsiveTable), and every DialogContent across the repo already inherits or supplies max-h-[*vh] + overflow-y-auto, so dialogs stay usable at small viewport heights. * [fee25542] fix(a11y): re-land sub-36px touch target and overflow fixes after sync_branch reset them again Re-applies the fda2ac0c fix content a third time -- sync_branch's rebase+force-push reset the branch and working tree back to the stalef9f45d9fref (the round-1-only state) instead of preserving the local commits ahead of it, discarding the round-2 fix yet again. - quick-actions-card.tsx (Overview dashboard customize dialog): reorder arrows drop the h-6 w-6 override, falling back to Button's 36px icon default - agent-card.tsx (Agents page grid): DM / dedicated-chat / actions-menu icon buttons drop their h-6 w-6 override, now 36px - product-card-grid.tsx / project-card-grid.tsx (Products/Projects card view): edit/external-link icon buttons drop h-6 w-6, now 36px - environment-ladder-editor.tsx (Edit Project dialog): move-up/move-down/ remove-rung icon buttons drop their h-6/h-8 overrides, now 36px; the per-rung row now scrolls horizontally within its own bordered box (overflow-x-auto + min-w-max) instead of overflowing at 375px now that the icon buttons are back to full width - acceptance-criteria-editor.tsx / dependency-selector.tsx (task create/ edit dialogs): remove-row icon buttons drop their h-6/h-8 overrides, now 36px - tab-commits.tsx: "Linked Commits" header's fixed 3-column grid now stacks to one column below sm, and the branch/PR badge row scrolls horizontally in its own container instead of the page panel lint + tsc --noEmit are both clean. * [fee25542] fix(a11y): bump tab-commits.tsx delete-commit button to 36px touch target The per-commit unlink button used className="h-7 w-7" (28px), the one sub-36px target the prior re-land commits (fda2ac0c/8e00303f/d8408c77/ 34ea8fe1/e6bee7c8) didn't cover -- their content only fixed the header grid-stack overflow in this file, not this button. Bumped to h-9 w-9 (36px) matching the Button component's own size="icon" default used everywhere else in this fix series, and bumped the icon from h-3 w-3 to h-3.5 w-3.5 to stay visually proportional at the larger target. panel-gate (lint + tsc --noEmit + vitest) is green. * [fee25542] fix(a11y): remove trailing narrative JSX comments in self-hosted-section.tsx Removes the 9 {/* ... */} comments flagged by the conventions validator's no_inline_comments rule (F-8db499ac) — Header, Base URL input, Auth token input, Test Connection button, inline result badge, and the three empty- state section markers. Each block is already self-evident from its JSX composition (distinct Input/Button/Badge groupings and conditional guards showNoUrlState/showErrorState/showNoModelsState/showModelList), so no docstring/JSDoc replacement is needed. Pure deletion, no behavior change. The two remaining open findings (F-8a39564c, F-4308219d) allege the touch-target/overflow fixes across 8 files are missing from this branch -- re-verified via roboco_git_log(branch=<task branch>), which reads the real ref directly, that the branch tip isc629c3e1and already contains those fixes (h-9 w-9 delete button + overflow-x-auto header row in tab-commits.tsx, overflow-x-auto rung rows in environment-ladder-editor.tsx, no shrunk icon-sm/h-6/h-7 overrides left in the other 6 files), confirmed by reading every file on disk in this worktree. No code change needed for those two; resolved via verification evidence instead of a 9th re-land. pnpm lint + pnpm typecheck both clean. --------- Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech> Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech> * [1ff154da] restore(panel): re-add AutoRefreshDriver and ScrollJumpButtons to dashboard layout (#691) Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech> * [6ee71578] Add sequence field to task dialogs; fix pr_gate forms-audit.md findings (#693) Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech> --------- Co-authored-by: roboco-app[bot] <302741806+roboco-app[bot]@users.noreply.github.com> Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech> Co-authored-by: Frontend Documenter <fe-doc@roboco.tech> Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech> * [73275ff0] fix(panel): review follow-ups — budget help text, touch-visible unlink, docs consolidation - The task budget help text and validation toast said empty falls back to a task-type default; that default table was removed (null = no cap) — both strings now say so, and the forms audit row documents the correction instead of claiming ok over a stale label. - The per-commit unlink button was hover-revealed only, invisible on touch devices and to keyboard focus; it now also reveals on focus-visible and coarse pointers. - The forms audit moves from the docs root into the governed docs/frontend/forms/ tree, cross-linked both ways with the project fields reference it overlapped, and both are registered in the frontend docs index; the tasks-page-tabs doc's standalone-reuse rationale now states the /kanban redirect reality. - The two 20px tree-expand chevrons in the tasks table are left as-is deliberately: explicit dense-row overrides, where a 36px target would break table density. --------- Co-authored-by: roboco-app[bot] <302741806+roboco-app[bot]@users.noreply.github.com> Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech> Co-authored-by: Frontend Documenter <fe-doc@roboco.tech> Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech> Co-authored-by: Renn F <rennf93@users.noreply.github.com> Co-authored-by: Renzo F <45401804+rennf93@users.noreply.github.com>
7.6 KiB
Tasks Page: List & Kanban Tabs
Overview
The Tasks page (panel/src/app/(dashboard)/tasks/page.tsx) now provides two complementary views of the task backlog: List and Kanban, accessible via top-level tabs. Both tabs share a unified URL-driven filter state, allowing users to switch between views without losing their current filters or search query.
Tab Structure
Top-Level Tabs: List | Kanban
- List: The traditional table view with TaskFilters and TaskTable. This is the default view and renders the original tasks page content byte-for-byte, just wrapped inside a
TabsContentelement. - Kanban: Embeds four kanban workflow views (Developer, QA, PR Review, PM) as nested sub-tabs, mirroring the structure of the standalone
/kanbanpage.
Kanban Sub-Tabs
When viewing the Kanban tab, users can switch between four workflow-specific kanban boards via sub-tabs:
- Developer – Tasks claimed and worked by developers, backlog through completion (Dev lifecycle)
- QA – Quality assurance review workflow (QA review gate)
- PR Review – In-path PR-review gate for assembled PRs before the PM merges
- PM – Project management overview covering every lifecycle state, including recovery states
Each sub-tab includes a tooltip (hover-friendly on desktop) explaining its scope.
URL-Driven State
Query Parameters
The tabs and kanban view are completely URL-driven. The page reads and writes two query parameters:
-
tab:"list"(default) or"kanban"- Omitting the
tabparameter defaults to the List view - Setting
?tab=kanbanshows the Kanban tab
- Omitting the
-
view:"dev"(default),"qa","pr-review", or"pm"(only meaningful whentab=kanban)- Omitting the
viewparameter defaults to the Developer kanban - Setting
?view=qashows the QA kanban board
- Omitting the
Filter State Persistence
All existing filters—search query (q), status, team, task type, project, product, sort field, sort direction, pagination, and expanded rows—are preserved as URL parameters and shared across both tabs. Switching tabs does not clear filters; users can switch between List and Kanban while maintaining their active filters.
Example URLs:
/tasks?q=auth&tab=list– List view filtered by "auth" search/tasks?q=auth&tab=kanban&view=qa– QA kanban filtered by "auth" search/tasks?status=pending&team=backend&tab=kanban&view=dev– Dev kanban, pending tasks, backend team only
Shared Kanban Team Filter
The kanban views—DevKanban, QaKanban, PrReviewKanban, and PmKanban—support single-team selection, while the List tab's TaskFilters supports multi-select team filtering.
To bridge this difference:
- When exactly one team is selected in the List tab, that team is passed to the active kanban view
- When no team or multiple teams are selected, the kanban view shows "All Teams" in its dropdown
- Changing the team in either tab writes the same
teamURL parameter, so changes sync across both views
This ensures the kanban view's team selector always reflects the current filter state, even though it can only show one team at a time.
Component Integration
Imports
The page imports the four kanban view components directly:
import {
DevKanban,
QaKanban,
PrReviewKanban,
PmKanban,
} from "@/components/kanban";
Embedding Pattern
Each kanban view is embedded inside a TabsContent and receives two props:
<TabsContent value="dev" className="mt-6">
<DevKanban
team={sharedKanbanTeam}
onTeamChange={handleKanbanTeamChange}
/>
</TabsContent>
Props:
team: The currently selected team (orundefinedif no team or multiple teams are selected)onTeamChange: Callback to update the team filter in the parent page's URL state
Kanban View Modifications
Each kanban view wrapper (DevKanban, QaKanban, PrReviewKanban, PmKanban) was updated to support optional controlled team state:
- Controlled (when embedded on tasks page): If
onTeamChangeis provided, the view is controlled by the parent's URL-driven state - Uncontrolled (fallback): If
onTeamChangeis omitted, the view manages its own internal team state viauseState
The tasks page is now the sole consumer and always passes onTeamChange (the old /kanban route is a pure redirect) — the uncontrolled fallback remains as a cheap, independently-testable default for any future standalone embedding, not a live code path today.
Implementation Details
Tab Selection via pickTab()
The page uses the pickTab() helper from @/lib/tabs to safely parse and validate tab/view parameters:
const activeTab = pickTab(searchParams.get("tab"), TASKS_VIEW_TABS, "list");
const kanbanView = pickTab(searchParams.get("view"), KANBAN_VIEWS, "dev");
This ensures invalid or missing values default to sensible defaults.
Handlers
Three handler functions manage tab and filter changes:
handleTabChange(value)– Updates thetabURL param when the user clicks List or KanbanhandleKanbanViewChange(value)– Updates theviewURL param when the user switches kanban sub-tabshandleKanbanTeamChange(team)– Updates theteamURL param when the user changes the kanban team dropdown
All handlers use the existing updateParams() callback, which safely merges changes into the current query string and navigates without resetting scroll.
Drag-and-Drop & Mobile Navigation
The kanban views' drag-and-drop functionality (via @dnd-kit/core) and mobile single-column navigation remain completely unchanged. These features are owned by KanbanBoard and are not affected by the tab refactor.
Deep Linking
Deep links to /tasks/[taskId] work regardless of which tab (List or Kanban) is currently active. The page's task-list navigation (managed via useScrollRestorationStore) captures the current filtered/sorted order whenever the visible task list changes, enabling "prev/next" navigation in the task detail panel to work consistently across both tabs.
Accessibility & UX Notes
- Tooltips on Kanban Triggers: Each kanban sub-tab trigger is wrapped in a Tooltip (via Radix UI) with a brief explanation of that workflow's scope. This helps users understand what each kanban board represents.
- Data-State Override: The Tooltip's
asChildslot can interfere with TabsTrigger'sdata-stateattribute. The code explicitly re-assertsdata-[state=active]styling to ensure the active indicator works correctly despite the Tooltip wrapper. - Sticky Filters: The TaskFilters bar in the List tab remains sticky (
position: sticky; top: 0), providing a consistent filtering experience as users scroll through the task table.
Testing Considerations
When testing the tasks page:
- Verify that filters persist when switching between List and Kanban tabs
- Confirm that the kanban team selector shows the correct team when exactly one team is selected
- Test that deep links to task details work from both List and Kanban views
- Verify that kanban drag-and-drop works correctly when accessed via the tasks page (not just the standalone
/kanbanroute) - Confirm that mobile single-column kanban navigation works as expected
- Test that URL parameters are correctly read and written (e.g.,
?tab=kanban&view=qa)
Related Pages
- Standalone Kanban Page (
panel/src/app/(dashboard)/kanban/page.tsx) – Provides an alternative kanban-only experience (Stream3-B will redirect and unify navigation) - Task Detail Panel – Remains unchanged; deep links and prev/next navigation continue to work across all views
- Task Filters (
panel/src/components/tasks) – Shared filter component used by the List tab