@conduction/nextcloud-vue 2.108.0 → 2.109.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 (155) hide show
  1. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue.js +10 -0
  2. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue.js.map +1 -0
  3. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue2.js +305 -0
  4. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue2.js.map +1 -0
  5. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue3.js +38 -0
  6. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue3.js.map +1 -0
  7. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue.js +10 -0
  8. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue.js.map +1 -0
  9. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue2.js +398 -0
  10. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue2.js.map +1 -0
  11. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue3.js +155 -0
  12. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue3.js.map +1 -0
  13. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue.js +9 -0
  14. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue.js.map +1 -0
  15. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue2.js +281 -0
  16. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue2.js.map +1 -0
  17. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue3.js +137 -0
  18. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue3.js.map +1 -0
  19. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue.js +9 -0
  20. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue.js.map +1 -0
  21. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue2.js +225 -0
  22. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue2.js.map +1 -0
  23. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue3.js +110 -0
  24. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue3.js.map +1 -0
  25. package/dist/esm/components/CnFormDialog/CnFormDialog.vue.js +1 -1
  26. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +19 -3
  27. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  28. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  29. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +30 -0
  30. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  31. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +513 -481
  32. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  33. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue.js +9 -0
  34. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue.js.map +1 -0
  35. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue2.js +181 -0
  36. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue2.js.map +1 -0
  37. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue3.js +50 -0
  38. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue3.js.map +1 -0
  39. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue.js +1 -1
  40. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +102 -1
  41. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  42. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +6 -6
  43. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  44. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue.js +9 -0
  45. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue.js.map +1 -0
  46. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue2.js +190 -0
  47. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue2.js.map +1 -0
  48. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue3.js +91 -0
  49. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue3.js.map +1 -0
  50. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue.js +9 -0
  51. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue.js.map +1 -0
  52. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue2.js +64 -0
  53. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue2.js.map +1 -0
  54. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue3.js +49 -0
  55. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue3.js.map +1 -0
  56. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue.js +9 -0
  57. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue.js.map +1 -0
  58. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue2.js +382 -0
  59. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue2.js.map +1 -0
  60. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue3.js +285 -0
  61. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue3.js.map +1 -0
  62. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue.js +9 -0
  63. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue.js.map +1 -0
  64. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue2.js +277 -0
  65. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue2.js.map +1 -0
  66. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue3.js +183 -0
  67. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue3.js.map +1 -0
  68. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +16 -14
  69. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
  70. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +53 -22
  71. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  72. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue.js +9 -0
  73. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue.js.map +1 -0
  74. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue2.js +246 -0
  75. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue2.js.map +1 -0
  76. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue3.js +197 -0
  77. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue3.js.map +1 -0
  78. package/dist/esm/index.js +12 -0
  79. package/dist/esm/index.js.map +1 -1
  80. package/dist/esm/l10n/en.json.js +106 -1
  81. package/dist/esm/l10n/en.json.js.map +1 -1
  82. package/dist/esm/l10n/nl.json.js +105 -1
  83. package/dist/esm/l10n/nl.json.js.map +1 -1
  84. package/dist/esm/library-style.js +1 -1
  85. package/dist/esm/nextcloud-vue.css +495 -61
  86. package/dist/esm/utils/actionsDispatcher.js +6 -1
  87. package/dist/esm/utils/actionsDispatcher.js.map +1 -1
  88. package/dist/esm/utils/builtInModals.js +3 -1
  89. package/dist/esm/utils/builtInModals.js.map +1 -1
  90. package/dist/esm/utils/duplicateWarning.js +62 -0
  91. package/dist/esm/utils/duplicateWarning.js.map +1 -0
  92. package/dist/esm/utils/errors.js +4 -0
  93. package/dist/esm/utils/errors.js.map +1 -1
  94. package/dist/esm/utils/libraryWidgetKeys.js +4 -0
  95. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  96. package/dist/esm/utils/openDuplicateWarning.js +39 -0
  97. package/dist/esm/utils/openDuplicateWarning.js.map +1 -0
  98. package/dist/esm/utils/optionsFrom.js +69 -2
  99. package/dist/esm/utils/optionsFrom.js.map +1 -1
  100. package/dist/esm/utils/planTree.js +57 -0
  101. package/dist/esm/utils/planTree.js.map +1 -0
  102. package/dist/esm/utils/redactionSegments.js +53 -0
  103. package/dist/esm/utils/redactionSegments.js.map +1 -0
  104. package/dist/esm/utils/registerNcDashboardWidgets.js +61 -0
  105. package/dist/esm/utils/registerNcDashboardWidgets.js.map +1 -0
  106. package/dist/esm/utils/searchRefusal.js +62 -0
  107. package/dist/esm/utils/searchRefusal.js.map +1 -0
  108. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  109. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  110. package/dist/nextcloud-vue.cjs.js +17409 -12832
  111. package/dist/nextcloud-vue.cjs.js.map +2 -2
  112. package/dist/nextcloud-vue.css +495 -61
  113. package/l10n/en.json +106 -1
  114. package/l10n/nl.json +105 -1
  115. package/package.json +1 -1
  116. package/src/components/CnAddressSearch/CnAddressSearch.vue +343 -0
  117. package/src/components/CnAddressSearch/index.js +12 -0
  118. package/src/components/CnAssignDialog/CnAssignDialog.vue +525 -0
  119. package/src/components/CnAssignDialog/index.js +12 -0
  120. package/src/components/CnDecisionListWidget/CnDecisionListWidget.vue +388 -0
  121. package/src/components/CnDecisionListWidget/index.js +12 -0
  122. package/src/components/CnDuplicateWarning/CnDuplicateWarning.vue +318 -0
  123. package/src/components/CnDuplicateWarning/index.js +12 -0
  124. package/src/components/CnFormDialog/CnFormDialog.vue +19 -3
  125. package/src/components/CnIndexPage/CnIndexPage.vue +52 -0
  126. package/src/components/CnNcDashboardList/CnNcDashboardList.vue +218 -0
  127. package/src/components/CnNcDashboardList/index.js +12 -0
  128. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +107 -6
  129. package/src/components/CnPlanWidget/CnPlanWidget.vue +246 -0
  130. package/src/components/CnPlanWidget/CnPlanWidgetRow.vue +117 -0
  131. package/src/components/CnPlanWidget/index.js +12 -0
  132. package/src/components/CnRedactionEditor/CnRedactionEditor.vue +655 -0
  133. package/src/components/CnRedactionEditor/index.js +13 -0
  134. package/src/components/CnRetentionWidget/CnRetentionWidget.vue +413 -0
  135. package/src/components/CnRetentionWidget/index.js +12 -0
  136. package/src/components/CnWidgetGrid/builtInWidgets.js +2 -0
  137. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +31 -0
  138. package/src/components/CnWorkQueue/CnWorkQueue.vue +456 -0
  139. package/src/components/CnWorkQueue/index.js +12 -0
  140. package/src/components/index.js +9 -0
  141. package/src/css/index-page.css +24 -0
  142. package/src/index.js +12 -0
  143. package/src/schemas/app-manifest-v2.schema.json +119 -3
  144. package/src/utils/actionsDispatcher.js +6 -1
  145. package/src/utils/builtInModals.js +3 -1
  146. package/src/utils/duplicateWarning.js +59 -0
  147. package/src/utils/errors.js +4 -0
  148. package/src/utils/libraryWidgetKeys.js +4 -0
  149. package/src/utils/openDuplicateWarning.js +35 -0
  150. package/src/utils/optionsFrom.js +68 -1
  151. package/src/utils/planTree.js +54 -0
  152. package/src/utils/redactionSegments.js +50 -0
  153. package/src/utils/registerNcDashboardWidgets.js +57 -0
  154. package/src/utils/searchRefusal.js +59 -0
  155. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnRetentionWidget.vue2.js","sources":["../../../../src/components/CnRetentionWidget/CnRetentionWidget.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div class=\"cn-retention\" data-testid=\"cn-retention\">\n\t\t<header class=\"cn-retention__head\">\n\t\t\t<h3 class=\"cn-retention__title\">\n\t\t\t\t{{ text(content.title) || t('nextcloud-vue', 'Archiving') }}\n\t\t\t</h3>\n\t\t\t<p class=\"cn-retention__muted\">\n\t\t\t\t{{ text(content.subtitle) || t('nextcloud-vue', 'What happens to this record once it is closed') }}\n\t\t\t</p>\n\t\t</header>\n\n\t\t<NcLoadingIcon v-if=\"loading\" :size=\"24\" />\n\t\t<NcEmptyContent v-else-if=\"error\"\n\t\t\t:name=\"t('nextcloud-vue', 'The archival facts are unavailable')\"\n\t\t\t:description=\"error\"\n\t\t\tdata-testid=\"cn-retention-error\">\n\t\t\t<template #action>\n\t\t\t\t<NcButton data-testid=\"cn-retention-retry\" @click=\"load\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Try again') }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</NcEmptyContent>\n\n\t\t<template v-else>\n\t\t\t<p v-if=\"archived\" class=\"cn-retention__archived\" data-testid=\"cn-retention-archived\">\n\t\t\t\t{{ t('nextcloud-vue', 'Archived on {at} by {by}. {reason}', { at: String(archived.at ?? ''), by: String(archived.by ?? ''), reason: String(archived.reason ?? '') }) }}\n\t\t\t</p>\n\t\t\t<NcNoteCard v-if=\"disagrees\" type=\"warning\" data-testid=\"cn-retention-disagreement\">\n\t\t\t\t{{ t('nextcloud-vue', 'This record and OpenRegister do not agree on whether it is archived.') }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<NcNoteCard v-if=\"nomination && nomination.status === 'unnominatable'\" type=\"warning\" data-testid=\"cn-retention-unnominatable\">\n\t\t\t\t{{ t('nextcloud-vue', 'Nothing could decide what happens to this record.') }}\n\t\t\t\t{{ String(nomination.unnominatableReason ?? '') }}\n\t\t\t</NcNoteCard>\n\t\t\t<div v-else-if=\"!nomination\" data-testid=\"cn-retention-pending\">\n\t\t\t\t<dl class=\"cn-retention__facts\">\n\t\t\t\t\t<div v-for=\"fact in pendingFacts\" :key=\"fact.key\" class=\"cn-retention__fact\">\n\t\t\t\t\t\t<dt>{{ fact.label }}</dt>\n\t\t\t\t\t\t<dd>{{ fact.value }}</dd>\n\t\t\t\t\t</div>\n\t\t\t\t</dl>\n\t\t\t\t<NcNoteCard type=\"info\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'This record has not been closed yet. Its archival future is recorded when it closes.') }}\n\t\t\t\t</NcNoteCard>\n\t\t\t</div>\n\t\t\t<dl v-else class=\"cn-retention__facts\" data-testid=\"cn-retention-facts\">\n\t\t\t\t<div v-for=\"fact in facts\" :key=\"fact.key\" class=\"cn-retention__fact\">\n\t\t\t\t\t<dt>{{ fact.label }}</dt>\n\t\t\t\t\t<dd :data-testid=\"`cn-retention-${fact.key}`\">\n\t\t\t\t\t\t{{ fact.value }}\n\t\t\t\t\t</dd>\n\t\t\t\t</div>\n\t\t\t</dl>\n\n\t\t\t<div v-if=\"outcome\" class=\"cn-retention__outcome\" data-testid=\"cn-retention-outcome\">\n\t\t\t\t<h4>{{ t('nextcloud-vue', 'Outcome') }}</h4>\n\t\t\t\t<p>{{ t('nextcloud-vue', 'Handed over as {kind} on {at} by {by}.', { kind: String(outcome.kind ?? ''), at: String(outcome.at ?? ''), by: String(outcome.by ?? '') }) }}</p>\n\t\t\t\t<p v-if=\"outcome.transferListUuid\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Transfer list') }}: {{ outcome.transferListUuid }}\n\t\t\t\t</p>\n\t\t\t</div>\n\n\t\t\t<div v-if=\"content.recompute !== false\" class=\"cn-retention__recompute\">\n\t\t\t\t<NcButton v-if=\"!mayRecompute\" disabled data-testid=\"cn-retention-recompute-denied\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Recomputing needs the archivist role') }}\n\t\t\t\t</NcButton>\n\t\t\t\t<template v-else>\n\t\t\t\t\t<NcTextField :modelValue=\"reason\"\n\t\t\t\t\t\t:label=\"t('nextcloud-vue', 'Why are you recomputing this?')\"\n\t\t\t\t\t\tdata-testid=\"cn-retention-reason\"\n\t\t\t\t\t\t@update:modelValue=\"(v) => (reason = String(v ?? ''))\" />\n\t\t\t\t\t<p class=\"cn-retention__muted\">\n\t\t\t\t\t\t{{ t('nextcloud-vue', 'This is recorded against {user}.', { user: currentUid }) }}\n\t\t\t\t\t</p>\n\t\t\t\t\t<NcButton :disabled=\"busy || reason.trim() === ''\" data-testid=\"cn-retention-recompute\" @click=\"recompute\">\n\t\t\t\t\t\t{{ t('nextcloud-vue', 'Recompute the nomination') }}\n\t\t\t\t\t</NcButton>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</template>\n\t</div>\n</template>\n\n<script>\nimport { getCurrentUser } from '@nextcloud/auth'\nimport axios from '@nextcloud/axios'\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcButton, NcEmptyContent, NcLoadingIcon, NcNoteCard, NcTextField } from '@nextcloud/vue'\nimport { readPath } from '../../utils/readPath.js'\n\n/**\n * CnRetentionWidget — the `retention` detail widget: what happens to a\n * record when its business use ends, as OpenRegister decided it. Every value\n * is read off the record's `@self._retention` (appraisal, disposal date,\n * retention period, selection list row, the rule and when it was written)\n * and `@self.archived`; the widget derives nothing, so it can never disagree\n * with the stored decision. A failed read is an error with a retry, never an\n * empty block. A record nothing could nominate is drawn apart from one that\n * is not closed yet. An archivist (or an admin) may ask OpenRegister to\n * recompute the nomination, with a reason. Any app on OpenRegister uses it;\n * dossiq's case Archiving tab is the first.\n *\n * `content`:\n * - `title`, `subtitle`: texts, through the host translate.\n * - `statusField`, `archivedValues`: a record field and the values that mean\n * archived (`archiveStatus`, `[\"archived\", ...]`); when set, a mismatch with\n * `@self.archived` is said out loud.\n * - `archivistGroups`: groups that may recompute (default `[\"archivaris\"]`;\n * admins always may); `recompute: false` hides the control.\n *\n * The record is read fresh from OpenRegister by `register`, `schema` and\n * `objectId` (props, else the bound record's `@self`).\n */\nexport default {\n\tname: 'CnRetentionWidget',\n\n\tcomponents: { NcButton, NcEmptyContent, NcLoadingIcon, NcNoteCard, NcTextField },\n\n\tinject: {\n\t\t/** The host app's translate (CnAppRoot `cnTranslate`). */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The widget's configuration (see the component docs).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tcontent: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * The bound record, on a detail page.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tobjectData: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The record's register (else the bound record's `@self.register`). */\n\t\tregister: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The record's schema (else the bound record's `@self.schema`); a schema object gives its slug.\n\t\t *\n\t\t * @type {string|number|object}\n\t\t */\n\t\tschema: {\n\t\t\ttype: [String, Number, Object],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The record's id (else the bound record's). */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tloading: true,\n\t\t\terror: '',\n\t\t\trecord: null,\n\t\t\treason: '',\n\t\t\tbusy: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {object} The bound record's `@self`. */\n\t\tboundSelf() {\n\t\t\treturn (this.objectData && this.objectData['@self']) || {}\n\t\t},\n\n\t\t/** @return {string} The record id. */\n\t\tid() {\n\t\t\treturn String(this.objectId || (this.objectData && this.objectData.id) || this.boundSelf.id || '')\n\t\t},\n\n\t\t/** @return {string} The register. */\n\t\tregisterRef() {\n\t\t\treturn String(this.register || this.boundSelf.register || '')\n\t\t},\n\n\t\t/** @return {string} The schema. */\n\t\tschemaRef() {\n\t\t\tconst s = this.schema || this.boundSelf.schema || ''\n\t\t\treturn String(typeof s === 'object' ? (s.slug || s.id || '') : s)\n\t\t},\n\n\t\t/** @return {object} The record's `@self`. */\n\t\tself() {\n\t\t\treturn (this.record && this.record['@self']) || {}\n\t\t},\n\n\t\t/** @return {object|null} OpenRegister's stored retention decision. */\n\t\tretention() {\n\t\t\treturn this.self._retention || null\n\t\t},\n\n\t\t/** @return {object|null} The nomination. */\n\t\tnomination() {\n\t\t\treturn (this.retention && this.retention.nomination) || null\n\t\t},\n\n\t\t/** @return {object|null} The hand-over outcome. */\n\t\toutcome() {\n\t\t\treturn (this.retention && this.retention.outcome) || null\n\t\t},\n\n\t\t/** @return {object|null} OpenRegister's archived marker. */\n\t\tarchived() {\n\t\t\treturn this.self.archived || null\n\t\t},\n\n\t\t/**\n\t\t * Whether the record's own field and the platform marker disagree.\n\t\t *\n\t\t * @spec openspec/changes/retention-widget/specs/retention-widget/spec.md#requirement-a-record-shows-its-stored-retention\n\t\t * @return {boolean}\n\t\t */\n\t\tdisagrees() {\n\t\t\tconst field = this.content.statusField\n\t\t\tif (!field || !this.record) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst values = Array.isArray(this.content.archivedValues) ? this.content.archivedValues.map(String) : ['archived']\n\t\t\tconst saysArchived = values.includes(String(readPath(this.record, field) ?? ''))\n\t\t\treturn saysArchived !== Boolean(this.archived)\n\t\t},\n\n\t\t/**\n\t\t * The stored facts that have a value, in reading order.\n\t\t *\n\t\t * @spec openspec/changes/retention-widget/specs/retention-widget/spec.md#requirement-a-record-shows-its-stored-retention\n\t\t * @return {Array<{key: string, label: string, value: string}>}\n\t\t */\n\t\tfacts() {\n\t\t\tconst r = this.retention || {}\n\t\t\tconst n = this.nomination || {}\n\t\t\treturn [\n\t\t\t\t{ key: 'appraisal', label: t('nextcloud-vue', 'Appraisal'), value: r.appraisal },\n\t\t\t\t{ key: 'disposal-date', label: t('nextcloud-vue', 'Disposal date'), value: r.disposalDate },\n\t\t\t\t{ key: 'retention-period', label: t('nextcloud-vue', 'Retention period'), value: r.retentionPeriod },\n\t\t\t\t{ key: 'selection-list-row', label: t('nextcloud-vue', 'Selection list row'), value: r.selectionListRow },\n\t\t\t\t{ key: 'rule', label: t('nextcloud-vue', 'Decided by'), value: n.rule },\n\t\t\t\t{ key: 'decided-at', label: t('nextcloud-vue', 'Written on'), value: n.at },\n\t\t\t].filter((fact) => fact.value !== undefined && fact.value !== null && fact.value !== '').map((fact) => ({ ...fact, value: String(fact.value) }))\n\t\t},\n\n\t\t/** @return {Array<{key: string, label: string, value: string}>} The facts of a record not closed yet. */\n\t\tpendingFacts() {\n\t\t\tconst atClosure = t('nextcloud-vue', 'Decided when it closes')\n\t\t\treturn [\n\t\t\t\t{ key: 'appraisal', label: t('nextcloud-vue', 'Appraisal'), value: atClosure },\n\t\t\t\t{ key: 'retention-period', label: t('nextcloud-vue', 'Retention period'), value: atClosure },\n\t\t\t\t{ key: 'disposal-date', label: t('nextcloud-vue', 'Disposal date'), value: atClosure },\n\t\t\t\t{ key: 'decided-at', label: t('nextcloud-vue', 'Written on'), value: t('nextcloud-vue', 'Not yet') },\n\t\t\t]\n\t\t},\n\n\t\t/** @return {string} The signed-in user's id. */\n\t\tcurrentUid() {\n\t\t\tconst user = getCurrentUser()\n\t\t\treturn String((user && user.uid) || '')\n\t\t},\n\n\t\t/**\n\t\t * Whether this user may recompute: an admin or an archivist group member.\n\t\t * Shown disabled otherwise, so the user learns which role it needs.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tmayRecompute() {\n\t\t\tconst user = getCurrentUser()\n\t\t\tif (user && user.isAdmin === true) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tconst groups = Array.isArray(user && user.groups) ? user.groups : []\n\t\t\tconst allowed = Array.isArray(this.content.archivistGroups) ? this.content.archivistGroups : ['archivaris']\n\t\t\treturn allowed.some((g) => groups.includes(g))\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.load()\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * A config text through the host translate.\n\t\t *\n\t\t * @param {unknown} value The text.\n\t\t * @return {string}\n\t\t */\n\t\ttext(value) {\n\t\t\treturn typeof value === 'string' && value !== '' ? this.cnTranslate(value) : ''\n\t\t},\n\n\t\t/**\n\t\t * Read the record fresh from OpenRegister; a failure is an error, never an empty block.\n\t\t *\n\t\t * @spec openspec/changes/retention-widget/specs/retention-widget/spec.md#requirement-a-record-shows-its-stored-retention\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync load() {\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\ttry {\n\t\t\t\tif (!this.registerRef || !this.schemaRef || !this.id) {\n\t\t\t\t\tthrow new Error(t('nextcloud-vue', 'This widget has no record to read.'))\n\t\t\t\t}\n\t\t\t\tconst { data } = await axios.get(generateUrl(`/apps/openregister/api/objects/${encodeURIComponent(this.registerRef)}/${encodeURIComponent(this.schemaRef)}/${encodeURIComponent(this.id)}`))\n\t\t\t\tthis.record = data && typeof data === 'object' ? data : null\n\t\t\t} catch (failure) {\n\t\t\t\tconst body = failure && failure.response && failure.response.data\n\t\t\t\tthis.error = String((body && (body.message || body.error)) || (failure && failure.message) || failure)\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Ask OpenRegister to derive the nomination again, then read it back.\n\t\t *\n\t\t * @spec openspec/changes/retention-widget/specs/retention-widget/spec.md#requirement-a-record-shows-its-stored-retention\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync recompute() {\n\t\t\tif (this.busy || this.reason.trim() === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.busy = true\n\t\t\ttry {\n\t\t\t\tawait axios.post(generateUrl(`/apps/openregister/api/archival/objects/${encodeURIComponent(this.id)}/nomination/recompute`), { reason: this.reason.trim() })\n\t\t\t\tthis.reason = ''\n\t\t\t\tawait this.load()\n\t\t\t} catch (failure) {\n\t\t\t\tconst body = failure && failure.response && failure.response.data\n\t\t\t\tthis.error = String((body && (body.message || body.error)) || (failure && failure.message) || failure)\n\t\t\t} finally {\n\t\t\t\tthis.busy = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-retention {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n}\n\n.cn-retention__head {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n\n.cn-retention__title {\n\tmargin: 0;\n\tfont-size: 18px;\n\tfont-weight: 700;\n}\n\n.cn-retention__muted {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-retention__facts {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n\tgap: 12px 24px;\n\tmargin: 0;\n}\n\n.cn-retention__fact dt {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-retention__fact dd {\n\tmargin: 0;\n\tfont-weight: 600;\n}\n\n.cn-retention__recompute {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmax-width: 480px;\n}\n</style>\n"],"names":["t","axios"],"mappings":";;;;;;;AAgGA;;AAEC;AACA;;AAEA;;;;AAIA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;;;;AAID,aAAe;CACd,IAAI,EAAE,mBAAmB;;AAEzB,CAAA,UAAU,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa;;AAEhF,CAAA,MAAM,EAAE;;AAEP,EAAA,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,KAAK,KAAK;EAC5C;;AAED,CAAA,KAAK,EAAE;AACN;;AAEC;;;AAGD,EAAA,OAAO,EAAE;GACR,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,OAAO,EAAE,CAAC;GACnB;;AAED;;AAEC;AACA;;EAED,UAAU,EAAE;GACX,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,IAAI;GACb;;AAED;AACA,EAAA,QAAQ,EAAE;AACT,GAAA,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;GACtB,OAAO,EAAE,EAAE;GACX;;AAED;AACC;AACA;;;AAGD,EAAA,MAAM,EAAE;GACP,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;GAC9B,OAAO,EAAE,EAAE;GACX;;AAED;AACA,EAAA,QAAQ,EAAE;AACT,GAAA,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;GACtB,OAAO,EAAE,EAAE;GACX;EACD;;AAED,CAAA,IAAI,GAAG;AACN,EAAA,OAAO;GACN,OAAO,EAAE,IAAI;AACb,GAAA,KAAK,EAAE,EAAE;GACT,MAAM,EAAE,IAAI;AACZ,GAAA,MAAM,EAAE,EAAE;GACV,IAAI,EAAE,KAAK;AACZ,GAAA;EACA;;AAED,CAAA,QAAQ,EAAE;AACT;EACA,SAAS,GAAG;GACX,OAAO,CAAC,IAAI,CAAC,UAAS,IAAK,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAC;GACzD;;AAED;EACA,EAAE,GAAG;AACJ,GAAA,OAAO,MAAM,CAAC,IAAI,CAAC,QAAO,KAAM,IAAI,CAAC,UAAS,IAAK,IAAI,CAAC,UAAU,CAAC,EAAE,CAAE,IAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAA;GACjG;;AAED;EACA,WAAW,GAAG;GACb,OAAO,MAAM,CAAC,IAAI,CAAC,QAAS,IAAG,IAAI,CAAC,SAAS,CAAC,QAAS,IAAG,EAAE,CAAA;GAC5D;;;EAGD,SAAS,GAAG;AACX,GAAA,MAAM,CAAE,GAAE,IAAI,CAAC,MAAO,IAAG,IAAI,CAAC,SAAS,CAAC,MAAO,IAAG,GAAC;GACnD,OAAO,MAAM,CAAC,OAAO,MAAM,QAAS,IAAG,CAAC,CAAC,IAAG,IAAK,CAAC,CAAC,EAAG,IAAG,EAAE,IAAI,CAAC,CAAA;GAChE;;AAED;AACA,EAAA,IAAI,GAAG;AACN,GAAA,OAAO,CAAC,IAAI,CAAC,MAAO,IAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAC;GACjD;;AAED;EACA,SAAS,GAAG;AACX,GAAA,OAAO,IAAI,CAAC,IAAI,CAAC,UAAW,IAAG,IAAG;GAClC;;AAED;EACA,UAAU,GAAG;GACZ,OAAO,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,UAAU,KAAK,IAAG;GAC3D;;AAED;AACA,EAAA,OAAO,GAAG;GACT,OAAO,CAAC,IAAI,CAAC,SAAQ,IAAK,IAAI,CAAC,SAAS,CAAC,OAAO,KAAK,IAAG;GACxD;;;EAGD,QAAQ,GAAG;GACV,OAAO,IAAI,CAAC,IAAI,CAAC,QAAO,IAAK,IAAG;GAChC;;AAED;;AAEC;;AAEA;;EAED,SAAS,GAAG;AACX,GAAA,MAAM,KAAI,GAAI,IAAI,CAAC,OAAO,CAAC,YAAU;GACrC,IAAI,CAAC,KAAM,IAAG,CAAC,IAAI,CAAC,MAAM,EAAE;IAC3B,OAAO,KAAI;AACZ,IAAA;GACA,MAAM,MAAO,GAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,UAAU,EAAA;AACjH,GAAA,MAAM,YAAW,GAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAE,IAAG,EAAE,CAAC,EAAA;AAC/E,GAAA,OAAO,YAAW,KAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAA;GAC7C;;AAED;AACC;AACA;;;;AAID,EAAA,KAAK,GAAG;GACP,MAAM,IAAI,IAAI,CAAC,SAAQ,IAAK,GAAC;GAC7B,MAAM,IAAI,IAAI,CAAC,UAAS,IAAK,GAAC;AAC9B,GAAA,OAAO;AACN,IAAA,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,WAAW;AAChF,IAAA,EAAE,GAAG,EAAE,eAAe,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,eAAe,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,cAAc;AAC3F,IAAA,EAAE,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,kBAAkB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,iBAAiB;IACpG,EAAE,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,oBAAoB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,gBAAe,EAAG;AACzG,IAAA,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAG,EAAG;AACvE,IAAA,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI;IAC3E,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAM,KAAI,SAAU,IAAG,IAAI,CAAC,KAAM,KAAI,IAAG,IAAK,IAAI,CAAC,KAAI,KAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAE,EAAC,CAAC,CAAA;GAC/I;;AAED;AACA,EAAA,YAAY,GAAG;GACd,MAAM,YAAYA,SAAC,CAAC,eAAe,EAAE,wBAAwB,EAAA;AAC7D,GAAA,OAAO;AACN,IAAA,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,WAAW,CAAC,EAAE,KAAK,EAAE,WAAW;AAC9E,IAAA,EAAE,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,kBAAkB,CAAC,EAAE,KAAK,EAAE,WAAW;AAC5F,IAAA,EAAE,GAAG,EAAE,eAAe,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,eAAe,CAAC,EAAE,KAAK,EAAE,WAAW;AACtF,IAAA,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,YAAY,CAAC,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,SAAS,GAAG;AACrG,IAAA;GACA;;AAED;EACA,UAAU,GAAG;GACZ,MAAM,IAAK,GAAE,cAAc,GAAC;AAC5B,GAAA,OAAO,MAAM,CAAC,CAAC,IAAG,IAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAA;GACtC;;AAED;;;AAGC;AACA;;AAED,EAAA,YAAY,GAAG;GACd,MAAM,IAAK,GAAE,cAAc,GAAC;GAC5B,IAAI,IAAK,IAAG,IAAI,CAAC,OAAQ,KAAI,IAAI,EAAE;AAClC,IAAA,OAAO,IAAG;AACX,IAAA;GACA,MAAM,MAAO,GAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAA,GAAI,IAAI,CAAC,MAAO,GAAE,GAAC;GACnE,MAAM,UAAU,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,CAAC,eAAc,GAAI,CAAC,YAAY,EAAA;AAC1G,GAAA,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;GAC7C;EACD;;AAED,CAAA,OAAO,GAAG;EACT,IAAI,CAAC,IAAI,GAAC;EACV;;AAED,CAAA,OAAO,EAAE;KACRA,SAAC;;AAED;AACC;AACA;;AAEA;;EAED,IAAI,CAAC,KAAK,EAAE;AACX,GAAA,OAAO,OAAO,KAAM,KAAI,QAAO,IAAK,KAAI,KAAM,EAAG,GAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAA,GAAI,EAAC;GAC9E;;AAED;AACC;AACA;;;;EAID,MAAM,IAAI,GAAG;AACZ,GAAA,IAAI,CAAC,OAAM,GAAI,KAAG;GAClB,IAAI,CAAC,KAAM,GAAE,GAAC;AACd,GAAA,IAAI;IACH,IAAI,CAAC,IAAI,CAAC,WAAU,IAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE;AACrD,KAAA,MAAM,IAAI,KAAK,CAACA,SAAC,CAAC,eAAe,EAAE,oCAAoC,CAAC,CAAA;AACzE,KAAA;AACA,IAAA,MAAM,EAAE,IAAG,EAAI,GAAE,MAAMC,cAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,+BAA+B,EAAE,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAA;IAC3L,IAAI,CAAC,MAAK,GAAI,IAAK,IAAG,OAAO,SAAS,QAAO,GAAI,IAAK,GAAE,KAAG;AAC5D,IAAA,CAAE,OAAO,OAAO,EAAE;IACjB,MAAM,IAAG,GAAI,OAAQ,IAAG,OAAO,CAAC,QAAO,IAAK,OAAO,CAAC,QAAQ,CAAC,KAAG;AAChE,IAAA,IAAI,CAAC,KAAI,GAAI,MAAM,CAAC,CAAC,IAAG,KAAM,IAAI,CAAC,OAAM,IAAK,IAAI,CAAC,KAAK,CAAC,MAAM,WAAW,OAAO,CAAC,OAAO,CAAE,IAAG,OAAO,EAAA;AACtG,IAAA,SAAU;AACT,IAAA,IAAI,CAAC,OAAQ,GAAE,MAAI;AACpB,IAAA;GACA;;AAED;;AAEC;;;;AAID,EAAA,MAAM,SAAS,GAAG;AACjB,GAAA,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,OAAO,EAAE,EAAE;IAC3C,MAAK;AACN,IAAA;GACA,IAAI,CAAC,IAAK,GAAE,KAAG;AACf,GAAA,IAAI;AACH,IAAA,MAAMA,cAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,wCAAwC,EAAE,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,qBAAqB,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,EAAA;IAC3J,IAAI,CAAC,MAAO,GAAE,GAAC;AACf,IAAA,MAAM,IAAI,CAAC,IAAI,GAAC;AACjB,IAAA,CAAE,OAAO,OAAO,EAAE;IACjB,MAAM,IAAG,GAAI,OAAQ,IAAG,OAAO,CAAC,QAAO,IAAK,OAAO,CAAC,QAAQ,CAAC,KAAG;AAChE,IAAA,IAAI,CAAC,KAAI,GAAI,MAAM,CAAC,CAAC,IAAG,KAAM,IAAI,CAAC,OAAM,IAAK,IAAI,CAAC,KAAK,CAAC,MAAM,WAAW,OAAO,CAAC,OAAO,CAAE,IAAG,OAAO,EAAA;AACtG,IAAA,SAAU;AACT,IAAA,IAAI,CAAC,IAAG,GAAI,MAAI;AACjB,IAAA;GACA;EACD;AACF;;;;"}
