fix(admin): absolute sidebar nav links so /admin URLs don't accumulate (v0.52.2)
The /admin left-rail NavLinks used relative targets (to="users", etc.). Under the /admin/* nested route a relative link resolves against the current URL, so each click appended a segment — Users→Allowlist→Graduation yielded /admin/users/allowlist/graduation instead of /admin/graduation. Use absolute targets (/admin/<tab>) + `end` for exact active matching. Patch 0.52.1 → 0.52.2; CHANGELOG updated. Caught by the operator on PPE. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,18 @@ skip versions are the composition of each intervening adjacent
|
||||
release's steps in order — no A-to-B path is pre-computed beyond
|
||||
that.
|
||||
|
||||
## 0.52.2 — 2026-06-09
|
||||
|
||||
**Patch — admin sidebar nav links no longer accumulate URL segments (no
|
||||
operator action required).**
|
||||
|
||||
- **The `/admin` left-rail links were relative**, so under the `/admin/*`
|
||||
nested route each click resolved against the current URL and *appended* a
|
||||
segment — e.g. clicking Users → Allowlist → Graduation produced
|
||||
`/admin/users/allowlist/graduation` instead of `/admin/graduation`. Fixed:
|
||||
the rail `NavLink`s now use absolute targets (`/admin/<tab>`) with `end`
|
||||
for exact active-state matching.
|
||||
|
||||
## 0.52.1 — 2026-06-08
|
||||
|
||||
**Patch — collection-scoped entry-detail fetch fix (no operator action
|
||||
|
||||
+15
-6
@@ -43,15 +43,22 @@ test('SLICE-4: edit one entry\'s priority from the detail panel', async ({ page
|
||||
|
||||
const panel = page.locator('.metadata-fields-panel')
|
||||
await expect(panel).toBeVisible()
|
||||
// Seeded at P1; change to P2 and save (direct sidecar commit, D7).
|
||||
await expect(panel.locator('#mf-priority')).toHaveValue('P1')
|
||||
await panel.locator('#mf-priority').selectOption('P2')
|
||||
const select = panel.locator('#mf-priority')
|
||||
// Value-agnostic so the test is idempotent across retries and re-runs: a
|
||||
// prior (committed) edit may have already moved it off the P1 seed. Pick a
|
||||
// target distinct from the current value so Save is a real change.
|
||||
const current = await select.inputValue()
|
||||
const target = current === 'P2' ? 'P1' : 'P2'
|
||||
await select.selectOption(target)
|
||||
await panel.getByRole('button', { name: 'Save' }).click()
|
||||
await expect(panel.getByText('Saved')).toBeVisible()
|
||||
// The save is a real git sidecar commit via the bot (D7); over the deployed
|
||||
// edge the round trip can take tens of seconds — wait generously for the
|
||||
// confirmation rather than the default expect timeout.
|
||||
await expect(panel.getByText('Saved')).toBeVisible({ timeout: 60_000 })
|
||||
|
||||
// Persisted across a reload (read back from the committed sidecar).
|
||||
await page.reload()
|
||||
await expect(page.locator('.metadata-fields-panel #mf-priority')).toHaveValue('P2')
|
||||
await expect(page.locator('.metadata-fields-panel #mf-priority')).toHaveValue(target)
|
||||
})
|
||||
|
||||
// SLICE-5 (PUC-2) — multi-select + bulk action bar, one commit (authed).
|
||||
@@ -71,8 +78,10 @@ test('SLICE-5: bulk-set priority on multiple selected entries', async ({ page })
|
||||
await expect(bar.getByText('2 selected')).toBeVisible()
|
||||
|
||||
// Set priority P1 across both → one commit; a toast reports the result.
|
||||
// Like SLICE-4, the bulk write is a real git commit via the bot; allow the
|
||||
// deployed-edge round trip generous time before the result toast appears.
|
||||
await bar.getByLabel('Set Priority').selectOption('P1')
|
||||
await expect(page.getByText(/2 updated/)).toBeVisible()
|
||||
await expect(page.getByText(/2 updated/)).toBeVisible({ timeout: 60_000 })
|
||||
|
||||
// The change is reflected server-side: the Priority P1 facet now counts the
|
||||
// two newly-updated entries plus the pre-existing P1 (checkout-returning was
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "rfc-app-frontend",
|
||||
"private": true,
|
||||
"version": "0.52.1",
|
||||
"version": "0.52.2",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -59,7 +59,8 @@ export default function Admin({ viewer }) {
|
||||
{tabs.map(t => (
|
||||
<li key={t.path}>
|
||||
<NavLink
|
||||
to={t.path}
|
||||
to={`/admin/${t.path}`}
|
||||
end
|
||||
className={({ isActive }) => `admin-rail-link ${isActive ? 'active' : ''}`}
|
||||
>
|
||||
{t.label}
|
||||
|
||||
@@ -103,6 +103,17 @@ put_file() {
|
||||
201 "create $_repo/$_path"
|
||||
}
|
||||
|
||||
# delete_file <repo> <path> — remove the file if it exists (no-op if absent).
|
||||
delete_file() {
|
||||
_repo="$1"; _path="$2"
|
||||
_sha=$(file_sha "$_repo" "$_path")
|
||||
[ -n "$_sha" ] || { echo "seed-ppe: $_repo/$_path absent, nothing to delete"; return 0; }
|
||||
echo "seed-ppe: deleting $_repo/$_path"
|
||||
mutate DELETE "$GITEA/api/v1/repos/$ORG/$_repo/contents/$_path" \
|
||||
"{\"message\":\"reseed: drop sidecar $_path\",\"sha\":\"$_sha\",\"branch\":\"main\"}" \
|
||||
200 "delete $_repo/$_path"
|
||||
}
|
||||
|
||||
ensure_repo "$REGISTRY_REPO"
|
||||
ensure_repo "$CONTENT_REPO"
|
||||
|
||||
@@ -182,4 +193,17 @@ tags: [search]
|
||||
Faceted search scenario.
|
||||
" "$RESEED"
|
||||
|
||||
# RESEED also drops any metadata sidecars (<slug>.meta.yaml) left by prior
|
||||
# SLICE-4/5 edits. A sidecar takes precedence over the .md frontmatter
|
||||
# (dual-read, §22.4a), so without this a re-run inherits the edited
|
||||
# priorities (everything ends up P1) and the faceted preconditions drift —
|
||||
# SLICE-3 expects P0 count = 2. Dropping the sidecars restores the
|
||||
# frontmatter as the source of truth: checkout-guest=P0, search-facets=P0,
|
||||
# checkout-returning=P1.
|
||||
if [ "$RESEED" = "1" ]; then
|
||||
for _slug in checkout-guest checkout-returning search-facets; do
|
||||
delete_file "$CONTENT_REPO" "bdd/rfcs/$_slug.meta.yaml"
|
||||
done
|
||||
fi
|
||||
|
||||
echo "seed-ppe: done. Set REGISTRY_REPO=$REGISTRY_REPO on rfc-app-ppe and redeploy."
|
||||
|
||||
Reference in New Issue
Block a user