Skip to main content

CnFactsWidget

A card of facts about ONE object: label/value rows, a bold title line that may link, muted meta lines, a status pill, and one link at the foot. Registered under the facts widget type.

It is the side card the screens draw on almost every detail page (a portal's domain, theme and status; a task's owner, team and deadline; the case a task belongs to). Before this widget each app drew that card with its own component. Now an app declares which fields of which object it shows, and the library draws the card.

The object is the current detail-page object, or one other object named by source. Nothing in the widget knows an app.

Content shape​

{
"type": "facts",
"title": "Zaak",
"content": {
"source": { "register": "dossiq", "schema": "case", "id": "@object.case" },
"fields": [
{ "as": "title", "path": "title", "route": { "name": "CaseDetail", "params": { "id": "@source.id" } } },
{ "as": "line", "parts": ["identifier", "caseTypeTitle", "requesterName"] },
{ "as": "line", "parts": [{ "path": "assigneeName", "label": "Behandelaar" }, { "path": "deadline", "label": "termijn van de zaak", "format": "date" }] },
{ "as": "pill", "path": "status", "map": { "open": "In behandeling" }, "variantMap": { "open": "purple" } },
{ "path": "deadline", "label": "Termijn", "format": "date" }
],
"link": { "label": "Naar de zaak", "route": { "name": "CaseDetail", "params": { "id": "@source.id" } } },
"emptyText": "Geen zaak gekoppeld"
}
}

fields[]​

KeyMeaning
pathDot-path into the object (domains, @self.updated).
labelRow label, translated. An entry with a label and no as is a row.
asrow, title, line or pill. Without as and without label an entry is a line.
formattext (default), date (board short date: "5 okt", the year only outside this year), date-long (always with the year) or list (an array joined by ", ").
itemPathWith list: the path read off each array item (hostname of domains[]).
resolve{ register, schema, labelField? }. The value is a reference (an id, or a list of ids): the row shows the label of the referenced object (labelField, else title, then name) instead of the id. Works on a row, a title, and on a part of a line. The ids are read through the object store, one batched request per register and schema, and the labels are shared by every facts widget on the page. The entry stays empty until its label is known, and when none can be read; it never shows the id. With an array of objects, itemPath names the id (default id, then uuid).
mapRaw value to label, translated ({ "published": "Published" }). Booleans read "true" / "false", else Yes / No.
partsOn a line: paths (or { path, label?, format? }) joined by separator (default " · "). Empty parts are dropped; a labelled part reads "label value".
routeOn a title: { name, params?, query? } so the title links. Takes @source.<field> tokens.
variant / variantMapOn a pill: the CnStatusBadge variant, or raw value to variant. An unknown variant falls back to default.
keyOptional stable key for the entry's data-testid (cn-fact-<key>).

Consecutive rows form one two-column list (max-content 1fr, gap 8px 16px, label muted), as the boards draw it.

Relation pages: contact details, identity and a lead​

The person and organisation boards (screens-relation-pages) draw their side cards with these keys. An entry that uses none of them renders as before.

KeyOnMeaning
format: "email" / "phone" / "url"a rowThe value is a mailto: / tel: / web link (a url opens in a new tab).
format: "masked"a rowOnly the last four characters show ("*****7609").
reveala masked rowtrue adds a Show button. Showing emits reveal with { path } and announces { path, objectId, register, schema } on the event bus channel cn:facts:reveal (FACTS_REVEAL_CHANNEL), so the app can log who saw it.
copya rowtrue adds a copy button that writes the raw value to the clipboard.
icona rowAn icon in place of the label (the label stays for a screen reader). A row with only an icon is a row too.
as: "lead"an entryAn icon tile (icon) or the initials of the value at initialsPath, beside a bold title and a muted subtitle. title and subtitle take a path, a part, or an array of parts joined as a line. tone (success, info) tints the tile. A lead with an empty title is left out.
as: "text"an entryA line in the normal ink (address lines), with parts as a line takes them.
{ "text": "..." }a partA constant part ("Handelsregister"). A line or text entry without path or parts shows its own text ("Het tonen van het BSN wordt gelogd.").
actioncontentAn action object (the header action shape) drawn as a tinted button under the facts. @objectId / @object.<field> resolve before it is dispatched.
headerActioncontentThe same, drawn as a small button in the card header ("+ Toevoegen"). The widget reports it through the header event; the detail page puts it in the card header, also on a side card.
{
"type": "facts",
"title": "Identiteit",
"content": {
"fields": [
{ "as": "lead", "icon": "ShieldAccountOutline", "tone": "success", "title": [{ "text": "Ingelogd met DigiD" }], "subtitle": [{ "path": "lastLoginAt", "label": "bij het contactmoment van", "format": "date" }] },
{ "label": "BSN", "path": "bsn", "format": "masked", "reveal": true },
{ "label": "Geheimhouding", "path": "confidential", "map": { "true": "Ja", "false": "Nee" } },
{ "as": "line", "text": "Het tonen van het BSN wordt gelogd." }
]
}
}

Other keys​

KeyMeaning
source{ register, schema, id } or { url }. Omitted: the current object. id takes the shared tokens (@object.<field>, @objectId, @workspace.<key>, @me); url takes them inside the string (/apps/x/api/summary/@objectId). While a token does not resolve the widget sends no request and shows the empty text.
link{ label, route } or { label, href } at the foot. Routes and hrefs take @source.<field> (@source.id reads id, else @self.id). A link whose token does not resolve is left out.
hideEmptyDrop an entry whose value is empty (default true).
emptyTextShown when no entry has a value. Default "Nothing to show yet".

Props​

PropTypeDefaultDescription
contentobject{}The widget configuration above.
objectDataobjectnullThe current detail-page object, passed by the detail page host. Read when content.source is not set, and for @object.<field> tokens.
objectIdstring|numbernullThe current object id, for the @objectId token.

Events​

EventPayloadDescription
reveal{ path }A masked value was shown.
header{ link, note, action }The card header's parts; action is the headerAction ({ label, icon, run }) or null.

Notes​

  • Chrome. facts is a content-only type: on a detail page the host wraps it in the titled card with the manifest title and icon; in a tab panel it renders bare. Under the board look the side column styles that card.
  • Three states. A failed source read shows one quiet line ("Could not load this information", the error goes to the console); an object with no values shows emptyText; loading shows a small spinner.
  • Translation. Labels, map values, the link label and the empty text go through the host app's cnTranslate. Values read off the object are shown as they are.
  • Renderer only: there is no config form, so the Add-widget picker does not offer it. Declare it in the manifest.