@conduction/nextcloud-vue 2.135.0 → 2.136.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.
Files changed (63) hide show
  1. package/dist/esm/components/CnActionDialog/CnActionDialog.vue.js +1 -1
  2. package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js +2 -1
  3. package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js.map +1 -1
  4. package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js +65 -50
  5. package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js.map +1 -1
  6. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue.js +1 -1
  7. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +6 -0
  8. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
  9. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js +9 -1
  10. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
  11. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue.js +1 -1
  12. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js.map +1 -1
  13. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js +4 -11
  14. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js.map +1 -1
  15. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +12 -0
  16. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  17. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +1 -1
  18. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  19. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +11 -0
  20. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  21. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +1 -1
  22. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  23. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +3 -1
  24. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  25. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +2 -1
  26. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  27. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  28. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +18 -0
  29. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  30. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +38 -23
  31. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  32. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue.js +1 -1
  33. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue2.js.map +1 -1
  34. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue3.js.map +1 -1
  35. package/dist/esm/composables/indexSources.js +69 -3
  36. package/dist/esm/composables/indexSources.js.map +1 -1
  37. package/dist/esm/l10n/en.json.js +20 -20
  38. package/dist/esm/l10n/nl.json.js +21 -21
  39. package/dist/esm/library-style.js +1 -1
  40. package/dist/esm/nextcloud-vue.css +322 -164
  41. package/dist/esm/utils/widgetDispatch.js +3 -1
  42. package/dist/esm/utils/widgetDispatch.js.map +1 -1
  43. package/dist/nextcloud-vue.cjs.js +739 -589
  44. package/dist/nextcloud-vue.cjs.js.map +2 -2
  45. package/dist/nextcloud-vue.css +322 -164
  46. package/l10n/en.json +20 -20
  47. package/l10n/nl.json +21 -21
  48. package/package.json +1 -1
  49. package/src/components/CnActionDialog/CnActionDialog.vue +45 -4
  50. package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +15 -0
  51. package/src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue +2 -10
  52. package/src/components/CnDataTable/CnDataTable.md +1 -0
  53. package/src/components/CnDataTable/CnDataTable.vue +13 -1
  54. package/src/components/CnDetailPage/CnDetailPage.md +1 -0
  55. package/src/components/CnDetailPage/CnDetailPage.vue +12 -1
  56. package/src/components/CnIndexPage/CnIndexPage.vue +4 -1
  57. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +38 -2
  58. package/src/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue +7 -0
  59. package/src/composables/indexSources.js +69 -3
  60. package/src/css/look-board-detail.css +47 -1
  61. package/src/css/look-board-index.css +26 -1
  62. package/src/css/look-board.css +46 -3
  63. package/src/utils/widgetDispatch.js +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CnAuditTrailWidget.vue2.js","sources":["../../../../src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div\n\t\tv-if=\"resolvedScope === 'app' || resolvedSource || resolvedEndpoint || (resolvedRegister && resolvedSchema && resolvedObjectId)\"\n\t\tclass=\"cn-audit-trail-widget\">\n\t\t<CnAuditTrailCard\n\t\t\t:source=\"resolvedSource\"\n\t\t\t:endpoint=\"resolvedEndpoint\"\n\t\t\t:register=\"resolvedRegister\"\n\t\t\t:schema=\"resolvedSchema\"\n\t\t\t:objectId=\"resolvedObjectId\"\n\t\t\t:scope=\"resolvedScope\"\n\t\t\t:title=\"resolvedTitle\"\n\t\t\t:maxDisplay=\"resolvedMaxDisplay\"\n\t\t\t:excludeActions=\"resolvedExcludeActions\"\n\t\t\t:actionLabels=\"actionLabels\"\n\t\t\t:valueLabels=\"valueLabels\"\n\t\t\t:relatedSources=\"relatedSources\"\n\t\t\tv-bind=\"emptyText ? { noEntriesLabel: emptyText } : {}\" />\n\t\t<p v-if=\"footnote\" class=\"cn-audit-trail-widget__footnote\" data-testid=\"cn-audit-trail-widget-footnote\">\n\t\t\t{{ footnote }}\n\t\t</p>\n\t</div>\n</template>\n\n<script>\nimport CnAuditTrailCard from '../CnAuditTrailCard/CnAuditTrailCard.vue'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\n\n/**\n * CnAuditTrailWidget — thin built-in widget wrapping CnAuditTrailCard with\n * unified object-context resolution (`audit-trail` widget key, Wave 1 of\n * nextcloud-vue#91).\n *\n * CnAuditTrailCard needs explicit `register` / `schema` / `objectId` props,\n * but the detail render paths surface the current object differently:\n * CnDetailPage's config grid provides a `cnObjectContext` inject, while\n * CnPageRenderer's slot CnWidgetGrid spreads the detail object context as\n * props, and CnDashboardPage's registry branch hands a stored `content`\n * blob. This widget reads whichever is present — explicit props win, then\n * the injects, then `content` — so the single `audit-trail` key works on\n * every surface. It replaces the three identical per-app adapters\n * (procest / zaakafhandelapp / scholiq).\n *\n * Registered in BOTH the v2 grid's BUILT_IN_WIDGETS and (detail-page\n * surface, like the `data` widget) the shared dashboardWidgetRegistry —\n * see `dashboardRegistration.js`.\n */\nexport default {\n\tname: 'CnAuditTrailWidget',\n\n\tcomponents: { CnAuditTrailCard },\n\n\tinject: {\n\t\t/** The host app's translate function, for `content.emptyText`. */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/**\n\t\t * Detail-page object context (`{ objectId, object, register, schema }`)\n\t\t * provided by CnDetailPage (raw object or `{ value }` holder).\n\t\t */\n\t\tcnObjectContext: { default: null },\n\t\t/**\n\t\t * Detail object context holder (`{ value: { objectData, schema,\n\t\t * objectType, objectId, register, store } | null }`) provided by\n\t\t * CnPageRenderer for the v2 slot grid.\n\t\t */\n\t\tcnDetailObjectContext: { default: null },\n\t},\n\n\tprops: {\n\t\t/** OpenRegister register slug/id — object context spread as props by CnWidgetGrid (slot path). */\n\t\tregister: { type: String, default: '' },\n\t\t/**\n\t\t * OpenRegister schema — a slug string, or the schema OBJECT the\n\t\t * detail-context merge supplies (its slug/name/id is used).\n\t\t *\n\t\t * @type {string|object}\n\t\t */\n\t\tschema: { type: [String, Object], default: '' },\n\t\t/** The audited object's id — object context spread as props by CnWidgetGrid (slot path). */\n\t\tobjectId: { type: String, default: '' },\n\t\t/** Optional card title override (defaults to the card's translated label). */\n\t\ttitle: { type: String, default: '' },\n\t\t/** Maximum audit rows to render (0 falls back to the card default). */\n\t\tmaxDisplay: { type: Number, default: 0 },\n\t\t/**\n\t\t * `app` lists the app-wide feed (every object the caller may read,\n\t\t * narrowed to `register` / `schema` when set) and needs no object;\n\t\t * `object` (the default) is one object's trail. Also read from\n\t\t * `content.scope`.\n\t\t *\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-the-audit-trail-widget-reads-the-app-wide-feed\n\t\t */\n\t\tscope: { type: String, default: '' },\n\t\t/** Read the trail of something that is not an object (`{ kind: 'flow-task', id? }`); also read from `content.source`. */\n\t\tsource: { type: Object, default: null },\n\t\t/** A trail URL of its own; also read from `content.endpoint`. */\n\t\tendpoint: { type: String, default: '' },\n\t\t/** Actions to leave out (`['read']`); also read from `content.excludeActions`. */\n\t\texcludeActions: { type: Array, default: () => [] },\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, footnote? }`. */\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, valueLabels? }`. */\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, valueLabels?, relatedSources? }`. */\n\t\tcontent: { type: Object, default: () => ({}) },\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The resolved object-context bag from either inject shape, or {}.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tctx() {\n\t\t\tconst inj = this.cnObjectContext && (this.cnObjectContext.value || this.cnObjectContext)\n\t\t\tconst holder = this.cnDetailObjectContext && this.cnDetailObjectContext.value\n\t\t\treturn inj || holder || {}\n\t\t},\n\n\t\t/**\n\t\t * The audited object's id: explicit prop → inject context → content.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedObjectId() {\n\t\t\treturn this.objectId || this.ctx.objectId || this.content.objectId || ''\n\t\t},\n\n\t\t/**\n\t\t * The register slug/id: explicit prop → inject context → content.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedRegister() {\n\t\t\treturn this.register || this.ctx.register || this.content.register || ''\n\t\t},\n\n\t\t/**\n\t\t * The schema SLUG: explicit prop → inject context → content; a\n\t\t * schema object collapses to its slug/name/id.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedSchema() {\n\t\t\tconst s = this.schema || this.ctx.schema || this.content.schema || ''\n\t\t\treturn typeof s === 'string' ? s : (s && (s.slug || s.name || s.id)) || ''\n\t\t},\n\n\t\t/**\n\t\t * The feed scope: explicit prop → content → `object`.\n\t\t *\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-the-audit-trail-widget-reads-the-app-wide-feed\n\t\t * @return {('object'|'app')}\n\t\t */\n\t\tresolvedScope() {\n\t\t\tconst s = this.scope || this.content.scope\n\t\t\treturn s === 'app' ? 'app' : 'object'\n\t\t},\n\n\t\t/**\n\t\t * The card title: explicit prop → content → '' (card default).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\t/** @return {object|null} The non-object anchor, from the prop or the content. */\n\t\tresolvedSource() {\n\t\t\tconst source = this.source || this.content.source\n\t\t\treturn source && typeof source === 'object' ? source : null\n\t\t},\n\n\t\t/** @return {string} The trail URL of its own, from the prop or the content. */\n\t\tresolvedEndpoint() {\n\t\t\treturn this.endpoint || (typeof this.content.endpoint === 'string' ? this.content.endpoint : '')\n\t\t},\n\n\t\t/** @return {string} The empty line the content names, through the host's translate, or ''. */\n\t\t/**\n\t\t * `content.actionLabels`, each label through the app's translate.\n\t\t *\n\t\t * @return {Object<string, string>|null}\n\t\t * @spec openspec/changes/audit-trail-action-labels/specs/audit-trail/spec.md#requirement-a-trail-can-say-what-happened-in-words\n\t\t */\n\t\tactionLabels() {\n\t\t\tconst labels = this.content.actionLabels\n\t\t\tif (!labels || typeof labels !== 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn Object.fromEntries(Object.entries(labels)\n\t\t\t\t.filter(([, text]) => typeof text === 'string' && text !== '')\n\t\t\t\t.map(([key, text]) => [key, translate(text)]))\n\t\t},\n\n\t\t/**\n\t\t * `content.footnote`, a muted line under the trail with the record's\n\t\t * fields filled in (\"Reference {identifier}\"); '' when a field is empty.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/audit-trail-footnote/specs/audit-trail/spec.md#requirement-a-history-card-can-end-in-a-line-about-the-record\n\t\t */\n\t\tfootnote() {\n\t\t\tconst note = this.content.footnote\n\t\t\tif (typeof note !== 'string' || note === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn fillTemplate(translate(note), this.ctx.object || this.ctx.objectData || null)\n\t\t},\n\n\t\t/**\n\t\t * `content.valueLabels`, each word through the app's translate.\n\t\t *\n\t\t * @return {{[key: string]: {[value: string]: string}}|null}\n\t\t * @spec openspec/changes/audit-label-changed-values/specs/audit-trail/spec.md#requirement-a-trail-label-can-quote-what-the-entry-recorded\n\t\t */\n\t\tvalueLabels() {\n\t\t\tconst labels = this.content.valueLabels\n\t\t\tif (!labels || typeof labels !== 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn Object.fromEntries(Object.entries(labels)\n\t\t\t\t.filter(([, words]) => words && typeof words === 'object')\n\t\t\t\t.map(([key, words]) => [key, Object.fromEntries(Object.entries(words)\n\t\t\t\t\t.filter(([, text]) => typeof text === 'string' && text !== '')\n\t\t\t\t\t.map(([value, text]) => [value, translate(text)]))]))\n\t\t},\n\n\t\t/**\n\t\t * `content.relatedSources`: records beside the object whose events\n\t\t * join its history (see CnAuditTrailCard).\n\t\t *\n\t\t * @return {Array<object>}\n\t\t * @spec openspec/changes/audit-trail-related-sources/specs/audit-trail/spec.md#requirement-an-objects-history-can-include-the-events-of-records-beside-it\n\t\t */\n\t\trelatedSources() {\n\t\t\treturn Array.isArray(this.content.relatedSources) ? this.content.relatedSources : []\n\t\t},\n\n\t\temptyText() {\n\t\t\tconst text = this.content.emptyText\n\t\t\tif (typeof text !== 'string' || text === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn typeof this.cnTranslate === 'function' ? this.cnTranslate(text) : text\n\t\t},\n\n\t\t/**\n\t\t * The actions to leave out: explicit prop → content → none.\n\t\t *\n\t\t * @spec openspec/changes/audit-trail-exclude-actions/specs/audit-trail/spec.md#requirement-a-history-card-can-leave-out-events-by-action\n\t\t * @return {Array<string>}\n\t\t */\n\t\tresolvedExcludeActions() {\n\t\t\tif (this.excludeActions.length > 0) {\n\t\t\t\treturn this.excludeActions\n\t\t\t}\n\t\t\tconst fromContent = this.content.excludeActions\n\t\t\treturn Array.isArray(fromContent) ? fromContent.filter((action) => typeof action === 'string' && action !== '') : []\n\t\t},\n\n\t\tresolvedTitle() {\n\t\t\treturn this.title || this.content.title || ''\n\t\t},\n\n\t\t/**\n\t\t * The row cap: explicit prop → content → the card's own default (5).\n\t\t *\n\t\t * @return {number}\n\t\t */\n\t\tresolvedMaxDisplay() {\n\t\t\tif (this.maxDisplay > 0) {\n\t\t\t\treturn this.maxDisplay\n\t\t\t}\n\t\t\tconst fromContent = Number(this.content.maxDisplay)\n\t\t\treturn Number.isFinite(fromContent) && fromContent > 0 ? fromContent : 5\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n/* The card keeps its own box; the wrapper only adds the line under it. */\n.cn-audit-trail-widget {\n\tdisplay: contents;\n}\n\n.cn-audit-trail-widget__footnote {\n\tmargin: 0;\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n</style>\n"],"names":["CnAuditTrailCard"],"mappings":"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"}