@@ -0,0 +1,183 @@
1
+ import { resolveComponent, openBlock, createElementBlock, createElementVNode, toDisplayString, createBlock, withCtx, createVNode, createTextVNode, Fragment, createCommentVNode, renderList } from 'vue';
2
+
3
+ const _hoisted_1 = {
4
+ class: "cn-retention",
5
+ "data-testid": "cn-retention"
6
+ };
7
+ const _hoisted_2 = { class: "cn-retention__head" };
8
+ const _hoisted_3 = { class: "cn-retention__title" };
9
+ const _hoisted_4 = { class: "cn-retention__muted" };
10
+ const _hoisted_5 = {
11
+ key: 0,
12
+ class: "cn-retention__archived",
13
+ "data-testid": "cn-retention-archived"
14
+ };
15
+ const _hoisted_6 = {
16
+ key: 3,
17
+ "data-testid": "cn-retention-pending"
18
+ };
19
+ const _hoisted_7 = { class: "cn-retention__facts" };
20
+ const _hoisted_8 = {
21
+ key: 4,
22
+ class: "cn-retention__facts",
23
+ "data-testid": "cn-retention-facts"
24
+ };
25
+ const _hoisted_9 = ["data-testid"];
26
+ const _hoisted_10 = {
27
+ key: 5,
28
+ class: "cn-retention__outcome",
29
+ "data-testid": "cn-retention-outcome"
30
+ };
31
+ const _hoisted_11 = { key: 0 };
32
+ const _hoisted_12 = {
33
+ key: 6,
34
+ class: "cn-retention__recompute"
35
+ };
36
+ const _hoisted_13 = { class: "cn-retention__muted" };
37
+
38
+ function render(_ctx, _cache, $props, $setup, $data, $options) {
39
+ const _component_NcLoadingIcon = resolveComponent("NcLoadingIcon");
40
+ const _component_NcButton = resolveComponent("NcButton");
41
+ const _component_NcEmptyContent = resolveComponent("NcEmptyContent");
42
+ const _component_NcNoteCard = resolveComponent("NcNoteCard");
43
+ const _component_NcTextField = resolveComponent("NcTextField");
44
+
45
+ return (openBlock(), createElementBlock("div", _hoisted_1, [
46
+ createElementVNode("header", _hoisted_2, [
47
+ createElementVNode("h3", _hoisted_3, toDisplayString($options.text($props.content.title) || $options.t('nextcloud-vue', 'Archiving')), 1 /* TEXT */),
48
+ createElementVNode("p", _hoisted_4, toDisplayString($options.text($props.content.subtitle) || $options.t('nextcloud-vue', 'What happens to this record once it is closed')), 1 /* TEXT */)
49
+ ]),
50
+ ($data.loading)
51
+ ? (openBlock(), createBlock(_component_NcLoadingIcon, {
52
+ key: 0,
53
+ size: 24
54
+ }))
55
+ : ($data.error)
56
+ ? (openBlock(), createBlock(_component_NcEmptyContent, {
57
+ key: 1,
58
+ name: $options.t('nextcloud-vue', 'The archival facts are unavailable'),
59
+ description: $data.error,
60
+ "data-testid": "cn-retention-error"
61
+ }, {
62
+ action: withCtx(() => [
63
+ createVNode(_component_NcButton, {
64
+ "data-testid": "cn-retention-retry",
65
+ onClick: $options.load
66
+ }, {
67
+ default: withCtx(() => [
68
+ createTextVNode(toDisplayString($options.t('nextcloud-vue', 'Try again')), 1 /* TEXT */)
69
+ ]),
70
+ _: 1 /* STABLE */
71
+ }, 8 /* PROPS */, ["onClick"])
72
+ ]),
73
+ _: 1 /* STABLE */
74
+ }, 8 /* PROPS */, ["name", "description"]))
75
+ : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
76
+ ($options.archived)
77
+ ? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString($options.t('nextcloud-vue', 'Archived on {at} by {by}. {reason}', { at: String($options.archived.at ?? ''), by: String($options.archived.by ?? ''), reason: String($options.archived.reason ?? '') })), 1 /* TEXT */))
78
+ : createCommentVNode("v-if", true),
79
+ ($options.disagrees)
80
+ ? (openBlock(), createBlock(_component_NcNoteCard, {
81
+ key: 1,
82
+ type: "warning",
83
+ "data-testid": "cn-retention-disagreement"
84
+ }, {
85
+ default: withCtx(() => [
86
+ createTextVNode(toDisplayString($options.t('nextcloud-vue', 'This record and OpenRegister do not agree on whether it is archived.')), 1 /* TEXT */)
87
+ ]),
88
+ _: 1 /* STABLE */
89
+ }))
90
+ : createCommentVNode("v-if", true),
91
+ ($options.nomination && $options.nomination.status === 'unnominatable')
92
+ ? (openBlock(), createBlock(_component_NcNoteCard, {
93
+ key: 2,
94
+ type: "warning",
95
+ "data-testid": "cn-retention-unnominatable"
96
+ }, {
97
+ default: withCtx(() => [
98
+ createTextVNode(toDisplayString($options.t('nextcloud-vue', 'Nothing could decide what happens to this record.')) + " " + toDisplayString(String($options.nomination.unnominatableReason ?? '')), 1 /* TEXT */)
99
+ ]),
100
+ _: 1 /* STABLE */
101
+ }))
102
+ : (!$options.nomination)
103
+ ? (openBlock(), createElementBlock("div", _hoisted_6, [
104
+ createElementVNode("dl", _hoisted_7, [
105
+ (openBlock(true), createElementBlock(Fragment, null, renderList($options.pendingFacts, (fact) => {
106
+ return (openBlock(), createElementBlock("div", {
107
+ key: fact.key,
108
+ class: "cn-retention__fact"
109
+ }, [
110
+ createElementVNode("dt", null, toDisplayString(fact.label), 1 /* TEXT */),
111
+ createElementVNode("dd", null, toDisplayString(fact.value), 1 /* TEXT */)
112
+ ]))
113
+ }), 128 /* KEYED_FRAGMENT */))
114
+ ]),
115
+ createVNode(_component_NcNoteCard, { type: "info" }, {
116
+ default: withCtx(() => [
117
+ createTextVNode(toDisplayString($options.t('nextcloud-vue', 'This record has not been closed yet. Its archival future is recorded when it closes.')), 1 /* TEXT */)
118
+ ]),
119
+ _: 1 /* STABLE */
120
+ })
121
+ ]))
122
+ : (openBlock(), createElementBlock("dl", _hoisted_8, [
123
+ (openBlock(true), createElementBlock(Fragment, null, renderList($options.facts, (fact) => {
124
+ return (openBlock(), createElementBlock("div", {
125
+ key: fact.key,
126
+ class: "cn-retention__fact"
127
+ }, [
128
+ createElementVNode("dt", null, toDisplayString(fact.label), 1 /* TEXT */),
129
+ createElementVNode("dd", {
130
+ "data-testid": `cn-retention-${fact.key}`
131
+ }, toDisplayString(fact.value), 9 /* TEXT, PROPS */, _hoisted_9)
132
+ ]))
133
+ }), 128 /* KEYED_FRAGMENT */))
134
+ ])),
135
+ ($options.outcome)
136
+ ? (openBlock(), createElementBlock("div", _hoisted_10, [
137
+ createElementVNode("h4", null, toDisplayString($options.t('nextcloud-vue', 'Outcome')), 1 /* TEXT */),
138
+ createElementVNode("p", null, toDisplayString($options.t('nextcloud-vue', 'Handed over as {kind} on {at} by {by}.', { kind: String($options.outcome.kind ?? ''), at: String($options.outcome.at ?? ''), by: String($options.outcome.by ?? '') })), 1 /* TEXT */),
139
+ ($options.outcome.transferListUuid)
140
+ ? (openBlock(), createElementBlock("p", _hoisted_11, toDisplayString($options.t('nextcloud-vue', 'Transfer list')) + ": " + toDisplayString($options.outcome.transferListUuid), 1 /* TEXT */))
141
+ : createCommentVNode("v-if", true)
142
+ ]))
143
+ : createCommentVNode("v-if", true),
144
+ ($props.content.recompute !== false)
145
+ ? (openBlock(), createElementBlock("div", _hoisted_12, [
146
+ (!$options.mayRecompute)
147
+ ? (openBlock(), createBlock(_component_NcButton, {
148
+ key: 0,
149
+ disabled: "",
150
+ "data-testid": "cn-retention-recompute-denied"
151
+ }, {
152
+ default: withCtx(() => [
153
+ createTextVNode(toDisplayString($options.t('nextcloud-vue', 'Recomputing needs the archivist role')), 1 /* TEXT */)
154
+ ]),
155
+ _: 1 /* STABLE */
156
+ }))
157
+ : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
158
+ createVNode(_component_NcTextField, {
159
+ modelValue: $data.reason,
160
+ label: $options.t('nextcloud-vue', 'Why are you recomputing this?'),
161
+ "data-testid": "cn-retention-reason",
162
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = (v) => ($data.reason = String(v ?? '')))
163
+ }, null, 8 /* PROPS */, ["modelValue", "label"]),
164
+ createElementVNode("p", _hoisted_13, toDisplayString($options.t('nextcloud-vue', 'This is recorded against {user}.', { user: $options.currentUid })), 1 /* TEXT */),
165
+ createVNode(_component_NcButton, {
166
+ disabled: $data.busy || $data.reason.trim() === '',
167
+ "data-testid": "cn-retention-recompute",
168
+ onClick: $options.recompute
169
+ }, {
170
+ default: withCtx(() => [
171
+ createTextVNode(toDisplayString($options.t('nextcloud-vue', 'Recompute the nomination')), 1 /* TEXT */)
172
+ ]),
173
+ _: 1 /* STABLE */
174
+ }, 8 /* PROPS */, ["disabled", "onClick"])
175
+ ], 64 /* STABLE_FRAGMENT */))
176
+ ]))
177
+ : createCommentVNode("v-if", true)
178
+ ], 64 /* STABLE_FRAGMENT */))
179
+ ]))
180
+ }
181
+
182
+ export { render };
183
+ //# sourceMappingURL=CnRetentionWidget.vue3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnRetentionWidget.vue3.js","sources":["../../../../src/components/CnRetentionWidget/CnRetentionWidget.vue?vue&type=template&id=d883c442&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div class=\"cn-retention\" data-testid=\"cn-retention\">\n\t\t<header class=\"cn-retention__head\">\n\t\t\t<h3 class=\"cn-retention__title\">\n\t\t\t\t{{ text(content.title) || t('nextcloud-vue', 'Archiving') }}\n\t\t\t</h3>\n\t\t\t<p class=\"cn-retention__muted\">\n\t\t\t\t{{ text(content.subtitle) || t('nextcloud-vue', 'What happens to this record once it is closed') }}\n\t\t\t</p>\n\t\t</header>\n\n\t\t<NcLoadingIcon v-if=\"loading\" :size=\"24\" />\n\t\t<NcEmptyContent v-else-if=\"error\"\n\t\t\t:name=\"t('nextcloud-vue', 'The archival facts are unavailable')\"\n\t\t\t:description=\"error\"\n\t\t\tdata-testid=\"cn-retention-error\">\n\t\t\t<template #action>\n\t\t\t\t<NcButton data-testid=\"cn-retention-retry\" @click=\"load\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Try again') }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</NcEmptyContent>\n\n\t\t<template v-else>\n\t\t\t<p v-if=\"archived\" class=\"cn-retention__archived\" data-testid=\"cn-retention-archived\">\n\t\t\t\t{{ t('nextcloud-vue', 'Archived on {at} by {by}. {reason}', { at: String(archived.at ?? ''), by: String(archived.by ?? ''), reason: String(archived.reason ?? '') }) }}\n\t\t\t</p>\n\t\t\t<NcNoteCard v-if=\"disagrees\" type=\"warning\" data-testid=\"cn-retention-disagreement\">\n\t\t\t\t{{ t('nextcloud-vue', 'This record and OpenRegister do not agree on whether it is archived.') }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<NcNoteCard v-if=\"nomination && nomination.status === 'unnominatable'\" type=\"warning\" data-testid=\"cn-retention-unnominatable\">\n\t\t\t\t{{ t('nextcloud-vue', 'Nothing could decide what happens to this record.') }}\n\t\t\t\t{{ String(nomination.unnominatableReason ?? '') }}\n\t\t\t</NcNoteCard>\n\t\t\t<div v-else-if=\"!nomination\" data-testid=\"cn-retention-pending\">\n\t\t\t\t<dl class=\"cn-retention__facts\">\n\t\t\t\t\t<div v-for=\"fact in pendingFacts\" :key=\"fact.key\" class=\"cn-retention__fact\">\n\t\t\t\t\t\t<dt>{{ fact.label }}</dt>\n\t\t\t\t\t\t<dd>{{ fact.value }}</dd>\n\t\t\t\t\t</div>\n\t\t\t\t</dl>\n\t\t\t\t<NcNoteCard type=\"info\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'This record has not been closed yet. Its archival future is recorded when it closes.') }}\n\t\t\t\t</NcNoteCard>\n\t\t\t</div>\n\t\t\t<dl v-else class=\"cn-retention__facts\" data-testid=\"cn-retention-facts\">\n\t\t\t\t<div v-for=\"fact in facts\" :key=\"fact.key\" class=\"cn-retention__fact\">\n\t\t\t\t\t<dt>{{ fact.label }}</dt>\n\t\t\t\t\t<dd :data-testid=\"`cn-retention-${fact.key}`\">\n\t\t\t\t\t\t{{ fact.value }}\n\t\t\t\t\t</dd>\n\t\t\t\t</div>\n\t\t\t</dl>\n\n\t\t\t<div v-if=\"outcome\" class=\"cn-retention__outcome\" data-testid=\"cn-retention-outcome\">\n\t\t\t\t<h4>{{ t('nextcloud-vue', 'Outcome') }}</h4>\n\t\t\t\t<p>{{ t('nextcloud-vue', 'Handed over as {kind} on {at} by {by}.', { kind: String(outcome.kind ?? ''), at: String(outcome.at ?? ''), by: String(outcome.by ?? '') }) }}</p>\n\t\t\t\t<p v-if=\"outcome.transferListUuid\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Transfer list') }}: {{ outcome.transferListUuid }}\n\t\t\t\t</p>\n\t\t\t</div>\n\n\t\t\t<div v-if=\"content.recompute !== false\" class=\"cn-retention__recompute\">\n\t\t\t\t<NcButton v-if=\"!mayRecompute\" disabled data-testid=\"cn-retention-recompute-denied\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Recomputing needs the archivist role') }}\n\t\t\t\t</NcButton>\n\t\t\t\t<template v-else>\n\t\t\t\t\t<NcTextField :modelValue=\"reason\"\n\t\t\t\t\t\t:label=\"t('nextcloud-vue', 'Why are you recomputing this?')\"\n\t\t\t\t\t\tdata-testid=\"cn-retention-reason\"\n\t\t\t\t\t\t@update:modelValue=\"(v) => (reason = String(v ?? ''))\" />\n\t\t\t\t\t<p class=\"cn-retention__muted\">\n\t\t\t\t\t\t{{ t('nextcloud-vue', 'This is recorded against {user}.', { user: currentUid }) }}\n\t\t\t\t\t</p>\n\t\t\t\t\t<NcButton :disabled=\"busy || reason.trim() === ''\" data-testid=\"cn-retention-recompute\" @click=\"recompute\">\n\t\t\t\t\t\t{{ t('nextcloud-vue', 'Recompute the nomination') }}\n\t\t\t\t\t</NcButton>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</template>\n\t</div>\n</template>\n\n<script>\nimport { getCurrentUser } from '@nextcloud/auth'\nimport axios from '@nextcloud/axios'\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcButton, NcEmptyContent, NcLoadingIcon, NcNoteCard, NcTextField } from '@nextcloud/vue'\nimport { readPath } from '../../utils/readPath.js'\n\n/**\n * CnRetentionWidget — the `retention` detail widget: what happens to a\n * record when its business use ends, as OpenRegister decided it. Every value\n * is read off the record's `@self._retention` (appraisal, disposal date,\n * retention period, selection list row, the rule and when it was written)\n * and `@self.archived`; the widget derives nothing, so it can never disagree\n * with the stored decision. A failed read is an error with a retry, never an\n * empty block. A record nothing could nominate is drawn apart from one that\n * is not closed yet. An archivist (or an admin) may ask OpenRegister to\n * recompute the nomination, with a reason. Any app on OpenRegister uses it;\n * dossiq's case Archiving tab is the first.\n *\n * `content`:\n * - `title`, `subtitle`: texts, through the host translate.\n * - `statusField`, `archivedValues`: a record field and the values that mean\n * archived (`archiveStatus`, `[\"archived\", ...]`); when set, a mismatch with\n * `@self.archived` is said out loud.\n * - `archivistGroups`: groups that may recompute (default `[\"archivaris\"]`;\n * admins always may); `recompute: false` hides the control.\n *\n * The record is read fresh from OpenRegister by `register`, `schema` and\n * `objectId` (props, else the bound record's `@self`).\n */\nexport default {\n\tname: 'CnRetentionWidget',\n\n\tcomponents: { NcButton, NcEmptyContent, NcLoadingIcon, NcNoteCard, NcTextField },\n\n\tinject: {\n\t\t/** The host app's translate (CnAppRoot `cnTranslate`). */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The widget's configuration (see the component docs).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tcontent: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * The bound record, on a detail page.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tobjectData: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The record's register (else the bound record's `@self.register`). */\n\t\tregister: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The record's schema (else the bound record's `@self.schema`); a schema object gives its slug.\n\t\t *\n\t\t * @type {string|number|object}\n\t\t */\n\t\tschema: {\n\t\t\ttype: [String, Number, Object],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The record's id (else the bound record's). */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tloading: true,\n\t\t\terror: '',\n\t\t\trecord: null,\n\t\t\treason: '',\n\t\t\tbusy: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {object} The bound record's `@self`. */\n\t\tboundSelf() {\n\t\t\treturn (this.objectData && this.objectData['@self']) || {}\n\t\t},\n\n\t\t/** @return {string} The record id. */\n\t\tid() {\n\t\t\treturn String(this.objectId || (this.objectData && this.objectData.id) || this.boundSelf.id || '')\n\t\t},\n\n\t\t/** @return {string} The register. */\n\t\tregisterRef() {\n\t\t\treturn String(this.register || this.boundSelf.register || '')\n\t\t},\n\n\t\t/** @return {string} The schema. */\n\t\tschemaRef() {\n\t\t\tconst s = this.schema || this.boundSelf.schema || ''\n\t\t\treturn String(typeof s === 'object' ? (s.slug || s.id || '') : s)\n\t\t},\n\n\t\t/** @return {object} The record's `@self`. */\n\t\tself() {\n\t\t\treturn (this.record && this.record['@self']) || {}\n\t\t},\n\n\t\t/** @return {object|null} OpenRegister's stored retention decision. */\n\t\tretention() {\n\t\t\treturn this.self._retention || null\n\t\t},\n\n\t\t/** @return {object|null} The nomination. */\n\t\tnomination() {\n\t\t\treturn (this.retention && this.retention.nomination) || null\n\t\t},\n\n\t\t/** @return {object|null} The hand-over outcome. */\n\t\toutcome() {\n\t\t\treturn (this.retention && this.retention.outcome) || null\n\t\t},\n\n\t\t/** @return {object|null} OpenRegister's archived marker. */\n\t\tarchived() {\n\t\t\treturn this.self.archived || null\n\t\t},\n\n\t\t/**\n\t\t * Whether the record's own field and the platform marker disagree.\n\t\t *\n\t\t * @spec openspec/changes/retention-widget/specs/retention-widget/spec.md#requirement-a-record-shows-its-stored-retention\n\t\t * @return {boolean}\n\t\t */\n\t\tdisagrees() {\n\t\t\tconst field = this.content.statusField\n\t\t\tif (!field || !this.record) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst values = Array.isArray(this.content.archivedValues) ? this.content.archivedValues.map(String) : ['archived']\n\t\t\tconst saysArchived = values.includes(String(readPath(this.record, field) ?? ''))\n\t\t\treturn saysArchived !== Boolean(this.archived)\n\t\t},\n\n\t\t/**\n\t\t * The stored facts that have a value, in reading order.\n\t\t *\n\t\t * @spec openspec/changes/retention-widget/specs/retention-widget/spec.md#requirement-a-record-shows-its-stored-retention\n\t\t * @return {Array<{key: string, label: string, value: string}>}\n\t\t */\n\t\tfacts() {\n\t\t\tconst r = this.retention || {}\n\t\t\tconst n = this.nomination || {}\n\t\t\treturn [\n\t\t\t\t{ key: 'appraisal', label: t('nextcloud-vue', 'Appraisal'), value: r.appraisal },\n\t\t\t\t{ key: 'disposal-date', label: t('nextcloud-vue', 'Disposal date'), value: r.disposalDate },\n\t\t\t\t{ key: 'retention-period', label: t('nextcloud-vue', 'Retention period'), value: r.retentionPeriod },\n\t\t\t\t{ key: 'selection-list-row', label: t('nextcloud-vue', 'Selection list row'), value: r.selectionListRow },\n\t\t\t\t{ key: 'rule', label: t('nextcloud-vue', 'Decided by'), value: n.rule },\n\t\t\t\t{ key: 'decided-at', label: t('nextcloud-vue', 'Written on'), value: n.at },\n\t\t\t].filter((fact) => fact.value !== undefined && fact.value !== null && fact.value !== '').map((fact) => ({ ...fact, value: String(fact.value) }))\n\t\t},\n\n\t\t/** @return {Array<{key: string, label: string, value: string}>} The facts of a record not closed yet. */\n\t\tpendingFacts() {\n\t\t\tconst atClosure = t('nextcloud-vue', 'Decided when it closes')\n\t\t\treturn [\n\t\t\t\t{ key: 'appraisal', label: t('nextcloud-vue', 'Appraisal'), value: atClosure },\n\t\t\t\t{ key: 'retention-period', label: t('nextcloud-vue', 'Retention period'), value: atClosure },\n\t\t\t\t{ key: 'disposal-date', label: t('nextcloud-vue', 'Disposal date'), value: atClosure },\n\t\t\t\t{ key: 'decided-at', label: t('nextcloud-vue', 'Written on'), value: t('nextcloud-vue', 'Not yet') },\n\t\t\t]\n\t\t},\n\n\t\t/** @return {string} The signed-in user's id. */\n\t\tcurrentUid() {\n\t\t\tconst user = getCurrentUser()\n\t\t\treturn String((user && user.uid) || '')\n\t\t},\n\n\t\t/**\n\t\t * Whether this user may recompute: an admin or an archivist group member.\n\t\t * Shown disabled otherwise, so the user learns which role it needs.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tmayRecompute() {\n\t\t\tconst user = getCurrentUser()\n\t\t\tif (user && user.isAdmin === true) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tconst groups = Array.isArray(user && user.groups) ? user.groups : []\n\t\t\tconst allowed = Array.isArray(this.content.archivistGroups) ? this.content.archivistGroups : ['archivaris']\n\t\t\treturn allowed.some((g) => groups.includes(g))\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.load()\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * A config text through the host translate.\n\t\t *\n\t\t * @param {unknown} value The text.\n\t\t * @return {string}\n\t\t */\n\t\ttext(value) {\n\t\t\treturn typeof value === 'string' && value !== '' ? this.cnTranslate(value) : ''\n\t\t},\n\n\t\t/**\n\t\t * Read the record fresh from OpenRegister; a failure is an error, never an empty block.\n\t\t *\n\t\t * @spec openspec/changes/retention-widget/specs/retention-widget/spec.md#requirement-a-record-shows-its-stored-retention\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync load() {\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\ttry {\n\t\t\t\tif (!this.registerRef || !this.schemaRef || !this.id) {\n\t\t\t\t\tthrow new Error(t('nextcloud-vue', 'This widget has no record to read.'))\n\t\t\t\t}\n\t\t\t\tconst { data } = await axios.get(generateUrl(`/apps/openregister/api/objects/${encodeURIComponent(this.registerRef)}/${encodeURIComponent(this.schemaRef)}/${encodeURIComponent(this.id)}`))\n\t\t\t\tthis.record = data && typeof data === 'object' ? data : null\n\t\t\t} catch (failure) {\n\t\t\t\tconst body = failure && failure.response && failure.response.data\n\t\t\t\tthis.error = String((body && (body.message || body.error)) || (failure && failure.message) || failure)\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Ask OpenRegister to derive the nomination again, then read it back.\n\t\t *\n\t\t * @spec openspec/changes/retention-widget/specs/retention-widget/spec.md#requirement-a-record-shows-its-stored-retention\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync recompute() {\n\t\t\tif (this.busy || this.reason.trim() === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.busy = true\n\t\t\ttry {\n\t\t\t\tawait axios.post(generateUrl(`/apps/openregister/api/archival/objects/${encodeURIComponent(this.id)}/nomination/recompute`), { reason: this.reason.trim() })\n\t\t\t\tthis.reason = ''\n\t\t\t\tawait this.load()\n\t\t\t} catch (failure) {\n\t\t\t\tconst body = failure && failure.response && failure.response.data\n\t\t\t\tthis.error = String((body && (body.message || body.error)) || (failure && failure.message) || failure)\n\t\t\t} finally {\n\t\t\t\tthis.busy = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-retention {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n}\n\n.cn-retention__head {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n\n.cn-retention__title {\n\tmargin: 0;\n\tfont-size: 18px;\n\tfont-weight: 700;\n}\n\n.cn-retention__muted {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-retention__facts {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n\tgap: 12px 24px;\n\tmargin: 0;\n}\n\n.cn-retention__fact dt {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-retention__fact dd {\n\tmargin: 0;\n\tfont-weight: 600;\n}\n\n.cn-retention__recompute {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmax-width: 480px;\n}\n</style>\n"],"names":["_createElementVNode","_toDisplayString","_createBlock","_createVNode","_createElementBlock","_createTextVNode","_Fragment","_renderList","_openBlock"],"mappings":"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"}
@@ -1,8 +1,9 @@
1
- import __sfc_main$c from '../CnAuditTrailWidget/CnAuditTrailWidget.vue.js';
1
+ import __sfc_main$d from '../CnAuditTrailWidget/CnAuditTrailWidget.vue.js';
2
2
  import __sfc_main$a from '../CnBannerWidget/CnBannerWidget.vue.js';
