/** * Admin Panel: Persona Catalogue (GET /admin/personas). * * CDPI Product Personas doc, Section 8: one representative persona per * persona type, with role mapping, allowed pages, and report * authorization/status all computed live from the real role/page * registry -- see persona_catalogue.py. This page is a read-only view * over that data, not a separate authorization system: selecting a * persona here never changes what any real account can do. * * Report status uses the spec's own three-state vocabulary: "available" * (real data, persona's role actually holds the gate), "planned" * (specified, not built yet), "data_dependent" (can't be built reliably * until the underlying data/instrumentation exists) -- never a fabricated * fourth state. */ var STATUS_LABEL = { available: "Available", planned: "Planned", data_dependent: "Data dependent" }; var STATUS_BADGE_CLASS = { available: "badge-good", planned: "badge-neutral", data_dependent: "badge-bad" }; function PersonaCatalogue(props) { var api = props.api; var snapshot = CDPI_REPORT_SNAPSHOT.useReportSnapshot("persona_catalogue", function () { return api.getPersonaCatalogue(); }); var data = snapshot.state; var selectedState = React.useState(0); var selected = selectedState[0]; var setSelected = selectedState[1]; if (data.loading && !data.data) return

Persona Catalogue

Loading…

; if (data.error && !data.data) return

Persona Catalogue

Couldn't load the persona catalogue: {data.error}
; var personas = data.data.personas; var problems = data.data.validation_problems || []; var persona = personas[selected]; return (

Persona Catalogue

The 12 representative persona configurations from the CDPI Product Personas doc (Section 8). Each persona's allowed pages and report access below are computed from the role and page registry as of the snapshot from {data.lastUpdated ? new Date(data.lastUpdated).toLocaleString() : "just now"} — click Refresh after changing roles/page access elsewhere to see the update here.

{problems.length > 0 && (
Validation found {problems.length} inconsistency(ies) between the catalogue and the live role data: {problems.join("; ")}
)}
{personas.map(function (p, i) { return ( ); })}

{persona.demo_display_name}

Role: {persona.role_display_name} ({persona.role_key})

{persona.export_permission ? "Export allowed" : "No export"}

{persona.responsibilities}

Data scope: {persona.data_scope}

Allowed pages ({persona.allowed_pages.length} of {persona.allowed_pages.length + persona.restricted_pages.length}) {persona.allowed_pages.map(function (pageId) { return {pageId}; })} {persona.allowed_pages.length === 0 && None}
Required reports ({persona.allowed_reports.length} of {persona.allowed_reports.length + persona.restricted_reports.length} in the full catalogue authorized)
{persona.allowed_reports.map(function (r) { return ( ); })}
ReportStatusNote
{r.name} {STATUS_LABEL[r.status]} {r.note}
); }