1
+ {"version":3,"file":"CnAuditTrailWidget.vue2.js","sources":["../../../../src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div\n\t\tv-if=\"resolvedScope === 'app' || resolvedSource || resolvedEndpoint || (resolvedRegister && resolvedSchema && resolvedObjectId)\"\n\t\tclass=\"cn-audit-trail-widget\">\n\t\t<CnAuditTrailCard\n\t\t\t:source=\"resolvedSource\"\n\t\t\t:endpoint=\"resolvedEndpoint\"\n\t\t\t:register=\"resolvedRegister\"\n\t\t\t:schema=\"resolvedSchema\"\n\t\t\t:objectId=\"resolvedObjectId\"\n\t\t\t:scope=\"resolvedScope\"\n\t\t\t:title=\"resolvedTitle\"\n\t\t\t:maxDisplay=\"resolvedMaxDisplay\"\n\t\t\t:excludeActions=\"resolvedExcludeActions\"\n\t\t\t:actionLabels=\"actionLabels\"\n\t\t\t:valueLabels=\"valueLabels\"\n\t\t\t:relatedSources=\"relatedSources\"\n\t\t\t:footnote=\"footnote\"\n\t\t\tv-bind=\"emptyText ? { noEntriesLabel: emptyText } : {}\" />\n\t</div>\n</template>\n\n<script>\nimport CnAuditTrailCard from '../CnAuditTrailCard/CnAuditTrailCard.vue'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\n\n/**\n * CnAuditTrailWidget — thin built-in widget wrapping CnAuditTrailCard with\n * unified object-context resolution (`audit-trail` widget key, Wave 1 of\n * nextcloud-vue#91).\n *\n * CnAuditTrailCard needs explicit `register` / `schema` / `objectId` props,\n * but the detail render paths surface the current object differently:\n * CnDetailPage's config grid provides a `cnObjectContext` inject, while\n * CnPageRenderer's slot CnWidgetGrid spreads the detail object context as\n * props, and CnDashboardPage's registry branch hands a stored `content`\n * blob. This widget reads whichever is present — explicit props win, then\n * the injects, then `content` — so the single `audit-trail` key works on\n * every surface. It replaces the three identical per-app adapters\n * (procest / zaakafhandelapp / scholiq).\n *\n * Registered in BOTH the v2 grid's BUILT_IN_WIDGETS and (detail-page\n * surface, like the `data` widget) the shared dashboardWidgetRegistry —\n * see `dashboardRegistration.js`.\n */\nexport default {\n\tname: 'CnAuditTrailWidget',\n\n\tcomponents: { CnAuditTrailCard },\n\n\tinject: {\n\t\t/** The host app's translate function, for `content.emptyText`. */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/**\n\t\t * Detail-page object context (`{ objectId, object, register, schema }`)\n\t\t * provided by CnDetailPage (raw object or `{ value }` holder).\n\t\t */\n\t\tcnObjectContext: { default: null },\n\t\t/**\n\t\t * Detail object context holder (`{ value: { objectData, schema,\n\t\t * objectType, objectId, register, store } | null }`) provided by\n\t\t * CnPageRenderer for the v2 slot grid.\n\t\t */\n\t\tcnDetailObjectContext: { default: null },\n\t},\n\n\tprops: {\n\t\t/** OpenRegister register slug/id — object context spread as props by CnWidgetGrid (slot path). */\n\t\tregister: { type: String, default: '' },\n\t\t/**\n\t\t * OpenRegister schema — a slug string, or the schema OBJECT the\n\t\t * detail-context merge supplies (its slug/name/id is used).\n\t\t *\n\t\t * @type {string|object}\n\t\t */\n\t\tschema: { type: [String, Object], default: '' },\n\t\t/** The audited object's id — object context spread as props by CnWidgetGrid (slot path). */\n\t\tobjectId: { type: String, default: '' },\n\t\t/** Optional card title override (defaults to the card's translated label). */\n\t\ttitle: { type: String, default: '' },\n\t\t/** Maximum audit rows to render (0 falls back to the card default). */\n\t\tmaxDisplay: { type: Number, default: 0 },\n\t\t/**\n\t\t * `app` lists the app-wide feed (every object the caller may read,\n\t\t * narrowed to `register` / `schema` when set) and needs no object;\n\t\t * `object` (the default) is one object's trail. Also read from\n\t\t * `content.scope`.\n\t\t *\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-the-audit-trail-widget-reads-the-app-wide-feed\n\t\t */\n\t\tscope: { type: String, default: '' },\n\t\t/** Read the trail of something that is not an object (`{ kind: 'flow-task', id? }`); also read from `content.source`. */\n\t\tsource: { type: Object, default: null },\n\t\t/** A trail URL of its own; also read from `content.endpoint`. */\n\t\tendpoint: { type: String, default: '' },\n\t\t/** Actions to leave out (`['read']`); also read from `content.excludeActions`. */\n\t\texcludeActions: { type: Array, default: () => [] },\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, footnote? }`. */\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, valueLabels? }`. */\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, valueLabels?, relatedSources? }`. */\n\t\tcontent: { type: Object, default: () => ({}) },\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The resolved object-context bag from either inject shape, or {}.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tctx() {\n\t\t\tconst inj = this.cnObjectContext && (this.cnObjectContext.value || this.cnObjectContext)\n\t\t\tconst holder = this.cnDetailObjectContext && this.cnDetailObjectContext.value\n\t\t\treturn inj || holder || {}\n\t\t},\n\n\t\t/**\n\t\t * The audited object's id: explicit prop → inject context → content.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedObjectId() {\n\t\t\treturn this.objectId || this.ctx.objectId || this.content.objectId || ''\n\t\t},\n\n\t\t/**\n\t\t * The register slug/id: explicit prop → inject context → content.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedRegister() {\n\t\t\treturn this.register || this.ctx.register || this.content.register || ''\n\t\t},\n\n\t\t/**\n\t\t * The schema SLUG: explicit prop → inject context → content; a\n\t\t * schema object collapses to its slug/name/id.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedSchema() {\n\t\t\tconst s = this.schema || this.ctx.schema || this.content.schema || ''\n\t\t\treturn typeof s === 'string' ? s : (s && (s.slug || s.name || s.id)) || ''\n\t\t},\n\n\t\t/**\n\t\t * The feed scope: explicit prop → content → `object`.\n\t\t *\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-the-audit-trail-widget-reads-the-app-wide-feed\n\t\t * @return {('object'|'app')}\n\t\t */\n\t\tresolvedScope() {\n\t\t\tconst s = this.scope || this.content.scope\n\t\t\treturn s === 'app' ? 'app' : 'object'\n\t\t},\n\n\t\t/**\n\t\t * The card title: explicit prop → content → '' (card default).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\t/** @return {object|null} The non-object anchor, from the prop or the content. */\n\t\tresolvedSource() {\n\t\t\tconst source = this.source || this.content.source\n\t\t\treturn source && typeof source === 'object' ? source : null\n\t\t},\n\n\t\t/** @return {string} The trail URL of its own, from the prop or the content. */\n\t\tresolvedEndpoint() {\n\t\t\treturn this.endpoint || (typeof this.content.endpoint === 'string' ? this.content.endpoint : '')\n\t\t},\n\n\t\t/** @return {string} The empty line the content names, through the host's translate, or ''. */\n\t\t/**\n\t\t * `content.actionLabels`, each label through the app's translate.\n\t\t *\n\t\t * @return {Object<string, string>|null}\n\t\t * @spec openspec/changes/audit-trail-action-labels/specs/audit-trail/spec.md#requirement-a-trail-can-say-what-happened-in-words\n\t\t */\n\t\tactionLabels() {\n\t\t\tconst labels = this.content.actionLabels\n\t\t\tif (!labels || typeof labels !== 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn Object.fromEntries(Object.entries(labels)\n\t\t\t\t.filter(([, text]) => typeof text === 'string' && text !== '')\n\t\t\t\t.map(([key, text]) => [key, translate(text)]))\n\t\t},\n\n\t\t/**\n\t\t * `content.footnote`, a muted line under the trail with the record's\n\t\t * fields filled in (\"Reference {identifier}\"); '' when a field is empty.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/audit-trail-footnote/specs/audit-trail/spec.md#requirement-a-history-card-can-end-in-a-line-about-the-record\n\t\t */\n\t\tfootnote() {\n\t\t\tconst note = this.content.footnote\n\t\t\tif (typeof note !== 'string' || note === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn fillTemplate(translate(note), this.ctx.object || this.ctx.objectData || null)\n\t\t},\n\n\t\t/**\n\t\t * `content.valueLabels`, each word through the app's translate.\n\t\t *\n\t\t * @return {{[key: string]: {[value: string]: string}}|null}\n\t\t * @spec openspec/changes/audit-label-changed-values/specs/audit-trail/spec.md#requirement-a-trail-label-can-quote-what-the-entry-recorded\n\t\t */\n\t\tvalueLabels() {\n\t\t\tconst labels = this.content.valueLabels\n\t\t\tif (!labels || typeof labels !== 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn Object.fromEntries(Object.entries(labels)\n\t\t\t\t.filter(([, words]) => words && typeof words === 'object')\n\t\t\t\t.map(([key, words]) => [key, Object.fromEntries(Object.entries(words)\n\t\t\t\t\t.filter(([, text]) => typeof text === 'string' && text !== '')\n\t\t\t\t\t.map(([value, text]) => [value, translate(text)]))]))\n\t\t},\n\n\t\t/**\n\t\t * `content.relatedSources`: records beside the object whose events\n\t\t * join its history (see CnAuditTrailCard).\n\t\t *\n\t\t * @return {Array<object>}\n\t\t * @spec openspec/changes/audit-trail-related-sources/specs/audit-trail/spec.md#requirement-an-objects-history-can-include-the-events-of-records-beside-it\n\t\t */\n\t\trelatedSources() {\n\t\t\treturn Array.isArray(this.content.relatedSources) ? this.content.relatedSources : []\n\t\t},\n\n\t\temptyText() {\n\t\t\tconst text = this.content.emptyText\n\t\t\tif (typeof text !== 'string' || text === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn typeof this.cnTranslate === 'function' ? this.cnTranslate(text) : text\n\t\t},\n\n\t\t/**\n\t\t * The actions to leave out: explicit prop → content → none.\n\t\t *\n\t\t * @spec openspec/changes/audit-trail-exclude-actions/specs/audit-trail/spec.md#requirement-a-history-card-can-leave-out-events-by-action\n\t\t * @return {Array<string>}\n\t\t */\n\t\tresolvedExcludeActions() {\n\t\t\tif (this.excludeActions.length > 0) {\n\t\t\t\treturn this.excludeActions\n\t\t\t}\n\t\t\tconst fromContent = this.content.excludeActions\n\t\t\treturn Array.isArray(fromContent) ? fromContent.filter((action) => typeof action === 'string' && action !== '') : []\n\t\t},\n\n\t\tresolvedTitle() {\n\t\t\treturn this.title || this.content.title || ''\n\t\t},\n\n\t\t/**\n\t\t * The row cap: explicit prop → content → the card's own default (5).\n\t\t *\n\t\t * @return {number}\n\t\t */\n\t\tresolvedMaxDisplay() {\n\t\t\tif (this.maxDisplay > 0) {\n\t\t\t\treturn this.maxDisplay\n\t\t\t}\n\t\t\tconst fromContent = Number(this.content.maxDisplay)\n\t\t\treturn Number.isFinite(fromContent) && fromContent > 0 ? fromContent : 5\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n/* The card keeps its own box, footnote included. */\n.cn-audit-trail-widget {\n\tdisplay: contents;\n}\n</style>\n"],"names":["CnAuditTrailCard"],"mappings":"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"}
@@ -1,14 +1,9 @@
1
- import { resolveComponent, openBlock, createElementBlock, createVNode, mergeProps, toDisplayString, createCommentVNode } from 'vue';
1
+ import { resolveComponent, openBlock, createElementBlock, createVNode, mergeProps, createCommentVNode } from 'vue';
2
2
 
