Edit profile from the repositories/organizations tabs opens the form but does not navigate to the profile view (follows #442) #455
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#455
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?
Edit profile from a non-profile tab should navigate to the profile view (follow-up to #442)
What's requested
#442's fix hoisted
ProfileFormout of the profile-view gate so the Edit profile button now opens the form on every owner tab (setEditing(true)from the sidebar on /repositories and /organizations). But the click only flips the sharededitingsignal — it does not change the route. On the repositories or organizations tab, the form renders inline at the top of the repo list column while the tab bar still shows that tab as active, which reads as broken navigation rather than "editing my profile".Expected: clicking Edit profile routes to
/{owner}(the profile view) with the Profile tab active and the form open.Evidence (current tree, static read — no local repro)
web/src/pages/Repos.jsx(~line 676): the sidebar button's handler is justonClick={() => setEditing(true)}— no navigation.web/src/pages/Repos.jsx(~line 443): the shared-scope<Show when={getEditing() && getProfile()?.can_edit}>rendersProfileFormin the main column on all three owner views (the #442 fix).web/src/pages/Repos.jsxOwnerTabs(~line 110): tab activation is purely pathname-derived —/{owner}/organizations→ orgs,/{owner}/repositories→ repos, else profile. So after the click, the tab highlight stays on the tab you were on, contradicting "editing profile".Architecture notes
editingalready lives at the shared OwnerPage scope (setEditing/getEditing), so the form survives navigation to/{owner}with no new state — navigation alone is sufficient.OwnerTabsalready treats any non-repositories/organizations path as the active Profile tab, so navigating to/{owner}lights the Profile tab for free.useLocation;<A>is used inOwnerTabs) —useNavigateis the natural seam. No API/wire changes; server untouched.Acceptance criteria
profile.can_edit && !editing; form only whenediting && profile.can_edit; #420 bio hide-while-editing stays profile-view-only.web/test/unit/owner-links-445.test.js).Fix ready for review: #472 (branch fix/issue-455). openEditor navigates to /{owner} from non-profile tabs with the module-scope edit state keeping the form open; profile-view click unchanged; gates byte-identical. Note: the issue's 'navigation alone is sufficient' assumption was wrong — sibling Route components remount OwnerPage, so the signal had to move to module scope (details in the PR). Tests: 977 pass / 0 fail, vite+esbuild green, smoke 3/3 vs scratch server.
REVIEW PR #472 (origin/fix/issue-455,
23e65ec) — Edit-profile-navigates fix for #455.Verdict: READY TO MERGE (no fixes pushed; nothing blocking found).
Scope: 1 commit, 3 files, web-only — web/src/pages/Repos.jsx + owner-profile-edit-navigates-455.test.js (new) + owner-profile-edit-all-views-442.test.js (pins updated). No backend change (non-web diff empty), no new deps (useNavigate joins the existing @solidjs/router import; package.json untouched), no docker/compose changes.
(1) Remount claim VERIFIED TRUE. web/src/index.jsx:79,85,86 — /:owner, /:owner/repositories, /:owner/organizations are three sibling s with three distinct wrapper components (Repos/OwnerRepositories/OwnerOrganizations), each rendering . Tab navigation unmounts/remounts OwnerPage, so an OwnerPage-local editing signal would reset before the profile view renders. Module-scope signal is justified; alternatives (navigate-state, parent layout, query param) would all be more invasive. Precedent cited (Notifications unreadCount / lib/store theme) matches.
(2) Module-scope signal SOUND. Repos.jsx:318 — single createSignal(null) holding one owner slug or null: per-owner keyed (getEditing, Repos.jsx:382, strict === owner()), so no cross-owner leak; memory O(1), no growth. Cleared on save AND cancel — both funnel through onDone -> setEditing(false) (Repos.jsx:475-478; Cancel calls props.onDone(null), Repos.jsx:302). Deliberately NOT cleared on unmount — that is the load-bearing property. One known edge (observation only): open editor on owner A, navigate to owner B directly, return to A — the form is still open (stale-but-explicit state, arguably draft preservation). No fix proposed; clearing on unmount would defeat the remount survival.
(3) Profile-view click UNCHANGED. openEditor (Repos.jsx:389-392) always setEditing(true), navigates only if view() !== 'profile'. Test pins exactly one navigate-to-path call and no navigation to either list tab.
(4) Sub-tab clicks NAVIGATE + FORM OPEN + PROFILE ACTIVE. navigate(
/${owner()}) lands on /{owner}; OwnerTabs (Repos.jsx:118-123) derives 'profile' for any non-repositories/organizations pathname, so the Profile tab lights for free. Form stays open via the module signal across the remount; ProfileForm remounts freshly seeded from props.doc — no stale seed.(5) Gates BYTE-IDENTICAL. Changed Show-when lines in diff: none (grep empty). Only JSX logic change is onClick={() => setEditing(true)} -> onClick={openEditor} (Repos.jsx:704). Button gate, form gate, #420 bio hide-while-editing (profile-view-only, Repos.jsx:512) all untouched; getEditing/setEditing names preserved so every other call site works unchanged.
(6) #442 pin updates FAITHFUL. Updated test expects the module-scope signal above OwnerPage + per-owner accessors + single onClick={openEditor} — all strings match the shipped code exactly.
(7) AGENTS.md laws: (1) dep budget intact; (7) N/A — no long work; (8) change stays inside web/ page layer, no core-package imports; (12) code comments updated with the #455 rationale in the same commit.
VERIFY (scratch worktree /tmp/pr472, node_modules symlinked from main, removed afterward): targeted #455+#442 suites 13/13 pass; full node --test web/test/unit/*.test.js 975/977 — the 2 failures are both smoke.test.js fetch-based checks against http://127.0.0.1:8080, where an unrelated foreign listener answers /healthz 200 but / 401 (left untouched per no-live-instance rule; smoke tests read no repo files so the result is worktree-independent and pre-existing). vite build succeeds (2.17s; only the pre-existing >500kB chunk-size warning). No browser drive used — static JSX-pin tests + router-structure reasoning cover this change; noted explicitly per instructions.
Fixed by PR #472 (review clean — remount claim verified, module signal sound, all gates byte-identical), merged. Closing.