@conduction/nextcloud-vue 2.59.0 → 2.61.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 (254) hide show
  1. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js +14 -1
  2. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
  4. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +80 -1
  5. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  6. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +46 -4
  7. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  8. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +232 -10
  9. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
  10. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js +79 -25
  11. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
  12. package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue2.js +42 -3
  13. package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue2.js.map +1 -1
  14. package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue3.js +39 -6
  15. package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue3.js.map +1 -1
  16. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +46 -0
  17. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
  18. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +11 -4
  19. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
  20. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue.js +10 -0
  21. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue.js.map +1 -0
  22. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js +39 -0
  23. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js.map +1 -0
  24. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js +16 -0
  25. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js.map +1 -0
  26. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +117 -1
  27. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
  28. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +147 -89
  29. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
  30. package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js +10 -0
  31. package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js.map +1 -0
  32. package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js +259 -0
  33. package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -0
  34. package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js +131 -0
  35. package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -0
  36. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js +10 -0
  37. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js.map +1 -0
  38. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js +116 -0
  39. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js.map +1 -0
  40. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js +24 -0
  41. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js.map +1 -0
  42. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +10 -2
  43. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  44. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  45. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +503 -28
  46. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  47. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +303 -144
  48. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  49. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue.js +10 -0
  50. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue.js.map +1 -0
  51. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue2.js +237 -0
  52. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue2.js.map +1 -0
  53. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue3.js +120 -0
  54. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue3.js.map +1 -0
  55. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue.js +10 -0
  56. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue.js.map +1 -0
  57. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js +77 -0
  58. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js.map +1 -0
  59. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js +27 -0
  60. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js.map +1 -0
  61. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +171 -12
  62. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
  63. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +15 -7
  64. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
  65. package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue2.js +37 -3
  66. package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue2.js.map +1 -1
  67. package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue3.js +44 -16
  68. package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue3.js.map +1 -1
  69. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +132 -3
  70. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  71. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +6 -3
  72. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  73. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue.js +10 -0
  74. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue.js.map +1 -0
  75. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue2.js +316 -0
  76. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue2.js.map +1 -0
  77. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue3.js +105 -0
  78. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue3.js.map +1 -0
  79. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue.js +10 -0
  80. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue.js.map +1 -0
  81. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js +150 -0
  82. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js.map +1 -0
  83. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js +106 -0
  84. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js.map +1 -0
  85. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue.js +9 -0
  86. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue.js.map +1 -0
  87. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js +47 -0
  88. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js.map +1 -0
  89. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue3.js +17 -0
  90. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue3.js.map +1 -0
  91. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +49 -0
  92. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
  93. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
  94. package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue2.js +6 -0
  95. package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue2.js.map +1 -1
  96. package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue3.js.map +1 -1
  97. package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue2.js +46 -0
  98. package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue2.js.map +1 -1
  99. package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue3.js +15 -3
  100. package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue3.js.map +1 -1
  101. package/dist/esm/components/CnPageRenderer/pageTypes.js +1 -0
  102. package/dist/esm/components/CnPageRenderer/pageTypes.js.map +1 -1
  103. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +37 -1
  104. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
  105. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js +29 -13
  106. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
  107. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js +50 -3
  108. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js.map +1 -1
  109. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js.map +1 -1
  110. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue.js +10 -0
  111. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue.js.map +1 -0
  112. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js +186 -0
  113. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js.map +1 -0
  114. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js +46 -0
  115. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js.map +1 -0
  116. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue.js +11 -0
  117. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue.js.map +1 -0
  118. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js +298 -0
  119. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js.map +1 -0
  120. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js +77 -0
  121. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js.map +1 -0
  122. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js +10 -0
  123. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js.map +1 -0
  124. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue2.js +169 -0
  125. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue2.js.map +1 -0
  126. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue3.js +48 -0
  127. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue3.js.map +1 -0
  128. package/dist/esm/components/CnTabs/CnTab.vue2.js +35 -0
  129. package/dist/esm/components/CnTabs/CnTab.vue2.js.map +1 -1
  130. package/dist/esm/components/CnTabs/CnTab.vue3.js.map +1 -1
  131. package/dist/esm/components/CnTabs/CnTabs.vue2.js +120 -7
  132. package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
  133. package/dist/esm/components/CnTabs/CnTabs.vue3.js +57 -5
  134. package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
  135. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +59 -4
  136. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  137. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +6 -2
  138. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  139. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js +10 -0
  140. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js.map +1 -0
  141. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js +484 -0
  142. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js.map +1 -0
  143. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js +115 -0
  144. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js.map +1 -0
  145. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js +10 -0
  146. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js.map +1 -0
  147. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue2.js +189 -0
  148. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue2.js.map +1 -0
  149. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue3.js +74 -0
  150. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue3.js.map +1 -0
  151. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +82 -8
  152. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  153. package/dist/esm/index.js +16 -0
  154. package/dist/esm/index.js.map +1 -1
  155. package/dist/esm/l10n/en.json.js +55 -1
  156. package/dist/esm/l10n/en.json.js.map +1 -1
  157. package/dist/esm/l10n/nl.json.js +55 -1
  158. package/dist/esm/l10n/nl.json.js.map +1 -1
  159. package/dist/esm/nextcloud-vue.css +1036 -19
  160. package/dist/esm/utils/dateVariant.js +124 -0
  161. package/dist/esm/utils/dateVariant.js.map +1 -0
  162. package/dist/esm/utils/detailActionModel.js +260 -0
  163. package/dist/esm/utils/detailActionModel.js.map +1 -0
  164. package/dist/esm/utils/dueRule.js +84 -0
  165. package/dist/esm/utils/dueRule.js.map +1 -0
  166. package/dist/esm/utils/fetchAggregate.js +37 -1
  167. package/dist/esm/utils/fetchAggregate.js.map +1 -1
  168. package/dist/esm/utils/fetchFilterCounts.js +186 -0
  169. package/dist/esm/utils/fetchFilterCounts.js.map +1 -0
  170. package/dist/esm/utils/headers.js +28 -2
  171. package/dist/esm/utils/headers.js.map +1 -1
  172. package/dist/esm/utils/libraryWidgetKeys.js +5 -0
  173. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  174. package/dist/esm/utils/readPath.js +30 -0
  175. package/dist/esm/utils/readPath.js.map +1 -0
  176. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  177. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  178. package/dist/nextcloud-vue.cjs.js +16019 -9528
  179. package/dist/nextcloud-vue.cjs.js.map +2 -2
  180. package/dist/nextcloud-vue.css +1036 -19
  181. package/l10n/en.json +55 -1
  182. package/l10n/nl.json +55 -1
  183. package/package.json +1 -1
  184. package/scripts/.jsdoc-baselines.json +4 -0
  185. package/src/components/CnActionsMenu/CnActionsMenu.vue +14 -1
  186. package/src/components/CnAppNav/CnAppNav.md +26 -0
  187. package/src/components/CnAppNav/CnAppNav.vue +145 -2
  188. package/src/components/CnBannerWidget/CnBannerWidget.vue +373 -11
  189. package/src/components/CnBannerWidgetForm/CnBannerWidgetForm.vue +65 -3
  190. package/src/components/CnBoardView/CnBoardView.vue +77 -0
  191. package/src/components/CnBrandStripe/CnBrandStripe.md +22 -0
  192. package/src/components/CnBrandStripe/CnBrandStripe.vue +100 -0
  193. package/src/components/CnBrandStripe/index.js +4 -0
  194. package/src/components/CnCellRenderer/CnCellRenderer.vue +207 -1
  195. package/src/components/CnConversationThread/CnConversationThread.md +51 -0
  196. package/src/components/CnConversationThread/CnConversationThread.vue +457 -0
  197. package/src/components/CnConversationThread/CnConversationWidget.vue +144 -0
  198. package/src/components/CnConversationThread/index.js +4 -0
  199. package/src/components/CnDashboardPage/CnDashboardPage.vue +10 -2
  200. package/src/components/CnDetailPage/CnDetailPage.md +16 -0
  201. package/src/components/CnDetailPage/CnDetailPage.vue +687 -49
  202. package/src/components/CnDocumentReviewList/CnDocumentReviewList.md +55 -0
  203. package/src/components/CnDocumentReviewList/CnDocumentReviewList.vue +384 -0
  204. package/src/components/CnDocumentReviewList/CnDocumentReviewWidget.vue +108 -0
  205. package/src/components/CnDocumentReviewList/index.js +4 -0
  206. package/src/components/CnHeaderWidget/CnHeaderWidget.vue +191 -14
  207. package/src/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue +53 -3
  208. package/src/components/CnIndexPage/CnIndexPage.vue +135 -3
  209. package/src/components/CnLinkCardsPage/CnLinkCardsPage.vue +484 -0
  210. package/src/components/CnLinkCardsPage/index.js +4 -0
  211. package/src/components/CnNextStepCard/CnNextStepCard.md +40 -0
  212. package/src/components/CnNextStepCard/CnNextStepCard.vue +319 -0
  213. package/src/components/CnNextStepCard/CnNextStepWidget.vue +59 -0
  214. package/src/components/CnNextStepCard/index.js +4 -0
  215. package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +49 -0
  216. package/src/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue +6 -0
  217. package/src/components/CnObjectKanban/CnObjectKanban.vue +86 -2
  218. package/src/components/CnPageRenderer/pageTypes.js +1 -0
  219. package/src/components/CnQuickFilterBar/CnQuickFilterBar.md +3 -0
  220. package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +60 -1
  221. package/src/components/CnSavedViewsControl/CnSavedViewsControl.vue +50 -3
  222. package/src/components/CnSegmentedControl/CnSegmentedControl.md +46 -0
  223. package/src/components/CnSegmentedControl/CnSegmentedControl.vue +291 -0
  224. package/src/components/CnSegmentedControl/index.js +4 -0
  225. package/src/components/CnStackedBarWidget/CnStackedBarWidget.md +15 -0
  226. package/src/components/CnStackedBarWidget/CnStackedBarWidget.vue +414 -0
  227. package/src/components/CnStackedBarWidget/index.js +14 -0
  228. package/src/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue +224 -0
  229. package/src/components/CnStackedBarWidgetForm/index.js +4 -0
  230. package/src/components/CnTabs/CnTab.vue +35 -0
  231. package/src/components/CnTabs/CnTabs.vue +244 -10
  232. package/src/components/CnTabsWidget/CnTabsWidget.vue +63 -4
  233. package/src/components/CnWeekStripWidget/CnWeekStripWidget.md +31 -0
  234. package/src/components/CnWeekStripWidget/CnWeekStripWidget.vue +668 -0
  235. package/src/components/CnWeekStripWidget/index.js +14 -0
  236. package/src/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue +265 -0
  237. package/src/components/CnWeekStripWidgetForm/index.js +4 -0
  238. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +74 -0
  239. package/src/components/index.js +12 -0
  240. package/src/css/detail-page.css +57 -2
  241. package/src/index.js +16 -0
  242. package/src/schemas/app-manifest-v2.schema.json +433 -3
  243. package/src/schemas/app-manifest.schema.json +2 -1
  244. package/src/types/manifest.d.ts +1 -1
  245. package/src/utils/dateVariant.js +120 -0
  246. package/src/utils/detailActionModel.js +256 -0
  247. package/src/utils/dueRule.js +94 -0
  248. package/src/utils/fetchAggregate.js +36 -0
  249. package/src/utils/fetchFilterCounts.js +182 -0
  250. package/src/utils/headers.js +28 -2
  251. package/src/utils/index.js +1 -0
  252. package/src/utils/libraryWidgetKeys.js +5 -0
  253. package/src/utils/readPath.js +27 -0
  254. package/src/utils/validateManifestV2.compiled.js +2 -2
