@conduction/nextcloud-vue 2.58.0 → 2.60.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 (507) hide show
  1. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +12 -2
  2. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +1 -2
  4. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
  5. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js +14 -1
  6. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
  7. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +0 -3
  8. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
  9. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
  10. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +1 -2
  11. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
  12. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +39 -0
  13. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  14. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +46 -4
  15. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  16. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +224 -9
  17. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
  18. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js +79 -25
  19. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
  20. package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue2.js +42 -3
  21. package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue2.js.map +1 -1
  22. package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue3.js +39 -6
  23. package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue3.js.map +1 -1
  24. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +58 -5
  25. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
  26. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +13 -5
  27. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
  28. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue.js +10 -0
  29. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue.js.map +1 -0
  30. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js +39 -0
  31. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js.map +1 -0
  32. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js +16 -0
  33. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js.map +1 -0
  34. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js +9 -1
  35. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js.map +1 -1
  36. package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js.map +1 -1
  37. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +117 -1
  38. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
  39. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +147 -89
  40. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
  41. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js +6 -1
  42. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js.map +1 -1
  43. package/dist/esm/components/CnContextMenu/CnContextMenu.vue3.js.map +1 -1
  44. package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js +10 -0
  45. package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js.map +1 -0
  46. package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js +259 -0
  47. package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -0
  48. package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js +131 -0
  49. package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -0
  50. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js +10 -0
  51. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js.map +1 -0
  52. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js +116 -0
  53. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js.map +1 -0
  54. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js +24 -0
  55. package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js.map +1 -0
  56. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +116 -15
  57. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  58. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +27 -14
  59. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  60. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js +13 -6
  61. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js.map +1 -1
  62. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js +2 -0
  63. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js.map +1 -1
  64. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +532 -29
  65. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  66. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +300 -142
  67. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  68. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue.js +10 -0
  69. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue.js.map +1 -0
  70. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue2.js +237 -0
  71. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue2.js.map +1 -0
  72. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue3.js +120 -0
  73. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue3.js.map +1 -0
  74. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue.js +10 -0
  75. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue.js.map +1 -0
  76. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js +77 -0
  77. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js.map +1 -0
  78. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js +27 -0
  79. package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js.map +1 -0
  80. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
  81. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js +1 -2
  82. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
  83. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +3 -1
  84. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  85. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +17 -17
  86. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  87. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js +4 -21
  88. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js.map +1 -1
  89. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue3.js.map +1 -1
  90. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js +0 -13
  91. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js.map +1 -1
  92. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js +8 -8
  93. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js.map +1 -1
  94. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue2.js.map +1 -1
  95. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js +3 -2
  96. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js.map +1 -1
  97. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +169 -12
  98. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
  99. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +15 -7
  100. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
  101. package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue2.js +37 -3
  102. package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue2.js.map +1 -1
  103. package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue3.js +44 -16
  104. package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue3.js.map +1 -1
  105. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +199 -16
  106. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  107. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +20 -10
  108. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  109. package/dist/esm/components/CnIndexPage/manifestActionDispatch.js +31 -11
  110. package/dist/esm/components/CnIndexPage/manifestActionDispatch.js.map +1 -1
  111. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue2.js.map +1 -1
  112. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js +1 -2
  113. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js.map +1 -1
  114. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue2.js.map +1 -1
  115. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js +0 -1
  116. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js.map +1 -1
  117. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js +2 -17
  118. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js.map +1 -1
  119. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue3.js.map +1 -1
  120. package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js +35 -11
  121. package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js.map +1 -1
  122. package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js +3 -2
  123. package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js.map +1 -1
  124. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue.js +10 -0
  125. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue.js.map +1 -0
  126. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js +150 -0
  127. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js.map +1 -0
  128. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js +106 -0
  129. package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js.map +1 -0
  130. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue.js +9 -0
  131. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue.js.map +1 -0
  132. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js +47 -0
  133. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js.map +1 -0
  134. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue3.js +17 -0
  135. package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue3.js.map +1 -0
  136. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js +23 -5
  137. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js.map +1 -1
  138. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js +1 -1
  139. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js.map +1 -1
  140. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +49 -0
  141. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
  142. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
  143. package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue2.js +6 -0
  144. package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue2.js.map +1 -1
  145. package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue3.js.map +1 -1
  146. package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue2.js +46 -0
  147. package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue2.js.map +1 -1
  148. package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue3.js +15 -3
  149. package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue3.js.map +1 -1
  150. package/dist/esm/components/CnObjectList/CnObjectList.vue2.js +19 -3
  151. package/dist/esm/components/CnObjectList/CnObjectList.vue2.js.map +1 -1
  152. package/dist/esm/components/CnObjectList/CnObjectList.vue3.js.map +1 -1
  153. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +45 -15
  154. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  155. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -2
  156. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  157. package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js +24 -6
  158. package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js.map +1 -1
  159. package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js +1 -1
  160. package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js.map +1 -1
  161. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  162. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +0 -1
  163. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  164. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
  165. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js +4 -2
  166. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
  167. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +37 -1
  168. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
  169. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js +29 -13
  170. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
  171. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js +100 -3
  172. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js.map +1 -1
  173. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue3.js.map +1 -1
  174. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js +7 -2
  175. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js.map +1 -1
  176. package/dist/esm/components/CnRowActions/CnRowActions.vue3.js.map +1 -1
  177. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js +50 -3
  178. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js.map +1 -1
  179. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js.map +1 -1
  180. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue.js +10 -0
  181. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue.js.map +1 -0
  182. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js +186 -0
  183. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js.map +1 -0
  184. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js +46 -0
  185. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js.map +1 -0
  186. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js +5 -3
  187. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js.map +1 -1
  188. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue3.js.map +1 -1
  189. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue.js +11 -0
  190. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue.js.map +1 -0
  191. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js +298 -0
  192. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js.map +1 -0
  193. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js +77 -0
  194. package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js.map +1 -0
  195. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js +10 -0
  196. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js.map +1 -0
  197. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue2.js +169 -0
  198. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue2.js.map +1 -0
  199. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue3.js +48 -0
  200. package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue3.js.map +1 -0
  201. package/dist/esm/components/CnTabs/CnTab.vue2.js +35 -0
  202. package/dist/esm/components/CnTabs/CnTab.vue2.js.map +1 -1
  203. package/dist/esm/components/CnTabs/CnTab.vue3.js.map +1 -1
  204. package/dist/esm/components/CnTabs/CnTabs.vue2.js +120 -7
  205. package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
  206. package/dist/esm/components/CnTabs/CnTabs.vue3.js +57 -5
  207. package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
  208. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +59 -4
  209. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  210. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +6 -2
  211. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  212. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js +3 -1
  213. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js.map +1 -1
  214. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js +1 -0
  215. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js.map +1 -1
  216. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js +10 -0
  217. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js.map +1 -0
  218. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js +484 -0
  219. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js.map +1 -0
  220. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js +115 -0
  221. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js.map +1 -0
  222. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js +10 -0
  223. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js.map +1 -0
  224. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue2.js +189 -0
  225. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue2.js.map +1 -0
  226. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue3.js +74 -0
  227. package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue3.js.map +1 -0
  228. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +82 -8
  229. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  230. package/dist/esm/index.js +10 -0
  231. package/dist/esm/index.js.map +1 -1
  232. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js +3 -1
  233. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js.map +1 -1
  234. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue3.js.map +1 -1
  235. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -1
  236. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
  237. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js +2 -4
  238. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
  239. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js +6 -0
  240. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js.map +1 -1
  241. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js +68 -53
  242. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js.map +1 -1
  243. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js +17 -0
  244. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js.map +1 -1
  245. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js +21 -19
  246. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js.map +1 -1
  247. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js +3 -1
  248. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js.map +1 -1
  249. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue3.js.map +1 -1
  250. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js +3 -1
  251. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js.map +1 -1
  252. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js +2 -4
  253. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js.map +1 -1
  254. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js +2 -1
  255. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js.map +1 -1
  256. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue3.js.map +1 -1
  257. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js +2 -1
  258. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js.map +1 -1
  259. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js +1 -2
  260. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js.map +1 -1
  261. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js +2 -1
  262. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js.map +1 -1
  263. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js.map +1 -1
  264. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +2 -1
  265. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
  266. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js +1 -2
  267. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
  268. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js.map +1 -1
  269. package/dist/esm/integrations/builtin/email/CnEmailCard.vue3.js.map +1 -1
  270. package/dist/esm/integrations/builtin/email/CnEmailTab.vue2.js.map +1 -1
  271. package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js +1 -2
  272. package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js.map +1 -1
  273. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js +2 -1
  274. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js.map +1 -1
  275. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue3.js.map +1 -1
  276. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js +2 -1
  277. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js.map +1 -1
  278. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js +1 -2
  279. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js.map +1 -1
  280. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js +3 -1
  281. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js.map +1 -1
  282. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue3.js.map +1 -1
  283. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js +3 -1
  284. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js.map +1 -1
  285. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js +2 -4
  286. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js.map +1 -1
  287. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js +3 -1
  288. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js.map +1 -1
  289. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue3.js.map +1 -1
  290. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js +3 -1
  291. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js.map +1 -1
  292. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js +2 -4
  293. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js.map +1 -1
  294. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js +3 -1
  295. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js.map +1 -1
  296. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue3.js.map +1 -1
  297. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js +3 -1
  298. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js.map +1 -1
  299. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js +2 -4
  300. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js.map +1 -1
  301. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js +2 -1
  302. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js.map +1 -1
  303. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue3.js.map +1 -1
  304. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js +2 -1
  305. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js.map +1 -1
  306. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js +1 -2
  307. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js.map +1 -1
  308. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js +2 -1
  309. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js.map +1 -1
  310. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue3.js.map +1 -1
  311. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js +2 -1
  312. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js.map +1 -1
  313. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js +1 -2
  314. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js.map +1 -1
  315. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue2.js.map +1 -1
  316. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js +3 -6
  317. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js.map +1 -1
  318. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js +3 -1
  319. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js.map +1 -1
  320. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue3.js.map +1 -1
  321. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js +3 -1
  322. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js.map +1 -1
  323. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js +2 -4
  324. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js.map +1 -1
  325. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js +2 -1
  326. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js.map +1 -1
  327. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue3.js.map +1 -1
  328. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js +2 -1
  329. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js.map +1 -1
  330. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js +1 -2
  331. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js.map +1 -1
  332. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js +4 -1
  333. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js.map +1 -1
  334. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue3.js.map +1 -1
  335. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js +6 -3
  336. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js.map +1 -1
  337. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js +2 -4
  338. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js.map +1 -1
  339. package/dist/esm/l10n/en.json.js +55 -1
  340. package/dist/esm/l10n/en.json.js.map +1 -1
  341. package/dist/esm/l10n/nl.json.js +55 -1
  342. package/dist/esm/l10n/nl.json.js.map +1 -1
  343. package/dist/esm/nextcloud-vue.css +998 -7
  344. package/dist/esm/utils/actionLink.js +5 -0
  345. package/dist/esm/utils/actionLink.js.map +1 -1
  346. package/dist/esm/utils/actionsDispatcher.js +16 -1
  347. package/dist/esm/utils/actionsDispatcher.js.map +1 -1
  348. package/dist/esm/utils/dateVariant.js +124 -0
  349. package/dist/esm/utils/dateVariant.js.map +1 -0
  350. package/dist/esm/utils/detailActionModel.js +260 -0
  351. package/dist/esm/utils/detailActionModel.js.map +1 -0
  352. package/dist/esm/utils/dueRule.js +84 -0
  353. package/dist/esm/utils/dueRule.js.map +1 -0
  354. package/dist/esm/utils/fetchAggregate.js +37 -1
  355. package/dist/esm/utils/fetchAggregate.js.map +1 -1
  356. package/dist/esm/utils/fetchFilterCounts.js +186 -0
  357. package/dist/esm/utils/fetchFilterCounts.js.map +1 -0
  358. package/dist/esm/utils/libraryWidgetKeys.js +5 -0
  359. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  360. package/dist/esm/utils/linkNavigation.js +6 -3
  361. package/dist/esm/utils/linkNavigation.js.map +1 -1
  362. package/dist/esm/utils/readPath.js +30 -0
  363. package/dist/esm/utils/readPath.js.map +1 -0
  364. package/dist/esm/utils/rowAuxClick.js +30 -5
  365. package/dist/esm/utils/rowAuxClick.js.map +1 -1
  366. package/dist/esm/utils/safeHref.js +18 -3
  367. package/dist/esm/utils/safeHref.js.map +1 -1
  368. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  369. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  370. package/dist/nextcloud-vue.cjs.js +15855 -9353
  371. package/dist/nextcloud-vue.cjs.js.map +2 -2
  372. package/dist/nextcloud-vue.css +998 -7
  373. package/l10n/en.json +55 -1
  374. package/l10n/nl.json +55 -1
  375. package/package.json +1 -1
  376. package/scripts/.jsdoc-baselines.json +3 -0
  377. package/src/components/CnActionsBar/CnActionsBar.vue +14 -5
  378. package/src/components/CnActionsMenu/CnActionsMenu.vue +14 -4
  379. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +1 -2
  380. package/src/components/CnAppNav/CnAppNav.md +26 -0
  381. package/src/components/CnAppNav/CnAppNav.vue +104 -1
  382. package/src/components/CnBannerWidget/CnBannerWidget.vue +365 -10
  383. package/src/components/CnBannerWidgetForm/CnBannerWidgetForm.vue +65 -3
  384. package/src/components/CnBoardView/CnBoardView.vue +90 -5
  385. package/src/components/CnBrandStripe/CnBrandStripe.md +22 -0
  386. package/src/components/CnBrandStripe/CnBrandStripe.vue +100 -0
  387. package/src/components/CnBrandStripe/index.js +4 -0
  388. package/src/components/CnCardGrid/CnCardGrid.vue +9 -1
  389. package/src/components/CnCellRenderer/CnCellRenderer.vue +207 -1
  390. package/src/components/CnContextMenu/CnContextMenu.vue +6 -1
  391. package/src/components/CnConversationThread/CnConversationThread.md +51 -0
  392. package/src/components/CnConversationThread/CnConversationThread.vue +457 -0
  393. package/src/components/CnConversationThread/CnConversationWidget.vue +144 -0
  394. package/src/components/CnConversationThread/index.js +4 -0
  395. package/src/components/CnDataTable/CnDataTable.md +1 -1
  396. package/src/components/CnDataTable/CnDataTable.vue +131 -17
  397. package/src/components/CnDateAxisView/CnDateAxisView.vue +15 -6
  398. package/src/components/CnDetailPage/CnDetailPage.md +17 -1
  399. package/src/components/CnDetailPage/CnDetailPage.vue +712 -49
  400. package/src/components/CnDocumentReviewList/CnDocumentReviewList.md +55 -0
  401. package/src/components/CnDocumentReviewList/CnDocumentReviewList.vue +384 -0
  402. package/src/components/CnDocumentReviewList/CnDocumentReviewWidget.vue +108 -0
  403. package/src/components/CnDocumentReviewList/index.js +4 -0
  404. package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +1 -2
  405. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +5 -3
  406. package/src/components/CnFilesWidget/CnFilesWidget.vue +4 -21
  407. package/src/components/CnFlowRunsWidget/CnFlowRunsWidget.vue +8 -21
  408. package/src/components/CnFlowsPage/CnFlowsPage.vue +2 -1
  409. package/src/components/CnHeaderWidget/CnHeaderWidget.vue +189 -14
  410. package/src/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue +53 -3
  411. package/src/components/CnIndexPage/CnIndexPage.vue +210 -17
  412. package/src/components/CnIndexPage/manifestActionDispatch.js +31 -11
  413. package/src/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue +1 -2
  414. package/src/components/CnInteractionFormWidget/CnInteractionFormWidget.vue +0 -1
  415. package/src/components/CnLinkButtonWidget/CnLinkButtonWidget.vue +2 -17
  416. package/src/components/CnLogsPage/CnLogsPage.vue +37 -12
  417. package/src/components/CnNextStepCard/CnNextStepCard.md +40 -0
  418. package/src/components/CnNextStepCard/CnNextStepCard.vue +319 -0
  419. package/src/components/CnNextStepCard/CnNextStepWidget.vue +59 -0
  420. package/src/components/CnNextStepCard/index.js +4 -0
  421. package/src/components/CnObjectCard/CnObjectCard.vue +24 -6
  422. package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +49 -0
  423. package/src/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue +6 -0
  424. package/src/components/CnObjectKanban/CnObjectKanban.vue +86 -2
  425. package/src/components/CnObjectList/CnObjectList.vue +19 -3
  426. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +47 -15
  427. package/src/components/CnObjectRow/CnObjectRow.vue +25 -7
  428. package/src/components/CnObjectSidebar/CnFilesTab.vue +0 -1
  429. package/src/components/CnPageRenderer/CnPageRenderer.vue +2 -0
  430. package/src/components/CnQuickFilterBar/CnQuickFilterBar.md +3 -0
  431. package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +60 -1
  432. package/src/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue +100 -3
  433. package/src/components/CnRowActions/CnRowActions.vue +7 -2
  434. package/src/components/CnSavedViewsControl/CnSavedViewsControl.vue +50 -3
  435. package/src/components/CnSegmentedControl/CnSegmentedControl.md +46 -0
  436. package/src/components/CnSegmentedControl/CnSegmentedControl.vue +291 -0
  437. package/src/components/CnSegmentedControl/index.js +4 -0
  438. package/src/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue +5 -3
  439. package/src/components/CnStackedBarWidget/CnStackedBarWidget.md +15 -0
  440. package/src/components/CnStackedBarWidget/CnStackedBarWidget.vue +414 -0
  441. package/src/components/CnStackedBarWidget/index.js +14 -0
  442. package/src/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue +224 -0
  443. package/src/components/CnStackedBarWidgetForm/index.js +4 -0
  444. package/src/components/CnTabs/CnTab.vue +35 -0
  445. package/src/components/CnTabs/CnTabs.vue +251 -13
  446. package/src/components/CnTabsWidget/CnTabsWidget.vue +63 -4
  447. package/src/components/CnTasksWidget/CnTasksWidget.vue +4 -1
  448. package/src/components/CnWeekStripWidget/CnWeekStripWidget.md +31 -0
  449. package/src/components/CnWeekStripWidget/CnWeekStripWidget.vue +668 -0
  450. package/src/components/CnWeekStripWidget/index.js +14 -0
  451. package/src/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue +265 -0
  452. package/src/components/CnWeekStripWidgetForm/index.js +4 -0
  453. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +74 -0
  454. package/src/components/index.js +11 -0
  455. package/src/css/detail-page.css +47 -0
  456. package/src/css/table.css +26 -0
  457. package/src/index.js +9 -0
  458. package/src/integrations/builtin/analytics/CnAnalyticsCard.vue +3 -2
  459. package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +5 -6
  460. package/src/integrations/builtin/bookmarks/CnBookmarksCard.vue +12 -1
  461. package/src/integrations/builtin/bookmarks/CnBookmarksTab.vue +23 -6
  462. package/src/integrations/builtin/bookmarks/__tests__/CnBookmarksTab.spec.js +7 -2
  463. package/src/integrations/builtin/collectives/CnCollectivesCard.vue +3 -2
  464. package/src/integrations/builtin/collectives/CnCollectivesTab.vue +5 -6
  465. package/src/integrations/builtin/cospend/CnCospendCard.vue +2 -2
  466. package/src/integrations/builtin/cospend/CnCospendTab.vue +3 -4
  467. package/src/integrations/builtin/deck/CnDeckCard.vue +2 -2
  468. package/src/integrations/builtin/deck/CnDeckTab.vue +3 -4
  469. package/src/integrations/builtin/email/CnEmailCard.vue +6 -2
  470. package/src/integrations/builtin/email/CnEmailTab.vue +7 -4
  471. package/src/integrations/builtin/flow/CnFlowCard.vue +2 -2
  472. package/src/integrations/builtin/flow/CnFlowTab.vue +3 -4
  473. package/src/integrations/builtin/forms/CnFormsCard.vue +3 -2
  474. package/src/integrations/builtin/forms/CnFormsTab.vue +5 -6
  475. package/src/integrations/builtin/maps/CnMapsCard.vue +3 -2
  476. package/src/integrations/builtin/maps/CnMapsTab.vue +5 -6
  477. package/src/integrations/builtin/maps/__tests__/CnMapsTab.spec.js +9 -0
  478. package/src/integrations/builtin/openproject/CnOpenprojectCard.vue +3 -2
  479. package/src/integrations/builtin/openproject/CnOpenprojectTab.vue +5 -6
  480. package/src/integrations/builtin/photos/CnPhotosCard.vue +2 -2
  481. package/src/integrations/builtin/photos/CnPhotosTab.vue +3 -4
  482. package/src/integrations/builtin/polls/CnPollsCard.vue +2 -2
  483. package/src/integrations/builtin/polls/CnPollsTab.vue +3 -4
  484. package/src/integrations/builtin/shares/CnSharesTab.vue +3 -6
  485. package/src/integrations/builtin/talk/CnTalkCard.vue +3 -2
  486. package/src/integrations/builtin/talk/CnTalkTab.vue +5 -6
  487. package/src/integrations/builtin/time-tracker/CnTimeTrackerCard.vue +2 -2
  488. package/src/integrations/builtin/time-tracker/CnTimeTrackerTab.vue +3 -4
  489. package/src/integrations/builtin/xwiki/CnXwikiCard.vue +4 -2
  490. package/src/integrations/builtin/xwiki/CnXwikiTab.vue +7 -7
  491. package/src/integrations/builtin/xwiki/__tests__/CnXwikiTab.spec.js +9 -0
  492. package/src/schemas/app-manifest-v2.schema.json +389 -1
  493. package/src/schemas/app-manifest.schema.json +2 -1
  494. package/src/utils/actionLink.js +5 -0
  495. package/src/utils/actionsDispatcher.js +15 -0
  496. package/src/utils/dateVariant.js +120 -0
  497. package/src/utils/detailActionModel.js +256 -0
  498. package/src/utils/dueRule.js +94 -0
  499. package/src/utils/fetchAggregate.js +36 -0
  500. package/src/utils/fetchFilterCounts.js +182 -0
  501. package/src/utils/index.js +1 -0
  502. package/src/utils/libraryWidgetKeys.js +5 -0
  503. package/src/utils/linkNavigation.js +6 -3
  504. package/src/utils/readPath.js +27 -0
  505. package/src/utils/rowAuxClick.js +29 -4
  506. package/src/utils/safeHref.js +18 -3
  507. package/src/utils/validateManifestV2.compiled.js +2 -2
