From a6ab8deff6b2c03dd2475126fae5f36a90e14705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Salavisa?= Date: Sat, 23 May 2026 16:13:31 +0100 Subject: [PATCH] feat(github): mobile-friendly /github page with sidebar drawer (#1041) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(github): mobile-friendly /github page with sidebar drawer On narrow viewports the preset sidebar consumed most of the screen and the list toolbar's fixed-width filters wrapped awkwardly. Hide the inline aside below md and add a hamburger button in the topbar that opens the same PresetsSidebar inside a right-side Sheet, mirroring the kanban mobile pattern. Reflow ListToolbar so title + count + refresh stack on top with the repo filter and custom-query input going full-width below. Selecting a preset in the drawer closes it. Includes a Pixel 5 Playwright spec covering the open → select → close flow. Co-Authored-By: Claude Opus 4.7 * test(github): use data-testid for mobile toolbar title selector Replace brittle class-based locator (h2.text-sm.font-semibold) in the mobile page object with a stable data-testid on the heading so the spec doesn't silently break if Tailwind classes change. Co-Authored-By: Claude Opus 4.7 * refactor(github): address mobile /github bot review feedback - Drop useCallback wrappers on onMobileSidebarSelect / onMobileSaveCurrent. `state` from useGitHubPageState() is a fresh object every render, so the [state] dep caused the callbacks to be re-created every pass anyway — the useCallback was deceptive. Use plain arrow functions and document. (Claude inline, Greptile P2) - Remove the sr-only on the hamburger button. `aria-label` takes precedence over child sr-only text for screen readers, so the span was unreachable duplicate content. (Claude inline) - MobileGitHubPage.goto() now waits on the mobile menu button instead of the ambiguous "GitHub" breadcrumb text — deterministic and matches the mobile mount semantics. (CodeRabbit inline) Co-Authored-By: Claude Opus 4.7 --------- Co-authored-by: Kandev Agent Co-authored-by: Claude Opus 4.7 --- apps/web/app/github/github-page-client.tsx | 63 +++++++++++++- .../github/my-github/list-toolbar.tsx | 84 ++++++++++++++----- apps/web/e2e/pages/mobile-github-page.ts | 27 ++++++ .../github/mobile-github-sidebar.spec.ts | 48 +++++++++++ 4 files changed, 195 insertions(+), 27 deletions(-) create mode 100644 apps/web/e2e/pages/mobile-github-page.ts create mode 100644 apps/web/e2e/tests/github/mobile-github-sidebar.spec.ts diff --git a/apps/web/app/github/github-page-client.tsx b/apps/web/app/github/github-page-client.tsx index 649c45916c..5065c89af8 100644 --- a/apps/web/app/github/github-page-client.tsx +++ b/apps/web/app/github/github-page-client.tsx @@ -2,8 +2,10 @@ import Link from "next/link"; import { useCallback, useEffect, useMemo, useState } from "react"; -import { IconBrandGithub } from "@tabler/icons-react"; +import { IconBrandGithub, IconMenu2 } from "@tabler/icons-react"; import { Alert, AlertDescription } from "@kandev/ui/alert"; +import { Button } from "@kandev/ui/button"; +import { Sheet, SheetContent, SheetHeader, SheetTitle } from "@kandev/ui/sheet"; import { PageTopbar } from "@/components/page-topbar"; import { useGitHubStatus } from "@/hooks/domains/github/use-github-status"; import { usePRKeyToTasks } from "@/hooks/domains/github/use-pr-key-to-tasks"; @@ -50,12 +52,26 @@ type GitHubPageClientProps = { repositories: Repository[]; }; -function PageHeader() { +function PageHeader({ onOpenMobileSidebar }: { onOpenMobileSidebar?: () => void }) { return ( } + actions={ + onOpenMobileSidebar && ( + + ) + } /> ); } @@ -295,7 +311,10 @@ function AuthenticatedLayout({ useAllWorkflowSnapshots(workspaceId ?? null); return (
-