Add PR triage filters#560
Conversation
Maintainers need to narrow the PR queue by review state, draft/readiness, CI failure, merge conflicts, and workflow status without changing the provider-neutral pulls API. Keep these facets as local list filters so the existing sync and query contract stays stable while the sidebar can stack triage constraints quickly. Generated with Codex Co-authored-by: Codex <codex@openai.com>
The new PR filter should behave like the existing Activity filter menu instead of opening as an end-aligned menu. Using the shared default placement keeps the dropdown visually connected to its trigger in the narrow PR sidebar. Generated with Codex Co-authored-by: Codex <codex@openai.com>
roborev: Combined Review (
|
The PR sidebar can narrow enough that separate state/group and local PR filter controls either overflow or compete for the same compact space. Collapse state, grouping, PR attributes, and kanban status into one compact filter menu, and remeasure the floating menu after filter selections so the dropdown stays anchored to its trigger. Validation: vp test run --project unit; vp run ui-package-typecheck; vp fmt --check packages/ui frontend/tests/e2e/pull-list-filters.spec.ts frontend/tests/e2e-full/sidebar-collapse.spec.ts; playwright pull-list-filters; playwright-e2e sidebar-collapse; live dev-ephemeral DOM measurement for compact overflow and dropdown left-edge alignment. Generated with Codex Co-authored-by: Codex <codex@openai.com>
roborev: Combined Review (
|
The compact PR filter menu had review-state labels that overlapped with Kanban and grouping labels, and its medium-width breakpoint lived outside the actual sidebar clamp. That made the UI harder to verify and left the scoped PR filter trigger inaccessible in supported widths. Use distinct compact menu labels, keep the all-in-one reset scoped as a view reset, and cover both the reachable breakpoint and real API-backed compact filtering so future changes cannot drift back to positional selectors. Validation: vp test run --project unit; vp run ui-package-typecheck; vp fmt --check packages/ui/src/components/sidebar/PullList.svelte frontend/tests/e2e/pull-list-filters.spec.ts frontend/tests/e2e-full/sidebar-collapse.spec.ts; playwright pull-list-filters; playwright-e2e sidebar-collapse; live dev-ephemeral screenshot/DOM measurement for compact dropdown alignment and overflow. Generated with Codex Co-authored-by: Codex <codex@openai.com>
roborev: Combined Review (
|
The compact PR filter menu now uses clearer labels than the expanded segmented controls. Existing full-stack helpers still looked for toolbar labels inside the compact dropdown, so Chromium CI selected the pull-state All option instead of the flat grouping option. Map PR grouping helper labels to their compact-menu names so the tests cover the same user intent in both expanded and compact sidebars. Validation: playwright-e2e grouping-toggle pull-list collapsible-repos; vp test run --project unit; vp run ui-package-typecheck; vp fmt --check affected filter and grouping specs. Generated with Codex Co-authored-by: Codex <codex@openai.com>
roborev: Combined Review (
|
PRs without an explicit kanban row can arrive from the API with an empty KanbanStatus even though workflow grouping treats them as New. The local Kanban filter needs the same normalization, otherwise selecting New hides those default-new PRs. Reuse the workflow normalization helper for local PR filter matching and add a store regression for the empty API value. Validation: vp test run --project unit; vp run ui-package-typecheck; vp fmt --check affected store files; playwright pull-list-filters; playwright-e2e sidebar-collapse. Generated with Codex Co-authored-by: Codex <codex@openai.com>
Pull list responses can carry an empty or missing kanban status when no middleman_kanban_state row exists. Workflow grouping already presents those PRs as New, so the local status filter needs the same normalization instead of dropping them from the filtered list. Validation: watched the new store regression fail before the fix, then pass through the frontend unit project; ran ui-package-typecheck and targeted formatting checks. Generated with Codex Co-authored-by: Codex <codex@openai.com>
roborev: Combined Review (
|
The frontend filter fix still left the API contract ambiguous: SQLite can represent a missing kanban row as an empty status while the generated response schema promises a concrete enum. Normalize merge-request responses to New at the server boundary so clients see the documented shape. Add a DB-backed API regression for a PR with no kanban row and full-stack compact filter coverage that selects New against the real pulls response. Validation: go test ./internal/server -run TestAPIPullResponsesNormalizeMissingKanbanStateToNew -shuffle=on; vp test run --project unit; vp run ui-package-typecheck; vp fmt --check affected files; playwright-e2e sidebar-collapse. Generated with Codex Co-authored-by: Codex <codex@openai.com>
The PR branch had already received kanban normalization and API coverage while this local follow-up was committed. Merge origin/codex/pr-triage-filters so the push preserves those remote commits and keeps the broader local store regression for missing and unknown kanban statuses. Validation: targeted frontend store tests and affected formatting check after conflict resolution; full frontend-check passed before retrying the hook. Generated with Codex Co-authored-by: Codex <codex@openai.com>
roborev: Combined Review (
|
The API response contract presents missing kanban rows as New, but the list query still treated those same rows as empty when callers requested kanban=new. That made the documented response shape and server-side filtering disagree for PRs created before an explicit kanban row exists. Use the same default only for the New predicate, keep other kanban filters tied to stored rows, and log unexpected stored statuses before coercing them into the response enum so data drift is visible instead of completely silent. Validation: go test ./internal/db -run TestListPullRequestsFilterByKanban -shuffle=on; go test ./internal/server -run TestAPIPullResponsesNormalizeMissingKanbanStateToNew -shuffle=on; go test ./internal/server/e2etest -run TestFleetSnapshotEmptyTmuxServerE2E -short -shuffle=on; git diff --check. Generated with Codex Co-authored-by: Codex <codex@openai.com>
The compact PR and issue filter menus combine State, Group, and local filter controls so users can adjust more than one selector in a single pass. Closing the menu after clicking State or Group made that merged menu feel broken and forced repeated reopening for adjacent choices. Let compact State and Group rows use the dropdown default of staying open after selection, matching the multi-select PR/Kanban entries, and cover the behavior in the full-stack sidebar collapse tests. Validation: node ./node_modules/vite-plus/bin/vp exec svelte-mcp svelte-autofixer packages/ui/src/components/sidebar/PullList.svelte --svelte-version 5; node ./node_modules/vite-plus/bin/vp exec svelte-mcp svelte-autofixer packages/ui/src/components/sidebar/IssueList.svelte --svelte-version 5; node ./node_modules/vite-plus/bin/vp fmt --check packages/ui/src/components/sidebar/PullList.svelte packages/ui/src/components/sidebar/IssueList.svelte frontend/tests/e2e-full/sidebar-collapse.spec.ts; node ../node_modules/vite-plus/bin/vp test run --project unit; node ./node_modules/vite-plus/bin/vp run ui-package-typecheck; node ../node_modules/vite-plus/bin/vp exec -- playwright test --config=playwright-e2e.config.ts tests/e2e-full/sidebar-collapse.spec.ts; make frontend-check. Generated with Codex Co-authored-by: Codex <codex@openai.com>
The compact PR filter menu intentionally stays open for multi-filter workflows. The list-view e2e helpers were still treating state and grouping selections as one-shot actions, which left the dropdown over status headers or blindly toggled it into the wrong state in CI. Dismiss the compact menu after these helper selections so the tests exercise the intended user path without changing product behavior. Validation: cd frontend && node ../node_modules/vite-plus/bin/vp exec -- playwright test --config=playwright-e2e.config.ts --project=chromium tests/e2e-full/collapsible-repos.spec.ts tests/e2e-full/pull-list.spec.ts; cd frontend && node ../node_modules/vite-plus/bin/vp exec -- playwright test --config=playwright-e2e.config.ts --project=firefox tests/e2e-full/collapsible-repos.spec.ts tests/e2e-full/pull-list.spec.ts; cd frontend && node ../node_modules/vite-plus/bin/vp exec -- playwright test --config=playwright-e2e.config.ts --project=chromium; cd frontend && node ../node_modules/vite-plus/bin/vp exec -- playwright test --config=playwright-e2e.config.ts --project=firefox; cd frontend && node ../node_modules/vite-plus/bin/vp test run --project unit; cd frontend && node ../node_modules/vite-plus/bin/vp test run --project browser; node node_modules/vite-plus/bin/vp fmt --check frontend/tests/e2e-full/collapsible-repos.spec.ts frontend/tests/e2e-full/pull-list.spec.ts --threads=1; git diff --check. Generated with Codex Co-authored-by: Codex <codex@openai.com>
roborev: Review Unavailable (
|
Screenshot: