mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
* [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>
154 lines
7.6 KiB
Markdown
154 lines
7.6 KiB
Markdown
# 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 `TabsContent` element.
|
||
- **Kanban**: Embeds four kanban workflow views (Developer, QA, PR Review, PM) as nested sub-tabs, mirroring the structure of the standalone `/kanban` page.
|
||
|
||
### Kanban Sub-Tabs
|
||
|
||
When viewing the Kanban tab, users can switch between four workflow-specific kanban boards via sub-tabs:
|
||
|
||
1. **Developer** – Tasks claimed and worked by developers, backlog through completion (Dev lifecycle)
|
||
2. **QA** – Quality assurance review workflow (QA review gate)
|
||
3. **PR Review** – In-path PR-review gate for assembled PRs before the PM merges
|
||
4. **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 `tab` parameter defaults to the List view
|
||
- Setting `?tab=kanban` shows the Kanban tab
|
||
|
||
- **`view`**: `"dev"` (default), `"qa"`, `"pr-review"`, or `"pm"` (only meaningful when `tab=kanban`)
|
||
- Omitting the `view` parameter defaults to the Developer kanban
|
||
- Setting `?view=qa` shows the QA kanban board
|
||
|
||
### 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 `team` URL 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:
|
||
|
||
```typescript
|
||
import {
|
||
DevKanban,
|
||
QaKanban,
|
||
PrReviewKanban,
|
||
PmKanban,
|
||
} from "@/components/kanban";
|
||
```
|
||
|
||
### Embedding Pattern
|
||
|
||
Each kanban view is embedded inside a `TabsContent` and receives two props:
|
||
|
||
```typescript
|
||
<TabsContent value="dev" className="mt-6">
|
||
<DevKanban
|
||
team={sharedKanbanTeam}
|
||
onTeamChange={handleKanbanTeamChange}
|
||
/>
|
||
</TabsContent>
|
||
```
|
||
|
||
**Props:**
|
||
- `team`: The currently selected team (or `undefined` if 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 `onTeamChange` is provided, the view is controlled by the parent's URL-driven state
|
||
- **Uncontrolled (fallback)**: If `onTeamChange` is omitted, the view manages its own internal team state via `useState`
|
||
|
||
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:
|
||
|
||
```typescript
|
||
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 the `tab` URL param when the user clicks List or Kanban
|
||
- `handleKanbanViewChange(value)` – Updates the `view` URL param when the user switches kanban sub-tabs
|
||
- `handleKanbanTeamChange(team)` – Updates the `team` URL 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 `asChild` slot can interfere with TabsTrigger's `data-state` attribute. The code explicitly re-asserts `data-[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:
|
||
|
||
1. Verify that filters persist when switching between List and Kanban tabs
|
||
2. Confirm that the kanban team selector shows the correct team when exactly one team is selected
|
||
3. Test that deep links to task details work from both List and Kanban views
|
||
4. Verify that kanban drag-and-drop works correctly when accessed via the tasks page (not just the standalone `/kanban` route)
|
||
5. Confirm that mobile single-column kanban navigation works as expected
|
||
6. 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
|