3
- import __sfc_main$g from '../CnDividerWidget/CnDividerWidget.vue.js';
4
- import __sfc_main$i from '../CnExportsWidget/CnExportsWidget.vue.js';
5
- import __sfc_main$e from '../CnHeaderWidget/CnHeaderWidget.vue.js';
3
+ import __sfc_main$c from '../CnDecisionListWidget/CnDecisionListWidget.vue.js';
4
+ import __sfc_main$h from '../CnDividerWidget/CnDividerWidget.vue.js';
5
+ import __sfc_main$j from '../CnExportsWidget/CnExportsWidget.vue.js';
6
+ import __sfc_main$f from '../CnHeaderWidget/CnHeaderWidget.vue.js';
6
7
  import __sfc_main$9 from '../CnIntegrationWidget/CnIntegrationWidget.vue.js';
7
8
  import __sfc_main$5 from '../CnNavCardGrid/CnNavCardGrid.vue.js';
8
9
  import __sfc_main$b from '../CnNoticeWidget/CnNoticeWidget.vue.js';
@@ -10,9 +11,9 @@ import __sfc_main$6 from '../CnObjectDataWidget/CnObjectDataWidget.vue.js';
10
11
  import __sfc_main$3 from '../CnObjectGeoWidget/CnObjectGeoWidget.vue.js';