@@ -0,0 +1,77 @@
1
+ import { resolveComponent, openBlock, createElementBlock, createVNode, createElementVNode, toDisplayString, Fragment, renderList, normalizeStyle, createTextVNode } from 'vue';
2
+
3
+ const _hoisted_1 = {
4
+ class: "cn-stacked-bar",
5
+ "data-testid": "cn-stacked-bar"
6
+ };
7
+ const _hoisted_2 = {
8
+ key: 0,
9
+ class: "cn-stacked-bar__state",
10
+ role: "status"
11
+ };
12
+ const _hoisted_3 = {
13
+ key: 1,
14
+ class: "cn-stacked-bar__state",
15
+ role: "status"
16
+ };
17
+ const _hoisted_4 = {
18
+ key: 2,
19
+ class: "cn-stacked-bar__state",
20
+ "data-testid": "cn-stacked-bar-empty"
21
+ };
22
+ const _hoisted_5 = {
23
+ class: "cn-stacked-bar__bar",
24
+ "aria-hidden": "true"
25
+ };
26
+ const _hoisted_6 = { class: "cn-stacked-bar__legend" };
27
+ const _hoisted_7 = { class: "cn-stacked-bar__label" };
28
+ const _hoisted_8 = { class: "cn-stacked-bar__count" };
29
+
30
+ function render(_ctx, _cache, $props, $setup, $data, $options) {
31
+ const _component_NcLoadingIcon = resolveComponent("NcLoadingIcon");
32
+
33
+ return (openBlock(), createElementBlock("div", _hoisted_1, [
34
+ ($data.loading)
35
+ ? (openBlock(), createElementBlock("div", _hoisted_2, [
36
+ createVNode(_component_NcLoadingIcon, { size: 20 }),
37
+ createElementVNode("span", null, toDisplayString($options.loadingLabel), 1 /* TEXT */)
38
+ ]))
39
+ : ($data.error)
40
+ ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString($options.errorLabel), 1 /* TEXT */))
41
+ : ($options.total === 0)
42
+ ? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString($options.emptyLabel), 1 /* TEXT */))
43
+ : (openBlock(), createElementBlock(Fragment, { key: 3 }, [
44
+ createElementVNode("div", _hoisted_5, [
45
+ (openBlock(true), createElementBlock(Fragment, null, renderList($options.barSegments, (segment) => {
46
+ return (openBlock(), createElementBlock("span", {
47
+ key: segment.key,
48
+ class: "cn-stacked-bar__segment",
49
+ style: normalizeStyle({ flexGrow: segment.count, backgroundColor: segment.color })
50
+ }, null, 4 /* STYLE */))
51
+ }), 128 /* KEYED_FRAGMENT */))
52
+ ]),
53
+ createElementVNode("ul", _hoisted_6, [
54
+ (openBlock(true), createElementBlock(Fragment, null, renderList($options.segments, (segment) => {
55
+ return (openBlock(), createElementBlock("li", {
56
+ key: segment.key,
57
+ class: "cn-stacked-bar__legend-item",
58
+ "data-testid": "cn-stacked-bar-legend-item"
59
+ }, [
60
+ createElementVNode("span", _hoisted_7, [
61
+ createElementVNode("span", {
62
+ class: "cn-stacked-bar__dot",
63
+ "aria-hidden": "true",
64
+ style: normalizeStyle({ backgroundColor: segment.color })
65
+ }, null, 4 /* STYLE */),
66
+ createTextVNode(" " + toDisplayString(segment.label), 1 /* TEXT */)
67
+ ]),
68
+ createElementVNode("strong", _hoisted_8, toDisplayString(' ' + segment.count), 1 /* TEXT */)
69
+ ]))
70
+ }), 128 /* KEYED_FRAGMENT */))
71
+ ])
72
+ ], 64 /* STABLE_FRAGMENT */))
73
+ ]))
74
+ }
75
+
76
+ export { render };
77
+ //# sourceMappingURL=CnStackedBarWidget.vue3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnStackedBarWidget.vue3.js","sources":["../../../../src/components/CnStackedBarWidget/CnStackedBarWidget.vue?vue&type=template&id=c0bac1a2&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-stacked-bar\" data-testid=\"cn-stacked-bar\">\n\t\t<div v-if=\"loading\" class=\"cn-stacked-bar__state\" role=\"status\">\n\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t<span>{{ loadingLabel }}</span>\n\t\t</div>\n\t\t<p v-else-if=\"error\" class=\"cn-stacked-bar__state\" role=\"status\">\n\t\t\t{{ errorLabel }}\n\t\t</p>\n\t\t<p v-else-if=\"total === 0\" class=\"cn-stacked-bar__state\" data-testid=\"cn-stacked-bar-empty\">\n\t\t\t{{ emptyLabel }}\n\t\t</p>\n\t\t<template v-else>\n\t\t\t<!-- The bar is a picture of the legend below it. The legend holds\n\t\t\t every label and number, so the bar itself is hidden from\n\t\t\t assistive technology rather than described twice. -->\n\t\t\t<div class=\"cn-stacked-bar__bar\" aria-hidden=\"true\">\n\t\t\t\t<span\n\t\t\t\t\tv-for=\"segment in barSegments\"\n\t\t\t\t\t:key=\"segment.key\"\n\t\t\t\t\tclass=\"cn-stacked-bar__segment\"\n\t\t\t\t\t:style=\"{ flexGrow: segment.count, backgroundColor: segment.color }\" />\n\t\t\t</div>\n\t\t\t<ul class=\"cn-stacked-bar__legend\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"segment in segments\"\n\t\t\t\t\t:key=\"segment.key\"\n\t\t\t\t\tclass=\"cn-stacked-bar__legend-item\"\n\t\t\t\t\tdata-testid=\"cn-stacked-bar-legend-item\">\n\t\t\t\t\t<span class=\"cn-stacked-bar__label\">\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclass=\"cn-stacked-bar__dot\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t:style=\"{ backgroundColor: segment.color }\" />\n\t\t\t\t\t\t{{ segment.label }}\n\t\t\t\t\t</span>\n\t\t\t\t\t<!-- The leading space keeps label and count two words for a\n\t\t\t\t\t screen reader; it is not drawn in this flex column. -->\n\t\t\t\t\t<strong class=\"cn-stacked-bar__count\">{{ ' ' + segment.count }}</strong>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</template>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcLoadingIcon } from '@nextcloud/vue'\nimport { fetchGroupedCounts } from '../../utils/fetchAggregate.js'\n\n/** The lightest step keeps this share of the primary colour, so it still stands out from the page. */\nconst LIGHTEST_PRIMARY_SHARE = 70\n\n/**\n * The colour of step `index` out of `count`, on one ramp that runs from a\n * light tint of the primary colour, through the primary colour, to the text\n * colour. Steps differ in LIGHTNESS, so they stay apart for somebody who\n * cannot tell hues apart, and the ramp follows the theme because it is built\n * from Nextcloud's own variables.\n *\n * @param {number} index The step, 0-based.\n * @param {number} count The number of steps.\n * @return {string} A CSS colour.\n * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n */\nexport function rampColor(index, count) {\n\tif (count <= 1) {\n\t\treturn 'var(--color-primary-element)'\n\t}\n\tconst position = index / (count - 1)\n\tif (position < 0.5) {\n\t\tconst share = Math.round(LIGHTEST_PRIMARY_SHARE + (position / 0.5) * (100 - LIGHTEST_PRIMARY_SHARE))\n\t\treturn `color-mix(in srgb, var(--color-primary-element) ${share}%, var(--color-main-background))`\n\t}\n\tconst textShare = Math.round(((position - 0.5) / 0.5) * 100)\n\tif (textShare === 0) {\n\t\treturn 'var(--color-primary-element)'\n\t}\n\tif (textShare === 100) {\n\t\treturn 'var(--color-main-text)'\n\t}\n\treturn `color-mix(in srgb, var(--color-main-text) ${textShare}%, var(--color-primary-element))`\n}\n\n/**\n * CnStackedBarWidget shows how a total divides over a few groups: ONE bar cut\n * into segments, with a legend below it that names every segment and gives\n * its count. Use it for \"my cases per step\" or \"requests per channel\".\n *\n * Segments come from one grouped count request against an OpenRegister\n * source (`source.groupBy`), or from static `segments`. `order` fixes the\n * order of the segments, and `labels` gives a group key a readable name.\n * Colours come from one ramp built on the theme's primary colour; the steps\n * differ in lightness, never in hue alone. Resolved by its registry type key\n * `stacked-bar`.\n *\n * ```json\n * {\n * \"widgetKey\": \"stacked-bar\",\n * \"props\": {\n * \"content\": {\n * \"source\": { \"register\": \"dossiq\", \"schema\": \"case\", \"groupBy\": \"status\", \"filter\": { \"assignee\": \"@me\" } },\n * \"order\": [\"received\", \"in_progress\", \"decision\", \"publish\"],\n * \"labels\": { \"received\": \"Received\", \"in_progress\": \"In progress\", \"decision\": \"Decision\", \"publish\": \"Publish\" }\n * }\n * }\n * }\n * ```\n */\nexport default {\n\tname: 'CnStackedBarWidget',\n\n\tcomponents: { NcLoadingIcon },\n\n\tinject: {\n\t\t/**\n\t\t * Host translate function provided by CnAppRoot. Segment labels and\n\t\t * the empty text run through it. Identity by default.\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The widget's configuration. `source` names the OpenRegister\n\t\t * register and schema, the `groupBy` field and an optional `filter`\n\t\t * (the shared @-token grammar). `segments` are static entries\n\t\t * `{ key?, label, value }` used when there is no source. `order` lists\n\t\t * group keys in the order they render; groups it does not list follow\n\t\t * in the order they arrive, and a listed key without records renders\n\t\t * with a count of 0. `labels` maps a group key to its label.\n\t\t * `emptyText` is shown when there is nothing to count.\n\t\t *\n\t\t * @type {{source?: {register?: string, schema?: string, groupBy?: string, filter?: object}, segments?: Array<{key?: string, label: string, value: number}>, order?: Array<string>, labels?: {[key: string]: string}, emptyText?: string}}\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 * Translate function. Falls back to the injected `cnTranslate`. Pass it\n\t\t * when mounting the widget outside a CnAppRoot.\n\t\t *\n\t\t * @type {((key: string) => string)|null}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tgroups: [],\n\t\t\tloading: false,\n\t\t\terror: '',\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The translate function in use.\n\t\t *\n\t\t * @return {(key: string) => string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\teffectiveTranslate() {\n\t\t\treturn this.translate ?? this.cnTranslate\n\t\t},\n\n\t\t/**\n\t\t * Whether the segments come from OpenRegister.\n\t\t *\n\t\t * @return {boolean}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\thasSource() {\n\t\t\tconst s = this.content.source || {}\n\t\t\treturn Boolean(s.register && s.schema && s.groupBy)\n\t\t},\n\n\t\t/**\n\t\t * The raw groups, from the source or the static list, as `{ key, label, count }`.\n\t\t *\n\t\t * @return {Array<{key: string, label: string, count: number}>}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\trawGroups() {\n\t\t\tif (this.hasSource) {\n\t\t\t\treturn this.groups.map((group) => ({ key: group.key, label: group.key, count: group.count }))\n\t\t\t}\n\t\t\tconst list = Array.isArray(this.content.segments) ? this.content.segments : []\n\t\t\treturn list\n\t\t\t\t.filter((segment) => segment && typeof segment === 'object')\n\t\t\t\t.map((segment, index) => {\n\t\t\t\t\tconst count = Number(segment.value)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tkey: String(segment.key ?? segment.label ?? index),\n\t\t\t\t\t\tlabel: String(segment.label ?? segment.key ?? ''),\n\t\t\t\t\t\tcount: Number.isFinite(count) && count > 0 ? count : 0,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The segments in render order, each with its label and colour.\n\t\t *\n\t\t * @return {Array<{key: string, label: string, count: number, color: string}>}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tsegments() {\n\t\t\tconst order = Array.isArray(this.content.order) ? this.content.order.map(String) : []\n\t\t\tconst labels = (this.content.labels && typeof this.content.labels === 'object') ? this.content.labels : {}\n\t\t\tconst byKey = {}\n\t\t\tfor (const group of this.rawGroups) {\n\t\t\t\tbyKey[group.key] = group\n\t\t\t}\n\t\t\tconst ordered = []\n\t\t\tfor (const key of order) {\n\t\t\t\tordered.push(byKey[key] || { key, label: key, count: 0 })\n\t\t\t}\n\t\t\tfor (const group of this.rawGroups) {\n\t\t\t\tif (!order.includes(group.key)) {\n\t\t\t\t\tordered.push(group)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ordered.map((group, index) => ({\n\t\t\t\tkey: group.key,\n\t\t\t\tlabel: this.effectiveTranslate(typeof labels[group.key] === 'string' ? labels[group.key] : group.label),\n\t\t\t\tcount: group.count,\n\t\t\t\tcolor: rampColor(index, ordered.length),\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * The segments that take up room in the bar.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tbarSegments() {\n\t\t\treturn this.segments.filter((segment) => segment.count > 0)\n\t\t},\n\n\t\t/**\n\t\t * The sum of all counts.\n\t\t *\n\t\t * @return {number}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\ttotal() {\n\t\t\treturn this.segments.reduce((sum, segment) => sum + segment.count, 0)\n\t\t},\n\n\t\t/**\n\t\t * The text shown when there is nothing to count.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\temptyLabel() {\n\t\t\tconst text = this.content.emptyText\n\t\t\treturn (typeof text === 'string' && text !== '')\n\t\t\t\t? this.effectiveTranslate(text)\n\t\t\t\t: t('nextcloud-vue', 'Nothing to show yet')\n\t\t},\n\n\t\t/**\n\t\t * @return {string} The loading text.\n\t\t *\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tloadingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Loading…')\n\t\t},\n\n\t\t/**\n\t\t * @return {string} The text shown when the counts could not be loaded.\n\t\t *\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\terrorLabel() {\n\t\t\treturn t('nextcloud-vue', 'The numbers could not be loaded.')\n\t\t},\n\n\t\t/**\n\t\t * Changes whenever a new fetch is needed.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tsourceKey() {\n\t\t\treturn JSON.stringify(this.content.source || {})\n\t\t},\n\t},\n\n\twatch: {\n\t\t/** @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget */\n\t\tsourceKey() {\n\t\t\tthis.fetchGroups()\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.fetchGroups()\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Load the count per group in one request.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tasync fetchGroups() {\n\t\t\tif (!this.hasSource) {\n\t\t\t\tthis.groups = []\n\t\t\t\tthis.error = ''\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst requestKey = this.sourceKey\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\ttry {\n\t\t\t\tconst groups = await fetchGroupedCounts(this.content.source)\n\t\t\t\tif (requestKey !== this.sourceKey) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.groups = groups\n\t\t\t} catch (e) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn('[CnStackedBarWidget] failed to load counts:', e)\n\t\t\t\tthis.error = (e && e.message) || 'error'\n\t\t\t\tthis.groups = []\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-stacked-bar {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n\twidth: 100%;\n}\n\n.cn-stacked-bar__state {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-stacked-bar__bar {\n\tdisplay: flex;\n\tgap: 3px;\n\theight: 12px;\n}\n\n.cn-stacked-bar__segment {\n\tflex-basis: 0;\n\tmin-width: 4px;\n\tborder-radius: 6px;\n}\n\n.cn-stacked-bar__legend {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n\tgap: 12px;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-stacked-bar__legend-item {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tmin-width: 0;\n}\n\n.cn-stacked-bar__label {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tfont-size: 0.95em;\n\tcolor: var(--color-text-maxcontrast);\n\toverflow-wrap: anywhere;\n}\n\n.cn-stacked-bar__dot {\n\tflex: none;\n\twidth: 10px;\n\theight: 10px;\n\tborder-radius: 3px;\n}\n\n.cn-stacked-bar__count {\n\tfont-size: 1.5em;\n\tfont-weight: 700;\n\tline-height: 1.2;\n\tcolor: var(--color-main-text);\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_createVNode","_createElementVNode","_toDisplayString","_Fragment","_renderList","_normalizeStyle"],"mappings":";;;AASM,EAAA,KAAC,EAAA,gBAAA;AAAA,EAAA,aAAA,EAAA,gBAAA;;;;AACgB,EAAA,KAAI,EAAC,uBAAuB;AAAA,EAAA,IAAK,EAAC,QAAQ;;;;AAI/C,EAAA,KAAA,EAAA,uBAAA;AAAA,EAAA,IAAA,EAAA,QAAA;;;;AAGW,EAAA,KAAK,EAAE,uBAAsB;AAAC,EAAA,aAAS,EAAA,sBAAA;;;AAO5D,EAAA,KAAK,EAAC,qBAAqB;AAAA,EAAA,aAAA,EAAA,MAAA;;AAO5B,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,wBAAwB,GAAA;AAM1B,MAAA,UAAA,GAAA,EAAA,KAAI,EAAE,uBAAuB,GAAA;AASlC,MAAA,UAAA,GAAA,EAAA,KAAA,EAAA,uBAAA,GAAA;;;;;;KApCO,KAAO,CAAA,OAAA;AAAlB,SAAAA,SAAA,EAAA,EAAAC,kBAAA,CAGM,OAHN,UAGM,EAAA;UAFLC,WAAe,CAAA,wBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AACf,UAAAC,kBAAA,CAAE,8BAAA,QAAA,CAAA,YAAA,CAAA,EAAA,CAAA,YAAA;;SAEU,KAAG,CAAA,KAAA;0CAEZ,CAAA,GAAA,YAAA,EAAAC,eAAA,CADD,QAAA,CAAA,UAAA,CAAA,EAAA,CAAA,YAAA;WAEW,QAAK,CAAA,KAAA,KAAA,CAAA;8EACb,QAAQ,CAAA,UAAA,CAAA,EAAA,CAAA,YAAA;;AAMX,cAAAD,kBAAA,CAMI,OANJ,UAMI,EAAA;kCALJF,kBAI0B,CAAAI,QAAA,EAAA,IAAA,EAAAC,UAAA,CAHvB,QAAA,CAAA,WAAA,EAAA,CAAA,OAAA,KAAA;uCADHL,kBAI0B,CAAA,MAAA,EAAA;oBAF1B,GAAI,EAAE,OAAO,CAAC,GAAG;AACjB,oBAAA,KAAC,EAAA,yBAAA;AACA,oBAAA,KAAK,6BAAc,OAAM,CAAA,KAAA,EAAA,eAAA,EAAA,OAAA,CAAA,KAAA,EAAA,CAAA;;;;AAE1B,cAAAE,kBAAA,OAAA;kCACAF,8CACkB,QAAQ,CAAA,QAAA,EAAA,CAAnB,OAAO,KAAA;uCADdA;oBAEC,GAAG,EAAC,OAAA,CAAA,GAAA;yBACA,EAAC,6BAAsB;AAC1B,oBAAA,aAAS,EAAC,4BAAO;;AACjB,oBAAAE,kBAAA,CAMC,QAND,UAMC,EAAA;sBALFA,kBAGgD,CAAA,MAAA,EAAA;AAF/C,wBAAA,KAAI,EAAA,qBAAA;AACJ,wBAAA,aAAW,EAAC,MAAM;wBACf,KAAG,EAAAI,cAAA,CAAA,EAAA,eAAA,SAA4B,CAAC,KAAK,EAAA,CAAA;;sCAAO,GAChD,GAAAH,eAAA,CAAG,OAAO,CAAC,KAAK,CAAA,EAAA,CAAA,YAAA;;AAIjB,oBAAAD,kBAAA,CAAC,QAAD,EAAA,UAAC,EAAAC,eAAA,CAAA,GAAA,GAAA,OAAA,CAAA,KAAA,CAAA,EAAA,CAAA,YAAA;;;;;;;;;;"}
@@ -0,0 +1,10 @@
1
+ import script from './CnStackedBarWidgetForm.vue2.js';
2
+ import { render } from './CnStackedBarWidgetForm.vue3.js';
3
+
4
+ script.render = render;
5
+ script.__scopeId = "data-v-56e6c6a2";
6
+ script.__file = "src/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue";
7
+ const __sfc_main = script;
8
+
9
+ export { __sfc_main as default };
10
+ //# sourceMappingURL=CnStackedBarWidgetForm.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnStackedBarWidgetForm.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
@@ -0,0 +1,169 @@
1
+ import { translate } from '@nextcloud/l10n';
2
+ import { NcTextField } from '@nextcloud/vue';
3
+ import __sfc_main from '../CnFieldPicker/CnFieldPicker.vue.js';
4
+ import __sfc_main$1 from '../CnFilterRowsEditor/CnFilterRowsEditor.vue.js';
5
+ import __sfc_main$2 from '../CnRegisterSchemaSelect/CnRegisterSchemaSelect.vue.js';
6
+ import { fetchSchemaProperties } from '../../utils/fetchSchemaProperties.js';
7
+ import { filterToRows, rowsToFilter } from '../CnFilterRowsEditor/filterRows.js';
8
+
9
+ /**
10
+ * CnStackedBarWidgetForm is the settings form of a `stacked-bar` widget. It
11
+ * edits the source (register, schema, filter), the field the records are
12
+ * grouped by, the order of the segments and the empty text. Static `segments`
13
+ * and the `labels` map are written in the manifest and pass through
14
+ * untouched. Emits `update:content` on every change; `validate()` asks for a
15
+ * register, a schema and a group field unless the widget has static segments.
16
+ */
17
+ var script = {
18
+ name: 'CnStackedBarWidgetForm',
19
+
20
+ components: { NcTextField, CnFieldPicker: __sfc_main, CnFilterRowsEditor: __sfc_main$1, CnRegisterSchemaSelect: __sfc_main$2 },
21
+
22
+ props: {
23
+ /**
24
+ * The placement being edited (pre-fills from `editingWidget.content`), or null.
25
+ *
26
+ * @type {{content: object}|null}
27
+ */
28
+ editingWidget: { type: Object, default: null },
29
+ /**
30
+ * Initial content values when not editing (registry defaults).
31
+ *
32
+ * @type {object}
33
+ */
34
+ value: { type: Object, default: () => ({}) },
35
+ },
36
+
37
+ emits: [
38
+ /**
39
+ * Emitted with the assembled content blob on every field change.
40
+ *
41
+ * @event update:content
42
+ * @type {object}
43
+ */
44
+ 'update:content',
45
+ ],
46
+
47
+ data() {
48
+ const initial = this.editingWidget?.content || this.value || {};
49
+ const src = initial.source || {};
50
+ return {
51
+ initial,
52
+ source: { register: src.register ?? '', schema: src.schema ?? '' },
53
+ groupBy: src.groupBy ?? '',
54
+ filterRows: filterToRows(src.filter || {}),
55
+ orderText: Array.isArray(initial.order) ? initial.order.join(', ') : '',
56
+ emptyText: initial.emptyText ?? '',
57
+ availableFields: [],
58
+ }
59
+ },
60
+
61
+ computed: {
62
+ /**
63
+ * The assembled content blob. Keys the form does not edit (static
64
+ * segments, labels) are carried over from the initial content.
65
+ *
66
+ * @return {object}
67
+ * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget
68
+ */
69
+ assembledContent() {
70
+ return {
71
+ ...this.initial,
72
+ source: {
73
+ register: this.source.register,
74
+ schema: this.source.schema,
75
+ groupBy: this.groupBy,
76
+ filter: rowsToFilter(this.filterRows),
77
+ },
78
+
79
+ order: this.orderText.split(',').map((key) => key.trim()).filter((key) => key !== ''),
80
+ emptyText: this.emptyText,
81
+ }
82
+ },
83
+ },
84
+
85
+ watch: {
86
+ 'source.register': 'loadFields',
87
+ 'source.schema': 'loadFields',
88
+ },
89
+
90
+ mounted() {
91
+ this.loadFields();
92
+ },
93
+
94
+ methods: {
95
+ t: translate,
96
+
97
+ /**
98
+ * Load the schema's field names for the picker.
99
+ *
100
+ * @return {Promise<void>}
101
+ * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget
102
+ */
103
+ async loadFields() {
104
+ this.availableFields = await fetchSchemaProperties(this.source.register, this.source.schema);
105
+ },
106
+
107
+ /**
108
+ * Set one field and emit the assembled content.
109
+ *
110
+ * @param {string} field The data key to write.
111
+ * @param {string} value The new value.
112
+ * @return {void}
113
+ * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget
114
+ */
115
+ updateField(field, value) {
116
+ this[field] = value;
117
+ this.$emit('update:content', this.assembledContent);
118
+ },
119
+
120
+ /**
121
+ * Set the register or the schema and emit.
122
+ *
123
+ * @param {'register'|'schema'} field The source key to write.
124
+ * @param {string} value The chosen slug.
125
+ * @return {void}
126
+ * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget
127
+ */
128
+ updateSource(field, value) {
129
+ this.source[field] = value;
130
+ this.$emit('update:content', this.assembledContent);
131
+ },
132
+
133
+ /**
134
+ * Take the filter editor's rows and emit.
135
+ *
136
+ * @param {Array<{key: string, op: string, value: string}>} rows The rows.
137
+ * @return {void}
138
+ * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget
139
+ */
140
+ onFilterRows(rows) {
141
+ this.filterRows = rows;
142
+ this.$emit('update:content', this.assembledContent);
143
+ },
144
+
145
+ /**
146
+ * Validate the form; an empty array means valid.
147
+ *
148
+ * @return {string[]} The validation errors.
149
+ * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget
150
+ */
151
+ validate() {
152
+ const hasStatic = Array.isArray(this.initial.segments) && this.initial.segments.length > 0;
153
+ if (hasStatic && !this.source.register && !this.source.schema) {
154
+ return []
155
+ }
156
+ const errors = [];
157
+ if (!this.source.register || !this.source.schema) {
158
+ errors.push(translate('nextcloud-vue', 'A register and schema are required'));
159
+ }
160
+ if (!this.groupBy) {
161
+ errors.push(translate('nextcloud-vue', 'A field to group by is required'));
162
+ }
163
+ return errors
164
+ },
165
+ },
166
+ };
167
+
168
+ export { script as default };
169
+ //# sourceMappingURL=CnStackedBarWidgetForm.vue2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnStackedBarWidgetForm.vue2.js","sources":["../../../../src/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div class=\"cn-stacked-bar-form\">\n\t\t<div class=\"cn-stacked-bar-form__row2\">\n\t\t\t<CnRegisterSchemaSelect\n\t\t\t\t:register=\"source.register\"\n\t\t\t\t:schema=\"source.schema\"\n\t\t\t\t@update:register=\"updateSource('register', $event)\"\n\t\t\t\t@update:schema=\"updateSource('schema', $event)\" />\n\t\t</div>\n\n\t\t<CnFieldPicker\n\t\t\t:value=\"groupBy\"\n\t\t\t:label=\"t('nextcloud-vue', 'Field to group by')\"\n\t\t\t:options=\"availableFields\"\n\t\t\tplaceholder=\"status\"\n\t\t\t@update=\"updateField('groupBy', $event)\" />\n\n\t\t<CnFilterRowsEditor :value=\"filterRows\" :fields=\"availableFields\" @input=\"onFilterRows\" />\n\n\t\t<NcTextField\n\t\t\t:modelValue=\"orderText\"\n\t\t\t:label=\"t('nextcloud-vue', 'Order of the segments (values, comma separated)')\"\n\t\t\tplaceholder=\"received, in_progress, decision\"\n\t\t\t@update:modelValue=\"updateField('orderText', $event)\" />\n\n\t\t<NcTextField\n\t\t\t:modelValue=\"emptyText\"\n\t\t\t:label=\"t('nextcloud-vue', 'Text when there is nothing to count')\"\n\t\t\t@update:modelValue=\"updateField('emptyText', $event)\" />\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcTextField } from '@nextcloud/vue'\nimport CnFieldPicker from '../CnFieldPicker/CnFieldPicker.vue'\nimport CnFilterRowsEditor from '../CnFilterRowsEditor/CnFilterRowsEditor.vue'\nimport CnRegisterSchemaSelect from '../CnRegisterSchemaSelect/CnRegisterSchemaSelect.vue'\nimport { fetchSchemaProperties } from '../../utils/fetchSchemaProperties.js'\nimport { filterToRows, rowsToFilter } from '../CnFilterRowsEditor/filterRows.js'\n\n/**\n * CnStackedBarWidgetForm is the settings form of a `stacked-bar` widget. It\n * edits the source (register, schema, filter), the field the records are\n * grouped by, the order of the segments and the empty text. Static `segments`\n * and the `labels` map are written in the manifest and pass through\n * untouched. Emits `update:content` on every change; `validate()` asks for a\n * register, a schema and a group field unless the widget has static segments.\n */\nexport default {\n\tname: 'CnStackedBarWidgetForm',\n\n\tcomponents: { NcTextField, CnFieldPicker, CnFilterRowsEditor, CnRegisterSchemaSelect },\n\n\tprops: {\n\t\t/**\n\t\t * The placement being edited (pre-fills from `editingWidget.content`), or null.\n\t\t *\n\t\t * @type {{content: object}|null}\n\t\t */\n\t\teditingWidget: { type: Object, default: null },\n\t\t/**\n\t\t * Initial content values when not editing (registry defaults).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tvalue: { type: Object, default: () => ({}) },\n\t},\n\n\temits: [\n\t\t/**\n\t\t * Emitted with the assembled content blob on every field change.\n\t\t *\n\t\t * @event update:content\n\t\t * @type {object}\n\t\t */\n\t\t'update:content',\n\t],\n\n\tdata() {\n\t\tconst initial = this.editingWidget?.content || this.value || {}\n\t\tconst src = initial.source || {}\n\t\treturn {\n\t\t\tinitial,\n\t\t\tsource: { register: src.register ?? '', schema: src.schema ?? '' },\n\t\t\tgroupBy: src.groupBy ?? '',\n\t\t\tfilterRows: filterToRows(src.filter || {}),\n\t\t\torderText: Array.isArray(initial.order) ? initial.order.join(', ') : '',\n\t\t\temptyText: initial.emptyText ?? '',\n\t\t\tavailableFields: [],\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The assembled content blob. Keys the form does not edit (static\n\t\t * segments, labels) are carried over from the initial content.\n\t\t *\n\t\t * @return {object}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tassembledContent() {\n\t\t\treturn {\n\t\t\t\t...this.initial,\n\t\t\t\tsource: {\n\t\t\t\t\tregister: this.source.register,\n\t\t\t\t\tschema: this.source.schema,\n\t\t\t\t\tgroupBy: this.groupBy,\n\t\t\t\t\tfilter: rowsToFilter(this.filterRows),\n\t\t\t\t},\n\n\t\t\t\torder: this.orderText.split(',').map((key) => key.trim()).filter((key) => key !== ''),\n\t\t\t\temptyText: this.emptyText,\n\t\t\t}\n\t\t},\n\t},\n\n\twatch: {\n\t\t'source.register': 'loadFields',\n\t\t'source.schema': 'loadFields',\n\t},\n\n\tmounted() {\n\t\tthis.loadFields()\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * Load the schema's field names for the picker.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tasync loadFields() {\n\t\t\tthis.availableFields = await fetchSchemaProperties(this.source.register, this.source.schema)\n\t\t},\n\n\t\t/**\n\t\t * Set one field and emit the assembled content.\n\t\t *\n\t\t * @param {string} field The data key to write.\n\t\t * @param {string} value The new value.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tupdateField(field, value) {\n\t\t\tthis[field] = value\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Set the register or the schema and emit.\n\t\t *\n\t\t * @param {'register'|'schema'} field The source key to write.\n\t\t * @param {string} value The chosen slug.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tupdateSource(field, value) {\n\t\t\tthis.source[field] = value\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Take the filter editor's rows and emit.\n\t\t *\n\t\t * @param {Array<{key: string, op: string, value: string}>} rows The rows.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tonFilterRows(rows) {\n\t\t\tthis.filterRows = rows\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Validate the form; an empty array means valid.\n\t\t *\n\t\t * @return {string[]} The validation errors.\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tvalidate() {\n\t\t\tconst hasStatic = Array.isArray(this.initial.segments) && this.initial.segments.length > 0\n\t\t\tif (hasStatic && !this.source.register && !this.source.schema) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst errors = []\n\t\t\tif (!this.source.register || !this.source.schema) {\n\t\t\t\terrors.push(t('nextcloud-vue', 'A register and schema are required'))\n\t\t\t}\n\t\t\tif (!this.groupBy) {\n\t\t\t\terrors.push(t('nextcloud-vue', 'A field to group by is required'))\n\t\t\t}\n\t\t\treturn errors\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-stacked-bar-form {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n.cn-stacked-bar-form__row2 {\n\tdisplay: flex;\n\tgap: 12px;\n\talign-items: flex-end;\n}\n\n.cn-stacked-bar-form__row2 > * {\n\tflex: 1;\n\tmin-width: 0;\n}\n</style>\n"],"names":["CnFieldPicker","CnFilterRowsEditor","CnRegisterSchemaSelect","t"],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { resolveComponent, openBlock, createElementBlock, createElementVNode, createVNode } from 'vue';
2
+
3
+ const _hoisted_1 = { class: "cn-stacked-bar-form" };
4
+ const _hoisted_2 = { class: "cn-stacked-bar-form__row2" };
5
+
6
+ function render(_ctx, _cache, $props, $setup, $data, $options) {
7
+ const _component_CnRegisterSchemaSelect = resolveComponent("CnRegisterSchemaSelect");
8
+ const _component_CnFieldPicker = resolveComponent("CnFieldPicker");
9
+ const _component_CnFilterRowsEditor = resolveComponent("CnFilterRowsEditor");
10
+ const _component_NcTextField = resolveComponent("NcTextField");
11
+
12
+ return (openBlock(), createElementBlock("div", _hoisted_1, [
13
+ createElementVNode("div", _hoisted_2, [
14
+ createVNode(_component_CnRegisterSchemaSelect, {
15
+ register: $data.source.register,
16
+ schema: $data.source.schema,
17
+ "onUpdate:register": _cache[0] || (_cache[0] = $event => ($options.updateSource('register', $event))),
18
+ "onUpdate:schema": _cache[1] || (_cache[1] = $event => ($options.updateSource('schema', $event)))
19
+ }, null, 8 /* PROPS */, ["register", "schema"])
20
+ ]),
21
+ createVNode(_component_CnFieldPicker, {
22
+ value: $data.groupBy,
23
+ label: $options.t('nextcloud-vue', 'Field to group by'),
24
+ options: $data.availableFields,
25
+ placeholder: "status",
26
+ onUpdate: _cache[2] || (_cache[2] = $event => ($options.updateField('groupBy', $event)))
27
+ }, null, 8 /* PROPS */, ["value", "label", "options"]),
28
+ createVNode(_component_CnFilterRowsEditor, {
29
+ value: $data.filterRows,
30
+ fields: $data.availableFields,
31
+ onInput: $options.onFilterRows
32
+ }, null, 8 /* PROPS */, ["value", "fields", "onInput"]),
33
+ createVNode(_component_NcTextField, {
34
+ modelValue: $data.orderText,
35
+ label: $options.t('nextcloud-vue', 'Order of the segments (values, comma separated)'),
36
+ placeholder: "received, in_progress, decision",
37
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = $event => ($options.updateField('orderText', $event)))
38
+ }, null, 8 /* PROPS */, ["modelValue", "label"]),
39
+ createVNode(_component_NcTextField, {
40
+ modelValue: $data.emptyText,
41
+ label: $options.t('nextcloud-vue', 'Text when there is nothing to count'),
42
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = $event => ($options.updateField('emptyText', $event)))
43
+ }, null, 8 /* PROPS */, ["modelValue", "label"])
44
+ ]))
45
+ }
46
+
47
+ export { render };
48
+ //# sourceMappingURL=CnStackedBarWidgetForm.vue3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnStackedBarWidgetForm.vue3.js","sources":["../../../../src/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue?vue&type=template&id=56e6c6a2&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div class=\"cn-stacked-bar-form\">\n\t\t<div class=\"cn-stacked-bar-form__row2\">\n\t\t\t<CnRegisterSchemaSelect\n\t\t\t\t:register=\"source.register\"\n\t\t\t\t:schema=\"source.schema\"\n\t\t\t\t@update:register=\"updateSource('register', $event)\"\n\t\t\t\t@update:schema=\"updateSource('schema', $event)\" />\n\t\t</div>\n\n\t\t<CnFieldPicker\n\t\t\t:value=\"groupBy\"\n\t\t\t:label=\"t('nextcloud-vue', 'Field to group by')\"\n\t\t\t:options=\"availableFields\"\n\t\t\tplaceholder=\"status\"\n\t\t\t@update=\"updateField('groupBy', $event)\" />\n\n\t\t<CnFilterRowsEditor :value=\"filterRows\" :fields=\"availableFields\" @input=\"onFilterRows\" />\n\n\t\t<NcTextField\n\t\t\t:modelValue=\"orderText\"\n\t\t\t:label=\"t('nextcloud-vue', 'Order of the segments (values, comma separated)')\"\n\t\t\tplaceholder=\"received, in_progress, decision\"\n\t\t\t@update:modelValue=\"updateField('orderText', $event)\" />\n\n\t\t<NcTextField\n\t\t\t:modelValue=\"emptyText\"\n\t\t\t:label=\"t('nextcloud-vue', 'Text when there is nothing to count')\"\n\t\t\t@update:modelValue=\"updateField('emptyText', $event)\" />\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcTextField } from '@nextcloud/vue'\nimport CnFieldPicker from '../CnFieldPicker/CnFieldPicker.vue'\nimport CnFilterRowsEditor from '../CnFilterRowsEditor/CnFilterRowsEditor.vue'\nimport CnRegisterSchemaSelect from '../CnRegisterSchemaSelect/CnRegisterSchemaSelect.vue'\nimport { fetchSchemaProperties } from '../../utils/fetchSchemaProperties.js'\nimport { filterToRows, rowsToFilter } from '../CnFilterRowsEditor/filterRows.js'\n\n/**\n * CnStackedBarWidgetForm is the settings form of a `stacked-bar` widget. It\n * edits the source (register, schema, filter), the field the records are\n * grouped by, the order of the segments and the empty text. Static `segments`\n * and the `labels` map are written in the manifest and pass through\n * untouched. Emits `update:content` on every change; `validate()` asks for a\n * register, a schema and a group field unless the widget has static segments.\n */\nexport default {\n\tname: 'CnStackedBarWidgetForm',\n\n\tcomponents: { NcTextField, CnFieldPicker, CnFilterRowsEditor, CnRegisterSchemaSelect },\n\n\tprops: {\n\t\t/**\n\t\t * The placement being edited (pre-fills from `editingWidget.content`), or null.\n\t\t *\n\t\t * @type {{content: object}|null}\n\t\t */\n\t\teditingWidget: { type: Object, default: null },\n\t\t/**\n\t\t * Initial content values when not editing (registry defaults).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tvalue: { type: Object, default: () => ({}) },\n\t},\n\n\temits: [\n\t\t/**\n\t\t * Emitted with the assembled content blob on every field change.\n\t\t *\n\t\t * @event update:content\n\t\t * @type {object}\n\t\t */\n\t\t'update:content',\n\t],\n\n\tdata() {\n\t\tconst initial = this.editingWidget?.content || this.value || {}\n\t\tconst src = initial.source || {}\n\t\treturn {\n\t\t\tinitial,\n\t\t\tsource: { register: src.register ?? '', schema: src.schema ?? '' },\n\t\t\tgroupBy: src.groupBy ?? '',\n\t\t\tfilterRows: filterToRows(src.filter || {}),\n\t\t\torderText: Array.isArray(initial.order) ? initial.order.join(', ') : '',\n\t\t\temptyText: initial.emptyText ?? '',\n\t\t\tavailableFields: [],\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The assembled content blob. Keys the form does not edit (static\n\t\t * segments, labels) are carried over from the initial content.\n\t\t *\n\t\t * @return {object}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tassembledContent() {\n\t\t\treturn {\n\t\t\t\t...this.initial,\n\t\t\t\tsource: {\n\t\t\t\t\tregister: this.source.register,\n\t\t\t\t\tschema: this.source.schema,\n\t\t\t\t\tgroupBy: this.groupBy,\n\t\t\t\t\tfilter: rowsToFilter(this.filterRows),\n\t\t\t\t},\n\n\t\t\t\torder: this.orderText.split(',').map((key) => key.trim()).filter((key) => key !== ''),\n\t\t\t\temptyText: this.emptyText,\n\t\t\t}\n\t\t},\n\t},\n\n\twatch: {\n\t\t'source.register': 'loadFields',\n\t\t'source.schema': 'loadFields',\n\t},\n\n\tmounted() {\n\t\tthis.loadFields()\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * Load the schema's field names for the picker.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tasync loadFields() {\n\t\t\tthis.availableFields = await fetchSchemaProperties(this.source.register, this.source.schema)\n\t\t},\n\n\t\t/**\n\t\t * Set one field and emit the assembled content.\n\t\t *\n\t\t * @param {string} field The data key to write.\n\t\t * @param {string} value The new value.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tupdateField(field, value) {\n\t\t\tthis[field] = value\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Set the register or the schema and emit.\n\t\t *\n\t\t * @param {'register'|'schema'} field The source key to write.\n\t\t * @param {string} value The chosen slug.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tupdateSource(field, value) {\n\t\t\tthis.source[field] = value\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Take the filter editor's rows and emit.\n\t\t *\n\t\t * @param {Array<{key: string, op: string, value: string}>} rows The rows.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tonFilterRows(rows) {\n\t\t\tthis.filterRows = rows\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Validate the form; an empty array means valid.\n\t\t *\n\t\t * @return {string[]} The validation errors.\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget\n\t\t */\n\t\tvalidate() {\n\t\t\tconst hasStatic = Array.isArray(this.initial.segments) && this.initial.segments.length > 0\n\t\t\tif (hasStatic && !this.source.register && !this.source.schema) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst errors = []\n\t\t\tif (!this.source.register || !this.source.schema) {\n\t\t\t\terrors.push(t('nextcloud-vue', 'A register and schema are required'))\n\t\t\t}\n\t\t\tif (!this.groupBy) {\n\t\t\t\terrors.push(t('nextcloud-vue', 'A field to group by is required'))\n\t\t\t}\n\t\t\treturn errors\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-stacked-bar-form {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n.cn-stacked-bar-form__row2 {\n\tdisplay: flex;\n\tgap: 12px;\n\talign-items: flex-end;\n}\n\n.cn-stacked-bar-form__row2 > * {\n\tflex: 1;\n\tmin-width: 0;\n}\n</style>\n"],"names":["_createVNode"],"mappings":";;AAWM,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,qBAAqB,GAAA;AAC1B,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,2BAA2B,GAAA;;;;;;;;;uBAMhC,iBAAA,EAAA;MALLA,WAI+C,CAAA,iCAAA,EAAA;;QAF7C,MAAM,EAAE,KAAE,CAAA,MAAA,CAAA,MAAA;QACV,mBAAa,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,MAAA,KAAA,QAAA,CAAA,YAAA,CAAA,UAAA,EAAA,MAAA,CAAA,CAAA,CAAA;QACb,iBAAa,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,MAAA,KAAE,QAAY,CAAA,YAAA,CAAA,QAAA,EAAW,MAAM,CAAA,CAAA,CAAA;;;IAG9CA,WAKsB,CAAA,wBAAA,EAAA;;AAHrB,MAAA,KAAK,EAAE,QAAC,CAAA,CAAA,CAAA,eAAA,EAAA,mBAAA,CAAA;;AAET,MAAA,WAAU,EAAA,QAAA;MACT,QAAM,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,MAAA,KAAE,QAAW,CAAA,WAAA,CAAA,SAAA,EAAE,MAAA,CAAA,CAAA,CAAA;;IAEtBA,WAA4C,CAAA,6BAAA,EAAA;AAAxB,MAAA,KAAK,EAAE,KAAU,CAAA,UAAA;AAAG,MAAA,MAAI,EAAA,KAAA,CAAA,eAAA;AAAA,MAAA,OAAA,EAAA,QAAA,CAAA,YAAA;;eAMW,CAAA,sBAAA,EAAA;AAHtD,MAAA,UAAS,EAAA,KAAA,CAAA,SAAA;AACT,MAAA,KAAK,EAAE,QAAC,CAAA,CAAA,CAAA,eAAA,EAAA,iDAAA,CAAA;AACT,MAAA,WAAW,EAAC,iCAAiC;MAC5C,qBAAiB,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,MAAA,KAAE,QAAW,CAAA,WAAA,CAAA,WAAA,EAAc,MAAM,CAAA,CAAA,CAAA;;;;;;;;;;;;"}
@@ -41,6 +41,28 @@ var script = defineComponent({
41
41
  type: Boolean,
42
42
  default: false,
43
43
  },
44
+
45
+ /**
46
+ * A count shown after the title, for example the number of documents
47
+ * behind the tab. `null` (the default) shows none; `0` is shown.
48
+ *
49
+ * @type {number|string|null}
50
+ */
51
+ count: {
52
+ type: [Number, String],
53
+ default: null,
54
+ },
55
+
56
+ /**
57
+ * List this tab under the strip's "More" menu instead of in the strip.
58
+ * Picking it there selects it, and while it is the selected tab it
59
+ * shows in the strip. Give an overflow tab a `title`: the menu needs
60
+ * plain text, and a `#title` slot is markup.
61
+ */
62
+ overflow: {
63
+ type: Boolean,
64
+ default: false,
65
+ },
44
66
  },