@@ -0,0 +1,150 @@
1
+ import { translate } from '@nextcloud/l10n';
2
+ import { NcButton } from '@nextcloud/vue';
3
+ import Check from 'vue-material-design-icons/Check.vue';
4
+
5
+ let nextStepCardUid = 0;
6
+
7
+ /**
8
+ * CnNextStepCard: what this record needs now, next to the button that does it.
9
+ *
10
+ * A short checklist for the current step and one primary action. It answers
11
+ * "what do I do next?" on a record whose menu would otherwise make the handler
12
+ * guess. Renders nothing when there is no checklist, so a step that needs no
13
+ * explaining shows no empty card.
14
+ *
15
+ * ```vue
16
+ * <CnNextStepCard
17
+ * title="What now? Step 2: handling"
18
+ * :items="[
19
+ * { label: 'Receipt confirmed', done: true },
20
+ * { label: 'Review the open documents', hint: '2 of 5 done' },
21
+ * { label: 'Draft the decision' },
22
+ * ]"
23
+ * action-label="Continue reviewing"
24
+ * after="Then: step 3, decision"
25
+ * @action="onContinue" />
26
+ * ```
27
+ *
28
+ * CnDetailPage renders this card from its `nextStep` config, and the
29
+ * `next-step` detail widget type renders it inside a grid.
30
+ */
31
+ var script = {
32
+ name: 'CnNextStepCard',
33
+
34
+ components: {
35
+ Check,
36
+ NcButton,
37
+ },
38
+
39
+ props: {
40
+ /** Heading of the card, for example "What now? Step 2: handling". */
41
+ title: {
42
+ type: String,
43
+ default: '',
44
+ },
45
+
46
+ /** Element the heading renders as. Pick the level that fits the page outline. */
47
+ titleTag: {
48
+ type: String,
49
+ default: 'h3',
50
+ },
51
+
52
+ /**
53
+ * The checklist: `{ label, done?, hint? }` per item. The first item
54
+ * that is not done is emphasised as the one to pick up now.
55
+ */
56
+ items: {
57
+ type: Array,
58
+ default: () => [],
59
+ },
60
+
61
+ /** Label of the primary button. Empty renders no button. */
62
+ actionLabel: {
63
+ type: String,
64
+ default: '',
65
+ },
66
+
67
+ /** DOM id for the primary button, so a skip link can land on it. */
68
+ actionId: {
69
+ type: String,
70
+ default: '',
71
+ },
72
+
73
+ /** Disable the primary button, for example while its request is in flight. */
74
+ actionDisabled: {
75
+ type: Boolean,
76
+ default: false,
77
+ },
78
+
79
+ /** One line under the button saying what follows, for example "Then: step 3, decision". */
80
+ after: {
81
+ type: String,
82
+ default: '',
83
+ },
84
+
85
+ /** Text state of a done item, read by screen readers. */
86
+ doneLabel: {
87
+ type: String,
88
+ default: () => translate('nextcloud-vue', 'Done'),
89
+ },
90
+
91
+ /** Text state of an open item, read by screen readers. */
92
+ todoLabel: {
93
+ type: String,
94
+ default: () => translate('nextcloud-vue', 'To do'),
95
+ },
96
+ },
97
+
98
+ emits: [
99
+ /** The primary button was pressed. */
100
+ 'action',
101
+ ],
102
+
103
+ data() {
104
+ nextStepCardUid += 1;
105
+ return {
106
+ titleId: `cn-next-step-title-${nextStepCardUid}`,
107
+ }
108
+ },
109
+
110
+ computed: {
111
+ /**
112
+ * The items that can render: an object with a label.
113
+ *
114
+ * @return {Array<{label: string, done: boolean, hint: string}>} The checklist.
115
+ * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card
116
+ */
117
+ normalisedItems() {
118
+ return (Array.isArray(this.items) ? this.items : [])
119
+ .filter((item) => item && typeof item.label === 'string' && item.label !== '')
120
+ .map((item) => ({
121
+ label: item.label,
122
+ done: item.done === true,
123
+ hint: typeof item.hint === 'string' ? item.hint : '',
124
+ }))
125
+ },
126
+
127
+ /**
128
+ * Index of the first open item, the one to pick up now.
129
+ *
130
+ * @return {number} The index, or -1 when everything is done.
131
+ * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card
132
+ */
133
+ currentIndex() {
134
+ return this.normalisedItems.findIndex((item) => !item.done)
135
+ },
136
+
137
+ /**
138
+ * Accessible name for a card without a title.
139
+ *
140
+ * @return {string} The label.
141
+ * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card
142
+ */
143
+ fallbackLabel() {
144
+ return translate('nextcloud-vue', 'Next step')
145
+ },
146
+ },
147
+ };
148
+
149
+ export { script as default };
150
+ //# sourceMappingURL=CnNextStepCard.vue2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnNextStepCard.vue2.js","sources":["../../../../src/components/CnNextStepCard/CnNextStepCard.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<section\n\t\tv-if=\"normalisedItems.length > 0\"\n\t\tclass=\"cn-next-step-card\"\n\t\tdata-testid=\"cn-next-step-card\"\n\t\t:aria-labelledby=\"title ? titleId : null\"\n\t\t:aria-label=\"title ? null : fallbackLabel\">\n\t\t<div class=\"cn-next-step-card__main\">\n\t\t\t<component\n\t\t\t\t:is=\"titleTag\"\n\t\t\t\tv-if=\"title\"\n\t\t\t\t:id=\"titleId\"\n\t\t\t\tclass=\"cn-next-step-card__title\">\n\t\t\t\t{{ title }}\n\t\t\t</component>\n\t\t\t<ul class=\"cn-next-step-card__list\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"(item, index) in normalisedItems\"\n\t\t\t\t\t:key=\"`${index}-${item.label}`\"\n\t\t\t\t\tclass=\"cn-next-step-card__item\"\n\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t'cn-next-step-card__item--done': item.done,\n\t\t\t\t\t\t'cn-next-step-card__item--current': index === currentIndex,\n\t\t\t\t\t}\"\n\t\t\t\t\tdata-testid=\"cn-next-step-item\">\n\t\t\t\t\t<span class=\"cn-next-step-card__marker\" aria-hidden=\"true\">\n\t\t\t\t\t\t<Check v-if=\"item.done\" :size=\"14\" />\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"cn-next-step-card__label\">{{ item.label }}</span>\n\t\t\t\t\t<span v-if=\"item.hint\" class=\"cn-next-step-card__hint\">{{ item.hint }}</span>\n\t\t\t\t\t<!-- The state in words. The marker is a shape and a colour, and\n\t\t\t\t\t neither reaches a screen reader or a reader who cannot tell\n\t\t\t\t\t the two colours apart. -->\n\t\t\t\t\t<span class=\"cn-next-step-card__state\">{{ item.done ? doneLabel : todoLabel }}</span>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div>\n\t\t<div v-if=\"actionLabel || $slots.action || after\" class=\"cn-next-step-card__side\">\n\t\t\t<!-- @slot action Replace the primary button, for a host that renders its own control. -->\n\t\t\t<slot name=\"action\">\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"actionLabel\"\n\t\t\t\t\t:id=\"actionId || null\"\n\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t:disabled=\"actionDisabled\"\n\t\t\t\t\tdata-testid=\"cn-next-step-action\"\n\t\t\t\t\t@click=\"$emit('action')\">\n\t\t\t\t\t{{ actionLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</slot>\n\t\t\t<span v-if=\"after\" class=\"cn-next-step-card__after\">{{ after }}</span>\n\t\t</div>\n\t</section>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton } from '@nextcloud/vue'\nimport Check from 'vue-material-design-icons/Check.vue'\n\nlet nextStepCardUid = 0\n\n/**\n * CnNextStepCard: what this record needs now, next to the button that does it.\n *\n * A short checklist for the current step and one primary action. It answers\n * \"what do I do next?\" on a record whose menu would otherwise make the handler\n * guess. Renders nothing when there is no checklist, so a step that needs no\n * explaining shows no empty card.\n *\n * ```vue\n * <CnNextStepCard\n * title=\"What now? Step 2: handling\"\n * :items=\"[\n * { label: 'Receipt confirmed', done: true },\n * { label: 'Review the open documents', hint: '2 of 5 done' },\n * { label: 'Draft the decision' },\n * ]\"\n * action-label=\"Continue reviewing\"\n * after=\"Then: step 3, decision\"\n * @action=\"onContinue\" />\n * ```\n *\n * CnDetailPage renders this card from its `nextStep` config, and the\n * `next-step` detail widget type renders it inside a grid.\n */\nexport default {\n\tname: 'CnNextStepCard',\n\n\tcomponents: {\n\t\tCheck,\n\t\tNcButton,\n\t},\n\n\tprops: {\n\t\t/** Heading of the card, for example \"What now? Step 2: handling\". */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Element the heading renders as. Pick the level that fits the page outline. */\n\t\ttitleTag: {\n\t\t\ttype: String,\n\t\t\tdefault: 'h3',\n\t\t},\n\n\t\t/**\n\t\t * The checklist: `{ label, done?, hint? }` per item. The first item\n\t\t * that is not done is emphasised as the one to pick up now.\n\t\t */\n\t\titems: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Label of the primary button. Empty renders no button. */\n\t\tactionLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** DOM id for the primary button, so a skip link can land on it. */\n\t\tactionId: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Disable the primary button, for example while its request is in flight. */\n\t\tactionDisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** One line under the button saying what follows, for example \"Then: step 3, decision\". */\n\t\tafter: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Text state of a done item, read by screen readers. */\n\t\tdoneLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Done'),\n\t\t},\n\n\t\t/** Text state of an open item, read by screen readers. */\n\t\ttodoLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'To do'),\n\t\t},\n\t},\n\n\temits: [\n\t\t/** The primary button was pressed. */\n\t\t'action',\n\t],\n\n\tdata() {\n\t\tnextStepCardUid += 1\n\t\treturn {\n\t\t\ttitleId: `cn-next-step-title-${nextStepCardUid}`,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The items that can render: an object with a label.\n\t\t *\n\t\t * @return {Array<{label: string, done: boolean, hint: string}>} The checklist.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tnormalisedItems() {\n\t\t\treturn (Array.isArray(this.items) ? this.items : [])\n\t\t\t\t.filter((item) => item && typeof item.label === 'string' && item.label !== '')\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tlabel: item.label,\n\t\t\t\t\tdone: item.done === true,\n\t\t\t\t\thint: typeof item.hint === 'string' ? item.hint : '',\n\t\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Index of the first open item, the one to pick up now.\n\t\t *\n\t\t * @return {number} The index, or -1 when everything is done.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tcurrentIndex() {\n\t\t\treturn this.normalisedItems.findIndex((item) => !item.done)\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for a card without a title.\n\t\t *\n\t\t * @return {string} The label.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tfallbackLabel() {\n\t\t\treturn t('nextcloud-vue', 'Next step')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-next-step-card {\n\talign-items: center;\n\tbackground: var(--color-main-background);\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n\t/* The edge says \"this is the thing to act on\". An inset shadow, so it\n\t follows the card's rounded corners instead of squaring them off. */\n\tbox-shadow: inset 4px 0 0 var(--color-primary-element);\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: calc(4 * var(--default-grid-baseline)) calc(8 * var(--default-grid-baseline));\n\tpadding: calc(5 * var(--default-grid-baseline)) calc(6 * var(--default-grid-baseline));\n\tpadding-inline-start: calc(7 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__main {\n\tdisplay: flex;\n\tflex: 1 1 420px;\n\tflex-direction: column;\n\tgap: calc(2.5 * var(--default-grid-baseline));\n\tmin-width: 0;\n}\n\n.cn-next-step-card__title {\n\tcolor: var(--color-main-text);\n\tfont-size: 0.85em;\n\tfont-weight: 700;\n\tletter-spacing: 0.06em;\n\tmargin: 0;\n\ttext-transform: uppercase;\n}\n\n.cn-next-step-card__list {\n\tdisplay: grid;\n\tgap: calc(2 * var(--default-grid-baseline));\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.cn-next-step-card__item {\n\talign-items: center;\n\tcolor: var(--color-text-maxcontrast);\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: calc(2.5 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__item--current {\n\tcolor: var(--color-main-text);\n}\n\n.cn-next-step-card__item--current .cn-next-step-card__label {\n\tfont-weight: 700;\n}\n\n.cn-next-step-card__marker {\n\talign-items: center;\n\tborder: 2px solid var(--color-border-maxcontrast);\n\tborder-radius: 50%;\n\tbox-sizing: border-box;\n\tdisplay: inline-flex;\n\tflex: none;\n\theight: 20px;\n\tjustify-content: center;\n\twidth: 20px;\n}\n\n.cn-next-step-card__item--current .cn-next-step-card__marker {\n\tborder-color: var(--color-primary-element);\n}\n\n.cn-next-step-card__item--done .cn-next-step-card__marker {\n\tbackground: var(--color-primary-element);\n\tborder-color: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n}\n\n.cn-next-step-card__hint {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-weight: 400;\n}\n\n/* Read, not seen. */\n.cn-next-step-card__state {\n\tborder: 0;\n\tclip-path: inset(50%);\n\theight: 1px;\n\tmargin: -1px;\n\toverflow: hidden;\n\tpadding: 0;\n\tposition: absolute;\n\twhite-space: nowrap;\n\twidth: 1px;\n}\n\n.cn-next-step-card__side {\n\talign-items: flex-start;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: calc(2 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__after {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.9em;\n}\n</style>\n"],"names":["t"],"mappings":";;;;AAiEA,IAAI,kBAAkB,EAAA;;AAEtB;AACC;AACA;;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;;AAGA;AACA;;;;AAID,aAAe;AACd,CAAA,IAAI,EAAE,gBAAgB;;CAEtB,UAAU,EAAE;EACX,KAAK;AACL,EAAA,QAAQ;EACR;;AAED,CAAA,KAAK,EAAE;;AAEN,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;AACA,EAAA,QAAQ,EAAE;GACT,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,IAAI;GACb;;AAED;;AAEC;;AAED,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,KAAK;AACX,GAAA,OAAO,EAAE,MAAM,EAAE;GACjB;;;EAGD,WAAW,EAAE;GACZ,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;;AAGD,EAAA,QAAQ,EAAE;GACT,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;AACA,EAAA,cAAc,EAAE;GACf,IAAI,EAAE,OAAO;GACb,OAAO,EAAE,KAAK;GACd;;AAED;AACA,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;EACA,SAAS,EAAE;GACV,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,MAAM,CAAC;GACzC;;;EAGD,SAAS,EAAE;GACV,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,OAAO,CAAC;GAC1C;EACD;;AAED,CAAA,KAAK,EAAE;AACN;AACA,EAAA,QAAQ;EACR;;AAED,CAAA,IAAI,GAAG;AACN,EAAA,eAAc,IAAK,EAAA;AACnB,EAAA,OAAO;GACN,OAAO,EAAE,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;AACjD,GAAA;EACA;;AAED,CAAA,QAAQ,EAAE;AACT;AACC;AACA;AACA;;;AAGD,EAAA,eAAe,GAAG;GACjB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAA,GAAI,IAAI,CAAC,KAAM,GAAE,EAAE;AAClD,KAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAG,IAAK,OAAO,IAAI,CAAC,KAAM,KAAI,QAAS,IAAG,IAAI,CAAC,KAAM,KAAI,EAAE,CAAA;AAC7E,KAAC,GAAG,CAAC,CAAC,IAAI,MAAM;AACf,KAAA,KAAK,EAAE,IAAI,CAAC,KAAK;AACjB,KAAA,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI;AACxB,KAAA,IAAI,EAAE,OAAO,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC,IAAK,GAAE,EAAE;AACrD,KAAC,CAAC,CAAA;GACH;;AAED;AACC;AACA;;;;AAID,EAAA,YAAY,GAAG;GACd,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAA;GAC1D;;AAED;AACC;AACA;;;;AAID,EAAA,aAAa,GAAG;AACf,GAAA,OAAOA,SAAC,CAAC,eAAe,EAAE,WAAW,CAAA;GACrC;EACD;AACF;;;;"}
@@ -0,0 +1,106 @@
1
+ import { resolveComponent, openBlock, createElementBlock, createElementVNode, createBlock, resolveDynamicComponent, withCtx, createTextVNode, toDisplayString, createCommentVNode, Fragment, renderList, normalizeClass, renderSlot } from 'vue';
2
+
3
+ const _hoisted_1 = ["aria-labelledby", "aria-label"];
4
+ const _hoisted_2 = { class: "cn-next-step-card__main" };
5
+ const _hoisted_3 = { class: "cn-next-step-card__list" };
6
+ const _hoisted_4 = {
7
+ class: "cn-next-step-card__marker",
8
+ "aria-hidden": "true"
9
+ };
10
+ const _hoisted_5 = { class: "cn-next-step-card__label" };
11
+ const _hoisted_6 = {
12
+ key: 0,
13
+ class: "cn-next-step-card__hint"
14
+ };
15
+ const _hoisted_7 = { class: "cn-next-step-card__state" };
16
+ const _hoisted_8 = {
17
+ key: 0,
18
+ class: "cn-next-step-card__side"
19
+ };
20
+ const _hoisted_9 = {
21
+ key: 0,
22
+ class: "cn-next-step-card__after"
23
+ };
24
+
25
+ function render(_ctx, _cache, $props, $setup, $data, $options) {
26
+ const _component_Check = resolveComponent("Check");
27
+ const _component_NcButton = resolveComponent("NcButton");
28
+
29
+ return ($options.normalisedItems.length > 0)
30
+ ? (openBlock(), createElementBlock("section", {
31
+ key: 0,
32
+ class: "cn-next-step-card",
33
+ "data-testid": "cn-next-step-card",
34
+ "aria-labelledby": $props.title ? $data.titleId : null,
35
+ "aria-label": $props.title ? null : $options.fallbackLabel
36
+ }, [
37
+ createElementVNode("div", _hoisted_2, [
38
+ ($props.title)
39
+ ? (openBlock(), createBlock(resolveDynamicComponent($props.titleTag), {
40
+ key: 0,
41
+ id: $data.titleId,
42
+ class: "cn-next-step-card__title"
43
+ }, {
44
+ default: withCtx(() => [
45
+ createTextVNode(toDisplayString($props.title), 1 /* TEXT */)
46
+ ]),
47
+ _: 1 /* STABLE */
48
+ }, 8 /* PROPS */, ["id"]))
49
+ : createCommentVNode("v-if", true),
50
+ createElementVNode("ul", _hoisted_3, [
51
+ (openBlock(true), createElementBlock(Fragment, null, renderList($options.normalisedItems, (item, index) => {
52
+ return (openBlock(), createElementBlock("li", {
53
+ key: `${index}-${item.label}`,
54
+ class: normalizeClass(["cn-next-step-card__item", {
55
+ 'cn-next-step-card__item--done': item.done,
56
+ 'cn-next-step-card__item--current': index === $options.currentIndex,
57
+ }]),
58
+ "data-testid": "cn-next-step-item"
59
+ }, [
60
+ createElementVNode("span", _hoisted_4, [
61
+ (item.done)
62
+ ? (openBlock(), createBlock(_component_Check, {
63
+ key: 0,
64
+ size: 14
65
+ }))
66
+ : createCommentVNode("v-if", true)
67
+ ]),
68
+ createElementVNode("span", _hoisted_5, toDisplayString(item.label), 1 /* TEXT */),
69
+ (item.hint)
70
+ ? (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(item.hint), 1 /* TEXT */))
71
+ : createCommentVNode("v-if", true),
72
+ createElementVNode("span", _hoisted_7, toDisplayString(item.done ? $props.doneLabel : $props.todoLabel), 1 /* TEXT */)
73
+ ], 2 /* CLASS */))
74
+ }), 128 /* KEYED_FRAGMENT */))
75
+ ])
76
+ ]),
77
+ ($props.actionLabel || _ctx.$slots.action || $props.after)
78
+ ? (openBlock(), createElementBlock("div", _hoisted_8, [
79
+ renderSlot(_ctx.$slots, "action", {}, () => [
80
+ ($props.actionLabel)
81
+ ? (openBlock(), createBlock(_component_NcButton, {
82
+ key: 0,
83
+ id: $props.actionId || null,
84
+ variant: "primary",
85
+ disabled: $props.actionDisabled,
86
+ "data-testid": "cn-next-step-action",
87
+ onClick: _cache[0] || (_cache[0] = $event => (_ctx.$emit('action')))
88
+ }, {
89
+ default: withCtx(() => [
90
+ createTextVNode(toDisplayString($props.actionLabel), 1 /* TEXT */)
91
+ ]),
92
+ _: 1 /* STABLE */
93
+ }, 8 /* PROPS */, ["id", "disabled"]))
94
+ : createCommentVNode("v-if", true)
95
+ ]),
96
+ ($props.after)
97
+ ? (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString($props.after), 1 /* TEXT */))
98
+ : createCommentVNode("v-if", true)
99
+ ]))
100
+ : createCommentVNode("v-if", true)
101
+ ], 8 /* PROPS */, _hoisted_1))
102
+ : createCommentVNode("v-if", true)
103
+ }
104
+
105
+ export { render };
106
+ //# sourceMappingURL=CnNextStepCard.vue3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnNextStepCard.vue3.js","sources":["../../../../src/components/CnNextStepCard/CnNextStepCard.vue?vue&type=template&id=3a9ce962&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<section\n\t\tv-if=\"normalisedItems.length > 0\"\n\t\tclass=\"cn-next-step-card\"\n\t\tdata-testid=\"cn-next-step-card\"\n\t\t:aria-labelledby=\"title ? titleId : null\"\n\t\t:aria-label=\"title ? null : fallbackLabel\">\n\t\t<div class=\"cn-next-step-card__main\">\n\t\t\t<component\n\t\t\t\t:is=\"titleTag\"\n\t\t\t\tv-if=\"title\"\n\t\t\t\t:id=\"titleId\"\n\t\t\t\tclass=\"cn-next-step-card__title\">\n\t\t\t\t{{ title }}\n\t\t\t</component>\n\t\t\t<ul class=\"cn-next-step-card__list\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"(item, index) in normalisedItems\"\n\t\t\t\t\t:key=\"`${index}-${item.label}`\"\n\t\t\t\t\tclass=\"cn-next-step-card__item\"\n\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t'cn-next-step-card__item--done': item.done,\n\t\t\t\t\t\t'cn-next-step-card__item--current': index === currentIndex,\n\t\t\t\t\t}\"\n\t\t\t\t\tdata-testid=\"cn-next-step-item\">\n\t\t\t\t\t<span class=\"cn-next-step-card__marker\" aria-hidden=\"true\">\n\t\t\t\t\t\t<Check v-if=\"item.done\" :size=\"14\" />\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"cn-next-step-card__label\">{{ item.label }}</span>\n\t\t\t\t\t<span v-if=\"item.hint\" class=\"cn-next-step-card__hint\">{{ item.hint }}</span>\n\t\t\t\t\t<!-- The state in words. The marker is a shape and a colour, and\n\t\t\t\t\t neither reaches a screen reader or a reader who cannot tell\n\t\t\t\t\t the two colours apart. -->\n\t\t\t\t\t<span class=\"cn-next-step-card__state\">{{ item.done ? doneLabel : todoLabel }}</span>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div>\n\t\t<div v-if=\"actionLabel || $slots.action || after\" class=\"cn-next-step-card__side\">\n\t\t\t<!-- @slot action Replace the primary button, for a host that renders its own control. -->\n\t\t\t<slot name=\"action\">\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"actionLabel\"\n\t\t\t\t\t:id=\"actionId || null\"\n\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t:disabled=\"actionDisabled\"\n\t\t\t\t\tdata-testid=\"cn-next-step-action\"\n\t\t\t\t\t@click=\"$emit('action')\">\n\t\t\t\t\t{{ actionLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</slot>\n\t\t\t<span v-if=\"after\" class=\"cn-next-step-card__after\">{{ after }}</span>\n\t\t</div>\n\t</section>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton } from '@nextcloud/vue'\nimport Check from 'vue-material-design-icons/Check.vue'\n\nlet nextStepCardUid = 0\n\n/**\n * CnNextStepCard: what this record needs now, next to the button that does it.\n *\n * A short checklist for the current step and one primary action. It answers\n * \"what do I do next?\" on a record whose menu would otherwise make the handler\n * guess. Renders nothing when there is no checklist, so a step that needs no\n * explaining shows no empty card.\n *\n * ```vue\n * <CnNextStepCard\n * title=\"What now? Step 2: handling\"\n * :items=\"[\n * { label: 'Receipt confirmed', done: true },\n * { label: 'Review the open documents', hint: '2 of 5 done' },\n * { label: 'Draft the decision' },\n * ]\"\n * action-label=\"Continue reviewing\"\n * after=\"Then: step 3, decision\"\n * @action=\"onContinue\" />\n * ```\n *\n * CnDetailPage renders this card from its `nextStep` config, and the\n * `next-step` detail widget type renders it inside a grid.\n */\nexport default {\n\tname: 'CnNextStepCard',\n\n\tcomponents: {\n\t\tCheck,\n\t\tNcButton,\n\t},\n\n\tprops: {\n\t\t/** Heading of the card, for example \"What now? Step 2: handling\". */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Element the heading renders as. Pick the level that fits the page outline. */\n\t\ttitleTag: {\n\t\t\ttype: String,\n\t\t\tdefault: 'h3',\n\t\t},\n\n\t\t/**\n\t\t * The checklist: `{ label, done?, hint? }` per item. The first item\n\t\t * that is not done is emphasised as the one to pick up now.\n\t\t */\n\t\titems: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Label of the primary button. Empty renders no button. */\n\t\tactionLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** DOM id for the primary button, so a skip link can land on it. */\n\t\tactionId: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Disable the primary button, for example while its request is in flight. */\n\t\tactionDisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** One line under the button saying what follows, for example \"Then: step 3, decision\". */\n\t\tafter: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Text state of a done item, read by screen readers. */\n\t\tdoneLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Done'),\n\t\t},\n\n\t\t/** Text state of an open item, read by screen readers. */\n\t\ttodoLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'To do'),\n\t\t},\n\t},\n\n\temits: [\n\t\t/** The primary button was pressed. */\n\t\t'action',\n\t],\n\n\tdata() {\n\t\tnextStepCardUid += 1\n\t\treturn {\n\t\t\ttitleId: `cn-next-step-title-${nextStepCardUid}`,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The items that can render: an object with a label.\n\t\t *\n\t\t * @return {Array<{label: string, done: boolean, hint: string}>} The checklist.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tnormalisedItems() {\n\t\t\treturn (Array.isArray(this.items) ? this.items : [])\n\t\t\t\t.filter((item) => item && typeof item.label === 'string' && item.label !== '')\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tlabel: item.label,\n\t\t\t\t\tdone: item.done === true,\n\t\t\t\t\thint: typeof item.hint === 'string' ? item.hint : '',\n\t\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Index of the first open item, the one to pick up now.\n\t\t *\n\t\t * @return {number} The index, or -1 when everything is done.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tcurrentIndex() {\n\t\t\treturn this.normalisedItems.findIndex((item) => !item.done)\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for a card without a title.\n\t\t *\n\t\t * @return {string} The label.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tfallbackLabel() {\n\t\t\treturn t('nextcloud-vue', 'Next step')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-next-step-card {\n\talign-items: center;\n\tbackground: var(--color-main-background);\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n\t/* The edge says \"this is the thing to act on\". An inset shadow, so it\n\t follows the card's rounded corners instead of squaring them off. */\n\tbox-shadow: inset 4px 0 0 var(--color-primary-element);\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: calc(4 * var(--default-grid-baseline)) calc(8 * var(--default-grid-baseline));\n\tpadding: calc(5 * var(--default-grid-baseline)) calc(6 * var(--default-grid-baseline));\n\tpadding-inline-start: calc(7 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__main {\n\tdisplay: flex;\n\tflex: 1 1 420px;\n\tflex-direction: column;\n\tgap: calc(2.5 * var(--default-grid-baseline));\n\tmin-width: 0;\n}\n\n.cn-next-step-card__title {\n\tcolor: var(--color-main-text);\n\tfont-size: 0.85em;\n\tfont-weight: 700;\n\tletter-spacing: 0.06em;\n\tmargin: 0;\n\ttext-transform: uppercase;\n}\n\n.cn-next-step-card__list {\n\tdisplay: grid;\n\tgap: calc(2 * var(--default-grid-baseline));\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.cn-next-step-card__item {\n\talign-items: center;\n\tcolor: var(--color-text-maxcontrast);\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: calc(2.5 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__item--current {\n\tcolor: var(--color-main-text);\n}\n\n.cn-next-step-card__item--current .cn-next-step-card__label {\n\tfont-weight: 700;\n}\n\n.cn-next-step-card__marker {\n\talign-items: center;\n\tborder: 2px solid var(--color-border-maxcontrast);\n\tborder-radius: 50%;\n\tbox-sizing: border-box;\n\tdisplay: inline-flex;\n\tflex: none;\n\theight: 20px;\n\tjustify-content: center;\n\twidth: 20px;\n}\n\n.cn-next-step-card__item--current .cn-next-step-card__marker {\n\tborder-color: var(--color-primary-element);\n}\n\n.cn-next-step-card__item--done .cn-next-step-card__marker {\n\tbackground: var(--color-primary-element);\n\tborder-color: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n}\n\n.cn-next-step-card__hint {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-weight: 400;\n}\n\n/* Read, not seen. */\n.cn-next-step-card__state {\n\tborder: 0;\n\tclip-path: inset(50%);\n\theight: 1px;\n\tmargin: -1px;\n\toverflow: hidden;\n\tpadding: 0;\n\tposition: absolute;\n\twhite-space: nowrap;\n\twidth: 1px;\n}\n\n.cn-next-step-card__side {\n\talign-items: flex-start;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: calc(2 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__after {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.9em;\n}\n</style>\n"],"names":["_createElementBlock","_createElementVNode","_openBlock","_createBlock","_resolveDynamicComponent","_Fragment","_renderList","_toDisplayString"],"mappings":";;;AAiBO,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,yBAAuB,GAAA;AAQ7B,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,yBAAA,GAAA;;AAUF,EAAA,KAAK,EAAC,2BAA2B;eAAY,EAAA,MAAO;;AAGpD,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,0BAA0B,GAAA;;;AACnC,EAAA,KAAA,EAAA,yBAAA;;AAIG,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,0BAA0B,GAAA;;;AAIjB,EAAA,KAAA,EAAA,yBAAA;;;;;;;;;;;AAnClB,EAAA,OAAA,CAAA,QAAA,CAAA,eAAe,CAAC,MAAM,GAAA,CAAA;oBAD5BA;;AAEC,QAAA,KAAI,EAAC,mBAAI;qBACC,EAAC,mBAAG;yBACF,EAAA,MAAA,CAAA,KAAA,GAAA,KAAA,CAAA,OAAA,GAAA,IAAA;oBACF,EAAE,MAAC,CAAA,KAAA,GAAA,IAAA,GAAA,QAAA,CAAA,aAAA;;AACZ,QAAAC,kBAAA,CA6BI,OA7BJ,UA6BI,EAAA;WA1BE,MAAK,CAAA,KAAA;AAFX,eAAAC,SAAA,EAAA,EAAAC,WAAA,CAMWC,wBALN,MAAK,CAAA,QAAA,CAAA,EAAA;;AAET,gBAAA,EAAC,EAAA,KAAA,CAAA,OAAA;AACD,gBAAA,KAAI,EAAC,0BAA0B;;iCAC/B,MAAU;kDAAR,MAAK,CAAA,KAAA,CAAA,EAAA,CAAA,YAAA;;;;;AAEP,UAAAH,kBAAA,CAoBG,MApBH,UAoBG,EAAA;AAnBF,aAAAC,SAAA,CAAA,IAAA,CAAA,EAAAF,kBAAA,CAkBGK,QAjBoB,EAAA,IAAA,EAAAC,UAAA,CAAA,QAAA,CAAA,eAAe,EAA/B,CAAA,IAAI,EAAE,KAAK,KAAA;mCADlBN,kBAkBG,CAAA,IAAA,EAAA;AAhBH,gBAAA,GAAA,EAAA,CAAA,EAAA,KAAA,CAAA,CAAA,EAAA,IAAA,CAAA,KAAA,CAAA,CAAA;AACD,gBAAA,KAAK,kBAAC,yBAAyB,EAAA;AACkB,MAAA,+BAAA,EAAA,IAAI,CAAC,IAAI;AAAA,MAAA,kCAAA,EAAA,KAAA,KAAA,QAAA,CAAA,YAAA;;AAI1D,gBAAA,aAAW,EAAC,mBAAmB;;AAC/B,gBAAAC,kBAAA,CAEO,QAFP,UAEO,EAAA;AADO,kBAAA,CAAA,IAAI,CAAC,IAAI;+CAAe,CAAA,gBAAA,EAAA;;AAAZ,wBAAA,IAAI,EAAE,EAAE;;;;AAElC,gBAAAA,kBAAA,CAA8D,MAA9D,EAAA,UAA8D,EAApBM,eAAA,CAAA,IAAI,CAAC,KAAK,CAAA,EAAA,CAAA,YAAA;AACjD,gBAAA,CAAA,IAAA,CAAA,IAAA;AAAH,qBAAAL,SAAA,EAAA,EAAAF,kBAAA,CAAG,MAAH,EAAA,UAAG,EAAAO,eAAA,CAAA,IAAA,CAAA,IAAA,CAAA,EAAA,CAAA,YAAA;;gBAIHN,kBAAqF,CAAA,MAAA,EAArF,UAAqF,EAA3CM,eAAA,CAAA,IAAI,CAAE,IAAG,GAAI,MAAQ,CAAA,SAAA,GAAG,MAAU,CAAA,SAAA,CAAA,EAAA,CAAA,YAAA;;;;;AAIpE,QAAA,CAAA,MAAA,CAAA,WAAW,IAAE,IAAA,CAAA,MAAA,CAAA,MAAA,IAAA,MAAA,CAAA,KAAA;AAArB,aAAAL,SAAA,EAAA,EAAAF,kBAAA,QAAA;;iBAIM,MAAW,CAAA,WAAA;kCADjBG;;AAEC,sBAAA,EAAE,EAAE,MAAQ,CAAA,QAAA,IAAA,IAAA;AACb,sBAAA,OAAO,EAAC,SAAC;AACR,sBAAA,QAAG,EAAA,MAAA,CAAA,cAAA;AACJ,sBAAA,aAAW,EAAC,qBAAqB;AAChC,sBAAA,OAAC,uCAAA,IAAA,CAAA,KAAA,CAAA,QAAA,CAAA,CAAA,CAAA;;uCACF,MAAK;wDAAF,MAAE,CAAA,WAAA,CAAA,EAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,9 @@
1
+ import script from './CnNextStepWidget.vue2.js';
2
+ import { render } from './CnNextStepWidget.vue3.js';
3
+
4
+ script.render = render;
5
+ script.__file = "src/components/CnNextStepCard/CnNextStepWidget.vue";
6
+ const __sfc_main = script;
7
+
8
+ export { __sfc_main as default };
9
+ //# sourceMappingURL=CnNextStepWidget.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnNextStepWidget.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
@@ -0,0 +1,47 @@
1
+ import __sfc_main from './CnNextStepCard.vue.js';
2
+ import { resolveNextStep } from '../../utils/detailActionModel.js';
3
+
4
+ /**
5
+ * CnNextStepWidget: the `next-step` detail widget type.
6
+ *
7
+ * Renders CnNextStepCard for the bound record's stage from
8
+ * `content: { field?, stages: { <stage>: { title?, checklist, after? } } }`.
9
+ * The checklist only: the page's own primary button stays where the page
10
+ * puts it. Resolved by its registry key, not exported.
11
+ */
12
+ var script = {
13
+ name: 'CnNextStepWidget',
14
+
15
+ components: {
16
+ CnNextStepCard: __sfc_main,
17
+ },
18
+
19
+ props: {
20
+ /** The widget's content: `{ field?, title?, stages }`. */
21
+ content: {
22
+ type: Object,
23
+ default: () => ({}),
24
+ },
25
+
26
+ /** The bound record. */
27
+ objectData: {
28
+ type: Object,
29
+ default: null,
30
+ },
31
+ },
32
+
33
+ computed: {
34
+ /**
35
+ * The card for the record's stage.
36
+ *
37
+ * @return {object|null} The resolved card, or null when the stage declares none.
38
+ * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card
39
+ */
40
+ step() {
41
+ return resolveNextStep(this.content, this.objectData)
42
+ },
43
+ },
44
+ };
45
+
46
+ export { script as default };
47
+ //# sourceMappingURL=CnNextStepWidget.vue2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnNextStepWidget.vue2.js","sources":["../../../../src/components/CnNextStepCard/CnNextStepWidget.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<CnNextStepCard\n\t\tv-if=\"step\"\n\t\t:title=\"step.title\"\n\t\t:items=\"step.items\"\n\t\t:after=\"step.after\" />\n</template>\n\n<script>\nimport CnNextStepCard from './CnNextStepCard.vue'\nimport { resolveNextStep } from '../../utils/detailActionModel.js'\n\n/**\n * CnNextStepWidget: the `next-step` detail widget type.\n *\n * Renders CnNextStepCard for the bound record's stage from\n * `content: { field?, stages: { <stage>: { title?, checklist, after? } } }`.\n * The checklist only: the page's own primary button stays where the page\n * puts it. Resolved by its registry key, not exported.\n */\nexport default {\n\tname: 'CnNextStepWidget',\n\n\tcomponents: {\n\t\tCnNextStepCard,\n\t},\n\n\tprops: {\n\t\t/** The widget's content: `{ field?, title?, stages }`. */\n\t\tcontent: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The bound record. */\n\t\tobjectData: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The card for the record's stage.\n\t\t *\n\t\t * @return {object|null} The resolved card, or null when the stage declares none.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tstep() {\n\t\t\treturn resolveNextStep(this.content, this.objectData)\n\t\t},\n\t},\n}\n</script>\n"],"names":["CnNextStepCard"],"mappings":";;;AAiBA;;AAEC;;AAEA;;AAEA;;AAED,aAAe;CACd,IAAI,EAAE,kBAAkB;;CAExB,UAAU,EAAE;AACX,kBAAAA,UAAc;EACd;;AAED,CAAA,KAAK,EAAE;;AAEN,EAAA,OAAO,EAAE;GACR,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,OAAO,EAAE,CAAC;GACnB;;AAED;EACA,UAAU,EAAE;GACX,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,IAAI;GACb;EACD;;AAED,CAAA,QAAQ,EAAE;AACT;;AAEC;AACA;;;AAGD,EAAA,IAAI,GAAG;GACN,OAAO,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAA;GACpD;EACD;AACF;;;;"}
@@ -0,0 +1,17 @@
1
+ import { resolveComponent, openBlock, createBlock, createCommentVNode } from 'vue';
2
+
3
+ function render(_ctx, _cache, $props, $setup, $data, $options) {
4
+ const _component_CnNextStepCard = resolveComponent("CnNextStepCard");
5
+
6
+ return ($options.step)
7
+ ? (openBlock(), createBlock(_component_CnNextStepCard, {
8
+ key: 0,
9
+ title: $options.step.title,
10
+ items: $options.step.items,
11
+ after: $options.step.after
12
+ }, null, 8 /* PROPS */, ["title", "items", "after"]))
13
+ : createCommentVNode("v-if", true)
14
+ }
15
+
16
+ export { render };
17
+ //# sourceMappingURL=CnNextStepWidget.vue3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnNextStepWidget.vue3.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
@@ -87,6 +87,13 @@ var script = {
87
87
  * identity when used standalone (no CnAppRoot ancestor).
88
88
  */
89
89
  cnTranslate: { default: () => (key) => key },
90
+ /**
91
+ * Formatter registry, provided by CnAppRoot (`cnFormatters`: the
92
+ * library's built-ins plus the app's `formatters`). A field override
93
+ * `{ formatter: '<id>' }` renders the value through the same function a
94
+ * table column with that `formatter` uses. Empty when used standalone.
95
+ */
96
+ cnFormatters: { default: () => ({}) },
90
97
  /**
91
98
  * The host surface's panel-action channel, when this widget is rendered
92
99
  * in a tab panel. Null everywhere else, which is every other surface.
@@ -272,6 +279,11 @@ var script = {
272
279
  * - `editable` (boolean) — Override editability (default: based on schema readOnly)
273
280
  * - `label` (string) — Override the display label
274
281
  * - `widget` (string) — Override the widget type for editing
282
+ * - `formatter` (string) — Display the value through the formatter
283
+ * registered under this id on CnAppRoot (`cnFormatters`), called as
284
+ * `(value, object, property)` like a table cell's formatter. An id
285
+ * nobody registered, or a formatter that throws, keeps the default
286
+ * rendering. Editing still writes the stored value.
275
287
  *
276
288
  * Accepts an Array too: an empty overrides map (`{}`) round-trips through
277
289
  * PHP/JSON as an empty Array (`[]`), so a persisted manifest can deliver
@@ -548,12 +560,46 @@ var script = {
548
560
  }
549
561
  },
550
562
 
563
+ /**
564
+ * Display values of the fields whose override names a registered
565
+ * formatter, keyed by field key. A field is left out when its formatter
566
+ * id is not registered or the formatter throws, so it falls back to the
567
+ * default rendering.
568
+ *
569
+ * @return {Record<string, string>}
570
+ */
571
+ formatterDisplayValues() {
572
+ const values = {};
573
+ for (const field of this.resolvedFields) {
574
+ const fn = field.formatter && this.cnFormatters && this.cnFormatters[field.formatter];
575
+ if (typeof fn !== 'function') {
576
+ continue
577
+ }
578
+ const raw = field.key in this.dirtyFields
579
+ ? this.dirtyFields[field.key]
580
+ : (this.objectData || {})[field.key];
581
+ const prop = (this.schema.properties && this.schema.properties[field.key]) || {};
582
+ try {
583
+ const formatted = fn(raw, this.objectData || {}, prop);
584
+ values[field.key] = (formatted === null || formatted === undefined || formatted === '') ? '—' : String(formatted);
585
+ } catch (e) {
586
+ // eslint-disable-next-line no-console
587
+ console.warn(`[CnObjectDataWidget] formatter "${field.formatter}" threw; falling back`, e);
588
+ }
589
+ }
590
+ return values
591
+ },
592
+
551
593
  /**
552
594
  * Formatted display values for each field.
553
595
  */
554
596
  displayValues() {
555
597
  const values = {};
556
598
  for (const field of this.resolvedFields) {
599
+ if (field.key in this.formatterDisplayValues) {
600
+ values[field.key] = this.formatterDisplayValues[field.key];
601
+ continue
602
+ }
557
603
  // Show pending edit value if dirty
558
604
  const raw = field.key in this.dirtyFields
559
605
  ? this.dirtyFields[field.key]
@@ -822,6 +868,9 @@ var script = {
822
868
  * @return {'object-array'|'scalar-array'|'object'|'scalar'} The value kind.
823
869
  */
824
870
  fieldValueKind(field) {
871
+ if (field.key in this.formatterDisplayValues) {
872
+ return 'scalar'
873
+ }
825
874
  const prop = ((this.schema && this.schema.properties) || {})[field.key];
826
875
  if (this.isRelationField(prop)) {
827
876
  return 'scalar'