@conduction/nextcloud-vue 2.56.0-beta.36 → 2.56.0-beta.38

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 (382) hide show
  1. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
  2. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js +131 -3
  3. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
  4. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +54 -18
  5. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
  6. package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue.js +1 -1
  7. package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue2.js +3 -2
  8. package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue2.js.map +1 -1
  9. package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue3.js.map +1 -1
  10. package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue.js +1 -1
  11. package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue2.js +5 -4
  12. package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue2.js.map +1 -1
  13. package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue3.js.map +1 -1
  14. package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue.js +1 -1
  15. package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue2.js +2 -1
  16. package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue2.js.map +1 -1
  17. package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue3.js.map +1 -1
  18. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue.js +1 -1
  19. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +2 -1
  20. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
  21. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
  22. package/dist/esm/components/CnBoardView/CnBoardView.vue.js +1 -1
  23. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +376 -6
  24. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
  25. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +146 -71
  26. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
  27. package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue.js +1 -1
  28. package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue2.js +2 -1
  29. package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue2.js.map +1 -1
  30. package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue3.js.map +1 -1
  31. package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue.js +1 -1
  32. package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue2.js +2 -1
  33. package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue2.js.map +1 -1
  34. package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue3.js.map +1 -1
  35. package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
  36. package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +6 -5
  37. package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
  38. package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
  39. package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue.js +1 -1
  40. package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue2.js +2 -1
  41. package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue2.js.map +1 -1
  42. package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue3.js.map +1 -1
  43. package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js +1 -1
  44. package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js +2 -1
  45. package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -1
  46. package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -1
  47. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue.js +1 -1
  48. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js +2 -1
  49. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js.map +1 -1
  50. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js.map +1 -1
  51. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  52. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +47 -1
  53. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  54. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +22 -12
  55. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  56. package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue.js +1 -1
  57. package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue2.js +3 -1
  58. package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue2.js.map +1 -1
  59. package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue3.js.map +1 -1
  60. package/dist/esm/components/CnDetailPage/CnDetailHeaderChips.vue2.js +2 -1
  61. package/dist/esm/components/CnDetailPage/CnDetailHeaderChips.vue2.js.map +1 -1
  62. package/dist/esm/components/CnDetailPage/CnDetailHeaderChips.vue3.js.map +1 -1
  63. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +23 -4
  64. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  65. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  66. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
  67. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +3 -1
  68. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  69. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  70. package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue.js +1 -1
  71. package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue2.js +2 -1
  72. package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue2.js.map +1 -1
  73. package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue3.js.map +1 -1
  74. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
  75. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +18 -5
  76. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
  77. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
  78. package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue.js +1 -1
  79. package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue2.js +3 -1
  80. package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue2.js.map +1 -1
  81. package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue3.js.map +1 -1
  82. package/dist/esm/components/CnFileManager/CnFileManager.vue.js +1 -1
  83. package/dist/esm/components/CnFileManager/CnFileManager.vue2.js +3 -1
  84. package/dist/esm/components/CnFileManager/CnFileManager.vue2.js.map +1 -1
  85. package/dist/esm/components/CnFileManager/CnFileManager.vue3.js.map +1 -1
  86. package/dist/esm/components/CnFilePreview/CnFilePreview.vue.js +1 -1
  87. package/dist/esm/components/CnFilePreview/CnFilePreview.vue2.js +2 -1
  88. package/dist/esm/components/CnFilePreview/CnFilePreview.vue2.js.map +1 -1
  89. package/dist/esm/components/CnFilePreview/CnFilePreview.vue3.js.map +1 -1
  90. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
  91. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +49 -1
  92. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  93. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +3 -3
  94. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  95. package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue.js +1 -1
  96. package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue2.js +2 -1
  97. package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue2.js.map +1 -1
  98. package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue3.js.map +1 -1
  99. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +571 -77
  100. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  101. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +191 -82
  102. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  103. package/dist/esm/components/CnIndexPage/useSelfFetchList.js +11 -2
  104. package/dist/esm/components/CnIndexPage/useSelfFetchList.js.map +1 -1
  105. package/dist/esm/components/CnNotesCard/CnNotesCard.vue.js +1 -1
  106. package/dist/esm/components/CnNotesCard/CnNotesCard.vue2.js +2 -1
  107. package/dist/esm/components/CnNotesCard/CnNotesCard.vue2.js.map +1 -1
  108. package/dist/esm/components/CnNotesCard/CnNotesCard.vue3.js.map +1 -1
  109. package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue.js +1 -1
  110. package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue2.js +3 -2
  111. package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue2.js.map +1 -1
  112. package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue3.js.map +1 -1
  113. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue.js +1 -1
  114. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +28 -0
  115. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
  116. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js +82 -75
  117. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
  118. package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue.js +1 -1
  119. package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue2.js +5 -4
  120. package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue2.js.map +1 -1
  121. package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue3.js.map +1 -1
  122. package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue.js +1 -1
  123. package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue2.js +2 -1
  124. package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue2.js.map +1 -1
  125. package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue3.js.map +1 -1
  126. package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue.js +1 -1
  127. package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue2.js +2 -1
  128. package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue2.js.map +1 -1
  129. package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue3.js.map +1 -1
  130. package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue.js +1 -1
  131. package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js +2 -1
  132. package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js.map +1 -1
  133. package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue3.js.map +1 -1
  134. package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue.js +1 -1
  135. package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue2.js +2 -1
  136. package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue2.js.map +1 -1
  137. package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue3.js.map +1 -1
  138. package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue.js +1 -1
  139. package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue2.js +2 -1
  140. package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue2.js.map +1 -1
  141. package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue3.js.map +1 -1
  142. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  143. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +70 -2
  144. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  145. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  146. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue.js +1 -1
  147. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue2.js +67 -5
  148. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue2.js.map +1 -1
  149. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue3.js +181 -124
  150. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue3.js.map +1 -1
  151. package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue.js +1 -1
  152. package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue2.js +2 -1
  153. package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue2.js.map +1 -1
  154. package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue3.js.map +1 -1
  155. package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue2.js +2 -0
  156. package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue2.js.map +1 -1
  157. package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue3.js +2 -2
  158. package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue3.js.map +1 -1
  159. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue.js +1 -1
  160. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js +5 -1
  161. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js.map +1 -1
  162. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js.map +1 -1
  163. package/dist/esm/components/CnStatWidget/CnStatWidget.vue.js +1 -1
  164. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +134 -10
  165. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
  166. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +6 -2
  167. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
  168. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue.js +1 -1
  169. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue2.js +2 -1
  170. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue2.js.map +1 -1
  171. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue3.js.map +1 -1
  172. package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue.js +1 -1
  173. package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue2.js +2 -1
  174. package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue2.js.map +1 -1
  175. package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue3.js.map +1 -1
  176. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
  177. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +6 -3
  178. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  179. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  180. package/dist/esm/components/CnTasksCard/CnTasksCard.vue.js +1 -1
  181. package/dist/esm/components/CnTasksCard/CnTasksCard.vue2.js +2 -1
  182. package/dist/esm/components/CnTasksCard/CnTasksCard.vue2.js.map +1 -1
  183. package/dist/esm/components/CnTasksCard/CnTasksCard.vue3.js.map +1 -1
  184. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +1 -1
  185. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +2 -1
  186. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -1
  187. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -1
  188. package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue.js +1 -1
  189. package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue2.js +140 -7
  190. package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue2.js.map +1 -1
  191. package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue3.js.map +1 -1
  192. package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue.js +1 -1
  193. package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue2.js +2 -1
  194. package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue2.js.map +1 -1
  195. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue.js +1 -1
  196. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue2.js +2 -1
  197. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue2.js.map +1 -1
  198. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue3.js.map +1 -1
  199. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue.js +1 -1
  200. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js +37 -9
  201. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js.map +1 -1
  202. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js +6 -5
  203. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js.map +1 -1
  204. package/dist/esm/components/CnWidgetCardGrid/CnWidgetCardGrid.vue2.js +53 -1
  205. package/dist/esm/components/CnWidgetCardGrid/CnWidgetCardGrid.vue2.js.map +1 -1
  206. package/dist/esm/components/CnWidgetCardGrid/CnWidgetCardGrid.vue3.js +3 -2
  207. package/dist/esm/components/CnWidgetCardGrid/CnWidgetCardGrid.vue3.js.map +1 -1
  208. package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue.js +1 -1
  209. package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +135 -0
  210. package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js.map +1 -1
  211. package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue3.js.map +1 -1
  212. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue.js +1 -1
  213. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +19 -0
  214. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
  215. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +37 -19
  216. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
  217. package/dist/esm/composables/useListView.js +21 -0
  218. package/dist/esm/composables/useListView.js.map +1 -1
  219. package/dist/esm/dialogs/CnNoteHistoryDialog.vue.js +1 -1
  220. package/dist/esm/dialogs/CnNoteHistoryDialog.vue2.js +2 -1
  221. package/dist/esm/dialogs/CnNoteHistoryDialog.vue2.js.map +1 -1
  222. package/dist/esm/dialogs/CnNoteHistoryDialog.vue3.js.map +1 -1
  223. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue.js +1 -1
  224. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue2.js +3 -2
  225. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue2.js.map +1 -1
  226. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue3.js.map +1 -1
  227. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue.js +1 -1
  228. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue2.js +4 -3
  229. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue2.js.map +1 -1
  230. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue3.js.map +1 -1
  231. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue.js +1 -1
  232. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -2
  233. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
  234. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
  235. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue.js +1 -1
  236. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js +2 -1
  237. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js.map +1 -1
  238. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue3.js.map +1 -1
  239. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue.js +1 -1
  240. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue2.js +6 -5
  241. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue2.js.map +1 -1
  242. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue3.js.map +1 -1
  243. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue.js +1 -1
  244. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue2.js +2 -1
  245. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue2.js.map +1 -1
  246. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue3.js.map +1 -1
  247. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue.js +1 -1
  248. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js +2 -1
  249. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js.map +1 -1
  250. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js.map +1 -1
  251. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue.js +1 -1
  252. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +2 -1
  253. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
  254. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
  255. package/dist/esm/integrations/builtin/email/CnEmailCard.vue.js +1 -1
  256. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js +2 -1
  257. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js.map +1 -1
  258. package/dist/esm/integrations/builtin/email/CnEmailCard.vue3.js.map +1 -1
  259. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue.js +1 -1
  260. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js +2 -1
  261. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js.map +1 -1
  262. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js.map +1 -1
  263. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue.js +1 -1
  264. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue2.js +2 -1
  265. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue2.js.map +1 -1
  266. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue3.js.map +1 -1
  267. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue.js +1 -1
  268. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js +2 -1
  269. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js.map +1 -1
  270. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js.map +1 -1
  271. package/dist/esm/l10n/en.json.js +57 -2
  272. package/dist/esm/l10n/en.json.js.map +1 -1
  273. package/dist/esm/l10n/nl.json.js +78 -2
  274. package/dist/esm/l10n/nl.json.js.map +1 -1
  275. package/dist/esm/library-style.js +1 -1
  276. package/dist/esm/nextcloud-vue.css +1541 -1166
  277. package/dist/esm/store/useObjectStore.js +23 -4
  278. package/dist/esm/store/useObjectStore.js.map +1 -1
  279. package/dist/esm/utils/boardColumns.js +58 -2
  280. package/dist/esm/utils/boardColumns.js.map +1 -1
  281. package/dist/esm/utils/boardReferenceColumns.js +330 -0
  282. package/dist/esm/utils/boardReferenceColumns.js.map +1 -0
  283. package/dist/esm/utils/buildManifest.js +4 -1
  284. package/dist/esm/utils/buildManifest.js.map +1 -1
  285. package/dist/esm/utils/schema.js +5 -4
  286. package/dist/esm/utils/schema.js.map +1 -1
  287. package/dist/esm/utils/userLocale.js +30 -0
  288. package/dist/esm/utils/userLocale.js.map +1 -0
  289. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  290. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  291. package/dist/esm/utils/widgetDispatch.js +8 -2
  292. package/dist/esm/utils/widgetDispatch.js.map +1 -1
  293. package/dist/nextcloud-vue.cjs.js +30291 -27618
  294. package/dist/nextcloud-vue.cjs.js.map +2 -2
  295. package/dist/nextcloud-vue.css +1541 -1166
  296. package/l10n/en.json +57 -2
  297. package/l10n/nl.json +78 -2
  298. package/package.json +1 -1
  299. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +160 -8
  300. package/src/components/CnAdvancedFormDialog/CnMetadataTab.vue +3 -2
  301. package/src/components/CnAdvancedFormDialog/CnPropertyValueCell.vue +5 -4
  302. package/src/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue +2 -1
  303. package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +2 -1
  304. package/src/components/CnBoardView/CnBoardView.vue +433 -12
  305. package/src/components/CnCalendarEventPicker/CnCalendarEventPicker.vue +2 -1
  306. package/src/components/CnCalendarWidget/CnCalendarWidget.vue +2 -1
  307. package/src/components/CnChartWidget/CnChartWidget.vue +6 -5
  308. package/src/components/CnCollectivePagePicker/CnCollectivePagePicker.vue +2 -1
  309. package/src/components/CnConversationThread/CnConversationThread.vue +2 -1
  310. package/src/components/CnCountdownWidget/CnCountdownWidget.vue +2 -1
  311. package/src/components/CnDashboardPage/CnDashboardPage.vue +59 -3
  312. package/src/components/CnDataMatrix/CnDataMatrix.vue +2 -1
  313. package/src/components/CnDetailPage/CnDetailHeaderChips.vue +2 -1
  314. package/src/components/CnDetailPage/CnDetailPage.md +1 -1
  315. package/src/components/CnDetailPage/CnDetailPage.vue +23 -4
  316. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +3 -1
  317. package/src/components/CnEmailPicker/CnEmailPicker.vue +2 -1
  318. package/src/components/CnFactsWidget/CnFactsWidget.vue +18 -5
  319. package/src/components/CnFederationStatus/CnFederationStatus.vue +3 -1
  320. package/src/components/CnFileManager/CnFileManager.vue +2 -1
  321. package/src/components/CnFilePreview/CnFilePreview.vue +2 -1
  322. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +54 -6
  323. package/src/components/CnFollowToggle/CnFollowToggle.vue +2 -1
  324. package/src/components/CnIndexPage/CnIndexPage.vue +610 -25
  325. package/src/components/CnIndexPage/useSelfFetchList.js +10 -1
  326. package/src/components/CnNotesCard/CnNotesCard.vue +2 -1
  327. package/src/components/CnObjectCalendar/CnObjectCalendar.vue +3 -2
  328. package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +36 -0
  329. package/src/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue +5 -4
  330. package/src/components/CnObjectSidebar/CnAuditTrailTab.vue +2 -1
  331. package/src/components/CnObjectSidebar/CnFlowTasksPanel.vue +2 -1
  332. package/src/components/CnObjectSidebar/CnNotesTab.vue +2 -1
  333. package/src/components/CnObjectSidebar/CnTasksTab.vue +2 -1
  334. package/src/components/CnPropertySourceField/CnPropertySourceField.vue +2 -1
  335. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +70 -2
  336. package/src/components/CnRegisterMapping/CnRegisterMapping.md +5 -0
  337. package/src/components/CnRegisterMapping/CnRegisterMapping.vue +231 -96
  338. package/src/components/CnRoadmapItem/CnRoadmapItem.vue +2 -1
  339. package/src/components/CnSchemaFormDialog/CnSchemaFormDialog.vue +4 -2
  340. package/src/components/CnSettingsPage/CnSettingsPage.vue +5 -1
  341. package/src/components/CnStatWidget/CnStatWidget.vue +136 -11
  342. package/src/components/CnStatsBlock/CnStatsBlock.vue +2 -1
  343. package/src/components/CnSummaryAggregates/CnSummaryAggregates.vue +2 -1
  344. package/src/components/CnTabsWidget/CnTabsWidget.vue +6 -3
  345. package/src/components/CnTasksCard/CnTasksCard.vue +2 -1
  346. package/src/components/CnTimelineWidget/CnTimelineWidget.vue +2 -1
  347. package/src/components/CnToggleTableWidget/CnToggleTableWidget.vue +140 -7
  348. package/src/components/CnTranslatedBadge/CnTranslatedBadge.vue +2 -1
  349. package/src/components/CnVersionHistory/CnVersionHistory.vue +2 -1
  350. package/src/components/CnVersionInfoCard/CnVersionInfoCard.md +2 -1
  351. package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +42 -13
  352. package/src/components/CnWidgetCardGrid/CnWidgetCardGrid.vue +55 -2
  353. package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +135 -0
  354. package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +10 -0
  355. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +44 -1
  356. package/src/composables/useListView.js +21 -0
  357. package/src/css/board.css +105 -4
  358. package/src/css/dialog.css +4 -2
  359. package/src/css/index-page.css +49 -0
  360. package/src/css/look-board.css +77 -7
  361. package/src/dialogs/CnNoteHistoryDialog.vue +2 -1
  362. package/src/integrations/builtin/activity/CnActivityCard.vue +3 -2
  363. package/src/integrations/builtin/activity/CnActivityTab.vue +4 -3
  364. package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +3 -2
  365. package/src/integrations/builtin/calendar/CnCalendarCard.vue +2 -1
  366. package/src/integrations/builtin/calendar/CnCalendarTab.vue +6 -5
  367. package/src/integrations/builtin/contactmoment/CnContactmomentCard.vue +2 -1
  368. package/src/integrations/builtin/cospend/CnCospendTab.vue +2 -1
  369. package/src/integrations/builtin/deck/CnDeckTab.vue +2 -1
  370. package/src/integrations/builtin/email/CnEmailCard.vue +2 -1
  371. package/src/integrations/builtin/field-inspection/CnFieldInspectionCard.vue +2 -1
  372. package/src/integrations/builtin/field-inspection/CnFieldInspectionTab.vue +2 -1
  373. package/src/integrations/builtin/photos/CnPhotosTab.vue +2 -1
  374. package/src/schemas/app-manifest-v2.schema.json +116 -5
  375. package/src/store/useObjectStore.js +23 -4
  376. package/src/utils/boardColumns.js +57 -1
  377. package/src/utils/boardReferenceColumns.js +326 -0
  378. package/src/utils/buildManifest.js +4 -1
  379. package/src/utils/schema.js +5 -4
  380. package/src/utils/userLocale.js +26 -0
  381. package/src/utils/validateManifestV2.compiled.js +3 -3
  382. package/src/utils/widgetDispatch.js +8 -2
