@conduction/nextcloud-vue 2.78.0 → 2.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundled-packages.json +0 -2
- package/dist/esm/bundled-packages.json +0 -2
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +113 -104
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +12 -2
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +80 -0
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +115 -91
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +139 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +140 -92
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +77 -0
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +4 -2
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +61 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +173 -5
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +181 -99
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowser.js +29 -11
- package/dist/esm/components/CnFilesBrowser/filesBrowser.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/openRegisterSource.js +252 -0
- package/dist/esm/components/CnFilesBrowser/openRegisterSource.js.map +1 -0
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +25 -2
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +3 -2
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +100 -3
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +4 -2
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +3 -2
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +30 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +13 -0
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue3.js.map +1 -1
- package/dist/esm/composables/useAppManifest.js +8 -3
- package/dist/esm/composables/useAppManifest.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +61 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +106 -2
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +314 -15
- package/dist/esm/utils/boardDate.js +193 -0
- package/dist/esm/utils/boardDate.js.map +1 -0
- package/dist/esm/utils/dynamicProperties.js +5 -1
- package/dist/esm/utils/dynamicProperties.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +57 -6
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +2039 -581
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +314 -15
- package/l10n/en.json +61 -1
- package/l10n/nl.json +106 -2
- package/package.json +1 -1
- package/scripts/build-validators.js +26 -0
- package/src/components/CnActionsBar/CnActionsBar.vue +48 -39
- package/src/components/CnAppRoot/CnAppRoot.vue +12 -2
- package/src/components/CnCellRenderer/CnCellRenderer.vue +119 -2
- package/src/components/CnDashboardPage/CnDashboardPage.vue +219 -4
- package/src/components/CnDataTable/CnDataTable.md +2 -0
- package/src/components/CnDataTable/CnDataTable.vue +81 -2
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +61 -1
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +232 -11
- package/src/components/CnFilesBrowser/filesBrowser.js +43 -2
- package/src/components/CnFilesBrowser/index.js +1 -0
- package/src/components/CnFilesBrowser/openRegisterSource.js +248 -0
- package/src/components/CnFormDialog/CnFormDialog.vue +1 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +27 -3
- package/src/components/CnObjectSidebar/CnFilesTab.vue +103 -4
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +3 -2
- package/src/components/CnSavedViewsControl/CnSavedViewsControl.vue +1 -1
- package/src/components/CnTabsWidget/CnTabsWidget.vue +30 -1
- package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +13 -0
- package/src/components/index.js +1 -1
- package/src/composables/useAppManifest.js +8 -3
- package/src/css/look-board-detail.css +10 -0
- package/src/css/look-board-index.css +92 -14
- package/src/css/look-board.css +77 -0
- package/src/css/table.css +37 -0
- package/src/index.js +4 -0
- package/src/schemas/app-manifest-v2.schema.json +46 -1
- package/src/utils/boardDate.js +189 -0
- package/src/utils/dynamicProperties.js +5 -1
- package/src/utils/validateManifestV2.compiled.js +57 -2
- package/dist/esm/_virtual/equal.js +0 -4
- package/dist/esm/_virtual/equal.js.map +0 -1
- package/dist/esm/_virtual/ucs2length.js +0 -4
- package/dist/esm/_virtual/ucs2length.js.map +0 -1
- package/dist/esm/node_modules/ajv/dist/runtime/equal.js +0 -9
- package/dist/esm/node_modules/ajv/dist/runtime/equal.js.map +0 -1
- package/dist/esm/node_modules/ajv/dist/runtime/ucs2length.js +0 -25
- package/dist/esm/node_modules/ajv/dist/runtime/ucs2length.js.map +0 -1
- package/dist/esm/node_modules/fast-deep-equal/index.js +0 -47
- package/dist/esm/node_modules/fast-deep-equal/index.js.map +0 -1
|
@@ -3,6 +3,8 @@ import { NcAvatar, NcDateTime } from '@nextcloud/vue';
|
|
|
3
3
|
import CheckBold from 'vue-material-design-icons/CheckBold.vue';
|
|
4
4
|
import __sfc_main$1 from '../CnFkResolveCell/CnFkResolveCell.vue.js';
|
|
5
5
|
import __sfc_main$2 from './CnGroupNameCell.vue.js';
|
|
6
|
+
import { normalizeLook } from '../../composables/useLook.js';
|
|
7
|
+
import { formatBoardDate, formatAge, resolveAgeVariant } from '../../utils/boardDate.js';
|
|
6
8
|
import { resolveDateVariant, parseDateValue } from '../../utils/dateVariant.js';
|
|
7
9
|
import { safeCurrencyCode } from '../../utils/formatMetric.js';
|
|
8
10
|
import { objectFieldValue } from '../../utils/objectName.js';
|
|
@@ -65,6 +67,12 @@ var script = {
|
|
|
65
67
|
* Defaults to identity so standalone use is unaffected.
|
|
66
68
|
*/
|
|
67
69
|
cnTranslate: { default: () => (key) => key },
|
|
70
|
+
/**
|
|
71
|
+
* The look the app is drawn in, provided by CnAppRoot (or a page with
|
|
72
|
+
* `config.look`). Under `board` a date cell reads the board's short
|
|
73
|
+
* form ("5 okt"). Defaults to `nextcloud`, which renders as before.
|
|
74
|
+
*/
|
|
75
|
+
cnLook: { default: 'nextcloud' },
|
|
68
76
|
},
|
|
69
77
|
|
|
70
78
|
props: {
|
|
@@ -119,6 +127,10 @@ var script = {
|
|
|
119
127
|
* a date whose colour follows `widgetProps.variantWhen`, rules on the
|
|
120
128
|
* number of days until the date (`[{ op: "lt", value: 0, variant:
|
|
121
129
|
* "error" }, { op: "lte", value: 5, variant: "warning" }]`).
|
|
130
|
+
* The built-in id `"age"` renders how long the row has waited since
|
|
131
|
+
* the date ("4 hours", "3 days"), coloured by `widgetProps.variantWhen`
|
|
132
|
+
* rules on the days it shows (`[{ op: "gte", value: 3, variant:
|
|
133
|
+
* "error" }]`).
|
|
122
134
|
* The built-in id `"group"` shows a Nextcloud group id (or a list of
|
|
123
135
|
* them) as the group's display name; a column whose property is
|
|
124
136
|
* marked `referenceType: "nextcloud-group"` gets it without asking.
|
|
@@ -321,6 +333,69 @@ var script = {
|
|
|
321
333
|
return variant === 'default' ? '' : variant
|
|
322
334
|
},
|
|
323
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Whether the app takes the board look (`cnLook` is `board`).
|
|
338
|
+
*
|
|
339
|
+
* @return {boolean}
|
|
340
|
+
* @spec openspec/changes/screens-cell-date-parity/specs/cell-date-age/spec.md#requirement-a-board-date-cell-reads-day-and-short-month-in-the-user-language
|
|
341
|
+
*/
|
|
342
|
+
isBoardLook() {
|
|
343
|
+
return normalizeLook(this.cnLook) === 'board'
|
|
344
|
+
},
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* The board's short date ("5 okt", "14 feb 2024" outside this year).
|
|
348
|
+
*
|
|
349
|
+
* @return {string}
|
|
350
|
+
* @spec openspec/changes/screens-cell-date-parity/specs/cell-date-age/spec.md#requirement-a-board-date-cell-reads-day-and-short-month-in-the-user-language
|
|
351
|
+
*/
|
|
352
|
+
boardDateLabel() {
|
|
353
|
+
return formatBoardDate(this.value)
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* The full date for a tooltip: day, month and year in the user's
|
|
358
|
+
* locale, with the time for a date-time value.
|
|
359
|
+
*
|
|
360
|
+
* @return {string|undefined}
|
|
361
|
+
* @spec openspec/changes/screens-cell-date-parity/specs/cell-date-age/spec.md#requirement-an-age-cell-says-how-long-something-has-waited
|
|
362
|
+
*/
|
|
363
|
+
absoluteDateLabel() {
|
|
364
|
+
const date = parseDateValue(this.value);
|
|
365
|
+
if (date === null) {
|
|
366
|
+
return undefined
|
|
367
|
+
}
|
|
368
|
+
const withTime = this.property?.format === 'date-time' || this.widget === 'age';
|
|
369
|
+
const options = { day: 'numeric', month: 'long', year: 'numeric', ...(withTime ? { hour: '2-digit', minute: '2-digit' } : {}) };
|
|
370
|
+
try {
|
|
371
|
+
return new Intl.DateTimeFormat(getCanonicalLocale() || undefined, options).format(date)
|
|
372
|
+
} catch {
|
|
373
|
+
return new Intl.DateTimeFormat(undefined, options).format(date)
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* `age` widget: how long the row has waited ("4 uur", "3 dagen").
|
|
379
|
+
*
|
|
380
|
+
* @return {string}
|
|
381
|
+
* @spec openspec/changes/screens-cell-date-parity/specs/cell-date-age/spec.md#requirement-an-age-cell-says-how-long-something-has-waited
|
|
382
|
+
*/
|
|
383
|
+
ageLabel() {
|
|
384
|
+
return formatAge(this.value)
|
|
385
|
+
},
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* `age` widget: the variant of the first `widgetProps.variantWhen`
|
|
389
|
+
* rule the shown days match, or '' for none.
|
|
390
|
+
*
|
|
391
|
+
* @return {string}
|
|
392
|
+
* @spec openspec/changes/screens-cell-date-parity/specs/cell-date-age/spec.md#requirement-an-age-cell-turns-red-past-its-threshold
|
|
393
|
+
*/
|
|
394
|
+
ageVariant() {
|
|
395
|
+
const variant = resolveAgeVariant(this.value, this.widgetProps && this.widgetProps.variantWhen);
|
|
396
|
+
return variant === 'default' ? '' : variant
|
|
397
|
+
},
|
|
398
|
+
|
|
324
399
|
/**
|
|
325
400
|
* `date` widget: the date written out in the user's locale.
|
|
326
401
|
*
|
|
@@ -337,6 +412,11 @@ var script = {
|
|
|
337
412
|
// 08:30"); `widgetProps.timeOnly: true` shows just the time
|
|
338
413
|
// ("08:30"), for a timetable row. Default: the date alone.
|
|
339
414
|
const props = this.widgetProps || {};
|
|
415
|
+
// The board look writes a plain date in its short form ("5 okt");
|
|
416
|
+
// a time of day keeps the full form below.
|
|
417
|
+
if (this.isBoardLook && props.timeOnly !== true && props.showTime !== true) {
|
|
418
|
+
return formatBoardDate(date)
|
|
419
|
+
}
|
|
340
420
|
const options = props.timeOnly === true
|
|
341
421
|
? { hour: '2-digit', minute: '2-digit' }
|
|
342
422
|
: { day: 'numeric', month: 'short', year: 'numeric', ...(props.showTime === true ? { hour: '2-digit', minute: '2-digit' } : {}) };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnCellRenderer.vue2.js","sources":["../../../../src/components/CnCellRenderer/CnCellRenderer.vue"],"sourcesContent":["<template>\n\t<span class=\"cn-cell-renderer\" :class=\"cellClass\">\n\t\t<!-- Consumer-registered cell widget (cnCellWidgets[column.widget]) -->\n\t\t<component\n\t\t\t:is=\"widgetComponent\"\n\t\t\tv-if=\"widgetComponent\"\n\t\t\t:value=\"value\"\n\t\t\t:row=\"row\"\n\t\t\t:property=\"property\"\n\t\t\t:formatted=\"formattedValue\"\n\t\t\tv-bind=\"widgetProps\" />\n\n\t\t<!-- Built-in \"group\" widget: a Nextcloud group id (or a list of them)\n\t\t shown as the group's display name, cached per id. Used on its own\n\t\t for a property marked `referenceType: nextcloud-group` /\n\t\t `format: nc-group` unless the column has a formatter. -->\n\t\t<template v-else-if=\"isGroupCell\">\n\t\t\t<span v-if=\"!groupIds.length\" class=\"cn-cell-renderer__dash\">—</span>\n\t\t\t<span v-else class=\"cn-cell-renderer__groups\">\n\t\t\t\t<template v-for=\"(gid, i) in groupIds\" :key=\"gid\">\n\t\t\t\t\t<span v-if=\"i > 0\">, </span>\n\t\t\t\t\t<CnGroupNameCell :gid=\"gid\" />\n\t\t\t\t</template>\n\t\t\t</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"badge\" widget: renders the value as a status pill. An enum\n\t\t value shows its label (x-enum-labels, translated) unless a formatter\n\t\t shapes it; the colour stays keyed on the raw value. -->\n\t\t<template v-else-if=\"widget === 'badge'\">\n\t\t\t<CnStatusBadge v-if=\"hasValue\"\n\t\t\t\t:label=\"labelledValue\"\n\t\t\t\t:variant=\"badgeVariant\"\n\t\t\t\t:colorMap=\"badgeColorMap\"\n\t\t\t\t:colorKey=\"badgeColorKey\" />\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"fkResolve\" widget — resolves a reference uuid to the related\n\t\t object's display label via the object store (per-schema caching).\n\t\t Config: widgetProps { register, schema, labelField }. -->\n\t\t<template v-else-if=\"widget === 'fkResolve'\">\n\t\t\t<CnFkResolveCell\n\t\t\t\tv-if=\"hasValue\"\n\t\t\t\t:value=\"value\"\n\t\t\t\t:register=\"(widgetProps && widgetProps.register) || ''\"\n\t\t\t\t:schema=\"(widgetProps && widgetProps.schema) || ''\"\n\t\t\t\t:labelField=\"(widgetProps && widgetProps.labelField) || 'name'\" />\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"refLabel\" widget — shows the label of the referenced object(s)\n\t\t from the batch CnIndexPage resolved for the column\n\t\t (widgetProps { labels: { id: label|null }, route? }). An id that is not\n\t\t in `labels` yet shows a placeholder; one that resolved to null shows the\n\t\t id in mono. With widgetProps.route (a manifest page id) each label links\n\t\t to that page for the referenced id. -->\n\t\t<template v-else-if=\"widget === 'refLabel'\">\n\t\t\t<span v-if=\"!refLabelItems.length\" class=\"cn-cell-renderer__dash\">—</span>\n\t\t\t<span v-else class=\"cn-cell-renderer__ref-labels\" data-testid=\"cn-cell-ref-labels\">\n\t\t\t\t<template v-for=\"(item, i) in refLabelItems\" :key=\"item.id\">\n\t\t\t\t\t<span v-if=\"i > 0\">, </span>\n\t\t\t\t\t<component\n\t\t\t\t\t\t:is=\"item.to ? 'router-link' : 'span'\"\n\t\t\t\t\t\t:to=\"item.to || undefined\"\n\t\t\t\t\t\t:class=\"[item.to ? 'cn-cell-renderer__link' : '', item.state === 'missing' ? 'cn-cell-renderer__mono' : '']\"\n\t\t\t\t\t\t:title=\"item.state === 'label' ? item.id : undefined\">\n\t\t\t\t\t\t{{ item.text }}\n\t\t\t\t\t</component>\n\t\t\t\t</template>\n\t\t\t</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"link\" widget — renders the (possibly formatter-shaped) value\n\t\t as a router-link (when widgetProps.route is a manifest page id, or\n\t\t widgetProps.routeMap picks one per row by widgetProps.routeField) or\n\t\t an external anchor (when widgetProps.href is set). Falls back to\n\t\t plain text + a once-per-session console.warn when neither resolves. -->\n\t\t<template v-else-if=\"widget === 'link'\">\n\t\t\t<router-link\n\t\t\t\tv-if=\"linkRoute\"\n\t\t\t\t:to=\"linkRoute\"\n\t\t\t\tclass=\"cn-cell-renderer__link\">\n\t\t\t\t{{ labelledValue }}\n\t\t\t</router-link>\n\t\t\t<a\n\t\t\t\tv-else-if=\"linkHref\"\n\t\t\t\t:href=\"linkHref\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener\"\n\t\t\t\tclass=\"cn-cell-renderer__link\">\n\t\t\t\t{{ labelledValue }}\n\t\t\t</a>\n\t\t\t<span v-else :title=\"rawTitle\">{{ labelledValue }}</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"avatar\" widget: a person as an avatar with the name beside\n\t\t it. A user id (widgetProps.userField, or widgetProps.user for a cell\n\t\t that holds the id itself) gets the Nextcloud avatar; a free name\n\t\t gets its initials. The picture is decoration: the name is the text. -->\n\t\t<template v-else-if=\"widget === 'avatar'\">\n\t\t\t<span v-if=\"avatarName || avatarUserId\" class=\"cn-cell-renderer__avatar\">\n\t\t\t\t<span v-if=\"avatarUserId\" class=\"cn-cell-renderer__avatar-picture\" aria-hidden=\"true\">\n\t\t\t\t\t<NcAvatar\n\t\t\t\t\t\t:user=\"avatarUserId\"\n\t\t\t\t\t\t:displayName=\"avatarName || avatarUserId\"\n\t\t\t\t\t\t:size=\"avatarSize\"\n\t\t\t\t\t\t:disableMenu=\"true\"\n\t\t\t\t\t\t:disableTooltip=\"true\" />\n\t\t\t\t</span>\n\t\t\t\t<span\n\t\t\t\t\tv-else\n\t\t\t\t\tclass=\"cn-cell-renderer__avatar-initials\"\n\t\t\t\t\t:style=\"{ width: avatarSize + 'px', height: avatarSize + 'px' }\"\n\t\t\t\t\taria-hidden=\"true\">{{ avatarInitials }}</span>\n\t\t\t\t<span class=\"cn-cell-renderer__avatar-name\" :title=\"avatarName || avatarUserId\">{{ avatarName || avatarUserId }}</span>\n\t\t\t</span>\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"date\" widget: a date whose colour follows\n\t\t widgetProps.variantWhen, rules on the number of days until it\n\t\t (0 = today, negative = overdue). -->\n\t\t<template v-else-if=\"widget === 'date'\">\n\t\t\t<time\n\t\t\t\tv-if=\"dateTimestamp\"\n\t\t\t\tclass=\"cn-cell-renderer__date\"\n\t\t\t\t:class=\"dateVariant ? 'cn-cell-renderer__date--' + dateVariant : null\"\n\t\t\t\t:datetime=\"dateTimestamp.toISOString()\"\n\t\t\t\t:title=\"rawTitle\">{{ dateLabel }}</time>\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Explicit column formatter — overrides the type-aware paths below -->\n\t\t<template v-else-if=\"hasFormatter\">\n\t\t\t<span :title=\"rawTitle\">{{ formattedValue }}</span>\n\t\t</template>\n\n\t\t<!-- Declarative swatch — a colour dot (from a sibling row field) + text -->\n\t\t<template v-else-if=\"isSwatch\">\n\t\t\t<span class=\"cn-cell-renderer__swatch-wrap\">\n\t\t\t\t<span\n\t\t\t\t\tv-if=\"swatchColor\"\n\t\t\t\t\tclass=\"cn-cell-renderer__swatch-dot\"\n\t\t\t\t\t:style=\"{ backgroundColor: swatchColor }\"\n\t\t\t\t\taria-hidden=\"true\" />\n\t\t\t\t<span v-if=\"hasValue\" :title=\"rawTitle\">{{ labelledValue }}</span>\n\t\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t\t</span>\n\t\t</template>\n\n\t\t<!-- Declarative built-in format (currency / duration / number / percent) -->\n\t\t<template v-else-if=\"hasBuiltinFormat\">\n\t\t\t<span :title=\"rawTitle\" class=\"cn-cell-renderer--number\">{{ formattedValue }}</span>\n\t\t</template>\n\n\t\t<!-- Date / date-time: dynamic NcDateTime (relative time, absolute on hover) -->\n\t\t<template v-else-if=\"isDate\">\n\t\t\t<NcDateTime v-if=\"dateTimestamp\" :timestamp=\"dateTimestamp\" />\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- URI / URL: external link -->\n\t\t<template v-else-if=\"isUri\">\n\t\t\t<a\n\t\t\t\tv-if=\"uriHref\"\n\t\t\t\t:href=\"uriHref\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener\"\n\t\t\t\tclass=\"cn-cell-renderer__link\">\n\t\t\t\t{{ formattedValue }}\n\t\t\t</a>\n\t\t\t<span v-else-if=\"hasValue\" :title=\"rawTitle\">{{ formattedValue }}</span>\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Boolean: icon -->\n\t\t<template v-else-if=\"propertyType === 'boolean'\">\n\t\t\t<CheckBold v-if=\"value\" :size=\"16\" class=\"cn-cell-renderer__icon cn-cell-renderer__icon--success\" />\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Enum: status badge (auto-coloured from the property's optional colorMap) -->\n\t\t<template v-else-if=\"isEnum\">\n\t\t\t<CnStatusBadge v-if=\"value\"\n\t\t\t\t:label=\"enumLabel\"\n\t\t\t\t:colorKey=\"String(value)\"\n\t\t\t\t:colorMap=\"enumColorMap\" />\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Array: comma-joined or count -->\n\t\t<template v-else-if=\"propertyType === 'array'\">\n\t\t\t<span v-if=\"!value || !value.length\" class=\"cn-cell-renderer__dash\">—</span>\n\t\t\t<span v-else :title=\"Array.isArray(value) ? value.join(', ') : ''\">\n\t\t\t\t{{ formattedValue }}\n\t\t\t</span>\n\t\t</template>\n\n\t\t<!-- Default: formatted text -->\n\t\t<template v-else>\n\t\t\t<span :title=\"rawTitle\">{{ formattedValue }}</span>\n\t\t</template>\n\t</span>\n</template>\n\n<script>\nimport { getCanonicalLocale } from '@nextcloud/l10n'\nimport { NcAvatar, NcDateTime } from '@nextcloud/vue'\nimport CheckBold from 'vue-material-design-icons/CheckBold.vue'\nimport CnFkResolveCell from '../CnFkResolveCell/CnFkResolveCell.vue'\nimport CnGroupNameCell from './CnGroupNameCell.vue'\nimport { parseDateValue, resolveDateVariant } from '../../utils/dateVariant.js'\nimport { safeCurrencyCode } from '../../utils/formatMetric.js'\nimport { objectFieldValue } from '../../utils/objectName.js'\nimport { safeHref } from '../../utils/safeHref.js'\nimport { formatValue, isGroupProp } from '../../utils/schema.js'\nimport { CnStatusBadge } from '../CnStatusBadge/index.js'\n\n/** A uuid in any version, the shape OpenRegister ids take. */\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\n/**\n * Module-level set of column keys already warned about for a\n * `widget:\"link\"` declaration with no resolvable target — guarantees\n * one warning per (page, column-key) rather than per row × render.\n */\nconst WARNED_LINK_KEYS = new Set()\n\n/**\n * CnCellRenderer — Type-aware cell renderer for schema-driven tables.\n *\n * Renders a single cell value based on its schema property definition.\n * Booleans render as icons, enums as status badges, dates as formatted strings,\n * and everything else as truncated text via `formatValue()`.\n *\n * ```vue\n * <CnCellRenderer :value=\"row.status\" :property=\"schema.properties.status\" />\n * ```\n */\nexport default {\n\tname: 'CnCellRenderer',\n\n\tcomponents: {\n\t\tCnStatusBadge,\n\t\tCnFkResolveCell,\n\t\tCnGroupNameCell,\n\t\tCheckBold,\n\t\tNcAvatar,\n\t\tNcDateTime,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Cell-formatter registry, provided by CnAppRoot (`cnFormatters`).\n\t\t * Map of formatter-id → `(value, row, property) => string|number`.\n\t\t * Defaults to an empty object so standalone use (no CnAppRoot\n\t\t * ancestor) is unaffected.\n\t\t */\n\t\tcnFormatters: { default: () => ({}) },\n\t\t/**\n\t\t * Cell-widget registry, provided by CnAppRoot (`cnCellWidgets`).\n\t\t * Map of widget-id → Vue component. Resolves a column's `widget` id;\n\t\t * the built-in `\"badge\"` is handled inline (no registry entry needed).\n\t\t * Defaults to an empty object.\n\t\t */\n\t\tcnCellWidgets: { default: () => ({}) },\n\t\t/**\n\t\t * Display-layer translation function, provided by CnAppRoot\n\t\t * (`cnTranslate: this.translate`, bound to the host app's id). Applied\n\t\t * to the enum badge label only — the underlying value is untouched.\n\t\t * Defaults to identity so standalone use is unaffected.\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** The raw cell value */\n\t\tvalue: {\n\t\t\ttype: [Boolean, String, Number, Array, Object],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Schema property definition: { type, format, enum, items, title } */\n\t\tproperty: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Optional cell-formatter id (e.g. `currency`, `automationTrigger`).\n\t\t * When set and resolvable in the injected `cnFormatters` registry,\n\t\t * the cell renders `cnFormatters[formatter](value, row, property,\n\t\t * formatterOptions)` as text — an explicit override of the type-aware\n\t\t * rendering below.\n\t\t */\n\t\tformatter: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Declarative options map passed as the formatter's fourth argument\n\t\t * (e.g. `{ currency: 'USD' }` for the built-in `currency` formatter,\n\t\t * or `{ negative, zero, positive }` phrases for `conditionalPhrase`).\n\t\t * Undefined-safe: three-argument formatters simply ignore it.\n\t\t */\n\t\tformatterOptions: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Optional cell-widget id (e.g. `badge`, or a consumer-registered\n\t\t * name). When it resolves in `cnCellWidgets` the cell renders that\n\t\t * component with `{ value, row, property, formatted, ...widgetProps }`;\n\t\t * the built-in id `\"badge\"` renders `CnStatusBadge` and the built-in\n\t\t * id `\"fkResolve\"` renders `CnFkResolveCell` (uuid → related object\n\t\t * label, config via `widgetProps { register, schema, labelField }`),\n\t\t * and the built-in id `\"refLabel\"` shows labels already resolved in a\n\t\t * batch (`widgetProps { labels, route? }`, set by CnIndexPage for a\n\t\t * column with `labelField`).\n\t\t * The built-in id `\"avatar\"` renders a person as an avatar with the\n\t\t * name beside it (`widgetProps { userField?, user?, nameField?, size? }`;\n\t\t * a free name gets its initials), and the built-in id `\"date\"` renders\n\t\t * a date whose colour follows `widgetProps.variantWhen`, rules on the\n\t\t * number of days until the date (`[{ op: \"lt\", value: 0, variant:\n\t\t * \"error\" }, { op: \"lte\", value: 5, variant: \"warning\" }]`).\n\t\t * The built-in id `\"group\"` shows a Nextcloud group id (or a list of\n\t\t * them) as the group's display name; a column whose property is\n\t\t * marked `referenceType: \"nextcloud-group\"` gets it without asking.\n\t\t * Takes precedence over `formatter`/the type-aware rendering, but the\n\t\t * value handed to the widget is the formatter-shaped `formatted` when\n\t\t * `formatter` is also set.\n\t\t */\n\t\twidget: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Extra props spread onto the resolved cell-widget component. The\n\t\t * built-in `\"link\"` reads its target from here: `route` (a manifest\n\t\t * page id), `params` (route param to row field), `href` (URL with\n\t\t * `{field}` placeholders), and `routeField` + `routeMap` to pick the\n\t\t * page per row from a sibling field (`{ person: 'ContactDetail' }`),\n\t\t * with `route` as the fallback for a value the map does not hold.\n\t\t */\n\t\twidgetProps: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Optional declarative cell-format spec — a no-code alternative to a\n\t\t * registry `formatter`. Recognised `style` values:\n\t\t *\n\t\t * - `'currency'` → `Intl.NumberFormat` currency (e.g. `€ 1.234,56`),\n\t\t * honouring `currency` (ISO code, default `'EUR'`) and `decimals`\n\t\t * (default 2).\n\t\t * - `'number'` / `'percent'` → localized number (percent appends `%`),\n\t\t * honouring `decimals` (default 0).\n\t\t * - `'duration'` → a seconds value rendered compact (`1u 23m`, `45m 10s`,\n\t\t * `12s`); pass `unit: 'milliseconds'` / `'minutes'` / `'hours'` when the\n\t\t * raw value is not in seconds. Sub-second millisecond values render as\n\t\t * `245ms` rather than rounding down to `0s`.\n\t\t * - `'swatch'` → a colour dot read from a sibling row field named by\n\t\t * `colorField` (the value renders as the cell text beside it).\n\t\t *\n\t\t * `prefix` / `suffix` are prepended/appended to the numeric styles.\n\t\t * Resolved AFTER `formatter` / `widget` (those win), but BEFORE the\n\t\t * type-aware rendering, so a manifest column can opt into currency or a\n\t\t * colour swatch without registering a function.\n\t\t *\n\t\t * @type {{style?: 'currency'|'number'|'percent'|'duration'|'swatch', currency?: string, decimals?: number, unit?: 'milliseconds'|'seconds'|'minutes'|'hours', prefix?: string, suffix?: string, colorField?: string}}\n\t\t */\n\t\tformat: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The full row object — passed so a formatter can be a function of\n\t\t * the whole record (e.g. \"days since `@self.updated`\"), not just\n\t\t * this one cell value.\n\t\t */\n\t\trow: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Maximum string length before truncation */\n\t\ttruncate: {\n\t\t\ttype: Number,\n\t\t\tdefault: 100,\n\t\t},\n\n\t\t/**\n\t\t * Row identifier field — used by the built-in `widget:\"link\"` when\n\t\t * the manifest doesn't specify an explicit `widgetProps.params`\n\t\t * map. Defaults to `'id'` so router-link param resolution works\n\t\t * with the manifest convention (`/x/:id`).\n\t\t */\n\t\trowKey: {\n\t\t\ttype: String,\n\t\t\tdefault: 'id',\n\t\t},\n\t},\n\n\tcomputed: {\n\t\tpropertyType() {\n\t\t\treturn this.property?.type || (typeof this.value)\n\t\t},\n\n\t\tisEnum() {\n\t\t\treturn !!(this.property?.enum && this.property.enum.length > 0)\n\t\t},\n\n\t\t/**\n\t\t * Badge text for an enum cell. Schema enum values are English source\n\t\t * codes, so a Dutch session otherwise reads `submitted` in a table whose\n\t\t * headers are Dutch. Only the label is translated — the cell's value,\n\t\t * sorting and filtering keep using the raw code.\n\t\t */\n\t\tenumLabel() {\n\t\t\tconst raw = String(this.value)\n\t\t\tconst labels = (this.property && (this.property.enumLabels || this.property['x-enum-labels'])) || {}\n\t\t\treturn this.cnTranslate(labels[raw] || raw)\n\t\t},\n\n\t\t/** True when the property is a date / date-time (rendered via NcDateTime). */\n\t\tisDate() {\n\t\t\treturn this.property?.format === 'date-time' || this.property?.format === 'date'\n\t\t},\n\n\t\t/**\n\t\t * The cell value as a Date for NcDateTime, or `null` when absent or\n\t\t * unparseable (the cell then falls back to a dash / plain text).\n\t\t *\n\t\t * @return {Date|null}\n\t\t */\n\t\tdateTimestamp() {\n\t\t\tif (!this.hasValue) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst date = new Date(this.value)\n\t\t\treturn Number.isNaN(date.getTime()) ? null : date\n\t\t},\n\n\t\t/**\n\t\t * `avatar` widget: the Nextcloud user id whose avatar to show, or ''\n\t\t * for a free name. Read from the row field `widgetProps.userField`,\n\t\t * or from the cell value itself when `widgetProps.user` is true.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t */\n\t\tavatarUserId() {\n\t\t\tconst props = this.widgetProps || {}\n\t\t\tlet id = ''\n\t\t\tif (typeof props.userField === 'string' && props.userField !== '') {\n\t\t\t\tid = objectFieldValue(this.row, props.userField)\n\t\t\t} else if (props.user === true) {\n\t\t\t\tid = this.value\n\t\t\t}\n\t\t\treturn (typeof id === 'string' || typeof id === 'number') ? String(id) : ''\n\t\t},\n\n\t\t/**\n\t\t * `avatar` widget: the name shown beside the picture. Read from the\n\t\t * row field `widgetProps.nameField` when set, else the cell value.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t */\n\t\tavatarName() {\n\t\t\tconst props = this.widgetProps || {}\n\t\t\tif (typeof props.nameField === 'string' && props.nameField !== '') {\n\t\t\t\tconst name = objectFieldValue(this.row, props.nameField)\n\t\t\t\tif (typeof name === 'string' && name !== '') {\n\t\t\t\t\treturn name\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!this.hasValue || typeof this.value === 'object') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn String(this.hasFormatter ? this.formattedValue : this.value)\n\t\t},\n\n\t\t/**\n\t\t * `avatar` widget: the initials of a free name, at most two letters\n\t\t * (first and last word).\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t */\n\t\tavatarInitials() {\n\t\t\tconst words = this.avatarName.trim().split(/\\s+/).filter((word) => word !== '')\n\t\t\tif (words.length === 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst first = Array.from(words[0])[0] || ''\n\t\t\tconst last = words.length > 1 ? (Array.from(words[words.length - 1])[0] || '') : ''\n\t\t\treturn (first + last).toLocaleUpperCase()\n\t\t},\n\n\t\t/**\n\t\t * `avatar` widget: the picture size in pixels (`widgetProps.size`, default 24).\n\t\t *\n\t\t * @return {number}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t */\n\t\tavatarSize() {\n\t\t\tconst size = Number(this.widgetProps && this.widgetProps.size)\n\t\t\treturn Number.isFinite(size) && size > 0 ? size : 24\n\t\t},\n\n\t\t/**\n\t\t * `date` widget: the variant of the first `widgetProps.variantWhen`\n\t\t * rule the date matches, or '' for none.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t */\n\t\tdateVariant() {\n\t\t\tconst rules = this.widgetProps && this.widgetProps.variantWhen\n\t\t\tconst variant = resolveDateVariant(this.value, rules)\n\t\t\treturn variant === 'default' ? '' : variant\n\t\t},\n\n\t\t/**\n\t\t * `date` widget: the date written out in the user's locale.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-small-opt-ins-from-the-decidiq-and-learniq-lanes\n\t\t */\n\t\tdateLabel() {\n\t\t\tconst date = parseDateValue(this.value)\n\t\t\tif (date === null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\t// `widgetProps.showTime: true` adds the time of day (\"5 Oct 2026,\n\t\t\t// 08:30\"); `widgetProps.timeOnly: true` shows just the time\n\t\t\t// (\"08:30\"), for a timetable row. Default: the date alone.\n\t\t\tconst props = this.widgetProps || {}\n\t\t\tconst options = props.timeOnly === true\n\t\t\t\t? { hour: '2-digit', minute: '2-digit' }\n\t\t\t\t: { day: 'numeric', month: 'short', year: 'numeric', ...(props.showTime === true ? { hour: '2-digit', minute: '2-digit' } : {}) }\n\t\t\tlet locale\n\t\t\ttry {\n\t\t\t\tlocale = getCanonicalLocale()\n\t\t\t} catch {\n\t\t\t\tlocale = undefined\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn new Intl.DateTimeFormat(locale || undefined, options).format(date)\n\t\t\t} catch {\n\t\t\t\treturn new Intl.DateTimeFormat(undefined, options).format(date)\n\t\t\t}\n\t\t},\n\n\t\t/** True when the property is a URI / URL (rendered as an external link). */\n\t\tisUri() {\n\t\t\treturn this.property?.format === 'uri' || this.property?.format === 'url'\n\t\t},\n\n\t\t/**\n\t\t * Safe external href for a URI/URL cell, or `null` when the value is\n\t\t * absent or fails `safeHref` validation (e.g. an unsafe scheme).\n\t\t *\n\t\t * @return {string|null}\n\t\t */\n\t\turiHref() {\n\t\t\tif (!this.hasValue) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn safeHref(String(this.value))\n\t\t},\n\n\t\t/** True when the cell has a renderable value (not null/undefined/empty string). */\n\t\thasValue() {\n\t\t\treturn this.value !== null && this.value !== undefined && this.value !== ''\n\t\t},\n\n\t\t/**\n\t\t * Resolved cell-widget component for this column, or `null`. A column's\n\t\t * `widget` id resolves against the injected `cnCellWidgets` registry;\n\t\t * the built-in `\"badge\"` is NOT resolved here (handled inline in the\n\t\t * template) so apps can still override `\"badge\"` via the registry.\n\t\t *\n\t\t * @return {import('vue').Component|null}\n\t\t */\n\t\twidgetComponent() {\n\t\t\tif (!this.widget) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst c = this.cnCellWidgets && this.cnCellWidgets[this.widget]\n\t\t\treturn c || null\n\t\t},\n\n\t\t/**\n\t\t * Whether this cell shows Nextcloud group names: the column asks for\n\t\t * `widget: \"group\"`, or it names no widget and no formatter and its\n\t\t * property is a group (or a list of groups).\n\t\t *\n\t\t * @spec openspec/changes/nextcloud-group-surfaces/specs/data-display/spec.md#requirement-a-group-cell-shows-the-groups-display-name\n\t\t * @return {boolean}\n\t\t */\n\t\tisGroupCell() {\n\t\t\tif (this.widget === 'group') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (this.widget || this.hasFormatter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst p = this.property\n\t\t\tif (!p || typeof p !== 'object') {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn isGroupProp(p) || (p.type === 'array' && isGroupProp(p.items))\n\t\t},\n\n\t\t/**\n\t\t * The group ids in this cell, empty ones dropped.\n\t\t *\n\t\t * @spec openspec/changes/nextcloud-group-surfaces/specs/data-display/spec.md#requirement-a-group-cell-shows-the-groups-display-name\n\t\t * @return {string[]}\n\t\t */\n\t\tgroupIds() {\n\t\t\tconst raw = this.value\n\t\t\tconst list = Array.isArray(raw) ? raw : [raw]\n\t\t\treturn list\n\t\t\t\t.filter((gid) => (typeof gid === 'string' && gid !== '') || typeof gid === 'number')\n\t\t\t\t.map((gid) => String(gid))\n\t\t},\n\n\t\t/**\n\t\t * The text a built-in widget (`badge`, `link`) or a swatch shows. An\n\t\t * enum value reads its label the way the plain enum cell does\n\t\t * (`enumLabel`: `x-enum-labels`, translated), so a list says \"Active\"\n\t\t * where the detail page does, not the stored \"active\". A column\n\t\t * formatter still wins: an app that shapes the value itself gets\n\t\t * exactly what its formatter returns.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/cell-labels-and-draft-indicator/specs/cell-labels-and-draft-indicator/spec.md#requirement-a-built-in-cell-widget-shows-an-enum-value-by-its-label\n\t\t */\n\t\tlabelledValue() {\n\t\t\tif (!this.hasFormatter && this.isEnum && this.hasValue && typeof this.value !== 'object') {\n\t\t\t\treturn this.enumLabel\n\t\t\t}\n\t\t\treturn String(this.formattedValue)\n\t\t},\n\n\t\t/**\n\t\t * The key the built-in `badge` looks its colour up by: the raw value\n\t\t * when `widgetProps.colorMap` has an entry for it (case-insensitive),\n\t\t * so a translated label keeps the colour the manifest keyed on the\n\t\t * stored code. Otherwise '' and the badge looks up its label, as before,\n\t\t * which keeps a map keyed on a formatter's output working.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/cell-labels-and-draft-indicator/specs/cell-labels-and-draft-indicator/spec.md#requirement-a-built-in-cell-widget-shows-an-enum-value-by-its-label\n\t\t */\n\t\tbadgeColorKey() {\n\t\t\tconst map = this.badgeColorMap\n\t\t\tif (!map || !this.hasValue || typeof this.value === 'object') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst raw = String(this.value).toLowerCase()\n\t\t\treturn Object.keys(map).some((key) => key.toLowerCase() === raw) ? String(this.value) : ''\n\t\t},\n\n\t\t/** Variant for the built-in `badge` widget — `widgetProps.variant` or `'default'`. */\n\t\tbadgeVariant() {\n\t\t\treturn (this.widgetProps && this.widgetProps.variant) || 'default'\n\t\t},\n\n\t\t/**\n\t\t * Color map for the built-in `badge` widget — `widgetProps.colorMap`,\n\t\t * a `{ value: variant }` map (e.g. `{ placed: 'primary', delivered: 'success' }`)\n\t\t * that CnStatusBadge resolves per label. Null when unset (falls back to\n\t\t * `badgeVariant`). Lets a manifest colour a status column without code.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tbadgeColorMap() {\n\t\t\treturn (this.widgetProps && this.widgetProps.colorMap) || null\n\t\t},\n\n\t\t/**\n\t\t * Color map for the auto-rendered enum badge — read from the schema\n\t\t * property's optional `colorMap` (or `x-color-map`). Null when unset, so\n\t\t * enum cells stay the default grey unless the schema opts into colours.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tenumColorMap() {\n\t\t\treturn (this.property && (this.property.colorMap || this.property['x-color-map'])) || null\n\t\t},\n\n\t\t/**\n\t\t * The manifest page id the built-in `widget:\"link\"` routes this row\n\t\t * to, or null.\n\t\t *\n\t\t * `widgetProps.routeField` names a sibling field on the row, and\n\t\t * `widgetProps.routeMap` maps that field's values to page ids, so one\n\t\t * column can link a person to `ContactDetail` and an organisation to\n\t\t * `OrganisationDetail` off `initiatorType`. A row whose value has no\n\t\t * entry in the map falls back to the fixed `widgetProps.route`, and\n\t\t * without one the cell renders as text. The map is the whole\n\t\t * vocabulary: a row value is only ever used as a KEY into it, never\n\t\t * as a route name itself, so row data cannot send a link to a page\n\t\t * the manifest did not name.\n\t\t *\n\t\t * @return {string|null} The page id, or null when none resolves.\n\t\t */\n\t\tlinkRouteName() {\n\t\t\tconst wp = this.widgetProps || {}\n\t\t\tconst map = wp.routeMap\n\t\t\tif (typeof wp.routeField === 'string' && wp.routeField !== '' && map && typeof map === 'object') {\n\t\t\t\tconst key = this.row ? this.row[wp.routeField] : undefined\n\t\t\t\tif (key !== undefined && key !== null && Object.hasOwn(map, String(key))) {\n\t\t\t\t\tconst mapped = map[String(key)]\n\t\t\t\t\tif (typeof mapped === 'string' && mapped !== '') {\n\t\t\t\t\t\treturn mapped\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (typeof wp.route === 'string' && wp.route !== '') ? wp.route : null\n\t\t},\n\n\t\t/**\n\t\t * Items of the built-in `widget:\"refLabel\"`: one per referenced id with\n\t\t * its text, state (`label`, `loading` or `missing`) and optional link.\n\t\t *\n\t\t * @return {Array<{id: string, text: string, state: string, to: (object|null)}>}\n\t\t */\n\t\trefLabelItems() {\n\t\t\tif (this.widget !== 'refLabel') {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst wp = this.widgetProps || {}\n\t\t\tconst labels = wp.labels || {}\n\t\t\tconst raw = this.value\n\t\t\tconst list = Array.isArray(raw) ? raw : [raw]\n\t\t\treturn list\n\t\t\t\t.filter((id) => id !== null && id !== undefined && id !== '')\n\t\t\t\t.map((id) => {\n\t\t\t\t\tconst key = String(id)\n\t\t\t\t\tconst known = Object.hasOwn(labels, key)\n\t\t\t\t\tconst label = known ? labels[key] : undefined\n\t\t\t\t\tconst state = !known ? 'loading' : (label ? 'label' : 'missing')\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: key,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\ttext: state === 'label' ? label : (state === 'loading' ? '…' : key),\n\t\t\t\t\t\tto: (state === 'label' && typeof wp.route === 'string' && wp.route !== '') ? { name: wp.route, params: { id: key } } : null,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Resolved router-link target for the built-in `widget:\"link\"`. When\n\t\t * a page id resolves (`widgetProps.route`, or the row's entry in\n\t\t * `widgetProps.routeMap`, see `linkRouteName`), returns\n\t\t * `{ name: route, params }`. Param map is `widgetProps.params`\n\t\t * (a map of route-param-name → row-field-name); when omitted,\n\t\t * defaults to `{ id: row[rowKey] }`. Returns null when no page id\n\t\t * resolves (the template falls through to `linkHref` or plain\n\t\t * text).\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tlinkRoute() {\n\t\t\tif (this.widget !== 'link') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst route = this.linkRouteName\n\t\t\tif (!route) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst paramMap = (this.widgetProps && this.widgetProps.params)\n\t\t\t\t|| { id: this.rowKey || 'id' }\n\t\t\tconst params = {}\n\t\t\tfor (const [routeParam, rowField] of Object.entries(paramMap)) {\n\t\t\t\tparams[routeParam] = this.row && this.row[rowField]\n\t\t\t}\n\t\t\treturn { name: route, params }\n\t\t},\n\n\t\t/**\n\t\t * Resolved external href for the built-in `widget:\"link\"` when\n\t\t * `widgetProps.href` is set. `{key}` placeholders in the href\n\t\t * are substituted from the row (`\"/x/{id}\"` + `row.id === \"42\"`\n\t\t * → `\"/x/42\"`). The final computed value is validated with\n\t\t * `safeHref` so row-injected values cannot introduce unsafe\n\t\t * schemes: a `javascript:` or `data:` result renders as plain text\n\t\t * instead of a link. Returns null when `href` isn't set.\n\t\t *\n\t\t * @return {string|null}\n\t\t */\n\t\tlinkHref() {\n\t\t\tif (this.widget !== 'link') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst href = this.widgetProps && this.widgetProps.href\n\t\t\tif (!href) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst resolved = String(href).replace(/\\{(\\w+)\\}/g, (_, key) => this.row && this.row[key] !== null && this.row[key] !== undefined ? String(this.row[key]) : '')\n\t\t\t// The safeHref retrofit (18700fd94) put this check here and a later\n\t\t\t// lint pass (e5ea00d51) dropped it, leaving the docblock above\n\t\t\t// promising a check the code no longer made: a template of `{url}`\n\t\t\t// put a row's `javascript:` value straight into `:href`. safeHref\n\t\t\t// answers '#' for anything unsafe; that is not a link worth\n\t\t\t// rendering, so fall through to plain text.\n\t\t\tconst safe = safeHref(resolved)\n\t\t\treturn safe === '#' ? null : safe\n\t\t},\n\n\t\t/**\n\t\t * Resolved formatter function for this cell, or `null`. A column's\n\t\t * `formatter` id resolves against the injected `cnFormatters` registry.\n\t\t *\n\t\t * @return {((value: unknown, row: object, property: object, options: object) => unknown)|null}\n\t\t */\n\t\tformatterFn() {\n\t\t\tconst fn = this.formatter && this.cnFormatters && this.cnFormatters[this.formatter]\n\t\t\treturn typeof fn === 'function' ? fn : null\n\t\t},\n\n\t\t/** True when an explicit formatter is in play for this cell. */\n\t\thasFormatter() {\n\t\t\treturn this.formatterFn !== null\n\t\t},\n\n\t\t/**\n\t\t * The declarative format `style`, or null when no (recognised) `format`\n\t\t * spec is set. Drives the built-in currency / duration / number / percent\n\t\t * / swatch rendering paths.\n\t\t *\n\t\t * @return {string|null}\n\t\t */\n\t\tformatStyle() {\n\t\t\tconst s = this.format && this.format.style\n\t\t\treturn typeof s === 'string' ? s : null\n\t\t},\n\n\t\t/** True when a built-in NUMERIC format (currency/number/percent/duration) applies. */\n\t\thasBuiltinFormat() {\n\t\t\treturn ['currency', 'number', 'percent', 'duration'].includes(this.formatStyle)\n\t\t},\n\n\t\t/** True when this cell renders as a colour swatch (`format.style:\"swatch\"`). */\n\t\tisSwatch() {\n\t\t\treturn this.formatStyle === 'swatch'\n\t\t},\n\n\t\t/**\n\t\t * The swatch colour — read from the sibling row field named by\n\t\t * `format.colorField` (default `'color'`). Returns null when no usable\n\t\t * colour string is present (the dot is then omitted).\n\t\t *\n\t\t * @return {string|null}\n\t\t */\n\t\tswatchColor() {\n\t\t\tif (!this.isSwatch) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst field = (this.format && this.format.colorField) || 'color'\n\t\t\tconst c = this.row && this.row[field]\n\t\t\treturn (typeof c === 'string' && c.trim() !== '') ? c : null\n\t\t},\n\n\t\tformattedValue() {\n\t\t\tif (this.formatterFn) {\n\t\t\t\ttry {\n\t\t\t\t\treturn this.formatterFn(this.value, this.row, this.property, this.formatterOptions || undefined)\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnCellRenderer] formatter \"${this.formatter}\" threw; falling back`, e)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.hasBuiltinFormat) {\n\t\t\t\treturn this.applyBuiltinFormat()\n\t\t\t}\n\t\t\treturn formatValue(this.value, this.property, { truncate: this.truncate })\n\t\t},\n\n\t\trawTitle() {\n\t\t\t// Show full value on hover if it was truncated\n\t\t\tconst raw = this.value\n\t\t\tif (typeof raw === 'string' && raw.length > this.truncate) {\n\t\t\t\treturn raw\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\n\t\t/**\n\t\t * Whether the cell draws a uuid, and so takes the monospace uuid\n\t\t * style. The property's `format: \"uuid\"` alone used to decide this,\n\t\t * so a reference that a formatter or a widget had resolved to its\n\t\t * name was still drawn as code. Now the value has to be a uuid AND\n\t\t * nothing resolves it: a resolving widget or formatter, or a value\n\t\t * that is not a uuid, renders in the normal text style.\n\t\t *\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-a-resolved-reference-is-not-drawn-as-a-uuid\n\t\t * @return {boolean}\n\t\t */\n\t\tshowsUuid() {\n\t\t\tif (this.property?.format !== 'uuid') {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (this.widgetComponent || this.widget || this.hasFormatter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn typeof this.value === 'string' && UUID_PATTERN.test(this.value)\n\t\t},\n\n\t\tcellClass() {\n\t\t\tconst classes = []\n\t\t\tif (this.propertyType === 'boolean') {\n\t\t\t\tclasses.push('cn-cell-renderer--boolean')\n\t\t\t}\n\t\t\tif (this.isEnum) {\n\t\t\t\tclasses.push('cn-cell-renderer--enum')\n\t\t\t}\n\t\t\tif (this.property?.format === 'date-time' || this.property?.format === 'date') {\n\t\t\t\tclasses.push('cn-cell-renderer--date')\n\t\t\t}\n\t\t\tif (this.showsUuid) {\n\t\t\t\tclasses.push('cn-cell-renderer--uuid')\n\t\t\t}\n\t\t\tif (this.propertyType === 'integer' || this.propertyType === 'number') {\n\t\t\t\tclasses.push('cn-cell-renderer--number')\n\t\t\t}\n\t\t\treturn classes\n\t\t},\n\t},\n\n\tmounted() {\n\t\t// Warn once per column-property-name when `widget:\"link\"` resolves\n\t\t// to neither a `route` nor an `href` — silent fallback hides\n\t\t// manifest mistakes, an every-row warn is too noisy.\n\t\t// A column with a `routeMap` has declared its targets; a row whose\n\t\t// value is not in the map (an empty requester, say) is data, not a\n\t\t// manifest mistake, so it renders as text without the warning. The\n\t\t// same holds for a declared `href` whose resolved value safeHref\n\t\t// refused: the manifest is fine, the row value is not.\n\t\tif (\n\t\t\tthis.widget === 'link'\n\t\t\t&& !this.linkRoute\n\t\t\t&& !this.widgetProps?.href\n\t\t\t&& this.widgetProps?.fallback !== 'silent'\n\t\t\t&& !(this.widgetProps?.routeMap && typeof this.widgetProps.routeMap === 'object')\n\t\t) {\n\t\t\tconst key = this.property?.title || String(this.value).slice(0, 20)\n\t\t\tif (!WARNED_LINK_KEYS.has(key)) {\n\t\t\t\tWARNED_LINK_KEYS.add(key)\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnCellRenderer] widget:\"link\" on \"${key}\" has no resolvable target — set widgetProps.route (page id) or widgetProps.href (URL with optional {field} placeholders); cell falls back to plain text.`)\n\t\t\t}\n\t\t}\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Render the cell value per the declarative `format` spec (currency /\n\t\t * number / percent / duration). Mirrors CnStatWidget's formatting so a\n\t\t * KPI tile and a table column read identically. Non-numeric values fall\n\t\t * back to `formatValue`; an empty value renders an em-dash.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tapplyBuiltinFormat() {\n\t\t\tif (!this.hasValue) {\n\t\t\t\treturn '—'\n\t\t\t}\n\t\t\tconst fmt = this.format || {}\n\t\t\tif (fmt.style === 'duration') {\n\t\t\t\treturn this.formatDuration()\n\t\t\t}\n\t\t\tconst num = Number(this.value)\n\t\t\tif (!Number.isFinite(num)) {\n\t\t\t\treturn formatValue(this.value, this.property, { truncate: this.truncate })\n\t\t\t}\n\t\t\tconst decimals = Number.isFinite(fmt.decimals)\n\t\t\t\t? fmt.decimals\n\t\t\t\t: (fmt.style === 'currency' ? 2 : 0)\n\t\t\tlet body\n\t\t\tif (fmt.style === 'currency') {\n\t\t\t\tbody = new Intl.NumberFormat(undefined, {\n\t\t\t\t\tstyle: 'currency',\n\t\t\t\t\tcurrency: safeCurrencyCode(fmt.currency),\n\t\t\t\t\tminimumFractionDigits: decimals,\n\t\t\t\t\tmaximumFractionDigits: decimals,\n\t\t\t\t}).format(num)\n\t\t\t} else if (fmt.style === 'percent') {\n\t\t\t\t// Values are stored as the literal percent (83.3), not a 0–1 ratio.\n\t\t\t\tbody = new Intl.NumberFormat(undefined, {\n\t\t\t\t\tminimumFractionDigits: decimals,\n\t\t\t\t\tmaximumFractionDigits: decimals,\n\t\t\t\t}).format(num) + '%'\n\t\t\t} else {\n\t\t\t\tbody = new Intl.NumberFormat(undefined, {\n\t\t\t\t\tminimumFractionDigits: decimals,\n\t\t\t\t\tmaximumFractionDigits: decimals,\n\t\t\t\t}).format(num)\n\t\t\t}\n\t\t\treturn `${fmt.prefix || ''}${body}${fmt.suffix || ''}`\n\t\t},\n\n\t\t/**\n\t\t * Render a numeric duration compactly (`1u 23m`, `45m 10s`, `12s`). The\n\t\t * raw value is seconds unless `format.unit` is `'milliseconds'` /\n\t\t * `'minutes'` / `'hours'`. The hour suffix is `u` (uur) to read naturally\n\t\t * under NL theming while staying digit-led for other locales.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tformatDuration() {\n\t\t\tconst fmt = this.format || {}\n\t\t\tlet secs = Number(this.value)\n\t\t\tif (!Number.isFinite(secs)) {\n\t\t\t\treturn formatValue(this.value, this.property, { truncate: this.truncate })\n\t\t\t}\n\t\t\tif (fmt.unit === 'milliseconds') {\n\t\t\t\t// Sub-second durations are the common case for a millisecond\n\t\t\t\t// field (request/step timings), and they would all collapse to\n\t\t\t\t// the `0s` floor below — so render them in ms directly.\n\t\t\t\tconst ms = Math.round(secs)\n\t\t\t\tif (Math.abs(ms) < 1000) {\n\t\t\t\t\treturn `${fmt.prefix || ''}${ms}ms${fmt.suffix || ''}`\n\t\t\t\t}\n\t\t\t\tsecs = ms / 1000\n\t\t\t} else if (fmt.unit === 'minutes') {\n\t\t\t\tsecs *= 60\n\t\t\t} else if (fmt.unit === 'hours') {\n\t\t\t\tsecs *= 3600\n\t\t\t}\n\t\t\tsecs = Math.round(secs)\n\t\t\tconst sign = secs < 0 ? '-' : ''\n\t\t\tsecs = Math.abs(secs)\n\t\t\tconst h = Math.floor(secs / 3600)\n\t\t\tconst m = Math.floor((secs % 3600) / 60)\n\t\t\tconst s = secs % 60\n\t\t\tconst parts = []\n\t\t\tif (h > 0) {\n\t\t\t\tparts.push(`${h}u`)\n\t\t\t}\n\t\t\tif (m > 0) {\n\t\t\t\tparts.push(`${m}m`)\n\t\t\t}\n\t\t\tif (s > 0 && h === 0) {\n\t\t\t\tparts.push(`${s}s`)\n\t\t\t}\n\t\t\tif (parts.length === 0) {\n\t\t\t\tparts.push('0s')\n\t\t\t}\n\t\t\treturn `${fmt.prefix || ''}${sign}${parts.join(' ')}${fmt.suffix || ''}`\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-cell-renderer__mono {\n\tfont-family: monospace;\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-cell-renderer--uuid {\n\tfont-family: monospace;\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-cell-renderer--number {\n\tfont-variant-numeric: tabular-nums;\n}\n\n.cn-cell-renderer--date {\n\twhite-space: nowrap;\n}\n\n.cn-cell-renderer__dash {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-cell-renderer__avatar {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 8px;\n\tmax-width: 100%;\n\tvertical-align: middle;\n}\n\n.cn-cell-renderer__avatar-picture {\n\tdisplay: inline-flex;\n\tflex: none;\n}\n\n.cn-cell-renderer__avatar-initials {\n\tdisplay: inline-flex;\n\tflex: none;\n\talign-items: center;\n\tjustify-content: center;\n\tborder-radius: 50%;\n\tbackground-color: var(--color-primary-element-light);\n\tcolor: var(--color-primary-element-light-text);\n\tfont-size: 0.75em;\n\tfont-weight: 700;\n\tline-height: 1;\n}\n\n.cn-cell-renderer__avatar-name {\n\tmin-width: 0;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n/* A date that matched a rule is also set in a heavier weight, so the signal\n does not rest on colour alone. */\n.cn-cell-renderer__date--success,\n.cn-cell-renderer__date--warning,\n.cn-cell-renderer__date--error {\n\tfont-weight: 600;\n}\n\n.cn-cell-renderer__date--success {\n\tcolor: var(--color-text-success, var(--color-success-text));\n}\n\n.cn-cell-renderer__date--warning {\n\tcolor: var(--color-text-warning, var(--color-warning-text));\n}\n\n.cn-cell-renderer__date--error {\n\tcolor: var(--color-text-error, var(--color-error-text));\n}\n\n/* The text variant, not the fill: from Nextcloud 32 `--color-success` is a\n background colour and too pale for a 16px glyph on a light theme. */\n.cn-cell-renderer__icon--success {\n\tcolor: var(--color-text-success, var(--color-success-text, var(--color-success)));\n}\n\n.cn-cell-renderer__swatch-wrap {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 8px;\n}\n\n.cn-cell-renderer__swatch-dot {\n\tdisplay: inline-block;\n\twidth: 12px;\n\theight: 12px;\n\tborder-radius: 50%;\n\tflex-shrink: 0;\n\tborder: 1px solid var(--color-border-dark);\n}\n</style>\n"],"names":["CnStatusBadge","CnFkResolveCell","CnGroupNameCell"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnCellRenderer.vue2.js","sources":["../../../../src/components/CnCellRenderer/CnCellRenderer.vue"],"sourcesContent":["<template>\n\t<span class=\"cn-cell-renderer\" :class=\"cellClass\">\n\t\t<!-- Consumer-registered cell widget (cnCellWidgets[column.widget]) -->\n\t\t<component\n\t\t\t:is=\"widgetComponent\"\n\t\t\tv-if=\"widgetComponent\"\n\t\t\t:value=\"value\"\n\t\t\t:row=\"row\"\n\t\t\t:property=\"property\"\n\t\t\t:formatted=\"formattedValue\"\n\t\t\tv-bind=\"widgetProps\" />\n\n\t\t<!-- Built-in \"group\" widget: a Nextcloud group id (or a list of them)\n\t\t shown as the group's display name, cached per id. Used on its own\n\t\t for a property marked `referenceType: nextcloud-group` /\n\t\t `format: nc-group` unless the column has a formatter. -->\n\t\t<template v-else-if=\"isGroupCell\">\n\t\t\t<span v-if=\"!groupIds.length\" class=\"cn-cell-renderer__dash\">—</span>\n\t\t\t<span v-else class=\"cn-cell-renderer__groups\">\n\t\t\t\t<template v-for=\"(gid, i) in groupIds\" :key=\"gid\">\n\t\t\t\t\t<span v-if=\"i > 0\">, </span>\n\t\t\t\t\t<CnGroupNameCell :gid=\"gid\" />\n\t\t\t\t</template>\n\t\t\t</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"badge\" widget: renders the value as a status pill. An enum\n\t\t value shows its label (x-enum-labels, translated) unless a formatter\n\t\t shapes it; the colour stays keyed on the raw value. -->\n\t\t<template v-else-if=\"widget === 'badge'\">\n\t\t\t<CnStatusBadge v-if=\"hasValue\"\n\t\t\t\t:label=\"labelledValue\"\n\t\t\t\t:variant=\"badgeVariant\"\n\t\t\t\t:colorMap=\"badgeColorMap\"\n\t\t\t\t:colorKey=\"badgeColorKey\" />\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"fkResolve\" widget — resolves a reference uuid to the related\n\t\t object's display label via the object store (per-schema caching).\n\t\t Config: widgetProps { register, schema, labelField }. -->\n\t\t<template v-else-if=\"widget === 'fkResolve'\">\n\t\t\t<CnFkResolveCell\n\t\t\t\tv-if=\"hasValue\"\n\t\t\t\t:value=\"value\"\n\t\t\t\t:register=\"(widgetProps && widgetProps.register) || ''\"\n\t\t\t\t:schema=\"(widgetProps && widgetProps.schema) || ''\"\n\t\t\t\t:labelField=\"(widgetProps && widgetProps.labelField) || 'name'\" />\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"refLabel\" widget — shows the label of the referenced object(s)\n\t\t from the batch CnIndexPage resolved for the column\n\t\t (widgetProps { labels: { id: label|null }, route? }). An id that is not\n\t\t in `labels` yet shows a placeholder; one that resolved to null shows the\n\t\t id in mono. With widgetProps.route (a manifest page id) each label links\n\t\t to that page for the referenced id. -->\n\t\t<template v-else-if=\"widget === 'refLabel'\">\n\t\t\t<span v-if=\"!refLabelItems.length\" class=\"cn-cell-renderer__dash\">—</span>\n\t\t\t<span v-else class=\"cn-cell-renderer__ref-labels\" data-testid=\"cn-cell-ref-labels\">\n\t\t\t\t<template v-for=\"(item, i) in refLabelItems\" :key=\"item.id\">\n\t\t\t\t\t<span v-if=\"i > 0\">, </span>\n\t\t\t\t\t<component\n\t\t\t\t\t\t:is=\"item.to ? 'router-link' : 'span'\"\n\t\t\t\t\t\t:to=\"item.to || undefined\"\n\t\t\t\t\t\t:class=\"[item.to ? 'cn-cell-renderer__link' : '', item.state === 'missing' ? 'cn-cell-renderer__mono' : '']\"\n\t\t\t\t\t\t:title=\"item.state === 'label' ? item.id : undefined\">\n\t\t\t\t\t\t{{ item.text }}\n\t\t\t\t\t</component>\n\t\t\t\t</template>\n\t\t\t</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"link\" widget — renders the (possibly formatter-shaped) value\n\t\t as a router-link (when widgetProps.route is a manifest page id, or\n\t\t widgetProps.routeMap picks one per row by widgetProps.routeField) or\n\t\t an external anchor (when widgetProps.href is set). Falls back to\n\t\t plain text + a once-per-session console.warn when neither resolves. -->\n\t\t<template v-else-if=\"widget === 'link'\">\n\t\t\t<router-link\n\t\t\t\tv-if=\"linkRoute\"\n\t\t\t\t:to=\"linkRoute\"\n\t\t\t\tclass=\"cn-cell-renderer__link\">\n\t\t\t\t{{ labelledValue }}\n\t\t\t</router-link>\n\t\t\t<a\n\t\t\t\tv-else-if=\"linkHref\"\n\t\t\t\t:href=\"linkHref\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener\"\n\t\t\t\tclass=\"cn-cell-renderer__link\">\n\t\t\t\t{{ labelledValue }}\n\t\t\t</a>\n\t\t\t<span v-else :title=\"rawTitle\">{{ labelledValue }}</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"avatar\" widget: a person as an avatar with the name beside\n\t\t it. A user id (widgetProps.userField, or widgetProps.user for a cell\n\t\t that holds the id itself) gets the Nextcloud avatar; a free name\n\t\t gets its initials. The picture is decoration: the name is the text. -->\n\t\t<template v-else-if=\"widget === 'avatar'\">\n\t\t\t<span v-if=\"avatarName || avatarUserId\" class=\"cn-cell-renderer__avatar\">\n\t\t\t\t<span v-if=\"avatarUserId\" class=\"cn-cell-renderer__avatar-picture\" aria-hidden=\"true\">\n\t\t\t\t\t<NcAvatar\n\t\t\t\t\t\t:user=\"avatarUserId\"\n\t\t\t\t\t\t:displayName=\"avatarName || avatarUserId\"\n\t\t\t\t\t\t:size=\"avatarSize\"\n\t\t\t\t\t\t:disableMenu=\"true\"\n\t\t\t\t\t\t:disableTooltip=\"true\" />\n\t\t\t\t</span>\n\t\t\t\t<span\n\t\t\t\t\tv-else\n\t\t\t\t\tclass=\"cn-cell-renderer__avatar-initials\"\n\t\t\t\t\t:style=\"{ width: avatarSize + 'px', height: avatarSize + 'px' }\"\n\t\t\t\t\taria-hidden=\"true\">{{ avatarInitials }}</span>\n\t\t\t\t<span class=\"cn-cell-renderer__avatar-name\" :title=\"avatarName || avatarUserId\">{{ avatarName || avatarUserId }}</span>\n\t\t\t</span>\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"age\" widget: how long something has waited (\"4 uur\",\n\t\t \"3 dagen\"), coloured by widgetProps.variantWhen rules on the days\n\t\t the cell shows. The full date is the tooltip. -->\n\t\t<template v-else-if=\"widget === 'age'\">\n\t\t\t<time\n\t\t\t\tv-if=\"dateTimestamp\"\n\t\t\t\tclass=\"cn-cell-renderer__age\"\n\t\t\t\t:class=\"ageVariant ? 'cn-cell-renderer__age--' + ageVariant : null\"\n\t\t\t\t:datetime=\"dateTimestamp.toISOString()\"\n\t\t\t\t:title=\"absoluteDateLabel\">{{ ageLabel }}</time>\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Built-in \"date\" widget: a date whose colour follows\n\t\t widgetProps.variantWhen, rules on the number of days until it\n\t\t (0 = today, negative = overdue). -->\n\t\t<template v-else-if=\"widget === 'date'\">\n\t\t\t<time\n\t\t\t\tv-if=\"dateTimestamp\"\n\t\t\t\tclass=\"cn-cell-renderer__date\"\n\t\t\t\t:class=\"dateVariant ? 'cn-cell-renderer__date--' + dateVariant : null\"\n\t\t\t\t:datetime=\"dateTimestamp.toISOString()\"\n\t\t\t\t:title=\"rawTitle\">{{ dateLabel }}</time>\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Explicit column formatter — overrides the type-aware paths below -->\n\t\t<template v-else-if=\"hasFormatter\">\n\t\t\t<span :title=\"rawTitle\">{{ formattedValue }}</span>\n\t\t</template>\n\n\t\t<!-- Declarative swatch — a colour dot (from a sibling row field) + text -->\n\t\t<template v-else-if=\"isSwatch\">\n\t\t\t<span class=\"cn-cell-renderer__swatch-wrap\">\n\t\t\t\t<span\n\t\t\t\t\tv-if=\"swatchColor\"\n\t\t\t\t\tclass=\"cn-cell-renderer__swatch-dot\"\n\t\t\t\t\t:style=\"{ backgroundColor: swatchColor }\"\n\t\t\t\t\taria-hidden=\"true\" />\n\t\t\t\t<span v-if=\"hasValue\" :title=\"rawTitle\">{{ labelledValue }}</span>\n\t\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t\t</span>\n\t\t</template>\n\n\t\t<!-- Declarative built-in format (currency / duration / number / percent) -->\n\t\t<template v-else-if=\"hasBuiltinFormat\">\n\t\t\t<span :title=\"rawTitle\" class=\"cn-cell-renderer--number\">{{ formattedValue }}</span>\n\t\t</template>\n\n\t\t<!-- Date / date-time: dynamic NcDateTime (relative time, absolute on hover) -->\n\t\t<template v-else-if=\"isDate\">\n\t\t\t<time\n\t\t\t\tv-if=\"dateTimestamp && isBoardLook\"\n\t\t\t\tclass=\"cn-cell-renderer__date\"\n\t\t\t\t:datetime=\"dateTimestamp.toISOString()\"\n\t\t\t\t:title=\"absoluteDateLabel\">{{ boardDateLabel }}</time>\n\t\t\t<NcDateTime v-else-if=\"dateTimestamp\" :timestamp=\"dateTimestamp\" />\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- URI / URL: external link -->\n\t\t<template v-else-if=\"isUri\">\n\t\t\t<a\n\t\t\t\tv-if=\"uriHref\"\n\t\t\t\t:href=\"uriHref\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener\"\n\t\t\t\tclass=\"cn-cell-renderer__link\">\n\t\t\t\t{{ formattedValue }}\n\t\t\t</a>\n\t\t\t<span v-else-if=\"hasValue\" :title=\"rawTitle\">{{ formattedValue }}</span>\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Boolean: icon -->\n\t\t<template v-else-if=\"propertyType === 'boolean'\">\n\t\t\t<CheckBold v-if=\"value\" :size=\"16\" class=\"cn-cell-renderer__icon cn-cell-renderer__icon--success\" />\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Enum: status badge (auto-coloured from the property's optional colorMap) -->\n\t\t<template v-else-if=\"isEnum\">\n\t\t\t<CnStatusBadge v-if=\"value\"\n\t\t\t\t:label=\"enumLabel\"\n\t\t\t\t:colorKey=\"String(value)\"\n\t\t\t\t:colorMap=\"enumColorMap\" />\n\t\t\t<span v-else class=\"cn-cell-renderer__dash\">—</span>\n\t\t</template>\n\n\t\t<!-- Array: comma-joined or count -->\n\t\t<template v-else-if=\"propertyType === 'array'\">\n\t\t\t<span v-if=\"!value || !value.length\" class=\"cn-cell-renderer__dash\">—</span>\n\t\t\t<span v-else :title=\"Array.isArray(value) ? value.join(', ') : ''\">\n\t\t\t\t{{ formattedValue }}\n\t\t\t</span>\n\t\t</template>\n\n\t\t<!-- Default: formatted text -->\n\t\t<template v-else>\n\t\t\t<span :title=\"rawTitle\">{{ formattedValue }}</span>\n\t\t</template>\n\t</span>\n</template>\n\n<script>\nimport { getCanonicalLocale } from '@nextcloud/l10n'\nimport { NcAvatar, NcDateTime } from '@nextcloud/vue'\nimport CheckBold from 'vue-material-design-icons/CheckBold.vue'\nimport CnFkResolveCell from '../CnFkResolveCell/CnFkResolveCell.vue'\nimport CnGroupNameCell from './CnGroupNameCell.vue'\nimport { normalizeLook } from '../../composables/useLook.js'\nimport { formatAge, formatBoardDate, resolveAgeVariant } from '../../utils/boardDate.js'\nimport { parseDateValue, resolveDateVariant } from '../../utils/dateVariant.js'\nimport { safeCurrencyCode } from '../../utils/formatMetric.js'\nimport { objectFieldValue } from '../../utils/objectName.js'\nimport { safeHref } from '../../utils/safeHref.js'\nimport { formatValue, isGroupProp } from '../../utils/schema.js'\nimport { CnStatusBadge } from '../CnStatusBadge/index.js'\n\n/** A uuid in any version, the shape OpenRegister ids take. */\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\n/**\n * Module-level set of column keys already warned about for a\n * `widget:\"link\"` declaration with no resolvable target — guarantees\n * one warning per (page, column-key) rather than per row × render.\n */\nconst WARNED_LINK_KEYS = new Set()\n\n/**\n * CnCellRenderer — Type-aware cell renderer for schema-driven tables.\n *\n * Renders a single cell value based on its schema property definition.\n * Booleans render as icons, enums as status badges, dates as formatted strings,\n * and everything else as truncated text via `formatValue()`.\n *\n * ```vue\n * <CnCellRenderer :value=\"row.status\" :property=\"schema.properties.status\" />\n * ```\n */\nexport default {\n\tname: 'CnCellRenderer',\n\n\tcomponents: {\n\t\tCnStatusBadge,\n\t\tCnFkResolveCell,\n\t\tCnGroupNameCell,\n\t\tCheckBold,\n\t\tNcAvatar,\n\t\tNcDateTime,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Cell-formatter registry, provided by CnAppRoot (`cnFormatters`).\n\t\t * Map of formatter-id → `(value, row, property) => string|number`.\n\t\t * Defaults to an empty object so standalone use (no CnAppRoot\n\t\t * ancestor) is unaffected.\n\t\t */\n\t\tcnFormatters: { default: () => ({}) },\n\t\t/**\n\t\t * Cell-widget registry, provided by CnAppRoot (`cnCellWidgets`).\n\t\t * Map of widget-id → Vue component. Resolves a column's `widget` id;\n\t\t * the built-in `\"badge\"` is handled inline (no registry entry needed).\n\t\t * Defaults to an empty object.\n\t\t */\n\t\tcnCellWidgets: { default: () => ({}) },\n\t\t/**\n\t\t * Display-layer translation function, provided by CnAppRoot\n\t\t * (`cnTranslate: this.translate`, bound to the host app's id). Applied\n\t\t * to the enum badge label only — the underlying value is untouched.\n\t\t * Defaults to identity so standalone use is unaffected.\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/**\n\t\t * The look the app is drawn in, provided by CnAppRoot (or a page with\n\t\t * `config.look`). Under `board` a date cell reads the board's short\n\t\t * form (\"5 okt\"). Defaults to `nextcloud`, which renders as before.\n\t\t */\n\t\tcnLook: { default: 'nextcloud' },\n\t},\n\n\tprops: {\n\t\t/** The raw cell value */\n\t\tvalue: {\n\t\t\ttype: [Boolean, String, Number, Array, Object],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Schema property definition: { type, format, enum, items, title } */\n\t\tproperty: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Optional cell-formatter id (e.g. `currency`, `automationTrigger`).\n\t\t * When set and resolvable in the injected `cnFormatters` registry,\n\t\t * the cell renders `cnFormatters[formatter](value, row, property,\n\t\t * formatterOptions)` as text — an explicit override of the type-aware\n\t\t * rendering below.\n\t\t */\n\t\tformatter: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Declarative options map passed as the formatter's fourth argument\n\t\t * (e.g. `{ currency: 'USD' }` for the built-in `currency` formatter,\n\t\t * or `{ negative, zero, positive }` phrases for `conditionalPhrase`).\n\t\t * Undefined-safe: three-argument formatters simply ignore it.\n\t\t */\n\t\tformatterOptions: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Optional cell-widget id (e.g. `badge`, or a consumer-registered\n\t\t * name). When it resolves in `cnCellWidgets` the cell renders that\n\t\t * component with `{ value, row, property, formatted, ...widgetProps }`;\n\t\t * the built-in id `\"badge\"` renders `CnStatusBadge` and the built-in\n\t\t * id `\"fkResolve\"` renders `CnFkResolveCell` (uuid → related object\n\t\t * label, config via `widgetProps { register, schema, labelField }`),\n\t\t * and the built-in id `\"refLabel\"` shows labels already resolved in a\n\t\t * batch (`widgetProps { labels, route? }`, set by CnIndexPage for a\n\t\t * column with `labelField`).\n\t\t * The built-in id `\"avatar\"` renders a person as an avatar with the\n\t\t * name beside it (`widgetProps { userField?, user?, nameField?, size? }`;\n\t\t * a free name gets its initials), and the built-in id `\"date\"` renders\n\t\t * a date whose colour follows `widgetProps.variantWhen`, rules on the\n\t\t * number of days until the date (`[{ op: \"lt\", value: 0, variant:\n\t\t * \"error\" }, { op: \"lte\", value: 5, variant: \"warning\" }]`).\n\t\t * The built-in id `\"age\"` renders how long the row has waited since\n\t\t * the date (\"4 hours\", \"3 days\"), coloured by `widgetProps.variantWhen`\n\t\t * rules on the days it shows (`[{ op: \"gte\", value: 3, variant:\n\t\t * \"error\" }]`).\n\t\t * The built-in id `\"group\"` shows a Nextcloud group id (or a list of\n\t\t * them) as the group's display name; a column whose property is\n\t\t * marked `referenceType: \"nextcloud-group\"` gets it without asking.\n\t\t * Takes precedence over `formatter`/the type-aware rendering, but the\n\t\t * value handed to the widget is the formatter-shaped `formatted` when\n\t\t * `formatter` is also set.\n\t\t */\n\t\twidget: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Extra props spread onto the resolved cell-widget component. The\n\t\t * built-in `\"link\"` reads its target from here: `route` (a manifest\n\t\t * page id), `params` (route param to row field), `href` (URL with\n\t\t * `{field}` placeholders), and `routeField` + `routeMap` to pick the\n\t\t * page per row from a sibling field (`{ person: 'ContactDetail' }`),\n\t\t * with `route` as the fallback for a value the map does not hold.\n\t\t */\n\t\twidgetProps: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Optional declarative cell-format spec — a no-code alternative to a\n\t\t * registry `formatter`. Recognised `style` values:\n\t\t *\n\t\t * - `'currency'` → `Intl.NumberFormat` currency (e.g. `€ 1.234,56`),\n\t\t * honouring `currency` (ISO code, default `'EUR'`) and `decimals`\n\t\t * (default 2).\n\t\t * - `'number'` / `'percent'` → localized number (percent appends `%`),\n\t\t * honouring `decimals` (default 0).\n\t\t * - `'duration'` → a seconds value rendered compact (`1u 23m`, `45m 10s`,\n\t\t * `12s`); pass `unit: 'milliseconds'` / `'minutes'` / `'hours'` when the\n\t\t * raw value is not in seconds. Sub-second millisecond values render as\n\t\t * `245ms` rather than rounding down to `0s`.\n\t\t * - `'swatch'` → a colour dot read from a sibling row field named by\n\t\t * `colorField` (the value renders as the cell text beside it).\n\t\t *\n\t\t * `prefix` / `suffix` are prepended/appended to the numeric styles.\n\t\t * Resolved AFTER `formatter` / `widget` (those win), but BEFORE the\n\t\t * type-aware rendering, so a manifest column can opt into currency or a\n\t\t * colour swatch without registering a function.\n\t\t *\n\t\t * @type {{style?: 'currency'|'number'|'percent'|'duration'|'swatch', currency?: string, decimals?: number, unit?: 'milliseconds'|'seconds'|'minutes'|'hours', prefix?: string, suffix?: string, colorField?: string}}\n\t\t */\n\t\tformat: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The full row object — passed so a formatter can be a function of\n\t\t * the whole record (e.g. \"days since `@self.updated`\"), not just\n\t\t * this one cell value.\n\t\t */\n\t\trow: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Maximum string length before truncation */\n\t\ttruncate: {\n\t\t\ttype: Number,\n\t\t\tdefault: 100,\n\t\t},\n\n\t\t/**\n\t\t * Row identifier field — used by the built-in `widget:\"link\"` when\n\t\t * the manifest doesn't specify an explicit `widgetProps.params`\n\t\t * map. Defaults to `'id'` so router-link param resolution works\n\t\t * with the manifest convention (`/x/:id`).\n\t\t */\n\t\trowKey: {\n\t\t\ttype: String,\n\t\t\tdefault: 'id',\n\t\t},\n\t},\n\n\tcomputed: {\n\t\tpropertyType() {\n\t\t\treturn this.property?.type || (typeof this.value)\n\t\t},\n\n\t\tisEnum() {\n\t\t\treturn !!(this.property?.enum && this.property.enum.length > 0)\n\t\t},\n\n\t\t/**\n\t\t * Badge text for an enum cell. Schema enum values are English source\n\t\t * codes, so a Dutch session otherwise reads `submitted` in a table whose\n\t\t * headers are Dutch. Only the label is translated — the cell's value,\n\t\t * sorting and filtering keep using the raw code.\n\t\t */\n\t\tenumLabel() {\n\t\t\tconst raw = String(this.value)\n\t\t\tconst labels = (this.property && (this.property.enumLabels || this.property['x-enum-labels'])) || {}\n\t\t\treturn this.cnTranslate(labels[raw] || raw)\n\t\t},\n\n\t\t/** True when the property is a date / date-time (rendered via NcDateTime). */\n\t\tisDate() {\n\t\t\treturn this.property?.format === 'date-time' || this.property?.format === 'date'\n\t\t},\n\n\t\t/**\n\t\t * The cell value as a Date for NcDateTime, or `null` when absent or\n\t\t * unparseable (the cell then falls back to a dash / plain text).\n\t\t *\n\t\t * @return {Date|null}\n\t\t */\n\t\tdateTimestamp() {\n\t\t\tif (!this.hasValue) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst date = new Date(this.value)\n\t\t\treturn Number.isNaN(date.getTime()) ? null : date\n\t\t},\n\n\t\t/**\n\t\t * `avatar` widget: the Nextcloud user id whose avatar to show, or ''\n\t\t * for a free name. Read from the row field `widgetProps.userField`,\n\t\t * or from the cell value itself when `widgetProps.user` is true.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t */\n\t\tavatarUserId() {\n\t\t\tconst props = this.widgetProps || {}\n\t\t\tlet id = ''\n\t\t\tif (typeof props.userField === 'string' && props.userField !== '') {\n\t\t\t\tid = objectFieldValue(this.row, props.userField)\n\t\t\t} else if (props.user === true) {\n\t\t\t\tid = this.value\n\t\t\t}\n\t\t\treturn (typeof id === 'string' || typeof id === 'number') ? String(id) : ''\n\t\t},\n\n\t\t/**\n\t\t * `avatar` widget: the name shown beside the picture. Read from the\n\t\t * row field `widgetProps.nameField` when set, else the cell value.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t */\n\t\tavatarName() {\n\t\t\tconst props = this.widgetProps || {}\n\t\t\tif (typeof props.nameField === 'string' && props.nameField !== '') {\n\t\t\t\tconst name = objectFieldValue(this.row, props.nameField)\n\t\t\t\tif (typeof name === 'string' && name !== '') {\n\t\t\t\t\treturn name\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!this.hasValue || typeof this.value === 'object') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn String(this.hasFormatter ? this.formattedValue : this.value)\n\t\t},\n\n\t\t/**\n\t\t * `avatar` widget: the initials of a free name, at most two letters\n\t\t * (first and last word).\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t */\n\t\tavatarInitials() {\n\t\t\tconst words = this.avatarName.trim().split(/\\s+/).filter((word) => word !== '')\n\t\t\tif (words.length === 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst first = Array.from(words[0])[0] || ''\n\t\t\tconst last = words.length > 1 ? (Array.from(words[words.length - 1])[0] || '') : ''\n\t\t\treturn (first + last).toLocaleUpperCase()\n\t\t},\n\n\t\t/**\n\t\t * `avatar` widget: the picture size in pixels (`widgetProps.size`, default 24).\n\t\t *\n\t\t * @return {number}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t */\n\t\tavatarSize() {\n\t\t\tconst size = Number(this.widgetProps && this.widgetProps.size)\n\t\t\treturn Number.isFinite(size) && size > 0 ? size : 24\n\t\t},\n\n\t\t/**\n\t\t * `date` widget: the variant of the first `widgetProps.variantWhen`\n\t\t * rule the date matches, or '' for none.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t */\n\t\tdateVariant() {\n\t\t\tconst rules = this.widgetProps && this.widgetProps.variantWhen\n\t\t\tconst variant = resolveDateVariant(this.value, rules)\n\t\t\treturn variant === 'default' ? '' : variant\n\t\t},\n\n\t\t/**\n\t\t * Whether the app takes the board look (`cnLook` is `board`).\n\t\t *\n\t\t * @return {boolean}\n\t\t * @spec openspec/changes/screens-cell-date-parity/specs/cell-date-age/spec.md#requirement-a-board-date-cell-reads-day-and-short-month-in-the-user-language\n\t\t */\n\t\tisBoardLook() {\n\t\t\treturn normalizeLook(this.cnLook) === 'board'\n\t\t},\n\n\t\t/**\n\t\t * The board's short date (\"5 okt\", \"14 feb 2024\" outside this year).\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/screens-cell-date-parity/specs/cell-date-age/spec.md#requirement-a-board-date-cell-reads-day-and-short-month-in-the-user-language\n\t\t */\n\t\tboardDateLabel() {\n\t\t\treturn formatBoardDate(this.value)\n\t\t},\n\n\t\t/**\n\t\t * The full date for a tooltip: day, month and year in the user's\n\t\t * locale, with the time for a date-time value.\n\t\t *\n\t\t * @return {string|undefined}\n\t\t * @spec openspec/changes/screens-cell-date-parity/specs/cell-date-age/spec.md#requirement-an-age-cell-says-how-long-something-has-waited\n\t\t */\n\t\tabsoluteDateLabel() {\n\t\t\tconst date = parseDateValue(this.value)\n\t\t\tif (date === null) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tconst withTime = this.property?.format === 'date-time' || this.widget === 'age'\n\t\t\tconst options = { day: 'numeric', month: 'long', year: 'numeric', ...(withTime ? { hour: '2-digit', minute: '2-digit' } : {}) }\n\t\t\ttry {\n\t\t\t\treturn new Intl.DateTimeFormat(getCanonicalLocale() || undefined, options).format(date)\n\t\t\t} catch {\n\t\t\t\treturn new Intl.DateTimeFormat(undefined, options).format(date)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * `age` widget: how long the row has waited (\"4 uur\", \"3 dagen\").\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/screens-cell-date-parity/specs/cell-date-age/spec.md#requirement-an-age-cell-says-how-long-something-has-waited\n\t\t */\n\t\tageLabel() {\n\t\t\treturn formatAge(this.value)\n\t\t},\n\n\t\t/**\n\t\t * `age` widget: the variant of the first `widgetProps.variantWhen`\n\t\t * rule the shown days match, or '' for none.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/screens-cell-date-parity/specs/cell-date-age/spec.md#requirement-an-age-cell-turns-red-past-its-threshold\n\t\t */\n\t\tageVariant() {\n\t\t\tconst variant = resolveAgeVariant(this.value, this.widgetProps && this.widgetProps.variantWhen)\n\t\t\treturn variant === 'default' ? '' : variant\n\t\t},\n\n\t\t/**\n\t\t * `date` widget: the date written out in the user's locale.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-small-opt-ins-from-the-decidiq-and-learniq-lanes\n\t\t */\n\t\tdateLabel() {\n\t\t\tconst date = parseDateValue(this.value)\n\t\t\tif (date === null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\t// `widgetProps.showTime: true` adds the time of day (\"5 Oct 2026,\n\t\t\t// 08:30\"); `widgetProps.timeOnly: true` shows just the time\n\t\t\t// (\"08:30\"), for a timetable row. Default: the date alone.\n\t\t\tconst props = this.widgetProps || {}\n\t\t\t// The board look writes a plain date in its short form (\"5 okt\");\n\t\t\t// a time of day keeps the full form below.\n\t\t\tif (this.isBoardLook && props.timeOnly !== true && props.showTime !== true) {\n\t\t\t\treturn formatBoardDate(date)\n\t\t\t}\n\t\t\tconst options = props.timeOnly === true\n\t\t\t\t? { hour: '2-digit', minute: '2-digit' }\n\t\t\t\t: { day: 'numeric', month: 'short', year: 'numeric', ...(props.showTime === true ? { hour: '2-digit', minute: '2-digit' } : {}) }\n\t\t\tlet locale\n\t\t\ttry {\n\t\t\t\tlocale = getCanonicalLocale()\n\t\t\t} catch {\n\t\t\t\tlocale = undefined\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn new Intl.DateTimeFormat(locale || undefined, options).format(date)\n\t\t\t} catch {\n\t\t\t\treturn new Intl.DateTimeFormat(undefined, options).format(date)\n\t\t\t}\n\t\t},\n\n\t\t/** True when the property is a URI / URL (rendered as an external link). */\n\t\tisUri() {\n\t\t\treturn this.property?.format === 'uri' || this.property?.format === 'url'\n\t\t},\n\n\t\t/**\n\t\t * Safe external href for a URI/URL cell, or `null` when the value is\n\t\t * absent or fails `safeHref` validation (e.g. an unsafe scheme).\n\t\t *\n\t\t * @return {string|null}\n\t\t */\n\t\turiHref() {\n\t\t\tif (!this.hasValue) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn safeHref(String(this.value))\n\t\t},\n\n\t\t/** True when the cell has a renderable value (not null/undefined/empty string). */\n\t\thasValue() {\n\t\t\treturn this.value !== null && this.value !== undefined && this.value !== ''\n\t\t},\n\n\t\t/**\n\t\t * Resolved cell-widget component for this column, or `null`. A column's\n\t\t * `widget` id resolves against the injected `cnCellWidgets` registry;\n\t\t * the built-in `\"badge\"` is NOT resolved here (handled inline in the\n\t\t * template) so apps can still override `\"badge\"` via the registry.\n\t\t *\n\t\t * @return {import('vue').Component|null}\n\t\t */\n\t\twidgetComponent() {\n\t\t\tif (!this.widget) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst c = this.cnCellWidgets && this.cnCellWidgets[this.widget]\n\t\t\treturn c || null\n\t\t},\n\n\t\t/**\n\t\t * Whether this cell shows Nextcloud group names: the column asks for\n\t\t * `widget: \"group\"`, or it names no widget and no formatter and its\n\t\t * property is a group (or a list of groups).\n\t\t *\n\t\t * @spec openspec/changes/nextcloud-group-surfaces/specs/data-display/spec.md#requirement-a-group-cell-shows-the-groups-display-name\n\t\t * @return {boolean}\n\t\t */\n\t\tisGroupCell() {\n\t\t\tif (this.widget === 'group') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (this.widget || this.hasFormatter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst p = this.property\n\t\t\tif (!p || typeof p !== 'object') {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn isGroupProp(p) || (p.type === 'array' && isGroupProp(p.items))\n\t\t},\n\n\t\t/**\n\t\t * The group ids in this cell, empty ones dropped.\n\t\t *\n\t\t * @spec openspec/changes/nextcloud-group-surfaces/specs/data-display/spec.md#requirement-a-group-cell-shows-the-groups-display-name\n\t\t * @return {string[]}\n\t\t */\n\t\tgroupIds() {\n\t\t\tconst raw = this.value\n\t\t\tconst list = Array.isArray(raw) ? raw : [raw]\n\t\t\treturn list\n\t\t\t\t.filter((gid) => (typeof gid === 'string' && gid !== '') || typeof gid === 'number')\n\t\t\t\t.map((gid) => String(gid))\n\t\t},\n\n\t\t/**\n\t\t * The text a built-in widget (`badge`, `link`) or a swatch shows. An\n\t\t * enum value reads its label the way the plain enum cell does\n\t\t * (`enumLabel`: `x-enum-labels`, translated), so a list says \"Active\"\n\t\t * where the detail page does, not the stored \"active\". A column\n\t\t * formatter still wins: an app that shapes the value itself gets\n\t\t * exactly what its formatter returns.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/cell-labels-and-draft-indicator/specs/cell-labels-and-draft-indicator/spec.md#requirement-a-built-in-cell-widget-shows-an-enum-value-by-its-label\n\t\t */\n\t\tlabelledValue() {\n\t\t\tif (!this.hasFormatter && this.isEnum && this.hasValue && typeof this.value !== 'object') {\n\t\t\t\treturn this.enumLabel\n\t\t\t}\n\t\t\treturn String(this.formattedValue)\n\t\t},\n\n\t\t/**\n\t\t * The key the built-in `badge` looks its colour up by: the raw value\n\t\t * when `widgetProps.colorMap` has an entry for it (case-insensitive),\n\t\t * so a translated label keeps the colour the manifest keyed on the\n\t\t * stored code. Otherwise '' and the badge looks up its label, as before,\n\t\t * which keeps a map keyed on a formatter's output working.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/cell-labels-and-draft-indicator/specs/cell-labels-and-draft-indicator/spec.md#requirement-a-built-in-cell-widget-shows-an-enum-value-by-its-label\n\t\t */\n\t\tbadgeColorKey() {\n\t\t\tconst map = this.badgeColorMap\n\t\t\tif (!map || !this.hasValue || typeof this.value === 'object') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst raw = String(this.value).toLowerCase()\n\t\t\treturn Object.keys(map).some((key) => key.toLowerCase() === raw) ? String(this.value) : ''\n\t\t},\n\n\t\t/** Variant for the built-in `badge` widget — `widgetProps.variant` or `'default'`. */\n\t\tbadgeVariant() {\n\t\t\treturn (this.widgetProps && this.widgetProps.variant) || 'default'\n\t\t},\n\n\t\t/**\n\t\t * Color map for the built-in `badge` widget — `widgetProps.colorMap`,\n\t\t * a `{ value: variant }` map (e.g. `{ placed: 'primary', delivered: 'success' }`)\n\t\t * that CnStatusBadge resolves per label. Null when unset (falls back to\n\t\t * `badgeVariant`). Lets a manifest colour a status column without code.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tbadgeColorMap() {\n\t\t\treturn (this.widgetProps && this.widgetProps.colorMap) || null\n\t\t},\n\n\t\t/**\n\t\t * Color map for the auto-rendered enum badge — read from the schema\n\t\t * property's optional `colorMap` (or `x-color-map`). Null when unset, so\n\t\t * enum cells stay the default grey unless the schema opts into colours.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tenumColorMap() {\n\t\t\treturn (this.property && (this.property.colorMap || this.property['x-color-map'])) || null\n\t\t},\n\n\t\t/**\n\t\t * The manifest page id the built-in `widget:\"link\"` routes this row\n\t\t * to, or null.\n\t\t *\n\t\t * `widgetProps.routeField` names a sibling field on the row, and\n\t\t * `widgetProps.routeMap` maps that field's values to page ids, so one\n\t\t * column can link a person to `ContactDetail` and an organisation to\n\t\t * `OrganisationDetail` off `initiatorType`. A row whose value has no\n\t\t * entry in the map falls back to the fixed `widgetProps.route`, and\n\t\t * without one the cell renders as text. The map is the whole\n\t\t * vocabulary: a row value is only ever used as a KEY into it, never\n\t\t * as a route name itself, so row data cannot send a link to a page\n\t\t * the manifest did not name.\n\t\t *\n\t\t * @return {string|null} The page id, or null when none resolves.\n\t\t */\n\t\tlinkRouteName() {\n\t\t\tconst wp = this.widgetProps || {}\n\t\t\tconst map = wp.routeMap\n\t\t\tif (typeof wp.routeField === 'string' && wp.routeField !== '' && map && typeof map === 'object') {\n\t\t\t\tconst key = this.row ? this.row[wp.routeField] : undefined\n\t\t\t\tif (key !== undefined && key !== null && Object.hasOwn(map, String(key))) {\n\t\t\t\t\tconst mapped = map[String(key)]\n\t\t\t\t\tif (typeof mapped === 'string' && mapped !== '') {\n\t\t\t\t\t\treturn mapped\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (typeof wp.route === 'string' && wp.route !== '') ? wp.route : null\n\t\t},\n\n\t\t/**\n\t\t * Items of the built-in `widget:\"refLabel\"`: one per referenced id with\n\t\t * its text, state (`label`, `loading` or `missing`) and optional link.\n\t\t *\n\t\t * @return {Array<{id: string, text: string, state: string, to: (object|null)}>}\n\t\t */\n\t\trefLabelItems() {\n\t\t\tif (this.widget !== 'refLabel') {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst wp = this.widgetProps || {}\n\t\t\tconst labels = wp.labels || {}\n\t\t\tconst raw = this.value\n\t\t\tconst list = Array.isArray(raw) ? raw : [raw]\n\t\t\treturn list\n\t\t\t\t.filter((id) => id !== null && id !== undefined && id !== '')\n\t\t\t\t.map((id) => {\n\t\t\t\t\tconst key = String(id)\n\t\t\t\t\tconst known = Object.hasOwn(labels, key)\n\t\t\t\t\tconst label = known ? labels[key] : undefined\n\t\t\t\t\tconst state = !known ? 'loading' : (label ? 'label' : 'missing')\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: key,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\ttext: state === 'label' ? label : (state === 'loading' ? '…' : key),\n\t\t\t\t\t\tto: (state === 'label' && typeof wp.route === 'string' && wp.route !== '') ? { name: wp.route, params: { id: key } } : null,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Resolved router-link target for the built-in `widget:\"link\"`. When\n\t\t * a page id resolves (`widgetProps.route`, or the row's entry in\n\t\t * `widgetProps.routeMap`, see `linkRouteName`), returns\n\t\t * `{ name: route, params }`. Param map is `widgetProps.params`\n\t\t * (a map of route-param-name → row-field-name); when omitted,\n\t\t * defaults to `{ id: row[rowKey] }`. Returns null when no page id\n\t\t * resolves (the template falls through to `linkHref` or plain\n\t\t * text).\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tlinkRoute() {\n\t\t\tif (this.widget !== 'link') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst route = this.linkRouteName\n\t\t\tif (!route) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst paramMap = (this.widgetProps && this.widgetProps.params)\n\t\t\t\t|| { id: this.rowKey || 'id' }\n\t\t\tconst params = {}\n\t\t\tfor (const [routeParam, rowField] of Object.entries(paramMap)) {\n\t\t\t\tparams[routeParam] = this.row && this.row[rowField]\n\t\t\t}\n\t\t\treturn { name: route, params }\n\t\t},\n\n\t\t/**\n\t\t * Resolved external href for the built-in `widget:\"link\"` when\n\t\t * `widgetProps.href` is set. `{key}` placeholders in the href\n\t\t * are substituted from the row (`\"/x/{id}\"` + `row.id === \"42\"`\n\t\t * → `\"/x/42\"`). The final computed value is validated with\n\t\t * `safeHref` so row-injected values cannot introduce unsafe\n\t\t * schemes: a `javascript:` or `data:` result renders as plain text\n\t\t * instead of a link. Returns null when `href` isn't set.\n\t\t *\n\t\t * @return {string|null}\n\t\t */\n\t\tlinkHref() {\n\t\t\tif (this.widget !== 'link') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst href = this.widgetProps && this.widgetProps.href\n\t\t\tif (!href) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst resolved = String(href).replace(/\\{(\\w+)\\}/g, (_, key) => this.row && this.row[key] !== null && this.row[key] !== undefined ? String(this.row[key]) : '')\n\t\t\t// The safeHref retrofit (18700fd94) put this check here and a later\n\t\t\t// lint pass (e5ea00d51) dropped it, leaving the docblock above\n\t\t\t// promising a check the code no longer made: a template of `{url}`\n\t\t\t// put a row's `javascript:` value straight into `:href`. safeHref\n\t\t\t// answers '#' for anything unsafe; that is not a link worth\n\t\t\t// rendering, so fall through to plain text.\n\t\t\tconst safe = safeHref(resolved)\n\t\t\treturn safe === '#' ? null : safe\n\t\t},\n\n\t\t/**\n\t\t * Resolved formatter function for this cell, or `null`. A column's\n\t\t * `formatter` id resolves against the injected `cnFormatters` registry.\n\t\t *\n\t\t * @return {((value: unknown, row: object, property: object, options: object) => unknown)|null}\n\t\t */\n\t\tformatterFn() {\n\t\t\tconst fn = this.formatter && this.cnFormatters && this.cnFormatters[this.formatter]\n\t\t\treturn typeof fn === 'function' ? fn : null\n\t\t},\n\n\t\t/** True when an explicit formatter is in play for this cell. */\n\t\thasFormatter() {\n\t\t\treturn this.formatterFn !== null\n\t\t},\n\n\t\t/**\n\t\t * The declarative format `style`, or null when no (recognised) `format`\n\t\t * spec is set. Drives the built-in currency / duration / number / percent\n\t\t * / swatch rendering paths.\n\t\t *\n\t\t * @return {string|null}\n\t\t */\n\t\tformatStyle() {\n\t\t\tconst s = this.format && this.format.style\n\t\t\treturn typeof s === 'string' ? s : null\n\t\t},\n\n\t\t/** True when a built-in NUMERIC format (currency/number/percent/duration) applies. */\n\t\thasBuiltinFormat() {\n\t\t\treturn ['currency', 'number', 'percent', 'duration'].includes(this.formatStyle)\n\t\t},\n\n\t\t/** True when this cell renders as a colour swatch (`format.style:\"swatch\"`). */\n\t\tisSwatch() {\n\t\t\treturn this.formatStyle === 'swatch'\n\t\t},\n\n\t\t/**\n\t\t * The swatch colour — read from the sibling row field named by\n\t\t * `format.colorField` (default `'color'`). Returns null when no usable\n\t\t * colour string is present (the dot is then omitted).\n\t\t *\n\t\t * @return {string|null}\n\t\t */\n\t\tswatchColor() {\n\t\t\tif (!this.isSwatch) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst field = (this.format && this.format.colorField) || 'color'\n\t\t\tconst c = this.row && this.row[field]\n\t\t\treturn (typeof c === 'string' && c.trim() !== '') ? c : null\n\t\t},\n\n\t\tformattedValue() {\n\t\t\tif (this.formatterFn) {\n\t\t\t\ttry {\n\t\t\t\t\treturn this.formatterFn(this.value, this.row, this.property, this.formatterOptions || undefined)\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnCellRenderer] formatter \"${this.formatter}\" threw; falling back`, e)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.hasBuiltinFormat) {\n\t\t\t\treturn this.applyBuiltinFormat()\n\t\t\t}\n\t\t\treturn formatValue(this.value, this.property, { truncate: this.truncate })\n\t\t},\n\n\t\trawTitle() {\n\t\t\t// Show full value on hover if it was truncated\n\t\t\tconst raw = this.value\n\t\t\tif (typeof raw === 'string' && raw.length > this.truncate) {\n\t\t\t\treturn raw\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\n\t\t/**\n\t\t * Whether the cell draws a uuid, and so takes the monospace uuid\n\t\t * style. The property's `format: \"uuid\"` alone used to decide this,\n\t\t * so a reference that a formatter or a widget had resolved to its\n\t\t * name was still drawn as code. Now the value has to be a uuid AND\n\t\t * nothing resolves it: a resolving widget or formatter, or a value\n\t\t * that is not a uuid, renders in the normal text style.\n\t\t *\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-a-resolved-reference-is-not-drawn-as-a-uuid\n\t\t * @return {boolean}\n\t\t */\n\t\tshowsUuid() {\n\t\t\tif (this.property?.format !== 'uuid') {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (this.widgetComponent || this.widget || this.hasFormatter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn typeof this.value === 'string' && UUID_PATTERN.test(this.value)\n\t\t},\n\n\t\tcellClass() {\n\t\t\tconst classes = []\n\t\t\tif (this.propertyType === 'boolean') {\n\t\t\t\tclasses.push('cn-cell-renderer--boolean')\n\t\t\t}\n\t\t\tif (this.isEnum) {\n\t\t\t\tclasses.push('cn-cell-renderer--enum')\n\t\t\t}\n\t\t\tif (this.property?.format === 'date-time' || this.property?.format === 'date') {\n\t\t\t\tclasses.push('cn-cell-renderer--date')\n\t\t\t}\n\t\t\tif (this.showsUuid) {\n\t\t\t\tclasses.push('cn-cell-renderer--uuid')\n\t\t\t}\n\t\t\tif (this.propertyType === 'integer' || this.propertyType === 'number') {\n\t\t\t\tclasses.push('cn-cell-renderer--number')\n\t\t\t}\n\t\t\treturn classes\n\t\t},\n\t},\n\n\tmounted() {\n\t\t// Warn once per column-property-name when `widget:\"link\"` resolves\n\t\t// to neither a `route` nor an `href` — silent fallback hides\n\t\t// manifest mistakes, an every-row warn is too noisy.\n\t\t// A column with a `routeMap` has declared its targets; a row whose\n\t\t// value is not in the map (an empty requester, say) is data, not a\n\t\t// manifest mistake, so it renders as text without the warning. The\n\t\t// same holds for a declared `href` whose resolved value safeHref\n\t\t// refused: the manifest is fine, the row value is not.\n\t\tif (\n\t\t\tthis.widget === 'link'\n\t\t\t&& !this.linkRoute\n\t\t\t&& !this.widgetProps?.href\n\t\t\t&& this.widgetProps?.fallback !== 'silent'\n\t\t\t&& !(this.widgetProps?.routeMap && typeof this.widgetProps.routeMap === 'object')\n\t\t) {\n\t\t\tconst key = this.property?.title || String(this.value).slice(0, 20)\n\t\t\tif (!WARNED_LINK_KEYS.has(key)) {\n\t\t\t\tWARNED_LINK_KEYS.add(key)\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnCellRenderer] widget:\"link\" on \"${key}\" has no resolvable target — set widgetProps.route (page id) or widgetProps.href (URL with optional {field} placeholders); cell falls back to plain text.`)\n\t\t\t}\n\t\t}\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Render the cell value per the declarative `format` spec (currency /\n\t\t * number / percent / duration). Mirrors CnStatWidget's formatting so a\n\t\t * KPI tile and a table column read identically. Non-numeric values fall\n\t\t * back to `formatValue`; an empty value renders an em-dash.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tapplyBuiltinFormat() {\n\t\t\tif (!this.hasValue) {\n\t\t\t\treturn '—'\n\t\t\t}\n\t\t\tconst fmt = this.format || {}\n\t\t\tif (fmt.style === 'duration') {\n\t\t\t\treturn this.formatDuration()\n\t\t\t}\n\t\t\tconst num = Number(this.value)\n\t\t\tif (!Number.isFinite(num)) {\n\t\t\t\treturn formatValue(this.value, this.property, { truncate: this.truncate })\n\t\t\t}\n\t\t\tconst decimals = Number.isFinite(fmt.decimals)\n\t\t\t\t? fmt.decimals\n\t\t\t\t: (fmt.style === 'currency' ? 2 : 0)\n\t\t\tlet body\n\t\t\tif (fmt.style === 'currency') {\n\t\t\t\tbody = new Intl.NumberFormat(undefined, {\n\t\t\t\t\tstyle: 'currency',\n\t\t\t\t\tcurrency: safeCurrencyCode(fmt.currency),\n\t\t\t\t\tminimumFractionDigits: decimals,\n\t\t\t\t\tmaximumFractionDigits: decimals,\n\t\t\t\t}).format(num)\n\t\t\t} else if (fmt.style === 'percent') {\n\t\t\t\t// Values are stored as the literal percent (83.3), not a 0–1 ratio.\n\t\t\t\tbody = new Intl.NumberFormat(undefined, {\n\t\t\t\t\tminimumFractionDigits: decimals,\n\t\t\t\t\tmaximumFractionDigits: decimals,\n\t\t\t\t}).format(num) + '%'\n\t\t\t} else {\n\t\t\t\tbody = new Intl.NumberFormat(undefined, {\n\t\t\t\t\tminimumFractionDigits: decimals,\n\t\t\t\t\tmaximumFractionDigits: decimals,\n\t\t\t\t}).format(num)\n\t\t\t}\n\t\t\treturn `${fmt.prefix || ''}${body}${fmt.suffix || ''}`\n\t\t},\n\n\t\t/**\n\t\t * Render a numeric duration compactly (`1u 23m`, `45m 10s`, `12s`). The\n\t\t * raw value is seconds unless `format.unit` is `'milliseconds'` /\n\t\t * `'minutes'` / `'hours'`. The hour suffix is `u` (uur) to read naturally\n\t\t * under NL theming while staying digit-led for other locales.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tformatDuration() {\n\t\t\tconst fmt = this.format || {}\n\t\t\tlet secs = Number(this.value)\n\t\t\tif (!Number.isFinite(secs)) {\n\t\t\t\treturn formatValue(this.value, this.property, { truncate: this.truncate })\n\t\t\t}\n\t\t\tif (fmt.unit === 'milliseconds') {\n\t\t\t\t// Sub-second durations are the common case for a millisecond\n\t\t\t\t// field (request/step timings), and they would all collapse to\n\t\t\t\t// the `0s` floor below — so render them in ms directly.\n\t\t\t\tconst ms = Math.round(secs)\n\t\t\t\tif (Math.abs(ms) < 1000) {\n\t\t\t\t\treturn `${fmt.prefix || ''}${ms}ms${fmt.suffix || ''}`\n\t\t\t\t}\n\t\t\t\tsecs = ms / 1000\n\t\t\t} else if (fmt.unit === 'minutes') {\n\t\t\t\tsecs *= 60\n\t\t\t} else if (fmt.unit === 'hours') {\n\t\t\t\tsecs *= 3600\n\t\t\t}\n\t\t\tsecs = Math.round(secs)\n\t\t\tconst sign = secs < 0 ? '-' : ''\n\t\t\tsecs = Math.abs(secs)\n\t\t\tconst h = Math.floor(secs / 3600)\n\t\t\tconst m = Math.floor((secs % 3600) / 60)\n\t\t\tconst s = secs % 60\n\t\t\tconst parts = []\n\t\t\tif (h > 0) {\n\t\t\t\tparts.push(`${h}u`)\n\t\t\t}\n\t\t\tif (m > 0) {\n\t\t\t\tparts.push(`${m}m`)\n\t\t\t}\n\t\t\tif (s > 0 && h === 0) {\n\t\t\t\tparts.push(`${s}s`)\n\t\t\t}\n\t\t\tif (parts.length === 0) {\n\t\t\t\tparts.push('0s')\n\t\t\t}\n\t\t\treturn `${fmt.prefix || ''}${sign}${parts.join(' ')}${fmt.suffix || ''}`\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-cell-renderer__mono {\n\tfont-family: monospace;\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-cell-renderer--uuid {\n\tfont-family: monospace;\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-cell-renderer--number {\n\tfont-variant-numeric: tabular-nums;\n}\n\n.cn-cell-renderer--date {\n\twhite-space: nowrap;\n}\n\n.cn-cell-renderer__dash {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-cell-renderer__avatar {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 8px;\n\tmax-width: 100%;\n\tvertical-align: middle;\n}\n\n.cn-cell-renderer__avatar-picture {\n\tdisplay: inline-flex;\n\tflex: none;\n}\n\n.cn-cell-renderer__avatar-initials {\n\tdisplay: inline-flex;\n\tflex: none;\n\talign-items: center;\n\tjustify-content: center;\n\tborder-radius: 50%;\n\tbackground-color: var(--color-primary-element-light);\n\tcolor: var(--color-primary-element-light-text);\n\tfont-size: 0.75em;\n\tfont-weight: 700;\n\tline-height: 1;\n}\n\n.cn-cell-renderer__avatar-name {\n\tmin-width: 0;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n/* A date that matched a rule is also set in a heavier weight, so the signal\n does not rest on colour alone. */\n.cn-cell-renderer__date--success,\n.cn-cell-renderer__date--warning,\n.cn-cell-renderer__date--error,\n.cn-cell-renderer__age--success,\n.cn-cell-renderer__age--warning,\n.cn-cell-renderer__age--error {\n\tfont-weight: 600;\n}\n\n.cn-cell-renderer__age {\n\twhite-space: nowrap;\n}\n\n.cn-cell-renderer__age--success {\n\tcolor: var(--color-text-success, var(--color-success-text));\n}\n\n.cn-cell-renderer__age--warning {\n\tcolor: var(--color-text-warning, var(--color-warning-text));\n}\n\n.cn-cell-renderer__age--error {\n\tcolor: var(--color-text-error, var(--color-error-text));\n}\n\n.cn-cell-renderer__date--success {\n\tcolor: var(--color-text-success, var(--color-success-text));\n}\n\n.cn-cell-renderer__date--warning {\n\tcolor: var(--color-text-warning, var(--color-warning-text));\n}\n\n.cn-cell-renderer__date--error {\n\tcolor: var(--color-text-error, var(--color-error-text));\n}\n\n/* The text variant, not the fill: from Nextcloud 32 `--color-success` is a\n background colour and too pale for a 16px glyph on a light theme. */\n.cn-cell-renderer__icon--success {\n\tcolor: var(--color-text-success, var(--color-success-text, var(--color-success)));\n}\n\n.cn-cell-renderer__swatch-wrap {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 8px;\n}\n\n.cn-cell-renderer__swatch-dot {\n\tdisplay: inline-block;\n\twidth: 12px;\n\theight: 12px;\n\tborder-radius: 50%;\n\tflex-shrink: 0;\n\tborder: 1px solid var(--color-border-dark);\n}\n</style>\n"],"names":["CnStatusBadge","CnFkResolveCell","CnGroupNameCell"],"mappings":"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"}
|