3
3
  const _hoisted_1 = {
4
4
  key: 0,
5
5
  class: "cn-audit-trail-widget"
6
6
  };
7
- const _hoisted_2 = {
8
- key: 0,
9
- class: "cn-audit-trail-widget__footnote",
10
- "data-testid": "cn-audit-trail-widget-footnote"
11
- };
12
7
 
13
8
  function render(_ctx, _cache, $props, $setup, $data, $options) {
14
9
  const _component_CnAuditTrailCard = resolveComponent("CnAuditTrailCard");
@@ -27,11 +22,9 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
27
22
  excludeActions: $options.resolvedExcludeActions,
28
23
  actionLabels: $options.actionLabels,
29
24
  valueLabels: $options.valueLabels,
30
- relatedSources: $options.relatedSources
31
- }, $options.emptyText ? { noEntriesLabel: $options.emptyText } : {}), null, 16 /* FULL_PROPS */, ["source", "endpoint", "register", "schema", "objectId", "scope", "title", "maxDisplay", "excludeActions", "actionLabels", "valueLabels", "relatedSources"]),
32
- ($options.footnote)
33
- ? (openBlock(), createElementBlock("p", _hoisted_2, toDisplayString($options.footnote), 1 /* TEXT */))
34
- : createCommentVNode("v-if", true)
25
+ relatedSources: $options.relatedSources,
26
+ footnote: $options.footnote
27
+ }, $options.emptyText ? { noEntriesLabel: $options.emptyText } : {}), null, 16 /* FULL_PROPS */, ["source", "endpoint", "register", "schema", "objectId", "scope", "title", "maxDisplay", "excludeActions", "actionLabels", "valueLabels", "relatedSources", "footnote"])
35
28
  ]))