11
12
  import __sfc_main$7 from '../CnObjectMetadataWidget/CnObjectMetadataWidget.vue.js';
12
13
  import __sfc_main$8 from '../CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue.js';
13
- import __sfc_main$h from '../CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js';
14
- import __sfc_main$f from '../CnTextWidget/CnTextWidget.vue.js';
15
- import __sfc_main$d from '../CnTimelineWidget/CnTimelineWidget.vue.js';
14
+ import __sfc_main$i from '../CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js';
15
+ import __sfc_main$g from '../CnTextWidget/CnTextWidget.vue.js';
16
+ import __sfc_main$e from '../CnTimelineWidget/CnTimelineWidget.vue.js';
16
17
  import __sfc_main$4 from '../CnWidgetCardGrid/CnWidgetCardGrid.vue.js';
17
18
  import __sfc_main$1 from '../CnWidgetFormRenderer/CnWidgetFormRenderer.vue.js';
18
19
  import __sfc_main$2 from '../CnWidgetMapViewer/CnWidgetMapViewer.vue.js';
@@ -89,13 +90,14 @@ const BUILT_IN_WIDGETS = {
89
90
  integration: __sfc_main$9,
90
91
  banner: __sfc_main$a,
91
92
  notice: __sfc_main$b,
92
- 'audit-trail': __sfc_main$c,
93
- timeline: __sfc_main$d,
94
- header: __sfc_main$e,
95
- text: __sfc_main$f,
96
- divider: __sfc_main$g,
97
- 'saved-view-alert': __sfc_main$h,
98
- exports: __sfc_main$i,
93
+ 'decision-list': __sfc_main$c,
94
+ 'audit-trail': __sfc_main$d,
95
+ timeline: __sfc_main$e,
96
+ header: __sfc_main$f,
97
+ text: __sfc_main$g,
98
+ divider: __sfc_main$h,
99
+ 'saved-view-alert': __sfc_main$i,
100
+ exports: __sfc_main$j,
99
101
  };