@@ -618,6 +618,7 @@ const baseActions = {
618
618
  * Fetch the schema definition for a registered type.
619
619
  * Uses cache — only fetches once per type per session.
620
620
  *
621
+ * @spec openspec/changes/zuiddrecht-pixel-gaps-2/specs/zuiddrecht-pixel-gaps-2/spec.md#requirement-a-schema-title-falls-back-to-its-written-form
621
622
  * @param {string} type The registered type slug
622
623
  * @return {Promise<object|null>} The schema object or null on error
623
624
  */
@@ -638,8 +639,12 @@ const baseActions = {
638
639
  const registerScope = config.register
639
640
  ? `?register=${encodeURIComponent(config.register)}`
640
641
  : ''
641
- const response = await trackedFetch(
642
- prefixUrl(`/apps/openregister/api/schemas/${config.schema}${registerScope}`),
642
+ // Through the schema fallback like every objects-API call: a type
643
+ // resolveObjectOpType registered from a title (`APInvoice` ->
644
+ // `ap-invoice`) retries once with the title as written on a 404.
645
+ const response = await this._fetchWithSchemaFallback(
646
+ type,
647
+ (schema) => prefixUrl(`/apps/openregister/api/schemas/${schema ?? config.schema}${registerScope}`),
643
648
  { method: 'GET', headers: this._buildHeaders() },
644
649
  )
645
650
 
@@ -707,6 +712,8 @@ const baseActions = {
707
712
  * @param {object} [params] Query parameters (_limit, _page, _search, _order, filters)
708
713
  * @param {object} [options] Call options
709
714
  * @param {{error?: object|null}} [options.outcome] Opt-in sink for THIS call's own result: `error` is set to the error it records on `errors[type]`, or `null` on success. Unlike `errors[type]`, which every call for the type shares, a later call cannot overwrite it.
715
+ * @param {boolean} [options.append] Add the fetched page after the rows already stored instead of replacing them. Dropped when the stored rows are no longer the page before it, or when `options.isCurrent()` returns false (the query changed meanwhile).
716
+ * @param {() => boolean} [options.isCurrent] With `append`: asked once the page arrives; false drops it.
710
717
  * @return {Promise<Array>} The fetched collection (also stored in state)
711
718
  */
712
719
  async fetchCollection(type, params = {}, options = {}) {
@@ -750,14 +757,26 @@ const baseActions = {
750
757
 
751
758
  const data = await response.json()
752
759
  const results = data.results || data
760
+ const append = options?.append === true
753
761
 
754
- this.collections = { ...this.collections, [type]: results }
762
+ const stale = append && (
763
+ Number(this.pagination[type]?.page || 1) !== Number(params._page || 1) - 1
764
+ || (typeof options.isCurrent === 'function' && !options.isCurrent())
765
+ )
766
+ if (stale) {
767
+ return []
768
+ }
769
+
770
+ this.collections = {
771
+ ...this.collections,
772
+ [type]: append ? [...(this.collections[type] || []), ...results] : results,
773
+ }
755
774
  // Why a personal lens came back empty, if it says (openregister#4514).
756
775
  this.lenses = { ...this.lenses, [type]: readLensReports(data) }
757
776
  this.pagination = {
758
777
  ...this.pagination,
759
778
  [type]: {
760
- total: data.total || results.length,
779
+ total: data.total || (append ? this.collections[type].length : results.length),
761
780
  page: data.page || 1,
762
781
  pages: data.pages || 1,
763
782
  limit: params._limit || 20,
@@ -55,12 +55,28 @@ export function stagesOf(field, colorField = '') {
55
55
  label: String(entry?.label ?? entry?.title ?? entry?.key ?? entry?.value ?? ''),
56
56
  hidden: entry?.hidden === true,
57
57
  color: colorOf(field, entry, colorField),
58
+ capacity: capacityValue(entry?.capacity),
58
59
  }))
59
60
  .filter((stage) => stage.key !== '')
60
61
 
61
62
  return { stages, usable: stages.length > 0 }
62
63
  }
63
64
 
65
+ /**
66
+ * A column limit as a usable number.
67
+ *
68
+ * @param {unknown} value - The declared limit.
69
+ * @return {number|null} The limit, or null when there is none (not a number above 0).
70
+ * @spec openspec/changes/board-column-capacity/specs/board-view/spec.md#requirement-a-column-can-carry-a-capacity
71
+ */
72
+ export function capacityValue(value) {
73
+ if (value === null || value === undefined || value === '') {
74
+ return null
75
+ }
76
+ const n = Number(value)
77
+ return Number.isFinite(n) && n > 0 ? n : null
78
+ }
79
+
64
80
  /**
65
81
  * The colour a state declares: the `colorField` key on the state, else its
66
82
  * `color`, else (for a plain enum value) the field's `enumColors` entry.
@@ -128,6 +144,10 @@ function labelFor(field, value) {
128
144
  * @param {string} options.statusField - The property name on a row.
129
145
  * @param {string} [options.offBoardLabel] - What to call the off-board column.
130
146
  * @param {string} [options.colorField] - The key on a state that holds its dot colour.
147
+ * @param {?((row: object) => string)} [options.keyOf] - The column a row
148
+ * belongs in, for a field whose raw value is not the column key (a
149
+ * reference whose rows are merged by name). Absent, the row's
150
+ * `statusField` value is the key.
131
151
  *
132
152
  * @return {{columns: Array<object>, usable: boolean}} The columns, each
133
153
  * `{ key, label, cards, count }`, and whether the field could back a board.
@@ -138,6 +158,7 @@ export function buildBoardColumns({
138
158
  statusField = '',
139
159
  offBoardLabel = 'Elsewhere',
140
160
  colorField = '',
161
+ keyOf = null,
141
162
  } = {}) {
142
163
  const { stages, usable } = stagesOf(field, colorField)
143
164
  if (usable === false) {
@@ -149,6 +170,7 @@ export function buildBoardColumns({
149
170
  key: stage.key,
150
171
  label: stage.label,
151
172
  color: stage.color,
173
+ capacity: stage.capacity ?? null,
152
174
  cards: [],
153
175
  count: 0,
154
176
  }))
@@ -156,7 +178,9 @@ export function buildBoardColumns({
156
178
 
157
179
  const offBoard = { key: OFF_BOARD_KEY, label: offBoardLabel, cards: [], count: 0 }
158
180
  for (const row of rows) {
159
- const value = String(row?.[statusField] ?? '')
181
+ const value = typeof keyOf === 'function'
182
+ ? String(keyOf(row) ?? '')
183
+ : String(row?.[statusField] ?? '')
160
184
  const column = byKey.get(value) || offBoard
161
185
  column.cards.push(row)
162
186
  column.count += 1
@@ -170,3 +194,35 @@ export function buildBoardColumns({
170
194
 
171
195
  return { columns, usable: true }
172
196
  }
197
+
198
+ /**
199
+ * Where a card may move, from what `allowedMoves` answered: plain column keys
200
+ * and `{ key, allowed, reason }` entries. A key any entry allows is allowed;
201
+ * a blocked key keeps the first reason given for it.
202
+ *
203
+ * @param {unknown} answer The answer.
204
+ * @return {{keys: Array<string>, reasons: object}|null} The allowed keys and the reasons by key, or null for everywhere.
205
+ * @spec openspec/changes/board-move-block-reasons/specs/board-view/spec.md#requirement-a-move-target-can-be-blocked-with-a-reason
206
+ */
207
+ export function normalizeAllowed(answer) {
208
+ if (!Array.isArray(answer)) {
209
+ return null
210
+ }
211
+ const keys = []
212
+ const reasons = {}
213
+ for (const entry of answer) {
214
+ if (entry && typeof entry === 'object') {
215
+ const key = String(entry.key ?? '')
216
+ if (entry.allowed === false) {
217
+ if (!reasons[key] && typeof entry.reason === 'string' && entry.reason.trim() !== '') {
218
+ reasons[key] = entry.reason.trim()
219
+ }
220
+ } else {
221
+ keys.push(key)
222
+ }
223
+ } else if (entry !== null && entry !== undefined) {
224
+ keys.push(String(entry))
225
+ }
226
+ }
227
+ return { keys, reasons }
228
+ }
@@ -0,0 +1,326 @@
1
+ /**
2
+ * SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl>
3
+ * SPDX-License-Identifier: EUPL-1.2
4
+ *
5
+ * Board columns from a REFERENCED field (screens-board-reference-columns).
6
+ *
7
+ * A status that is an enum or a lifecycle list carries its stages on the
8
+ * field, and `boardColumns.js` reads them there. A status that is a reference
9
+ * to another object (a case's `status` pointing at a statusType row) carries
10
+ * nothing on the field: the stages are the rows of the referenced schema. This
11
+ * module turns those rows into the same `states` list `stagesOf()` reads, plus
12
+ * the map from a row's raw value (the referenced id) to its column.
13
+ *
14
+ * 🔴 THE COLUMNS ARE STILL THE SCHEMA'S, NOT THE DATA'S. They are the
15
+ * referenced rows, fetched, not the values present on the loaded cards, so an
16
+ * empty stage is still a column to drop a card into. The one exception is a
17
+ * field with no referenced schema at all (a Nextcloud user id): there the
18
+ * values present are all there is, and a "nobody" column is always added so
19
+ * work without an owner stays visible and can be dropped back to nobody.
20
+ *
21
+ * 🔴 MERGED COLUMNS RESOLVE PER CARD. Referenced rows are often per parent
22
+ * (every case type has its own "In behandeling"). Merged by name they make one
23
+ * column, and a drop must then write the row of THAT card's parent. A column
24
+ * with no row for the card's parent is not a place the card can go, and the
25
+ * drop is refused rather than written to some other parent's row.
26
+ *
27
+ * Pure apart from `fetchReferenceObjects`: no store, no Vue.
28
+ */
29
+
30
+ import { capacityValue } from './boardColumns.js'
31
+ import { buildHeaders, buildQueryString, prefixUrl } from './headers.js'
32
+ import { readPath } from './readPath.js'
33
+ import { schemaRefSlug } from './schemaRefSlug.js'
34
+
35
+ /** The column of cards with no value, for a `values` column field. */
36
+ export const NO_VALUE_KEY = '__none__'
37
+
38
+ /**
39
+ * The id a reference value carries: a string as is, an object by its `id`,
40
+ * `uuid` or `@self.id`.
41
+ *
42
+ * @param {unknown} value A reference as a row holds it.
43
+ * @return {string} The id, '' when there is none.
44
+ */
45
+ export function refIdOf(value) {
46
+ if (value === null || value === undefined) {
47
+ return ''
48
+ }
49
+ if (typeof value === 'object') {
50
+ const id = value.id ?? value.uuid ?? value['@self']?.id ?? value.value ?? ''
51
+ return id === null || id === undefined ? '' : String(id)
52
+ }
53
+ return String(value)
54
+ }
55
+
56
+ /**
57
+ * A value as text: a string or number as is, an object by its name.
58
+ *
59
+ * @param {unknown} value The raw value.
60
+ * @return {string} The text.
61
+ */
62
+ function textOf(value) {
63
+ if (value === null || value === undefined) {
64
+ return ''
65
+ }
66
+ if (typeof value === 'object') {
67
+ return String(value.displayName ?? value.name ?? value.title ?? value.label ?? '').trim()
68
+ }
69
+ return String(value).trim()
70
+ }
71
+
72
+ /**
73
+ * The column fields a board offers, normalised. Without `columnFields` the
74
+ * board has one, its `statusField`, read from the schema as before.
75
+ *
76
+ * @param {object} board The board configuration (manifest `config.board`).
77
+ * @return {Array<{field: string, label: string, source: (object|null), kind: string, readOnly: boolean, moveHandler: string, moveTargetsHandler: string}>} The fields.
78
+ * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-a-board-can-switch-the-field-its-columns-come-from
79
+ */
80
+ export function columnFieldsOf(board) {
81
+ const declared = Array.isArray(board?.columnFields) ? board.columnFields : []
82
+ return declared
83
+ .map((entry) => (typeof entry === 'string' ? { field: entry } : entry))
84
+ .filter((entry) => entry && typeof entry.field === 'string' && entry.field !== '')
85
+ .map((entry) => ({
86
+ field: entry.field,
87
+ label: typeof entry.label === 'string' && entry.label !== '' ? entry.label : entry.field,
88
+ source: entry.source && typeof entry.source === 'object' ? entry.source : null,
89
+ kind: entry.kind === 'values' ? 'values' : (entry.source ? 'reference' : 'schema'),
90
+ readOnly: entry.readOnly === true,
91
+ moveHandler: typeof entry.moveHandler === 'string' ? entry.moveHandler : '',
92
+ moveTargetsHandler: typeof entry.moveTargetsHandler === 'string' ? entry.moveTargetsHandler : '',
93
+ valueLabels: entry.valueLabels && typeof entry.valueLabels === 'object' ? entry.valueLabels : null,
94
+ emptyLabel: typeof entry.emptyLabel === 'string' ? entry.emptyLabel : '',
95
+ }))
96
+ }
97
+
98
+ /**
99
+ * The register and schema a reference column reads its rows from: the
100
+ * source's own, else the page's register and the property's `$ref`.
101
+ *
102
+ * @param {object} source The column field's `source`.
103
+ * @param {object} options The context.
104
+ * @param {string} options.register The page's register.
105
+ * @param {object} [options.property] The field's schema property.
106
+ * @return {{register: string, schema: string}} Both, '' when unknown.
107
+ */
108
+ export function referenceTargetOf(source, { register = '', property = null } = {}) {
109
+ const schema = source?.schema || schemaRefSlug(property?.$ref ?? property?.items?.$ref ?? '')
110
+ return {
111
+ register: String(source?.register || register || ''),
112
+ schema: schema === '' || schema === null || schema === undefined ? '' : String(schema),
113
+ }
114
+ }
115
+
116
+ /**
117
+ * The stages of a referenced field: the referenced rows, narrowed to one
118
+ * parent when asked, ordered, and merged by a field when asked.
119
+ *
120
+ * @param {object} options The call.
121
+ * @param {Array<object>} options.refs The referenced rows.
122
+ * @param {string} [options.labelField] The row field that names a column.
123
+ * @param {string} [options.orderField] The numeric row field the columns are ordered by.
124
+ * @param {string} [options.colorField] The row field that holds the dot colour.
125
+ * @param {string} [options.mergeBy] The row field whose equal values make one column.
126
+ * @param {{field: string, rowField: string}|null} [options.narrowBy] The parent link.
127
+ * @param {string} [options.narrowValue] The parent the board is narrowed to, '' for all.
128
+ * @param {string} [options.capacityField] The numeric row field that holds a column's limit.
129
+ * A column merged from two or more rows shows none: each row has its own limit.
130
+ * @return {{states: Array<{key: string, label: string, color: string, capacity?: (number|null)}>, keyByValue: Map<string, string>, refsByKey: Map<string, Array<object>>}} The stages.
131
+ * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-columns-can-be-the-rows-a-field-references
132
+ */
133
+ export function buildReferenceStages({
134
+ refs = [],
135
+ labelField = '',
136
+ orderField = '',
137
+ colorField = '',
138
+ mergeBy = '',
139
+ narrowBy = null,
140
+ narrowValue = '',
141
+ capacityField = '',
142
+ } = {}) {
143
+ const list = (Array.isArray(refs) ? refs : []).filter((ref) => ref && typeof ref === 'object' && refIdOf(ref) !== '')
144
+ const narrowed = narrowBy && narrowBy.field && narrowValue !== ''
145
+ ? list.filter((ref) => refIdOf(readPath(ref, narrowBy.field)) === String(narrowValue))
146
+ : list
147
+
148
+ const orderOf = (ref) => {
149
+ const n = Number(orderField ? readPath(ref, orderField) : NaN)
150
+ return Number.isFinite(n) ? n : Number.MAX_SAFE_INTEGER
151
+ }
152
+ const ordered = narrowed
153
+ .map((ref, index) => ({ ref, index }))
154
+ .sort((a, b) => (orderOf(a.ref) - orderOf(b.ref)) || (a.index - b.index))
155
+ .map((entry) => entry.ref)
156
+
157
+ const states = []
158
+ const keyByValue = new Map()
159
+ const refsByKey = new Map()
160
+ for (const ref of ordered) {
161
+ const id = refIdOf(ref)
162
+ const label = textOf(labelField ? readPath(ref, labelField) : (ref.name ?? ref.title)) || id
163
+ const key = mergeBy ? (textOf(readPath(ref, mergeBy)) || id) : id
164
+ keyByValue.set(id, key)
165
+ if (!refsByKey.has(key)) {
166
+ refsByKey.set(key, [])
167
+ const color = colorField ? readPath(ref, colorField) : ref.color
168
+ const state = { key, label, color: typeof color === 'string' ? color : '' }
169
+ if (capacityField) {
170
+ state.capacity = capacityOfRef(ref, capacityField)
171
+ }
172
+ states.push(state)
173
+ }
174
+ refsByKey.get(key).push(ref)
175
+ }
176
+ for (const state of states) {
177
+ if (capacityField && refsByKey.get(state.key).length > 1) {
178
+ state.capacity = null
179
+ }
180
+ }
181
+ return { states, keyByValue, refsByKey }
182
+ }
183
+
184
+ /**
185
+ * The limit one referenced row declares.
186
+ *
187
+ * @param {object} ref The referenced row.
188
+ * @param {string} capacityField The row field that holds the limit.
189
+ * @return {number|null} The limit, or null when it has none.
190
+ * @spec openspec/changes/board-column-capacity/specs/board-view/spec.md#requirement-a-column-can-carry-a-capacity
191
+ */
192
+ export function capacityOfRef(ref, capacityField) {
193
+ return capacityField ? capacityValue(readPath(ref, capacityField)) : null
194
+ }
195
+
196
+ /**
197
+ * Whether a drop fills a referenced row past its limit: the cards that
198
+ * already carry that row, counted against the row's own limit. Counted per
199
+ * row, not per column, so a column merged from several rows still refuses
200
+ * the one that is full.
201
+ *
202
+ * @param {object} options The call.
203
+ * @param {object} options.target The referenced row the drop would write.
204
+ * @param {object} options.card The card being moved.
205
+ * @param {Array<object>} options.rows The cards the board holds.
206
+ * @param {string} options.field The row field the columns come from.
207
+ * @param {string} options.capacityField The referenced row's limit field.
208
+ * @param {string} [options.rowKey] The row key, so the moving card is not counted.
209
+ * @return {{count: number, capacity: number}|null} The count and limit when full, else null.
210
+ * @spec openspec/changes/board-column-capacity/specs/board-view/spec.md#requirement-a-drop-into-a-full-column-is-refused
211
+ */
212
+ export function fullTargetOf({ target, card, rows = [], field, capacityField, rowKey = 'id' } = {}) {
213
+ const capacity = capacityOfRef(target, capacityField)
214
+ if (capacity === null) {
215
+ return null
216
+ }
217
+ const id = refIdOf(target)
218
+ const self = String(card?.[rowKey] ?? '')
219
+ const count = (Array.isArray(rows) ? rows : []).filter((row) => String(row?.[rowKey] ?? '') !== self && refIdOf(readPath(row, field)) === id).length
220
+ return count >= capacity ? { count, capacity } : null
221
+ }
222
+
223
+ /**
224
+ * The stages of a field with no referenced schema (a user id): the values
225
+ * present on the rows, by label, then one column for no value.
226
+ *
227
+ * @param {object} options The call.
228
+ * @param {Array<object>} options.rows The rows the list holds.
229
+ * @param {string} options.field The row field.
230
+ * @param {object} [options.valueLabels] Raw value to the label to show.
231
+ * @param {string} [options.emptyLabel] The no-value column's label.
232
+ * @return {{states: Array<{key: string, label: string, color: string}>, keyByValue: Map<string, string>, refsByKey: Map<string, Array<object>>}} The stages.
233
+ * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-a-field-without-a-referenced-schema-takes-its-values
234
+ */
235
+ export function buildValueStages({ rows = [], field = '', valueLabels = null, emptyLabel = 'Nobody' } = {}) {
236
+ const labels = valueLabels && typeof valueLabels === 'object' ? valueLabels : {}
237
+ const seen = new Map()
238
+ for (const row of Array.isArray(rows) ? rows : []) {
239
+ const raw = readPath(row, field)
240
+ const id = refIdOf(raw)
241
+ if (id !== '' && !seen.has(id)) {
242
+ seen.set(id, typeof labels[id] === 'string' ? labels[id] : (textOf(raw) || id))
243
+ }
244
+ }
245
+ const states = [...seen.entries()]
246
+ .sort((a, b) => a[1].localeCompare(b[1]))
247
+ .map(([key, label]) => ({ key, label, color: '' }))
248
+ states.push({ key: NO_VALUE_KEY, label: emptyLabel, color: '' })
249
+ const keyByValue = new Map(states.map((state) => [state.key, state.key]))
250
+ keyByValue.set('', NO_VALUE_KEY)
251
+ return { states, keyByValue, refsByKey: new Map() }
252
+ }
253
+
254
+ /**
255
+ * The column a row sits in, under a value-to-column map.
256
+ *
257
+ * @param {object} row The row.
258
+ * @param {string} field The row field.
259
+ * @param {Map<string, string>} keyByValue The value-to-column map.
260
+ * @return {string} The column key, or the raw value when the map has none
261
+ * (which lands the card in the off-board column).
262
+ */
263
+ export function columnKeyOfRow(row, field, keyByValue) {
264
+ const id = refIdOf(readPath(row, field))
265
+ return keyByValue.has(id) ? keyByValue.get(id) : id
266
+ }
267
+
268
+ /**
269
+ * What a drop on a column writes for one card: the referenced row of that
270
+ * column which belongs to the card's parent, or null when the column has none
271
+ * (the card cannot go there).
272
+ *
273
+ * @param {object} options The call.
274
+ * @param {object} options.card The card.
275
+ * @param {string} options.toKey The column it was dropped on.
276
+ * @param {string} options.kind `reference` or `values`.
277
+ * @param {Map<string, Array<object>>} [options.refsByKey] The column's rows.
278
+ * @param {{field: string, rowField: string}|null} [options.narrowBy] The parent link.
279
+ * @return {{value: (string|null), target: (object|null)}|null} The value to write and its row, or null.
280
+ * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-a-drop-writes-the-reference
281
+ */
282
+ export function resolveDropValue({ card, toKey, kind, refsByKey = new Map(), narrowBy = null } = {}) {
283
+ if (kind === 'values') {
284
+ return { value: toKey === NO_VALUE_KEY ? null : String(toKey), target: null }
285
+ }
286
+ const candidates = refsByKey.get(String(toKey)) || []
287
+ if (candidates.length === 0) {
288
+ return null
289
+ }
290
+ if (narrowBy && narrowBy.field && narrowBy.rowField) {
291
+ const parent = refIdOf(readPath(card, narrowBy.rowField))
292
+ const match = candidates.find((ref) => refIdOf(readPath(ref, narrowBy.field)) === parent)
293
+ return match ? { value: refIdOf(match), target: match } : null
294
+ }
295
+ return { value: refIdOf(candidates[0]), target: candidates[0] }
296
+ }
297
+
298
+ /**
299
+ * Fetch the rows a reference column is built from, one list request.
300
+ *
301
+ * @param {object} options The call.
302
+ * @param {string} options.register The register slug.
303
+ * @param {string} options.schema The schema slug.
304
+ * @param {object} [options.filter] Equality filters, e.g. `{ isFinal: false }`.
305
+ * @param {number} [options.limit] The page size, 500 by default.
306
+ * @return {Promise<Array<object>>} The rows.
307
+ * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-columns-can-be-the-rows-a-field-references
308
+ */
309
+ export async function fetchReferenceObjects({ register, schema, filter = {}, limit = 500 } = {}) {
310
+ if (!register || !schema) {
311
+ return []
312
+ }
313
+ const params = { _limit: limit }
314
+ for (const [key, value] of Object.entries(filter || {})) {
315
+ if (value !== undefined && value !== null && typeof value !== 'object') {
316
+ params[key] = typeof value === 'boolean' ? String(value) : value
317
+ }
318
+ }
319
+ const url = prefixUrl(`/apps/openregister/api/objects/${encodeURIComponent(register)}/${encodeURIComponent(schema)}${buildQueryString(params)}`)
320
+ const response = await fetch(url, { headers: buildHeaders() })
321
+ if (!response.ok) {
322
+ throw new Error(`list returned ${response.status}`)
323
+ }
324
+ const data = await response.json()
325
+ return Array.isArray(data?.results) ? data.results : (Array.isArray(data) ? data : [])
326
+ }
@@ -137,7 +137,10 @@ export function mergeMenuItems(target, incoming) {
137
137
  target.push(copy)
138
138
  return
139
139
  }
140
- for (const key of ['label', 'icon', 'route', 'order', 'section', 'featureFlag', 'permission', 'visibleIf', 'href', 'action']) {
140
+ // `query` and `params` belong to `route`: an entry that takes its route
141
+ // from here without them opens the list unfiltered (a "board" entry to
142
+ // `Cases` with `{ _view: 'board' }` opened the table).
143
+ for (const key of ['label', 'icon', 'route', 'query', 'params', 'order', 'section', 'featureFlag', 'permission', 'visibleIf', 'href', 'action']) {
141
144
  if (existing[key] === undefined && item[key] !== undefined) {
142
145
  existing[key] = item[key]
143
146
  }
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  import { schemaRefSlug } from './schemaRefSlug.js'
10
+ import { userLocale } from './userLocale.js'
10
11
 
11
12
  /**
12
13
  * Default column widths per property type/format.
@@ -159,7 +160,7 @@ export function formatValue(value, property = {}, options = {}) {
159
160
  if (Number.isNaN(num)) {
160
161
  return String(value)
161
162
  }
162
- return num.toLocaleString()
163
+ return num.toLocaleString(userLocale())
163
164
  }
164
165
 
165
166
  // Array
@@ -213,17 +214,17 @@ export function formatValue(value, property = {}, options = {}) {
213
214
  return str
214
215
  }
215
216
  if (format === 'date') {
216
- return date.toLocaleDateString(undefined, {
217
+ return date.toLocaleDateString(userLocale(), {
217
218
  day: '2-digit',
218
219
  month: '2-digit',
219
220
  year: 'numeric',
220
221
  })
221
222
  }
222
- return date.toLocaleDateString(undefined, {
223
+ return date.toLocaleDateString(userLocale(), {
223
224
  day: '2-digit',
224
225
  month: '2-digit',
225
226
  year: 'numeric',
226
- }) + ', ' + date.toLocaleTimeString(undefined, {
227
+ }) + ', ' + date.toLocaleTimeString(userLocale(), {
227
228
  hour: '2-digit',
228
229
  minute: '2-digit',
229
230
  second: '2-digit',
@@ -0,0 +1,26 @@
1
+ /**
2
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
3
+ * SPDX-License-Identifier: EUPL-1.2
4
+ */
5
+
6
+ import { getCanonicalLocale } from '@nextcloud/l10n'
7
+
8
+ /**
9
+ * The BCP 47 tag dates and numbers are written in: the locale the user chose
10
+ * in Nextcloud (`nl_NL` becomes `nl-NL`), not the browser's.
11
+ *
12
+ * `toLocaleDateString(undefined)` answers in the BROWSER's locale, so a Dutch
13
+ * instance opened in an English browser wrote 10/15/2026. Pass this instead.
14
+ *
15
+ * @return {string|undefined} The tag, or undefined for the runtime default
16
+ * when Nextcloud names none or Intl does not accept it.
17
+ * @spec openspec/changes/dates-in-the-users-locale/specs/data-display/spec.md#requirement-a-date-reads-in-the-users-nextcloud-locale
18
+ */
19
+ export function userLocale() {
20
+ try {
21
+ const tag = getCanonicalLocale()
22
+ return tag && Intl.DateTimeFormat.supportedLocalesOf([tag]).length > 0 ? tag : undefined
23
+ } catch {
24
+ return undefined
25
+ }
26
+ }