Files
rfc-app/frontend/src/lib/entryPaths.js
T
Ben Stull cbaba76345 fix(§22): catalog scopes to the named collection in the URL (E2E-caught)
useCollectionId read useParams().collectionId, but the Catalog renders at
/p/:projectId/* — outside the c/:collectionId route — so it always fell back
to the default collection. The faceted filter (SLICE-3) and bulk action bar
(SLICE-5) therefore never scoped to a named (fields-bearing) collection in the
deployed app; the Catalog unit test had mocked useCollectionId, hiding it.
Resolve the /c/<id>/ segment from the pathname when the route param isn't in
scope. Caught by the new Playwright metadata suite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 22:28:57 -07:00

58 lines
2.5 KiB
JavaScript

// §22 three-tier — project + collection-scoped path builders. The canonical
// entry route now carries the collection segment: `/p/<project>/c/<collection>/…`.
// In S1 each project has a single (default) collection and serving stays
// project-scoped, so the builders emit the default collection segment; the
// collection-aware link layer (named collections) lands in S2. Components build
// links via these helpers so that flip happens in one place.
import { useParams, useLocation } from 'react-router-dom'
import { useProject } from '../components/ProjectLayout.jsx'
import { useDeployment } from '../context/DeploymentProvider'
// The default collection id (migration 029 seeds one per project at this id).
export const DEFAULT_COLLECTION = 'default'
export function entryPath(pid, slug, cid = DEFAULT_COLLECTION) {
return `/p/${pid}/c/${cid}/e/${slug}`
}
export function entryPrPath(pid, slug, prNumber, cid = DEFAULT_COLLECTION) {
return `/p/${pid}/c/${cid}/e/${slug}/pr/${prNumber}`
}
export function proposalPath(pid, prNumber, cid = DEFAULT_COLLECTION) {
return `/p/${pid}/c/${cid}/proposals/${prNumber}`
}
export function collectionHome(pid, cid = DEFAULT_COLLECTION) {
return `/p/${pid}/c/${cid}/`
}
export function projectHome(pid) {
return `/p/${pid}/`
}
// The project id a component should build links against: the contextual
// project when inside a `/p/:projectId/*` subtree, else the deployment default.
export function useProjectId() {
const ctx = useProject()
const { defaultProjectId } = useDeployment()
return (ctx && ctx.projectId) || defaultProjectId
}
// §22 S2 — the collection id a component should scope to: the `/c/:collectionId/`
// route segment when present, else the project's default collection.
//
// The route param is only in scope for components rendered *under* the
// `c/:collectionId` route (e.g. RFCView). The Catalog renders one level up at
// `/p/:projectId/*` — a sibling of that route — so `useParams().collectionId`
// is undefined there and it would wrongly fall back to the default collection
// (the faceted/bulk catalog UI would then never scope to a named collection).
// Fall back to parsing the `/c/<id>/` segment from the pathname so the Catalog
// scopes correctly regardless of its position in the route tree.
export function useCollectionId() {
const { collectionId } = useParams()
const { pathname } = useLocation()
const fromPath = pathname.match(/\/c\/([^/]+)/)
return collectionId || (fromPath && fromPath[1]) || DEFAULT_COLLECTION
}