100
102
 
101
103
  export { BUILT_IN_WIDGETS };
@@ -1 +1 @@
1
- {"version":3,"file":"builtInWidgets.js","sources":["../../../../src/components/CnWidgetGrid/builtInWidgets.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2024 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * builtInWidgets — internal registry of the library's built-in v2 widget components.\n *\n * Keys are the `widgetKey` values used in v2 manifests.\n * Values are the Vue component definitions.\n *\n * CnWidgetGrid resolves widget keys first against this registry, then against\n * the consumer-supplied `cnRegistry` inject. A consumer can override a built-in\n * by registering a custom component with the same key in `cnRegistry`.\n *\n * Spec: REQ-MVR-005 (manifest-v2-renderer) — widget key resolution\n */\n\nimport CnAuditTrailWidget from '../CnAuditTrailWidget/CnAuditTrailWidget.vue'\nimport CnBannerWidget from '../CnBannerWidget/CnBannerWidget.vue'\nimport CnDividerWidget from '../CnDividerWidget/CnDividerWidget.vue'\nimport CnExportsWidget from '../CnExportsWidget/CnExportsWidget.vue'\nimport CnHeaderWidget from '../CnHeaderWidget/CnHeaderWidget.vue'\nimport CnIntegrationWidget from '../CnIntegrationWidget/CnIntegrationWidget.vue'\nimport CnNavCardGrid from '../CnNavCardGrid/CnNavCardGrid.vue'\nimport CnNoticeWidget from '../CnNoticeWidget/CnNoticeWidget.vue'\nimport CnObjectDataWidget from '../CnObjectDataWidget/CnObjectDataWidget.vue'\nimport CnObjectGeoWidget from '../CnObjectGeoWidget/CnObjectGeoWidget.vue'\nimport CnObjectMetadataWidget from '../CnObjectMetadataWidget/CnObjectMetadataWidget.vue'\nimport CnRelatedObjectsWidget from '../CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue'\nimport CnSavedViewAlertWidget from '../CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue'\nimport CnTextWidget from '../CnTextWidget/CnTextWidget.vue'\nimport CnTimelineWidget from '../CnTimelineWidget/CnTimelineWidget.vue'\nimport CnWidgetCardGrid from '../CnWidgetCardGrid/CnWidgetCardGrid.vue'\nimport CnWidgetFormRenderer from '../CnWidgetFormRenderer/CnWidgetFormRenderer.vue'\nimport CnWidgetMapViewer from '../CnWidgetMapViewer/CnWidgetMapViewer.vue'\nimport CnWidgetObjectTable from '../CnWidgetObjectTable/CnWidgetObjectTable.vue'\n\n/**\n * Built-in widget registry.\n *\n * The `data` and `metadata` keys are the canonical object-detail widgets:\n * a manifest `type:\"detail\"` page that places `widgetKey:\"data\"` /\n * `widgetKey:\"metadata\"` gets the object's editable property grid /\n * read-only `@self` metadata respectively. Both need the loaded object —\n * `CnPageRenderer` loads it for the detail page and `CnWidgetGrid` merges\n * `{ objectData, schema, objectType, objectId, register, store }` into each\n * widget's props (see CnWidgetGrid.resolvedWidgets), so the manifest entry\n * needs no per-widget `props`.\n *\n * The `integration` key places an OpenRegister integration leaf\n * (`CnIntegrationWidget`) on the page — e.g. Integriq's `sync-contract`\n * (\"Synced from\"). Pick the leaf with `props.only: \"<integrationId>\"`; the\n * object's `register` / `objectId` arrive via the detail-context merge, and\n * the manifest should set `props.schema` to the schema slug (the merged\n * context `schema` is the schema *object*, so an explicit slug prop wins).\n *\n * The `banner` key places a declarative notice banner (CnBannerWidget):\n * `props { variant, text, visibleWhen?, route? }` — see the component for\n * the visibleWhen predicate shape.\n *\n * The `audit-trail` key places the object change-log card\n * (CnAuditTrailWidget) — a detail-page widget whose register / schema /\n * objectId arrive via the detail-context merge (or explicit `props`).\n *\n * The `header` / `text` / `divider` keys reuse the dashboard catalog's\n * content-only presentation widgets on v2 pages: each takes a single\n * `props.content` object with the same shape their dashboard `content`\n * blob uses (see the components' docblocks).\n *\n * The `nav-card-grid` key (ADR-044 §4 cards-collapse) places CnNavCardGrid:\n * a grid of arbitrary navigation-link cards from `props.entries` (the\n * navCardEntry shape). Unlike `card-grid` (CnWidgetCardGrid, which renders\n * OpenRegister objects as CnObjectCard), `nav-card-grid` renders links, not\n * data — the intended remedy for a deep menu group collapsed into one\n * top-level entry via `menu-layout.json` relocations.\n *\n * @type {Record<string, import('vue').Component>}\n */\nexport const BUILT_IN_WIDGETS = {\n\t'object-table': CnWidgetObjectTable,\n\t'form-renderer': CnWidgetFormRenderer,\n\t'map-viewer': CnWidgetMapViewer,\n\t'object-geo': CnObjectGeoWidget,\n\t'card-grid': CnWidgetCardGrid,\n\t'nav-card-grid': CnNavCardGrid,\n\tdata: CnObjectDataWidget,\n\tmetadata: CnObjectMetadataWidget,\n\trelated: CnRelatedObjectsWidget,\n\tintegration: CnIntegrationWidget,\n\tbanner: CnBannerWidget,\n\tnotice: CnNoticeWidget,\n\t'audit-trail': CnAuditTrailWidget,\n\ttimeline: CnTimelineWidget,\n\theader: CnHeaderWidget,\n\ttext: CnTextWidget,\n\tdivider: CnDividerWidget,\n\t'saved-view-alert': CnSavedViewAlertWidget,\n\texports: CnExportsWidget,\n}\n"],"names":["CnWidgetObjectTable","CnWidgetFormRenderer","CnWidgetMapViewer","CnObjectGeoWidget","CnWidgetCardGrid","CnNavCardGrid","CnObjectDataWidget","CnObjectMetadataWidget","CnRelatedObjectsWidget","CnIntegrationWidget","CnBannerWidget","CnNoticeWidget","CnAuditTrailWidget","CnTimelineWidget","CnHeaderWidget","CnTextWidget","CnDividerWidget","CnSavedViewAlertWidget","CnExportsWidget"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,gBAAgB,GAAG;AAChC,CAAC,cAAc,EAAEA,UAAmB;AACpC,CAAC,eAAe,EAAEC,YAAoB;AACtC,CAAC,YAAY,EAAEC,YAAiB;AAChC,CAAC,YAAY,EAAEC,YAAiB;AAChC,CAAC,WAAW,EAAEC,YAAgB;AAC9B,CAAC,eAAe,EAAEC,YAAa;AAC/B,CAAC,IAAI,EAAEC,YAAkB;AACzB,CAAC,QAAQ,EAAEC,YAAsB;AACjC,CAAC,OAAO,EAAEC,YAAsB;AAChC,CAAC,WAAW,EAAEC,YAAmB;AACjC,CAAC,MAAM,EAAEC,YAAc;AACvB,CAAC,MAAM,EAAEC,YAAc;AACvB,CAAC,aAAa,EAAEC,YAAkB;AAClC,CAAC,QAAQ,EAAEC,YAAgB;AAC3B,CAAC,MAAM,EAAEC,YAAc;AACvB,CAAC,IAAI,EAAEC,YAAY;AACnB,CAAC,OAAO,EAAEC,YAAe;AACzB,CAAC,kBAAkB,EAAEC,YAAsB;AAC3C,CAAC,OAAO,EAAEC,YAAe;AACzB;;;;"}
1
+ {"version":3,"file":"builtInWidgets.js","sources":["../../../../src/components/CnWidgetGrid/builtInWidgets.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2024 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * builtInWidgets — internal registry of the library's built-in v2 widget components.\n *\n * Keys are the `widgetKey` values used in v2 manifests.\n * Values are the Vue component definitions.\n *\n * CnWidgetGrid resolves widget keys first against this registry, then against\n * the consumer-supplied `cnRegistry` inject. A consumer can override a built-in\n * by registering a custom component with the same key in `cnRegistry`.\n *\n * Spec: REQ-MVR-005 (manifest-v2-renderer) — widget key resolution\n */\n\nimport CnAuditTrailWidget from '../CnAuditTrailWidget/CnAuditTrailWidget.vue'\nimport CnBannerWidget from '../CnBannerWidget/CnBannerWidget.vue'\nimport CnDecisionListWidget from '../CnDecisionListWidget/CnDecisionListWidget.vue'\nimport CnDividerWidget from '../CnDividerWidget/CnDividerWidget.vue'\nimport CnExportsWidget from '../CnExportsWidget/CnExportsWidget.vue'\nimport CnHeaderWidget from '../CnHeaderWidget/CnHeaderWidget.vue'\nimport CnIntegrationWidget from '../CnIntegrationWidget/CnIntegrationWidget.vue'\nimport CnNavCardGrid from '../CnNavCardGrid/CnNavCardGrid.vue'\nimport CnNoticeWidget from '../CnNoticeWidget/CnNoticeWidget.vue'\nimport CnObjectDataWidget from '../CnObjectDataWidget/CnObjectDataWidget.vue'\nimport CnObjectGeoWidget from '../CnObjectGeoWidget/CnObjectGeoWidget.vue'\nimport CnObjectMetadataWidget from '../CnObjectMetadataWidget/CnObjectMetadataWidget.vue'\nimport CnRelatedObjectsWidget from '../CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue'\nimport CnSavedViewAlertWidget from '../CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue'\nimport CnTextWidget from '../CnTextWidget/CnTextWidget.vue'\nimport CnTimelineWidget from '../CnTimelineWidget/CnTimelineWidget.vue'\nimport CnWidgetCardGrid from '../CnWidgetCardGrid/CnWidgetCardGrid.vue'\nimport CnWidgetFormRenderer from '../CnWidgetFormRenderer/CnWidgetFormRenderer.vue'\nimport CnWidgetMapViewer from '../CnWidgetMapViewer/CnWidgetMapViewer.vue'\nimport CnWidgetObjectTable from '../CnWidgetObjectTable/CnWidgetObjectTable.vue'\n\n/**\n * Built-in widget registry.\n *\n * The `data` and `metadata` keys are the canonical object-detail widgets:\n * a manifest `type:\"detail\"` page that places `widgetKey:\"data\"` /\n * `widgetKey:\"metadata\"` gets the object's editable property grid /\n * read-only `@self` metadata respectively. Both need the loaded object —\n * `CnPageRenderer` loads it for the detail page and `CnWidgetGrid` merges\n * `{ objectData, schema, objectType, objectId, register, store }` into each\n * widget's props (see CnWidgetGrid.resolvedWidgets), so the manifest entry\n * needs no per-widget `props`.\n *\n * The `integration` key places an OpenRegister integration leaf\n * (`CnIntegrationWidget`) on the page — e.g. Integriq's `sync-contract`\n * (\"Synced from\"). Pick the leaf with `props.only: \"<integrationId>\"`; the\n * object's `register` / `objectId` arrive via the detail-context merge, and\n * the manifest should set `props.schema` to the schema slug (the merged\n * context `schema` is the schema *object*, so an explicit slug prop wins).\n *\n * The `banner` key places a declarative notice banner (CnBannerWidget):\n * `props { variant, text, visibleWhen?, route? }` — see the component for\n * the visibleWhen predicate shape.\n *\n * The `audit-trail` key places the object change-log card\n * (CnAuditTrailWidget) — a detail-page widget whose register / schema /\n * objectId arrive via the detail-context merge (or explicit `props`).\n *\n * The `header` / `text` / `divider` keys reuse the dashboard catalog's\n * content-only presentation widgets on v2 pages: each takes a single\n * `props.content` object with the same shape their dashboard `content`\n * blob uses (see the components' docblocks).\n *\n * The `nav-card-grid` key (ADR-044 §4 cards-collapse) places CnNavCardGrid:\n * a grid of arbitrary navigation-link cards from `props.entries` (the\n * navCardEntry shape). Unlike `card-grid` (CnWidgetCardGrid, which renders\n * OpenRegister objects as CnObjectCard), `nav-card-grid` renders links, not\n * data — the intended remedy for a deep menu group collapsed into one\n * top-level entry via `menu-layout.json` relocations.\n *\n * @type {Record<string, import('vue').Component>}\n */\nexport const BUILT_IN_WIDGETS = {\n\t'object-table': CnWidgetObjectTable,\n\t'form-renderer': CnWidgetFormRenderer,\n\t'map-viewer': CnWidgetMapViewer,\n\t'object-geo': CnObjectGeoWidget,\n\t'card-grid': CnWidgetCardGrid,\n\t'nav-card-grid': CnNavCardGrid,\n\tdata: CnObjectDataWidget,\n\tmetadata: CnObjectMetadataWidget,\n\trelated: CnRelatedObjectsWidget,\n\tintegration: CnIntegrationWidget,\n\tbanner: CnBannerWidget,\n\tnotice: CnNoticeWidget,\n\t'decision-list': CnDecisionListWidget,\n\t'audit-trail': CnAuditTrailWidget,\n\ttimeline: CnTimelineWidget,\n\theader: CnHeaderWidget,\n\ttext: CnTextWidget,\n\tdivider: CnDividerWidget,\n\t'saved-view-alert': CnSavedViewAlertWidget,\n\texports: CnExportsWidget,\n}\n"],"names":["CnWidgetObjectTable","CnWidgetFormRenderer","CnWidgetMapViewer","CnObjectGeoWidget","CnWidgetCardGrid","CnNavCardGrid","CnObjectDataWidget","CnObjectMetadataWidget","CnRelatedObjectsWidget","CnIntegrationWidget","CnBannerWidget","CnNoticeWidget","CnDecisionListWidget","CnAuditTrailWidget","CnTimelineWidget","CnHeaderWidget","CnTextWidget","CnDividerWidget","CnSavedViewAlertWidget","CnExportsWidget"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAqBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,gBAAgB,GAAG;AAChC,CAAC,cAAc,EAAEA,UAAmB;AACpC,CAAC,eAAe,EAAEC,YAAoB;AACtC,CAAC,YAAY,EAAEC,YAAiB;AAChC,CAAC,YAAY,EAAEC,YAAiB;AAChC,CAAC,WAAW,EAAEC,YAAgB;AAC9B,CAAC,eAAe,EAAEC,YAAa;AAC/B,CAAC,IAAI,EAAEC,YAAkB;AACzB,CAAC,QAAQ,EAAEC,YAAsB;AACjC,CAAC,OAAO,EAAEC,YAAsB;AAChC,CAAC,WAAW,EAAEC,YAAmB;AACjC,CAAC,MAAM,EAAEC,YAAc;AACvB,CAAC,MAAM,EAAEC,YAAc;AACvB,CAAC,eAAe,EAAEC,YAAoB;AACtC,CAAC,aAAa,EAAEC,YAAkB;AAClC,CAAC,QAAQ,EAAEC,YAAgB;AAC3B,CAAC,MAAM,EAAEC,YAAc;AACvB,CAAC,IAAI,EAAEC,YAAY;AACnB,CAAC,OAAO,EAAEC,YAAe;AACzB,CAAC,kBAAkB,EAAEC,YAAsB;AAC3C,CAAC,OAAO,EAAEC,YAAe;AACzB;;;;"}
@@ -1,9 +1,9 @@
1
1
  import __sfc_main from '../CnChartWidget/CnChartWidget.vue.js';
2
2
  import __sfc_main$1 from '../CnChartWidgetForm/CnChartWidgetForm.vue.js';
3
- import __sfc_main$i from '../CnConversationThread/CnConversationWidget.vue.js';
3
+ import __sfc_main$l from '../CnConversationThread/CnConversationWidget.vue.js';
4
4
  import __sfc_main$e from '../CnCountdownWidget/CnCountdownWidget.vue.js';
5
5
  import __sfc_main$f from '../CnCountdownWidgetForm/CnCountdownWidgetForm.vue.js';
6
- import __sfc_main$h from '../CnDocumentReviewList/CnDocumentReviewWidget.vue.js';
6
+ import __sfc_main$k from '../CnDocumentReviewList/CnDocumentReviewWidget.vue.js';
7
7
  import __sfc_main$c from '../CnMapWidget/CnMapWidget.vue.js';
8
8
  import __sfc_main$d from '../CnMapWidgetForm/CnMapWidgetForm.vue.js';
9
9
  import __sfc_main$8 from '../CnMarkdownWidget/CnMarkdownWidget.vue.js';
@@ -11,21 +11,24 @@ import __sfc_main$9 from '../CnMarkdownWidgetForm/CnMarkdownWidgetForm.vue.js';
11
11
  import __sfc_main$g from '../CnNextStepCard/CnNextStepWidget.vue.js';
12
12
  import __sfc_main$4 from '../CnObjectListWidget/CnObjectListWidget.vue.js';
13
13
  import __sfc_main$5 from '../CnObjectListWidgetForm/CnObjectListWidgetForm.vue.js';
14
+ import __sfc_main$i from '../CnPlanWidget/CnPlanWidget.vue.js';
14
15
  import __sfc_main$a from '../CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue.js';
15
16
  import __sfc_main$b from '../CnRelatedObjectsWidgetForm/CnRelatedObjectsWidgetForm.vue.js';
17
+ import __sfc_main$h from '../CnRetentionWidget/CnRetentionWidget.vue.js';
16
18
  import __sfc_main$6 from '../CnSavedViewWidget/CnSavedViewWidget.vue.js';
17
19
  import __sfc_main$7 from '../CnSavedViewWidgetForm/CnSavedViewWidgetForm.vue.js';
18
- import __sfc_main$p from '../CnStackedBarWidget/CnStackedBarWidget.vue.js';
19
- import __sfc_main$q from '../CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js';
20
- import __sfc_main$j from '../CnStagesWidget/CnStagesWidget.vue.js';
21
- import __sfc_main$k from '../CnStagesWidgetForm/CnStagesWidgetForm.vue.js';
20
+ import __sfc_main$s from '../CnStackedBarWidget/CnStackedBarWidget.vue.js';
21
+ import __sfc_main$t from '../CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js';
22
+ import __sfc_main$m from '../CnStagesWidget/CnStagesWidget.vue.js';
23
+ import __sfc_main$n from '../CnStagesWidgetForm/CnStagesWidgetForm.vue.js';
22
24
  import __sfc_main$2 from '../CnStatsBlockWidget/CnStatsBlockWidget.vue.js';
23
25
  import __sfc_main$3 from '../CnStatsBlockWidgetForm/CnStatsBlockWidgetForm.vue.js';
24
- import __sfc_main$l from '../CnTabsWidget/CnTabsWidget.vue.js';
25
- import __sfc_main$m from '../CnTabsWidgetForm/CnTabsWidgetForm.vue.js';
26
- import __sfc_main$r from '../CnTeamWorkloadWidget/CnTeamWorkloadWidget.vue.js';
27
- import __sfc_main$n from '../CnWeekStripWidget/CnWeekStripWidget.vue.js';
28
- import __sfc_main$o from '../CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js';
26
+ import __sfc_main$o from '../CnTabsWidget/CnTabsWidget.vue.js';
27
+ import __sfc_main$p from '../CnTabsWidgetForm/CnTabsWidgetForm.vue.js';
28
+ import __sfc_main$u from '../CnTeamWorkloadWidget/CnTeamWorkloadWidget.vue.js';
29
+ import __sfc_main$q from '../CnWeekStripWidget/CnWeekStripWidget.vue.js';
30
+ import __sfc_main$r from '../CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js';
31
+ import __sfc_main$j from '../CnWorkQueue/CnWorkQueue.vue.js';
29
32
  import { registerDashboardWidget } from './dashboardWidgetRegistry.js';
30
33
  import '../CnLabelWidget/index.js';
31
34
  import '../CnTextWidget/index.js';
@@ -283,9 +286,37 @@ registerDashboardWidget('next-step', {
283
286
  ownsTitle: true,
284
287
  });
285
288
 
286
- registerDashboardWidget('document-review', {
289
+ registerDashboardWidget('retention', {
287
290
  renderer: __sfc_main$h,
288
291
  form: null,
292
+ defaultContent: { statusField: '', archivedValues: [], archivistGroups: ['archivaris'] },
293
+ displayName: 'Retention',
294
+ icon: 'ArchiveOutline',
295
+ surfaces: ['detail-page'],
296
+ ownsTitle: true,
297
+ });
298
+
299
+ registerDashboardWidget('plan', {
300
+ renderer: __sfc_main$i,
301
+ form: null,
302
+ defaultContent: { emptyText: '' },
303
+ displayName: 'Plan',
304
+ icon: 'FormatListChecks',
305
+ surfaces: ['detail-page'],
306
+ ownsTitle: true,
307
+ });
308
+
309
+ registerDashboardWidget('work-queue', {
310
+ renderer: __sfc_main$j,
311
+ form: null,
312
+ defaultContent: { source: null },
313
+ displayName: 'Work queue',
314
+ icon: 'TrayFull',
315
+ });
316
+
317
+ registerDashboardWidget('document-review', {
318
+ renderer: __sfc_main$k,
319
+ form: null,
289
320
  defaultContent: { field: 'documents', statusField: 'reviewStatus', statuses: [] },
290
321
  displayName: 'Document review',
291
322
  icon: 'FileDocumentCheckOutline',
@@ -294,7 +325,7 @@ registerDashboardWidget('document-review', {
294
325
  });
295
326
 
296
327
  registerDashboardWidget('conversation', {
297
- renderer: __sfc_main$i,
328
+ renderer: __sfc_main$l,
298
329
  form: null,
299
330
  defaultContent: { field: 'messages', endpoint: '' },
300
331
  displayName: 'Conversation',
@@ -306,8 +337,8 @@ registerDashboardWidget('conversation', {
306
337
  // The record's stages, where clicking a stage moves the record there.
307
338
  // Registered inline for the same tree-shaking reason as `map` above.
308
339
  registerDashboardWidget('stages', {
309
- renderer: __sfc_main$j,
310
- form: __sfc_main$k,
340
+ renderer: __sfc_main$m,
341
+ form: __sfc_main$n,
311
342
  defaultContent: {
312
343
  currentField: 'status',
313
344
  orientation: 'horizontal',
@@ -327,8 +358,8 @@ registerDashboardWidget('stages', {
327
358
  });
328
359
 
329
360
  registerDashboardWidget('tabs', {
330
- renderer: __sfc_main$l,
331
- form: __sfc_main$m,
361
+ renderer: __sfc_main$o,
362
+ form: __sfc_main$p,
332
363
  defaultContent: {
333
364
  tabs: [],
334
365
  ariaLabel: '',
@@ -347,8 +378,8 @@ registerDashboardWidget('tabs', {
347
378
  // The current week as day columns, with the dated items under each day.
348
379
  // Registered inline for the same tree-shaking reason as `map` above.
349
380
  registerDashboardWidget('week-strip', {
350
- renderer: __sfc_main$n,
351
- form: __sfc_main$o,
381
+ renderer: __sfc_main$q,
382
+ form: __sfc_main$r,
352
383
  defaultContent: {
353
384
  source: { register: '', schema: '', filter: {} },
354
385
  dateField: '',
@@ -364,8 +395,8 @@ registerDashboardWidget('week-strip', {
364
395
 
365
396
  // One segmented bar with a legend that carries the numbers.
366
397
  registerDashboardWidget('stacked-bar', {
367
- renderer: __sfc_main$p,
368
- form: __sfc_main$q,
398
+ renderer: __sfc_main$s,
399
+ form: __sfc_main$t,
369
400
  defaultContent: {
370
401
  source: { register: '', schema: '', groupBy: '', filter: {} },
371
402
  order: [],
@@ -380,7 +411,7 @@ registerDashboardWidget('stacked-bar', {
380
411
  // person's open count from the app (DqTeamwachtrij "Team vandaag"). Placed
381
412
  // from the manifest: there is no config form yet.
382
413
  registerDashboardWidget('team-workload', {
383
- renderer: __sfc_main$r,
414
+ renderer: __sfc_main$u,
384
415
  form: null,
385
416
  defaultContent: { source: { url: '', responsePath: '', userField: 'userId', nameField: 'displayName', countField: 'count' } },
386
417
  displayName: 'Team workload',