45
67
 
46
68
  emits: [
@@ -77,6 +99,19 @@ var script = defineComponent({
77
99
  get disabled() {
78
100
  return props.disabled
79
101
  },
102
+
103
+ get count() {
104
+ return props.count
105
+ },
106
+
107
+ get overflow() {
108
+ return props.overflow
109
+ },
110
+
111
+ // Plain text for the "More" menu, where a `#title` slot cannot go.
112
+ get label() {
113
+ return props.title
114
+ },
80
115
  };
81
116
 
82
117
  onMounted(() => tabsApi?.register(entry));
@@ -1 +1 @@
1
- {"version":3,"file":"CnTab.vue2.js","sources":["../../../../src/components/CnTabs/CnTab.vue"],"sourcesContent":["<template>\n\t<div\n\t\t:id=\"panelId\"\n\t\tclass=\"cn-tab\"\n\t\trole=\"tabpanel\"\n\t\t:aria-labelledby=\"tabId\"\n\t\t:tabindex=\"visible ? 0 : -1\"\n\t\t:hidden=\"visible ? null : true\"\n\t\t:style=\"visible ? null : { display: 'none' }\">\n\t\t<!-- @slot The panel body. -->\n\t\t<slot v-if=\"rendered\" />\n\t</div>\n</template>\n\n<script>\n/**\n * CnTab — one panel inside a `CnTabs` strip.\n *\n * ```vue\n * <CnTab title=\"Documents\">…</CnTab>\n *\n * <CnTab :active=\"selected === i\" @click=\"selected = i\">\n * <template #title>\n * {{ label }} <CnIcon name=\"close\" @click.stop=\"close(i)\" />\n * </template>\n * …\n * </CnTab>\n * ```\n *\n * ## The panel stays in the DOM\n *\n * An inactive panel is hidden with `hidden` + `display: none`, not removed with\n * `v-if`. This matches bootstrap-vue's `<BTab>`, and it is load-bearing: panels\n * that fetch on `mounted()` would refire that request on every tab switch if\n * they were destroyed and recreated. Use `v-if` inside the panel yourself if\n * you specifically want teardown.\n *\n * `lazy` changes only the FIRST paint: the body waits until the tab is first\n * activated, and from then on the panel behaves exactly as above. It is for\n * strips whose panels are expensive to mount, not for saving memory.\n *\n * ## Rendered outside a CnTabs parent\n *\n * The panel shows its content rather than vanishing. That is deliberate: the\n * alternative failure — an app whose `inject()` misses because the library got\n * loaded twice — would otherwise render blank with no error at all. See\n * `tabsKey.js` for why the key is `Symbol.for`.\n */\nimport { computed, defineComponent, getCurrentInstance, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { CN_TABS_INJECTION_KEY } from './tabsKey.js'\n\nexport default defineComponent({\n\tname: 'CnTab',\n\n\tprops: {\n\t\t/** Plain-text tab title. Ignored when a `#title` slot is supplied. */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Select this tab. Honoured on mount and on every later change. */\n\t\tactive: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Render the nav button disabled and skip this tab in keyboard navigation. */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Hold the panel body back until this tab is first activated, then keep\n\t\t * it mounted for the rest of the strip's life.\n\t\t *\n\t\t * Off by default, because the eager panel is what makes a tab switch\n\t\t * instant and it is the behaviour every existing consumer already has.\n\t\t * Turn it on when the panels are expensive: six panels that each fetch\n\t\t * on `mounted()` fire six requests on page load, and five of those\n\t\t * answer questions nobody has asked yet.\n\t\t *\n\t\t * This is NOT `v-if`-per-switch. Once a panel has been shown it stays\n\t\t * in the DOM, so switching back to it never refetches. That is the\n\t\t * whole reason an inactive panel is hidden rather than destroyed.\n\t\t */\n\t\tlazy: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: [\n\t\t/** The user activated this tab. */\n\t\t'click',\n\t],\n\n\tsetup(props, { slots, emit }) {\n\t\tconst tabsApi = inject(CN_TABS_INJECTION_KEY, null)\n\t\tconst uid = getCurrentInstance().uid\n\t\tconst tabId = `cn-tab-${uid}`\n\t\tconst panelId = `cn-tabpanel-${uid}`\n\n\t\tconst entry = {\n\t\t\tuid,\n\t\t\ttabId,\n\t\t\tpanelId,\n\t\t\t// Invoked from the PARENT's render effect, so reading `props.title`\n\t\t\t// (or calling the slot) here is what keeps a computed title reactive\n\t\t\t// in the nav strip.\n\t\t\ttitleRender: () => (slots.title ? slots.title() : props.title),\n\t\t\tonActivate: () => {\n\t\t\t\tif (props.disabled) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttabsApi?.select(uid)\n\t\t\t\temit('click')\n\t\t\t},\n\n\t\t\tget active() {\n\t\t\t\treturn props.active\n\t\t\t},\n\n\t\t\tget disabled() {\n\t\t\t\treturn props.disabled\n\t\t\t},\n\t\t}\n\n\t\tonMounted(() => tabsApi?.register(entry))\n\t\tonBeforeUnmount(() => tabsApi?.unregister(uid))\n\n\t\twatch(() => props.active, (isActive) => {\n\t\t\tif (isActive && !props.disabled) {\n\t\t\t\ttabsApi?.select(uid)\n\t\t\t}\n\t\t})\n\n\t\tconst visible = computed(() => (tabsApi ? tabsApi.isActive(uid) : true))\n\n\t\t// Latches on first activation and never resets, so a lazy panel mounts\n\t\t// once and then behaves exactly like an eager one.\n\t\tconst shown = ref(false)\n\t\twatch(visible, (isVisible) => {\n\t\t\tif (isVisible) {\n\t\t\t\tshown.value = true\n\t\t\t}\n\t\t}, { immediate: true })\n\n\t\tconst rendered = computed(() => !props.lazy || shown.value)\n\n\t\treturn { visible, rendered, tabId, panelId }\n\t},\n})\n</script>\n"],"names":[],"mappings":";;;AAmDA,aAAe,eAAe,CAAC;CAC9B,IAAI,EAAE,OAAO;;AAEb,CAAA,KAAK,EAAE;;AAEN,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;;AAGD,EAAA,MAAM,EAAE;GACP,IAAI,EAAE,OAAO;GACb,OAAO,EAAE,KAAK;GACd;;AAED;AACA,EAAA,QAAQ,EAAE;GACT,IAAI,EAAE,OAAO;GACb,OAAO,EAAE,KAAK;GACd;;AAED;;AAEC;AACA;;;;;AAKA;AACA;;;;;EAKD,IAAI,EAAE;GACL,IAAI,EAAE,OAAO;GACb,OAAO,EAAE,KAAK;GACd;EACD;;AAED,CAAA,KAAK,EAAE;;AAEN,EAAA,OAAO;EACP;;CAED,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAK,EAAC,EAAE;EAC7B,MAAM,UAAU,MAAM,CAAC,qBAAqB,EAAE,IAAI,EAAA;AAClD,EAAA,MAAM,GAAI,GAAE,kBAAkB,EAAE,CAAC,IAAE;EACnC,MAAM,KAAI,GAAI,CAAC,OAAO,EAAE,GAAG,CAAC,EAAA;AAC5B,EAAA,MAAM,OAAQ,GAAE,CAAC,YAAY,EAAE,GAAG,CAAC,EAAA;;EAEnC,MAAM,KAAI,GAAI;AACb,GAAA,GAAG;GACH,KAAK;AACL,GAAA,OAAO;;;AAGP;GACA,WAAW,EAAE,OAAO,KAAK,CAAC,QAAQ,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC;AAC9D,GAAA,UAAU,EAAE,MAAM;AACjB,IAAA,IAAI,KAAK,CAAC,QAAQ,EAAE;KACnB,MAAK;AACN,KAAA;AACA,IAAA,OAAO,EAAE,MAAM,CAAC,GAAG,EAAA;IACnB,IAAI,CAAC,OAAO,EAAA;IACZ;;GAED,IAAI,MAAM,GAAG;AACZ,IAAA,OAAO,KAAK,CAAC,MAAK;IAClB;;GAED,IAAI,QAAQ,GAAG;AACd,IAAA,OAAO,KAAK,CAAC,QAAO;IACpB;AACF,IAAA;;AAEA,EAAA,SAAS,CAAC,MAAM,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAA;AACxC,EAAA,eAAe,CAAC,MAAM,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,EAAA;;AAE9C,EAAA,KAAK,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,KAAK;GACvC,IAAI,QAAS,IAAG,CAAC,KAAK,CAAC,QAAQ,EAAE;AAChC,IAAA,OAAO,EAAE,MAAM,CAAC,GAAG,EAAA;AACpB,IAAA;GACA,EAAA;;AAED,EAAA,MAAM,OAAQ,GAAE,QAAQ,CAAC,OAAO,OAAQ,GAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAE,GAAE,IAAI,CAAC,EAAA;;;AAGvE;AACA,EAAA,MAAM,KAAI,GAAI,GAAG,CAAC,KAAK,EAAA;EACvB,KAAK,CAAC,OAAO,EAAE,CAAC,SAAS,KAAK;GAC7B,IAAI,SAAS,EAAE;AACd,IAAA,KAAK,CAAC,KAAI,GAAI,KAAG;AAClB,IAAA;AACD,GAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAA;;EAEtB,MAAM,WAAW,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAG,IAAK,KAAK,CAAC,KAAK,EAAA;;AAE1D,EAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAQ,EAAA;EAC3C;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"CnTab.vue2.js","sources":["../../../../src/components/CnTabs/CnTab.vue"],"sourcesContent":["<template>\n\t<div\n\t\t:id=\"panelId\"\n\t\tclass=\"cn-tab\"\n\t\trole=\"tabpanel\"\n\t\t:aria-labelledby=\"tabId\"\n\t\t:tabindex=\"visible ? 0 : -1\"\n\t\t:hidden=\"visible ? null : true\"\n\t\t:style=\"visible ? null : { display: 'none' }\">\n\t\t<!-- @slot The panel body. -->\n\t\t<slot v-if=\"rendered\" />\n\t</div>\n</template>\n\n<script>\n/**\n * CnTab — one panel inside a `CnTabs` strip.\n *\n * ```vue\n * <CnTab title=\"Documents\">…</CnTab>\n *\n * <CnTab :active=\"selected === i\" @click=\"selected = i\">\n * <template #title>\n * {{ label }} <CnIcon name=\"close\" @click.stop=\"close(i)\" />\n * </template>\n * …\n * </CnTab>\n * ```\n *\n * ## The panel stays in the DOM\n *\n * An inactive panel is hidden with `hidden` + `display: none`, not removed with\n * `v-if`. This matches bootstrap-vue's `<BTab>`, and it is load-bearing: panels\n * that fetch on `mounted()` would refire that request on every tab switch if\n * they were destroyed and recreated. Use `v-if` inside the panel yourself if\n * you specifically want teardown.\n *\n * `lazy` changes only the FIRST paint: the body waits until the tab is first\n * activated, and from then on the panel behaves exactly as above. It is for\n * strips whose panels are expensive to mount, not for saving memory.\n *\n * ## Rendered outside a CnTabs parent\n *\n * The panel shows its content rather than vanishing. That is deliberate: the\n * alternative failure — an app whose `inject()` misses because the library got\n * loaded twice — would otherwise render blank with no error at all. See\n * `tabsKey.js` for why the key is `Symbol.for`.\n */\nimport { computed, defineComponent, getCurrentInstance, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { CN_TABS_INJECTION_KEY } from './tabsKey.js'\n\nexport default defineComponent({\n\tname: 'CnTab',\n\n\tprops: {\n\t\t/** Plain-text tab title. Ignored when a `#title` slot is supplied. */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Select this tab. Honoured on mount and on every later change. */\n\t\tactive: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Render the nav button disabled and skip this tab in keyboard navigation. */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Hold the panel body back until this tab is first activated, then keep\n\t\t * it mounted for the rest of the strip's life.\n\t\t *\n\t\t * Off by default, because the eager panel is what makes a tab switch\n\t\t * instant and it is the behaviour every existing consumer already has.\n\t\t * Turn it on when the panels are expensive: six panels that each fetch\n\t\t * on `mounted()` fire six requests on page load, and five of those\n\t\t * answer questions nobody has asked yet.\n\t\t *\n\t\t * This is NOT `v-if`-per-switch. Once a panel has been shown it stays\n\t\t * in the DOM, so switching back to it never refetches. That is the\n\t\t * whole reason an inactive panel is hidden rather than destroyed.\n\t\t */\n\t\tlazy: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * A count shown after the title, for example the number of documents\n\t\t * behind the tab. `null` (the default) shows none; `0` is shown.\n\t\t *\n\t\t * @type {number|string|null}\n\t\t */\n\t\tcount: {\n\t\t\ttype: [Number, String],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * List this tab under the strip's \"More\" menu instead of in the strip.\n\t\t * Picking it there selects it, and while it is the selected tab it\n\t\t * shows in the strip. Give an overflow tab a `title`: the menu needs\n\t\t * plain text, and a `#title` slot is markup.\n\t\t */\n\t\toverflow: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: [\n\t\t/** The user activated this tab. */\n\t\t'click',\n\t],\n\n\tsetup(props, { slots, emit }) {\n\t\tconst tabsApi = inject(CN_TABS_INJECTION_KEY, null)\n\t\tconst uid = getCurrentInstance().uid\n\t\tconst tabId = `cn-tab-${uid}`\n\t\tconst panelId = `cn-tabpanel-${uid}`\n\n\t\tconst entry = {\n\t\t\tuid,\n\t\t\ttabId,\n\t\t\tpanelId,\n\t\t\t// Invoked from the PARENT's render effect, so reading `props.title`\n\t\t\t// (or calling the slot) here is what keeps a computed title reactive\n\t\t\t// in the nav strip.\n\t\t\ttitleRender: () => (slots.title ? slots.title() : props.title),\n\t\t\tonActivate: () => {\n\t\t\t\tif (props.disabled) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttabsApi?.select(uid)\n\t\t\t\temit('click')\n\t\t\t},\n\n\t\t\tget active() {\n\t\t\t\treturn props.active\n\t\t\t},\n\n\t\t\tget disabled() {\n\t\t\t\treturn props.disabled\n\t\t\t},\n\n\t\t\tget count() {\n\t\t\t\treturn props.count\n\t\t\t},\n\n\t\t\tget overflow() {\n\t\t\t\treturn props.overflow\n\t\t\t},\n\n\t\t\t// Plain text for the \"More\" menu, where a `#title` slot cannot go.\n\t\t\tget label() {\n\t\t\t\treturn props.title\n\t\t\t},\n\t\t}\n\n\t\tonMounted(() => tabsApi?.register(entry))\n\t\tonBeforeUnmount(() => tabsApi?.unregister(uid))\n\n\t\twatch(() => props.active, (isActive) => {\n\t\t\tif (isActive && !props.disabled) {\n\t\t\t\ttabsApi?.select(uid)\n\t\t\t}\n\t\t})\n\n\t\tconst visible = computed(() => (tabsApi ? tabsApi.isActive(uid) : true))\n\n\t\t// Latches on first activation and never resets, so a lazy panel mounts\n\t\t// once and then behaves exactly like an eager one.\n\t\tconst shown = ref(false)\n\t\twatch(visible, (isVisible) => {\n\t\t\tif (isVisible) {\n\t\t\t\tshown.value = true\n\t\t\t}\n\t\t}, { immediate: true })\n\n\t\tconst rendered = computed(() => !props.lazy || shown.value)\n\n\t\treturn { visible, rendered, tabId, panelId }\n\t},\n})\n</script>\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CnTab.vue3.js","sources":["../../../../src/components/CnTabs/CnTab.vue?vue&type=template&id=5d643b98&lang.js"],"sourcesContent":["<template>\n\t<div\n\t\t:id=\"panelId\"\n\t\tclass=\"cn-tab\"\n\t\trole=\"tabpanel\"\n\t\t:aria-labelledby=\"tabId\"\n\t\t:tabindex=\"visible ? 0 : -1\"\n\t\t:hidden=\"visible ? null : true\"\n\t\t:style=\"visible ? null : { display: 'none' }\">\n\t\t<!-- @slot The panel body. -->\n\t\t<slot v-if=\"rendered\" />\n\t</div>\n</template>\n\n<script>\n/**\n * CnTab — one panel inside a `CnTabs` strip.\n *\n * ```vue\n * <CnTab title=\"Documents\">…</CnTab>\n *\n * <CnTab :active=\"selected === i\" @click=\"selected = i\">\n * <template #title>\n * {{ label }} <CnIcon name=\"close\" @click.stop=\"close(i)\" />\n * </template>\n * …\n * </CnTab>\n * ```\n *\n * ## The panel stays in the DOM\n *\n * An inactive panel is hidden with `hidden` + `display: none`, not removed with\n * `v-if`. This matches bootstrap-vue's `<BTab>`, and it is load-bearing: panels\n * that fetch on `mounted()` would refire that request on every tab switch if\n * they were destroyed and recreated. Use `v-if` inside the panel yourself if\n * you specifically want teardown.\n *\n * `lazy` changes only the FIRST paint: the body waits until the tab is first\n * activated, and from then on the panel behaves exactly as above. It is for\n * strips whose panels are expensive to mount, not for saving memory.\n *\n * ## Rendered outside a CnTabs parent\n *\n * The panel shows its content rather than vanishing. That is deliberate: the\n * alternative failure — an app whose `inject()` misses because the library got\n * loaded twice — would otherwise render blank with no error at all. See\n * `tabsKey.js` for why the key is `Symbol.for`.\n */\nimport { computed, defineComponent, getCurrentInstance, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { CN_TABS_INJECTION_KEY } from './tabsKey.js'\n\nexport default defineComponent({\n\tname: 'CnTab',\n\n\tprops: {\n\t\t/** Plain-text tab title. Ignored when a `#title` slot is supplied. */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Select this tab. Honoured on mount and on every later change. */\n\t\tactive: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Render the nav button disabled and skip this tab in keyboard navigation. */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Hold the panel body back until this tab is first activated, then keep\n\t\t * it mounted for the rest of the strip's life.\n\t\t *\n\t\t * Off by default, because the eager panel is what makes a tab switch\n\t\t * instant and it is the behaviour every existing consumer already has.\n\t\t * Turn it on when the panels are expensive: six panels that each fetch\n\t\t * on `mounted()` fire six requests on page load, and five of those\n\t\t * answer questions nobody has asked yet.\n\t\t *\n\t\t * This is NOT `v-if`-per-switch. Once a panel has been shown it stays\n\t\t * in the DOM, so switching back to it never refetches. That is the\n\t\t * whole reason an inactive panel is hidden rather than destroyed.\n\t\t */\n\t\tlazy: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: [\n\t\t/** The user activated this tab. */\n\t\t'click',\n\t],\n\n\tsetup(props, { slots, emit }) {\n\t\tconst tabsApi = inject(CN_TABS_INJECTION_KEY, null)\n\t\tconst uid = getCurrentInstance().uid\n\t\tconst tabId = `cn-tab-${uid}`\n\t\tconst panelId = `cn-tabpanel-${uid}`\n\n\t\tconst entry = {\n\t\t\tuid,\n\t\t\ttabId,\n\t\t\tpanelId,\n\t\t\t// Invoked from the PARENT's render effect, so reading `props.title`\n\t\t\t// (or calling the slot) here is what keeps a computed title reactive\n\t\t\t// in the nav strip.\n\t\t\ttitleRender: () => (slots.title ? slots.title() : props.title),\n\t\t\tonActivate: () => {\n\t\t\t\tif (props.disabled) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttabsApi?.select(uid)\n\t\t\t\temit('click')\n\t\t\t},\n\n\t\t\tget active() {\n\t\t\t\treturn props.active\n\t\t\t},\n\n\t\t\tget disabled() {\n\t\t\t\treturn props.disabled\n\t\t\t},\n\t\t}\n\n\t\tonMounted(() => tabsApi?.register(entry))\n\t\tonBeforeUnmount(() => tabsApi?.unregister(uid))\n\n\t\twatch(() => props.active, (isActive) => {\n\t\t\tif (isActive && !props.disabled) {\n\t\t\t\ttabsApi?.select(uid)\n\t\t\t}\n\t\t})\n\n\t\tconst visible = computed(() => (tabsApi ? tabsApi.isActive(uid) : true))\n\n\t\t// Latches on first activation and never resets, so a lazy panel mounts\n\t\t// once and then behaves exactly like an eager one.\n\t\tconst shown = ref(false)\n\t\twatch(visible, (isVisible) => {\n\t\t\tif (isVisible) {\n\t\t\t\tshown.value = true\n\t\t\t}\n\t\t}, { immediate: true })\n\n\t\tconst rendered = computed(() => !props.lazy || shown.value)\n\n\t\treturn { visible, rendered, tabId, panelId }\n\t},\n})\n</script>\n"],"names":["_createElementBlock","_renderSlot"],"mappings":";;;;;uBACCA,kBAUK,CAAA,KAAA,EAAA;AATH,IAAA,EAAE,EAAE,IAAO,CAAA,OAAA;AACZ,IAAA,KAAK,EAAC,QAAO;AACb,IAAA,IAAI,EAAC,UAAS;AACb,IAAA,iBAAe,EAAE,IAAK,CAAA,KAAA;AACtB,IAAA,QAAQ,EAAE;AACV,IAAA,MAAM,EAAE,IAAM,CAAA,OAAA,GAAA,IAAA,GAAA,IAAA;AACd,IAAA,KAAK,iBAAE,IAAQ,CAAA,OAAA,GAAA,IAAA,GAAA,EAAA,OAAA,EAAA,MAAA,EAAA,CAAA;;KAEJ,IAAQ,CAAA,QAAA;QAApBC,UAAuB,CAAA,IAAA,CAAA,MAAA,EAAA,SAAA,EAAA,EAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,CAAA;;;;;;;"}
1
+ {"version":3,"file":"CnTab.vue3.js","sources":["../../../../src/components/CnTabs/CnTab.vue?vue&type=template&id=5d643b98&lang.js"],"sourcesContent":["<template>\n\t<div\n\t\t:id=\"panelId\"\n\t\tclass=\"cn-tab\"\n\t\trole=\"tabpanel\"\n\t\t:aria-labelledby=\"tabId\"\n\t\t:tabindex=\"visible ? 0 : -1\"\n\t\t:hidden=\"visible ? null : true\"\n\t\t:style=\"visible ? null : { display: 'none' }\">\n\t\t<!-- @slot The panel body. -->\n\t\t<slot v-if=\"rendered\" />\n\t</div>\n</template>\n\n<script>\n/**\n * CnTab — one panel inside a `CnTabs` strip.\n *\n * ```vue\n * <CnTab title=\"Documents\">…</CnTab>\n *\n * <CnTab :active=\"selected === i\" @click=\"selected = i\">\n * <template #title>\n * {{ label }} <CnIcon name=\"close\" @click.stop=\"close(i)\" />\n * </template>\n * …\n * </CnTab>\n * ```\n *\n * ## The panel stays in the DOM\n *\n * An inactive panel is hidden with `hidden` + `display: none`, not removed with\n * `v-if`. This matches bootstrap-vue's `<BTab>`, and it is load-bearing: panels\n * that fetch on `mounted()` would refire that request on every tab switch if\n * they were destroyed and recreated. Use `v-if` inside the panel yourself if\n * you specifically want teardown.\n *\n * `lazy` changes only the FIRST paint: the body waits until the tab is first\n * activated, and from then on the panel behaves exactly as above. It is for\n * strips whose panels are expensive to mount, not for saving memory.\n *\n * ## Rendered outside a CnTabs parent\n *\n * The panel shows its content rather than vanishing. That is deliberate: the\n * alternative failure — an app whose `inject()` misses because the library got\n * loaded twice — would otherwise render blank with no error at all. See\n * `tabsKey.js` for why the key is `Symbol.for`.\n */\nimport { computed, defineComponent, getCurrentInstance, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { CN_TABS_INJECTION_KEY } from './tabsKey.js'\n\nexport default defineComponent({\n\tname: 'CnTab',\n\n\tprops: {\n\t\t/** Plain-text tab title. Ignored when a `#title` slot is supplied. */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Select this tab. Honoured on mount and on every later change. */\n\t\tactive: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Render the nav button disabled and skip this tab in keyboard navigation. */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Hold the panel body back until this tab is first activated, then keep\n\t\t * it mounted for the rest of the strip's life.\n\t\t *\n\t\t * Off by default, because the eager panel is what makes a tab switch\n\t\t * instant and it is the behaviour every existing consumer already has.\n\t\t * Turn it on when the panels are expensive: six panels that each fetch\n\t\t * on `mounted()` fire six requests on page load, and five of those\n\t\t * answer questions nobody has asked yet.\n\t\t *\n\t\t * This is NOT `v-if`-per-switch. Once a panel has been shown it stays\n\t\t * in the DOM, so switching back to it never refetches. That is the\n\t\t * whole reason an inactive panel is hidden rather than destroyed.\n\t\t */\n\t\tlazy: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * A count shown after the title, for example the number of documents\n\t\t * behind the tab. `null` (the default) shows none; `0` is shown.\n\t\t *\n\t\t * @type {number|string|null}\n\t\t */\n\t\tcount: {\n\t\t\ttype: [Number, String],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * List this tab under the strip's \"More\" menu instead of in the strip.\n\t\t * Picking it there selects it, and while it is the selected tab it\n\t\t * shows in the strip. Give an overflow tab a `title`: the menu needs\n\t\t * plain text, and a `#title` slot is markup.\n\t\t */\n\t\toverflow: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: [\n\t\t/** The user activated this tab. */\n\t\t'click',\n\t],\n\n\tsetup(props, { slots, emit }) {\n\t\tconst tabsApi = inject(CN_TABS_INJECTION_KEY, null)\n\t\tconst uid = getCurrentInstance().uid\n\t\tconst tabId = `cn-tab-${uid}`\n\t\tconst panelId = `cn-tabpanel-${uid}`\n\n\t\tconst entry = {\n\t\t\tuid,\n\t\t\ttabId,\n\t\t\tpanelId,\n\t\t\t// Invoked from the PARENT's render effect, so reading `props.title`\n\t\t\t// (or calling the slot) here is what keeps a computed title reactive\n\t\t\t// in the nav strip.\n\t\t\ttitleRender: () => (slots.title ? slots.title() : props.title),\n\t\t\tonActivate: () => {\n\t\t\t\tif (props.disabled) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttabsApi?.select(uid)\n\t\t\t\temit('click')\n\t\t\t},\n\n\t\t\tget active() {\n\t\t\t\treturn props.active\n\t\t\t},\n\n\t\t\tget disabled() {\n\t\t\t\treturn props.disabled\n\t\t\t},\n\n\t\t\tget count() {\n\t\t\t\treturn props.count\n\t\t\t},\n\n\t\t\tget overflow() {\n\t\t\t\treturn props.overflow\n\t\t\t},\n\n\t\t\t// Plain text for the \"More\" menu, where a `#title` slot cannot go.\n\t\t\tget label() {\n\t\t\t\treturn props.title\n\t\t\t},\n\t\t}\n\n\t\tonMounted(() => tabsApi?.register(entry))\n\t\tonBeforeUnmount(() => tabsApi?.unregister(uid))\n\n\t\twatch(() => props.active, (isActive) => {\n\t\t\tif (isActive && !props.disabled) {\n\t\t\t\ttabsApi?.select(uid)\n\t\t\t}\n\t\t})\n\n\t\tconst visible = computed(() => (tabsApi ? tabsApi.isActive(uid) : true))\n\n\t\t// Latches on first activation and never resets, so a lazy panel mounts\n\t\t// once and then behaves exactly like an eager one.\n\t\tconst shown = ref(false)\n\t\twatch(visible, (isVisible) => {\n\t\t\tif (isVisible) {\n\t\t\t\tshown.value = true\n\t\t\t}\n\t\t}, { immediate: true })\n\n\t\tconst rendered = computed(() => !props.lazy || shown.value)\n\n\t\treturn { visible, rendered, tabId, panelId }\n\t},\n})\n</script>\n"],"names":["_createElementBlock","_renderSlot"],"mappings":";;;;;uBACCA,kBAUK,CAAA,KAAA,EAAA;AATH,IAAA,EAAE,EAAE,IAAO,CAAA,OAAA;AACZ,IAAA,KAAK,EAAC,QAAO;AACb,IAAA,IAAI,EAAC,UAAS;AACb,IAAA,iBAAe,EAAE,IAAK,CAAA,KAAA;AACtB,IAAA,QAAQ,EAAE;AACV,IAAA,MAAM,EAAE,IAAM,CAAA,OAAA,GAAA,IAAA,GAAA,IAAA;AACd,IAAA,KAAK,iBAAE,IAAQ,CAAA,OAAA,GAAA,IAAA,GAAA,EAAA,OAAA,EAAA,MAAA,EAAA,CAAA;;KAEJ,IAAQ,CAAA,QAAA;QAApBC,UAAuB,CAAA,IAAA,CAAA,MAAA,EAAA,SAAA,EAAA,EAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,CAAA;;;;;;;"}