Fork page UX: top-level route, copy cleanup, mobile collapse, mobile-first rule, aligned Fork/Clone buttons #438
Labels
No labels
actions
bug
cli
duplicate
enhancement
fork
forum
git storage
help wanted
insights
invalid
issues
moderation
oidc
ownership transfer
packages
pr/merge protection rules
projects
pull requests
question
releases
sponsorships
tags
webhooks
wiki
wontfix
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
crueber/walhub#438
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fork page UX: top-level route, copy cleanup, mobile collapse, mobile-first AGENTS.md amendment, aligned Fork/Clone buttons
What's requested
One coherent UX pass over fork creation and the repo-header action row, five parts:
Fork becomes a top-level route (PR-composer style), not a nested repo-page route.
Today the fork form lives at
/:owner/:name/forkas a child of theRepolayout (web/src/index.jsx, inside the/:owner/:nameRoute). The PR composer (/:owner/:name/pulls/new→web/src/pages/PullNew.jsx) is the in-app precedent for a full-page composer, but the ask is stronger: move Fork OUT of the repo page shell to a top-level route like GitHub's/forkflow, so it renders as a standalone page (site header + page-level layout), not inside the repo tab strip/sidebar. Keep the parent repo as a query/route param (e.g./:owner/:name/fork→ top-level page, or a?from=param — planner's call, note it). The repo-page "Fork" pill links there.Copy cleanup on the fork form (
web/src/pages/Fork.jsx):<span class="muted text-xs">you and your orgs only</span>(line ~207).<span class="muted text-xs">becomes the fork's default branch</span>(line ~252).aria-labels, lines ~240/241/246). The<option value="">parent default</option>stays.Mobile field-collapse fix. The two
grid grid-cols-2 gap-3rows (Owner/Name ~line 187, Visibility/Default branch ~line 225) force side-by-side fields at phone widths; on narrow screens each pair should collapse to a single column (responsive:grid-cols-1base,sm:grid-cols-2). Verify no horizontal overflow at a 390px viewport after the change.AGENTS.md amendment: mobile is always considered. Add a working rule to AGENTS.md §2 (Working rules, after the "Real browser when you touched anything browser-facing" verification item or as a §2 bullet) stating that every browser-facing change is checked at a narrow/mobile viewport (e.g. ~390px width), not just desktop — UI work without a mobile-viewport check is not done. Draft text; final wording may be tightened by the implementer but the rule must be normative (same register as the existing laws/working rules).
Aligned text-only Fork/Clone buttons (
web/src/pages/Repo.jsx, repo header action row ~line 618-628): the Fork pill (⑂ Fork N) and the Clone pill/CloneMenusummary render as differently-sized/wide pills with an icon glyph on Fork. Make both text-only and visually aligned — same pill class, same height/weight, no icon glyph, so they read as one matched action pair (the Star/Watch toggles already establish the row's text-pill idiom; match it).Evidence (current tree, main @
ec820c5)web/src/index.jsx—<Route path="/fork" component={Fork} />nested inside<Route path="/:owner/:name" component={Repo}>.web/src/pages/Fork.jsxheader comment already ties the page to issue #424; the form rows at lines ~187 and ~225 usegrid grid-cols-2; hints at lines 207 and 252; "Starting branch" at 240/241/246.web/src/pages/Repo.jsx~line 620:<A class="pill" href={/${full()}/fork}>⑂ Fork…</A>;CloneMenusummary usesclass="pill"(line ~99).Architecture notes
repos.repo(full())) already supports the fork call — Fork.jsx keeps working unchanged if the route shape keeps owner/name in params.RepoRoute means it loses the repo layout (tab strip, shared summary); that is the point — replicate PullNew's page-level framing, but NOT nested under Repo.summary.forks(no extra fetch) — keep that.Acceptance criteria
make test-webpasses; real-browser check at desktop and 390px widths for the fork flow and the repo header.Fix ready for review: PR #441 (#441), branch fix/issue-438. All 6 acceptance criteria covered (5 code + test/build); browser proof at desktop + 390px open (shared-daemon loopback guard). Tests: node --test 919 total / 917 pass / 2 fail (pre-existing live-server smoke, identical on main); vite + esbuild green.
Review of PR #441 (origin/fix/issue-438 @
3afa46d) — verified in scratch worktrees /tmp/pr441 (branch) and /tmp/pr441-main (main baseline). No fixes pushed; none needed.(1) Top-level route — PASS. web/src/index.jsx:94 adds
<Route path="/:owner/:name/fork" component={Fork} />BEFORE the/:owner/:nameRepo parent, under the sharedRouter root={App}(index.jsx:53) so it renders standalone under the site header only, no repo tab strip/sidebar. Old nested<Route path="/fork"/>is deleted; exactly onecomponent={Fork}entry remains — no duplicate, no dead link. Same URL as before so the repo-header Fork pill (Repo.jsx:624) and all existing links keep working, no redirect needed. Standalone-safe: Fork.jsx reads owner/name only via useParams() (:30), zero useRepo/Repo-context references; page centers itself via mx-auto (Fork.jsx:182). web/sdk untouched.(2) Copy — PASS. Both hints deleted (no 'you and your orgs only', no 'becomes the fork's default branch' anywhere in Fork.jsx); 'Starting branch' fully gone, 'Default branch' is the visible label (Fork.jsx:243) plus both branch-select aria-labels (loading fallback :244, loaded :249 — test pins count=2);
<option value="">parent default</option>kept.(3) Mobile — PASS. Both field rows now
grid grid-cols-1 gap-3 sm:grid-cols-2(Fork.jsx:191 Owner/Name, :228 Visibility/Default branch); no unprefixedgrid-cols-2 gap-3remains. 390px reasoning: form cell = 390−32 (page px-4) = 358px; single-column rows are one fluid field wide, all controls fluid input/select, no fixed-width elements → zero page overflow. (Per review instructions: node tests + reasoning only, no browser driven — noted explicitly.)(4) AGENTS.md rule — PASS. AGENTS.md:51, §2 working-rules bullet: 'Mobile viewport is always checked. Every browser-facing change is verified at a narrow/mobile viewport (~390px width) as well as desktop — layout, overflow, and tap targets. UI work without a mobile-viewport check is not done.' Normative register matching the surrounding rules; §2-bullet placement satisfies the issue's 'verification item or §2 bullet' planner's call.
(5) Pill pair — PASS. Fork (Repo.jsx:624-626) is text-only
class="pill"(⑂ glyph gone), CloneMenu summary isclass="pill ...">Clone(Repo.jsx:99) — same pill class ⇒ same height/weight, matched text-only pair per the Star/Watch idiom. Count stills().forks(no extra fetch); Fork href/${full()}/forkunchanged.(6) Scope/docs — PASS. No .go files touched; no package.json/pnpm changes (no new deps); SDK untouched. docs/go/12_web_ui.md:229 route-table entry + decisions entry both accurate (counts verified below; 'esbuild green' not re-run — SDK untouched so bundle rebuild is a no-op, vite build confirmed green).
Tests (scratch worktree, node_modules symlinked from main): fork-page-438.test.js 6/6 pass. Full
node --test web/test/unit/*.test.js: branch 919 total / 917 pass / 2 fail; main baseline /tmp/pr441-main: 913 total / 911 pass / 2 fail — identical smoke.test.js live-server failures on pristine main (needs a server serving the build; something unrelated answers on :8080, left untouched), so +6 net new, zero PR-caused. Doc test-count accounting is exact.vite buildgreen (2.21s). Main worktree left clean/read-only (fetch + worktrees only).MERGE RECOMMENDATION: ready to merge. Only open item (as the PR itself notes): real-browser proof at desktop + 390px — same standing exception as #435/#437, not a blocker for this change.
Fixed by PR #441 (review clean — all 6 criteria pass, route hoist + copy + mobile + pill pair + AGENTS.md rule verified), merged. Closing.