36
29
  : createCommentVNode("v-if", true)
37
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CnAuditTrailWidget.vue3.js","sources":["../../../../src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue?vue&type=template&id=38035670&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div\n\t\tv-if=\"resolvedScope === 'app' || resolvedSource || resolvedEndpoint || (resolvedRegister && resolvedSchema && resolvedObjectId)\"\n\t\tclass=\"cn-audit-trail-widget\">\n\t\t<CnAuditTrailCard\n\t\t\t:source=\"resolvedSource\"\n\t\t\t:endpoint=\"resolvedEndpoint\"\n\t\t\t:register=\"resolvedRegister\"\n\t\t\t:schema=\"resolvedSchema\"\n\t\t\t:objectId=\"resolvedObjectId\"\n\t\t\t:scope=\"resolvedScope\"\n\t\t\t:title=\"resolvedTitle\"\n\t\t\t:maxDisplay=\"resolvedMaxDisplay\"\n\t\t\t:excludeActions=\"resolvedExcludeActions\"\n\t\t\t:actionLabels=\"actionLabels\"\n\t\t\t:valueLabels=\"valueLabels\"\n\t\t\t:relatedSources=\"relatedSources\"\n\t\t\tv-bind=\"emptyText ? { noEntriesLabel: emptyText } : {}\" />\n\t\t<p v-if=\"footnote\" class=\"cn-audit-trail-widget__footnote\" data-testid=\"cn-audit-trail-widget-footnote\">\n\t\t\t{{ footnote }}\n\t\t</p>\n\t</div>\n</template>\n\n<script>\nimport CnAuditTrailCard from '../CnAuditTrailCard/CnAuditTrailCard.vue'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\n\n/**\n * CnAuditTrailWidget — thin built-in widget wrapping CnAuditTrailCard with\n * unified object-context resolution (`audit-trail` widget key, Wave 1 of\n * nextcloud-vue#91).\n *\n * CnAuditTrailCard needs explicit `register` / `schema` / `objectId` props,\n * but the detail render paths surface the current object differently:\n * CnDetailPage's config grid provides a `cnObjectContext` inject, while\n * CnPageRenderer's slot CnWidgetGrid spreads the detail object context as\n * props, and CnDashboardPage's registry branch hands a stored `content`\n * blob. This widget reads whichever is present — explicit props win, then\n * the injects, then `content` — so the single `audit-trail` key works on\n * every surface. It replaces the three identical per-app adapters\n * (procest / zaakafhandelapp / scholiq).\n *\n * Registered in BOTH the v2 grid's BUILT_IN_WIDGETS and (detail-page\n * surface, like the `data` widget) the shared dashboardWidgetRegistry —\n * see `dashboardRegistration.js`.\n */\nexport default {\n\tname: 'CnAuditTrailWidget',\n\n\tcomponents: { CnAuditTrailCard },\n\n\tinject: {\n\t\t/** The host app's translate function, for `content.emptyText`. */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/**\n\t\t * Detail-page object context (`{ objectId, object, register, schema }`)\n\t\t * provided by CnDetailPage (raw object or `{ value }` holder).\n\t\t */\n\t\tcnObjectContext: { default: null },\n\t\t/**\n\t\t * Detail object context holder (`{ value: { objectData, schema,\n\t\t * objectType, objectId, register, store } | null }`) provided by\n\t\t * CnPageRenderer for the v2 slot grid.\n\t\t */\n\t\tcnDetailObjectContext: { default: null },\n\t},\n\n\tprops: {\n\t\t/** OpenRegister register slug/id — object context spread as props by CnWidgetGrid (slot path). */\n\t\tregister: { type: String, default: '' },\n\t\t/**\n\t\t * OpenRegister schema — a slug string, or the schema OBJECT the\n\t\t * detail-context merge supplies (its slug/name/id is used).\n\t\t *\n\t\t * @type {string|object}\n\t\t */\n\t\tschema: { type: [String, Object], default: '' },\n\t\t/** The audited object's id — object context spread as props by CnWidgetGrid (slot path). */\n\t\tobjectId: { type: String, default: '' },\n\t\t/** Optional card title override (defaults to the card's translated label). */\n\t\ttitle: { type: String, default: '' },\n\t\t/** Maximum audit rows to render (0 falls back to the card default). */\n\t\tmaxDisplay: { type: Number, default: 0 },\n\t\t/**\n\t\t * `app` lists the app-wide feed (every object the caller may read,\n\t\t * narrowed to `register` / `schema` when set) and needs no object;\n\t\t * `object` (the default) is one object's trail. Also read from\n\t\t * `content.scope`.\n\t\t *\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-the-audit-trail-widget-reads-the-app-wide-feed\n\t\t */\n\t\tscope: { type: String, default: '' },\n\t\t/** Read the trail of something that is not an object (`{ kind: 'flow-task', id? }`); also read from `content.source`. */\n\t\tsource: { type: Object, default: null },\n\t\t/** A trail URL of its own; also read from `content.endpoint`. */\n\t\tendpoint: { type: String, default: '' },\n\t\t/** Actions to leave out (`['read']`); also read from `content.excludeActions`. */\n\t\texcludeActions: { type: Array, default: () => [] },\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, footnote? }`. */\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, valueLabels? }`. */\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, valueLabels?, relatedSources? }`. */\n\t\tcontent: { type: Object, default: () => ({}) },\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The resolved object-context bag from either inject shape, or {}.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tctx() {\n\t\t\tconst inj = this.cnObjectContext && (this.cnObjectContext.value || this.cnObjectContext)\n\t\t\tconst holder = this.cnDetailObjectContext && this.cnDetailObjectContext.value\n\t\t\treturn inj || holder || {}\n\t\t},\n\n\t\t/**\n\t\t * The audited object's id: explicit prop → inject context → content.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedObjectId() {\n\t\t\treturn this.objectId || this.ctx.objectId || this.content.objectId || ''\n\t\t},\n\n\t\t/**\n\t\t * The register slug/id: explicit prop → inject context → content.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedRegister() {\n\t\t\treturn this.register || this.ctx.register || this.content.register || ''\n\t\t},\n\n\t\t/**\n\t\t * The schema SLUG: explicit prop → inject context → content; a\n\t\t * schema object collapses to its slug/name/id.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedSchema() {\n\t\t\tconst s = this.schema || this.ctx.schema || this.content.schema || ''\n\t\t\treturn typeof s === 'string' ? s : (s && (s.slug || s.name || s.id)) || ''\n\t\t},\n\n\t\t/**\n\t\t * The feed scope: explicit prop → content → `object`.\n\t\t *\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-the-audit-trail-widget-reads-the-app-wide-feed\n\t\t * @return {('object'|'app')}\n\t\t */\n\t\tresolvedScope() {\n\t\t\tconst s = this.scope || this.content.scope\n\t\t\treturn s === 'app' ? 'app' : 'object'\n\t\t},\n\n\t\t/**\n\t\t * The card title: explicit prop → content → '' (card default).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\t/** @return {object|null} The non-object anchor, from the prop or the content. */\n\t\tresolvedSource() {\n\t\t\tconst source = this.source || this.content.source\n\t\t\treturn source && typeof source === 'object' ? source : null\n\t\t},\n\n\t\t/** @return {string} The trail URL of its own, from the prop or the content. */\n\t\tresolvedEndpoint() {\n\t\t\treturn this.endpoint || (typeof this.content.endpoint === 'string' ? this.content.endpoint : '')\n\t\t},\n\n\t\t/** @return {string} The empty line the content names, through the host's translate, or ''. */\n\t\t/**\n\t\t * `content.actionLabels`, each label through the app's translate.\n\t\t *\n\t\t * @return {Object<string, string>|null}\n\t\t * @spec openspec/changes/audit-trail-action-labels/specs/audit-trail/spec.md#requirement-a-trail-can-say-what-happened-in-words\n\t\t */\n\t\tactionLabels() {\n\t\t\tconst labels = this.content.actionLabels\n\t\t\tif (!labels || typeof labels !== 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn Object.fromEntries(Object.entries(labels)\n\t\t\t\t.filter(([, text]) => typeof text === 'string' && text !== '')\n\t\t\t\t.map(([key, text]) => [key, translate(text)]))\n\t\t},\n\n\t\t/**\n\t\t * `content.footnote`, a muted line under the trail with the record's\n\t\t * fields filled in (\"Reference {identifier}\"); '' when a field is empty.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/audit-trail-footnote/specs/audit-trail/spec.md#requirement-a-history-card-can-end-in-a-line-about-the-record\n\t\t */\n\t\tfootnote() {\n\t\t\tconst note = this.content.footnote\n\t\t\tif (typeof note !== 'string' || note === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn fillTemplate(translate(note), this.ctx.object || this.ctx.objectData || null)\n\t\t},\n\n\t\t/**\n\t\t * `content.valueLabels`, each word through the app's translate.\n\t\t *\n\t\t * @return {{[key: string]: {[value: string]: string}}|null}\n\t\t * @spec openspec/changes/audit-label-changed-values/specs/audit-trail/spec.md#requirement-a-trail-label-can-quote-what-the-entry-recorded\n\t\t */\n\t\tvalueLabels() {\n\t\t\tconst labels = this.content.valueLabels\n\t\t\tif (!labels || typeof labels !== 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn Object.fromEntries(Object.entries(labels)\n\t\t\t\t.filter(([, words]) => words && typeof words === 'object')\n\t\t\t\t.map(([key, words]) => [key, Object.fromEntries(Object.entries(words)\n\t\t\t\t\t.filter(([, text]) => typeof text === 'string' && text !== '')\n\t\t\t\t\t.map(([value, text]) => [value, translate(text)]))]))\n\t\t},\n\n\t\t/**\n\t\t * `content.relatedSources`: records beside the object whose events\n\t\t * join its history (see CnAuditTrailCard).\n\t\t *\n\t\t * @return {Array<object>}\n\t\t * @spec openspec/changes/audit-trail-related-sources/specs/audit-trail/spec.md#requirement-an-objects-history-can-include-the-events-of-records-beside-it\n\t\t */\n\t\trelatedSources() {\n\t\t\treturn Array.isArray(this.content.relatedSources) ? this.content.relatedSources : []\n\t\t},\n\n\t\temptyText() {\n\t\t\tconst text = this.content.emptyText\n\t\t\tif (typeof text !== 'string' || text === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn typeof this.cnTranslate === 'function' ? this.cnTranslate(text) : text\n\t\t},\n\n\t\t/**\n\t\t * The actions to leave out: explicit prop → content → none.\n\t\t *\n\t\t * @spec openspec/changes/audit-trail-exclude-actions/specs/audit-trail/spec.md#requirement-a-history-card-can-leave-out-events-by-action\n\t\t * @return {Array<string>}\n\t\t */\n\t\tresolvedExcludeActions() {\n\t\t\tif (this.excludeActions.length > 0) {\n\t\t\t\treturn this.excludeActions\n\t\t\t}\n\t\t\tconst fromContent = this.content.excludeActions\n\t\t\treturn Array.isArray(fromContent) ? fromContent.filter((action) => typeof action === 'string' && action !== '') : []\n\t\t},\n\n\t\tresolvedTitle() {\n\t\t\treturn this.title || this.content.title || ''\n\t\t},\n\n\t\t/**\n\t\t * The row cap: explicit prop → content → the card's own default (5).\n\t\t *\n\t\t * @return {number}\n\t\t */\n\t\tresolvedMaxDisplay() {\n\t\t\tif (this.maxDisplay > 0) {\n\t\t\t\treturn this.maxDisplay\n\t\t\t}\n\t\t\tconst fromContent = Number(this.content.maxDisplay)\n\t\t\treturn Number.isFinite(fromContent) && fromContent > 0 ? fromContent : 5\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n/* The card keeps its own box; the wrapper only adds the line under it. */\n.cn-audit-trail-widget {\n\tdisplay: contents;\n}\n\n.cn-audit-trail-widget__footnote {\n\tmargin: 0;\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n</style>\n"],"names":[],"mappings":";;;;OAaO,EAAC,uBAAkB;;;;;;;;;;;UADlB,QAAa,CAAA,aAAA,KAAA,KAAA,IAAS,uBAAA,IAAA,QAAA,CAAA,gBAAA,KAAA,QAAA,CAAA,gBAAA,IAAA,QAAA,CAAA,cAAA,IAAA,QAAA,CAAA,gBAAA,CAAA;;;AAG1B,UAAA,MAAM,EAAE,QAAY,CAAA,cAAA;AACpB,UAAA,QAAQ,EAAE,QAAU,CAAA,gBAAA;AACpB,UAAA,QAAQ,EAAE,QAAgB,CAAA,gBAAA;AAC1B,UAAA,MAAM,EAAE,QAAc,CAAA,cAAA;AACtB,UAAA,QAAQ,EAAE,QAAgB,CAAA,gBAAA;AAC1B,UAAA,KAAK,EAAE,QAAa,CAAA,aAAA;AACpB,UAAA,KAAK,EAAE,QAAa,CAAA,aAAA;AACpB,UAAA,UAAU,EAAE,QAAkB,CAAA,kBAAA;AAC/B,UAAA,cAAe,EAAC,QAAuB,CAAA,sBAAA;AACtC,UAAA,YAAY,EAAA,QAAA,CAAA,YAAA;AACZ,UAAA,WAAC,EAAA,QAAA,CAAA,WAAA;AACD,UAAA,cAAE,EAAA,QAAA,CAAA,cAAA;;;;;;;;;;;"}
1
+ {"version":3,"file":"CnAuditTrailWidget.vue3.js","sources":["../../../../src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue?vue&type=template&id=3f7bbf0c&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div\n\t\tv-if=\"resolvedScope === 'app' || resolvedSource || resolvedEndpoint || (resolvedRegister && resolvedSchema && resolvedObjectId)\"\n\t\tclass=\"cn-audit-trail-widget\">\n\t\t<CnAuditTrailCard\n\t\t\t:source=\"resolvedSource\"\n\t\t\t:endpoint=\"resolvedEndpoint\"\n\t\t\t:register=\"resolvedRegister\"\n\t\t\t:schema=\"resolvedSchema\"\n\t\t\t:objectId=\"resolvedObjectId\"\n\t\t\t:scope=\"resolvedScope\"\n\t\t\t:title=\"resolvedTitle\"\n\t\t\t:maxDisplay=\"resolvedMaxDisplay\"\n\t\t\t:excludeActions=\"resolvedExcludeActions\"\n\t\t\t:actionLabels=\"actionLabels\"\n\t\t\t:valueLabels=\"valueLabels\"\n\t\t\t:relatedSources=\"relatedSources\"\n\t\t\t:footnote=\"footnote\"\n\t\t\tv-bind=\"emptyText ? { noEntriesLabel: emptyText } : {}\" />\n\t</div>\n</template>\n\n<script>\nimport CnAuditTrailCard from '../CnAuditTrailCard/CnAuditTrailCard.vue'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\n\n/**\n * CnAuditTrailWidget — thin built-in widget wrapping CnAuditTrailCard with\n * unified object-context resolution (`audit-trail` widget key, Wave 1 of\n * nextcloud-vue#91).\n *\n * CnAuditTrailCard needs explicit `register` / `schema` / `objectId` props,\n * but the detail render paths surface the current object differently:\n * CnDetailPage's config grid provides a `cnObjectContext` inject, while\n * CnPageRenderer's slot CnWidgetGrid spreads the detail object context as\n * props, and CnDashboardPage's registry branch hands a stored `content`\n * blob. This widget reads whichever is present — explicit props win, then\n * the injects, then `content` — so the single `audit-trail` key works on\n * every surface. It replaces the three identical per-app adapters\n * (procest / zaakafhandelapp / scholiq).\n *\n * Registered in BOTH the v2 grid's BUILT_IN_WIDGETS and (detail-page\n * surface, like the `data` widget) the shared dashboardWidgetRegistry —\n * see `dashboardRegistration.js`.\n */\nexport default {\n\tname: 'CnAuditTrailWidget',\n\n\tcomponents: { CnAuditTrailCard },\n\n\tinject: {\n\t\t/** The host app's translate function, for `content.emptyText`. */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/**\n\t\t * Detail-page object context (`{ objectId, object, register, schema }`)\n\t\t * provided by CnDetailPage (raw object or `{ value }` holder).\n\t\t */\n\t\tcnObjectContext: { default: null },\n\t\t/**\n\t\t * Detail object context holder (`{ value: { objectData, schema,\n\t\t * objectType, objectId, register, store } | null }`) provided by\n\t\t * CnPageRenderer for the v2 slot grid.\n\t\t */\n\t\tcnDetailObjectContext: { default: null },\n\t},\n\n\tprops: {\n\t\t/** OpenRegister register slug/id — object context spread as props by CnWidgetGrid (slot path). */\n\t\tregister: { type: String, default: '' },\n\t\t/**\n\t\t * OpenRegister schema — a slug string, or the schema OBJECT the\n\t\t * detail-context merge supplies (its slug/name/id is used).\n\t\t *\n\t\t * @type {string|object}\n\t\t */\n\t\tschema: { type: [String, Object], default: '' },\n\t\t/** The audited object's id — object context spread as props by CnWidgetGrid (slot path). */\n\t\tobjectId: { type: String, default: '' },\n\t\t/** Optional card title override (defaults to the card's translated label). */\n\t\ttitle: { type: String, default: '' },\n\t\t/** Maximum audit rows to render (0 falls back to the card default). */\n\t\tmaxDisplay: { type: Number, default: 0 },\n\t\t/**\n\t\t * `app` lists the app-wide feed (every object the caller may read,\n\t\t * narrowed to `register` / `schema` when set) and needs no object;\n\t\t * `object` (the default) is one object's trail. Also read from\n\t\t * `content.scope`.\n\t\t *\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-the-audit-trail-widget-reads-the-app-wide-feed\n\t\t */\n\t\tscope: { type: String, default: '' },\n\t\t/** Read the trail of something that is not an object (`{ kind: 'flow-task', id? }`); also read from `content.source`. */\n\t\tsource: { type: Object, default: null },\n\t\t/** A trail URL of its own; also read from `content.endpoint`. */\n\t\tendpoint: { type: String, default: '' },\n\t\t/** Actions to leave out (`['read']`); also read from `content.excludeActions`. */\n\t\texcludeActions: { type: Array, default: () => [] },\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, footnote? }`. */\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, valueLabels? }`. */\n\t\t/** Stored widget content blob (CnDashboardPage registry branch): `{ title, maxDisplay, register?, schema?, objectId?, source?, endpoint?, emptyText?, excludeActions?, actionLabels?, valueLabels?, relatedSources? }`. */\n\t\tcontent: { type: Object, default: () => ({}) },\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The resolved object-context bag from either inject shape, or {}.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tctx() {\n\t\t\tconst inj = this.cnObjectContext && (this.cnObjectContext.value || this.cnObjectContext)\n\t\t\tconst holder = this.cnDetailObjectContext && this.cnDetailObjectContext.value\n\t\t\treturn inj || holder || {}\n\t\t},\n\n\t\t/**\n\t\t * The audited object's id: explicit prop → inject context → content.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedObjectId() {\n\t\t\treturn this.objectId || this.ctx.objectId || this.content.objectId || ''\n\t\t},\n\n\t\t/**\n\t\t * The register slug/id: explicit prop → inject context → content.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedRegister() {\n\t\t\treturn this.register || this.ctx.register || this.content.register || ''\n\t\t},\n\n\t\t/**\n\t\t * The schema SLUG: explicit prop → inject context → content; a\n\t\t * schema object collapses to its slug/name/id.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedSchema() {\n\t\t\tconst s = this.schema || this.ctx.schema || this.content.schema || ''\n\t\t\treturn typeof s === 'string' ? s : (s && (s.slug || s.name || s.id)) || ''\n\t\t},\n\n\t\t/**\n\t\t * The feed scope: explicit prop → content → `object`.\n\t\t *\n\t\t * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-the-audit-trail-widget-reads-the-app-wide-feed\n\t\t * @return {('object'|'app')}\n\t\t */\n\t\tresolvedScope() {\n\t\t\tconst s = this.scope || this.content.scope\n\t\t\treturn s === 'app' ? 'app' : 'object'\n\t\t},\n\n\t\t/**\n\t\t * The card title: explicit prop → content → '' (card default).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\t/** @return {object|null} The non-object anchor, from the prop or the content. */\n\t\tresolvedSource() {\n\t\t\tconst source = this.source || this.content.source\n\t\t\treturn source && typeof source === 'object' ? source : null\n\t\t},\n\n\t\t/** @return {string} The trail URL of its own, from the prop or the content. */\n\t\tresolvedEndpoint() {\n\t\t\treturn this.endpoint || (typeof this.content.endpoint === 'string' ? this.content.endpoint : '')\n\t\t},\n\n\t\t/** @return {string} The empty line the content names, through the host's translate, or ''. */\n\t\t/**\n\t\t * `content.actionLabels`, each label through the app's translate.\n\t\t *\n\t\t * @return {Object<string, string>|null}\n\t\t * @spec openspec/changes/audit-trail-action-labels/specs/audit-trail/spec.md#requirement-a-trail-can-say-what-happened-in-words\n\t\t */\n\t\tactionLabels() {\n\t\t\tconst labels = this.content.actionLabels\n\t\t\tif (!labels || typeof labels !== 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn Object.fromEntries(Object.entries(labels)\n\t\t\t\t.filter(([, text]) => typeof text === 'string' && text !== '')\n\t\t\t\t.map(([key, text]) => [key, translate(text)]))\n\t\t},\n\n\t\t/**\n\t\t * `content.footnote`, a muted line under the trail with the record's\n\t\t * fields filled in (\"Reference {identifier}\"); '' when a field is empty.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/audit-trail-footnote/specs/audit-trail/spec.md#requirement-a-history-card-can-end-in-a-line-about-the-record\n\t\t */\n\t\tfootnote() {\n\t\t\tconst note = this.content.footnote\n\t\t\tif (typeof note !== 'string' || note === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn fillTemplate(translate(note), this.ctx.object || this.ctx.objectData || null)\n\t\t},\n\n\t\t/**\n\t\t * `content.valueLabels`, each word through the app's translate.\n\t\t *\n\t\t * @return {{[key: string]: {[value: string]: string}}|null}\n\t\t * @spec openspec/changes/audit-label-changed-values/specs/audit-trail/spec.md#requirement-a-trail-label-can-quote-what-the-entry-recorded\n\t\t */\n\t\tvalueLabels() {\n\t\t\tconst labels = this.content.valueLabels\n\t\t\tif (!labels || typeof labels !== 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : (text) => text\n\t\t\treturn Object.fromEntries(Object.entries(labels)\n\t\t\t\t.filter(([, words]) => words && typeof words === 'object')\n\t\t\t\t.map(([key, words]) => [key, Object.fromEntries(Object.entries(words)\n\t\t\t\t\t.filter(([, text]) => typeof text === 'string' && text !== '')\n\t\t\t\t\t.map(([value, text]) => [value, translate(text)]))]))\n\t\t},\n\n\t\t/**\n\t\t * `content.relatedSources`: records beside the object whose events\n\t\t * join its history (see CnAuditTrailCard).\n\t\t *\n\t\t * @return {Array<object>}\n\t\t * @spec openspec/changes/audit-trail-related-sources/specs/audit-trail/spec.md#requirement-an-objects-history-can-include-the-events-of-records-beside-it\n\t\t */\n\t\trelatedSources() {\n\t\t\treturn Array.isArray(this.content.relatedSources) ? this.content.relatedSources : []\n\t\t},\n\n\t\temptyText() {\n\t\t\tconst text = this.content.emptyText\n\t\t\tif (typeof text !== 'string' || text === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn typeof this.cnTranslate === 'function' ? this.cnTranslate(text) : text\n\t\t},\n\n\t\t/**\n\t\t * The actions to leave out: explicit prop → content → none.\n\t\t *\n\t\t * @spec openspec/changes/audit-trail-exclude-actions/specs/audit-trail/spec.md#requirement-a-history-card-can-leave-out-events-by-action\n\t\t * @return {Array<string>}\n\t\t */\n\t\tresolvedExcludeActions() {\n\t\t\tif (this.excludeActions.length > 0) {\n\t\t\t\treturn this.excludeActions\n\t\t\t}\n\t\t\tconst fromContent = this.content.excludeActions\n\t\t\treturn Array.isArray(fromContent) ? fromContent.filter((action) => typeof action === 'string' && action !== '') : []\n\t\t},\n\n\t\tresolvedTitle() {\n\t\t\treturn this.title || this.content.title || ''\n\t\t},\n\n\t\t/**\n\t\t * The row cap: explicit prop → content → the card's own default (5).\n\t\t *\n\t\t * @return {number}\n\t\t */\n\t\tresolvedMaxDisplay() {\n\t\t\tif (this.maxDisplay > 0) {\n\t\t\t\treturn this.maxDisplay\n\t\t\t}\n\t\t\tconst fromContent = Number(this.content.maxDisplay)\n\t\t\treturn Number.isFinite(fromContent) && fromContent > 0 ? fromContent : 5\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n/* The card keeps its own box, footnote included. */\n.cn-audit-trail-widget {\n\tdisplay: contents;\n}\n</style>\n"],"names":[],"mappings":";;;;OAaO,EAAC,uBAAkB;;;;;;UADlB,QAAa,CAAA,aAAA,KAAA,KAAA,IAAS,uBAAA,IAAA,QAAA,CAAA,gBAAA,KAAA,QAAA,CAAA,gBAAA,IAAA,QAAA,CAAA,cAAA,IAAA,QAAA,CAAA,gBAAA,CAAA;;;AAG1B,UAAA,MAAM,EAAE,QAAY,CAAA,cAAA;AACpB,UAAA,QAAQ,EAAE,QAAU,CAAA,gBAAA;AACpB,UAAA,QAAQ,EAAE,QAAgB,CAAA,gBAAA;AAC1B,UAAA,MAAM,EAAE,QAAc,CAAA,cAAA;AACtB,UAAA,QAAQ,EAAE,QAAgB,CAAA,gBAAA;AAC1B,UAAA,KAAK,EAAE,QAAa,CAAA,aAAA;AACpB,UAAA,KAAK,EAAE,QAAa,CAAA,aAAA;AACpB,UAAA,UAAU,EAAE,QAAM,CAAA,kBAAA;AAClB,UAAA,cAAc,EAAC,QAAuB,CAAA,sBAAA;AACtC,UAAA,YAAE,EAAA,QAAA,CAAA,YAAA;;;;;;;;;;;"}
@@ -611,6 +611,18 @@ var script = {
611
611
  default: null,
612
612
  },
613
613
 
614
+ /**
615
+ * Draw the active header filters as removable chips above the table.
616
+ * A host that lists them itself (the index page's board Active line)
617
+ * turns this off, so a filter is not shown twice.
618
+ *
619
+ * @spec openspec/changes/index-table-filter-chips-once/specs/cn-data-table/spec.md#requirement-a-host-that-lists-the-active-filters-itself-turns-the-table-chips-off
620
+ */
621
+ filterChips: {
622
+ type: Boolean,
623
+ default: true,
624
+ },
625
+
614
626
  /**
615
627
  * The active filter map, `{ paramKey: values[] }`: the same map the
616
628
  * facet sidebar writes, so a header filter and a sidebar filter on one