feat(slice4): schema-driven metadata edit panel in RFCView (§22.4a PUC-1 §5.2)
MetadataFieldsPanel renders one control per declared field (enum→select, tags→chips, text→input), read-only without contribute access, saving changed values via saveEntryMeta (direct sidecar commit). Wired into the canonical main view, gated on the collection declaring fields (INV-5). saveEntryMeta API client added. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,9 @@ import GraduateDialog from './GraduateDialog.jsx'
|
||||
import InvitationsModal from './InvitationsModal.jsx'
|
||||
import { claimOwnership, retireRFC, unretireRFC } from '../api'
|
||||
import { EVENTS, track } from '../lib/analytics'
|
||||
import { entryPath, entryPrPath, useProjectId } from '../lib/entryPaths'
|
||||
import { entryPath, entryPrPath, useProjectId, useCollectionId } from '../lib/entryPaths'
|
||||
import { getCollection } from '../api'
|
||||
import MetadataFieldsPanel from './MetadataFieldsPanel.jsx'
|
||||
|
||||
const MANUAL_IDLE_MS = 5 * 60 * 1000 // §8.6 idle window; exact value is impl detail.
|
||||
const MANUAL_DEBOUNCE_MS = 800
|
||||
@@ -70,10 +72,14 @@ export default function RFCView({ viewer }) {
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const navigate = useNavigate()
|
||||
const pid = useProjectId()
|
||||
const cid = useCollectionId()
|
||||
|
||||
const branchParam = searchParams.get('branch') || 'main'
|
||||
|
||||
const [entry, setEntry] = useState(null)
|
||||
// §22.4a SLICE-4: the collection's metadata field schema (null when the
|
||||
// collection declares none — the panel then renders nothing, INV-5).
|
||||
const [collectionFields, setCollectionFields] = useState(null)
|
||||
const [mainView, setMainView] = useState(null)
|
||||
const [branchView, setBranchView] = useState(null)
|
||||
const [error, setError] = useState(null)
|
||||
@@ -142,6 +148,15 @@ export default function RFCView({ viewer }) {
|
||||
.catch(() => {})
|
||||
}, [slug, pid])
|
||||
|
||||
// §22.4a SLICE-4: load the collection's metadata field schema for the
|
||||
// detail panel. Independent of the entry load; the panel reads the entry's
|
||||
// own `meta` values + `can_edit_meta` capability.
|
||||
useEffect(() => {
|
||||
getCollection(pid, cid)
|
||||
.then(c => setCollectionFields(c?.fields || null))
|
||||
.catch(() => setCollectionFields(null))
|
||||
}, [pid, cid])
|
||||
|
||||
// Per §9.4 / §17's routing-collapse rule, super-drafts render through
|
||||
// the same surface as active RFCs — the bot, the chat, the change
|
||||
// panel, and the PR flow all dispatch on the entry's state internally.
|
||||
@@ -747,6 +762,19 @@ export default function RFCView({ viewer }) {
|
||||
: <span style={{ color: '#999', fontStyle: 'italic' }}>Left blank by the proposer.</span>}
|
||||
</div>
|
||||
)}
|
||||
{/* §22.4a SLICE-4 (PUC-1, UX §5.2): schema-driven metadata panel on
|
||||
the canonical (main) view. Renders nothing when the collection
|
||||
declares no `fields` (INV-5). */}
|
||||
{branchParam === 'main' && collectionFields && (
|
||||
<MetadataFieldsPanel
|
||||
projectId={pid}
|
||||
collectionId={cid}
|
||||
slug={slug}
|
||||
fields={collectionFields}
|
||||
meta={entry.meta || {}}
|
||||
canEdit={!!entry.can_edit_meta}
|
||||
/>
|
||||
)}
|
||||
{inDiscuss && branchParam !== 'main' && (
|
||||
<div className="discuss-mode-banner">
|
||||
Discuss mode on <strong>{branchParam}</strong> — chat freely;
|
||||
|
||||
Reference in New Issue
Block a user