@conduction/nextcloud-vue 2.56.0-beta.37 → 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 (287) hide show
  1. package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue.js +1 -1
  2. package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue2.js +3 -2
  3. package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue2.js.map +1 -1
  4. package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue3.js.map +1 -1
  5. package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue.js +1 -1
  6. package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue2.js +5 -4
  7. package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue2.js.map +1 -1
  8. package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue3.js.map +1 -1
  9. package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue.js +1 -1
  10. package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue2.js +2 -1
  11. package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue2.js.map +1 -1
  12. package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue3.js.map +1 -1
  13. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue.js +1 -1
  14. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +2 -1
  15. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
  16. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
  17. package/dist/esm/components/CnBoardView/CnBoardView.vue.js +1 -1
  18. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +156 -14
  19. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
  20. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +105 -74
  21. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
  22. package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue.js +1 -1
  23. package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue2.js +2 -1
  24. package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue2.js.map +1 -1
  25. package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue3.js.map +1 -1
  26. package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue.js +1 -1
  27. package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue2.js +2 -1
  28. package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue2.js.map +1 -1
  29. package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue3.js.map +1 -1
  30. package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
  31. package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +6 -5
  32. package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
  33. package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
  34. package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue.js +1 -1
  35. package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue2.js +2 -1
  36. package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue2.js.map +1 -1
  37. package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue3.js.map +1 -1
  38. package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js +1 -1
  39. package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js +2 -1
  40. package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -1
  41. package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -1
  42. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue.js +1 -1
  43. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js +2 -1
  44. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js.map +1 -1
  45. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js.map +1 -1
  46. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  47. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +2 -1
  48. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  49. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  50. package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue.js +1 -1
  51. package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue2.js +3 -1
  52. package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue2.js.map +1 -1
  53. package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue3.js.map +1 -1
  54. package/dist/esm/components/CnDetailPage/CnDetailHeaderChips.vue2.js +2 -1
  55. package/dist/esm/components/CnDetailPage/CnDetailHeaderChips.vue2.js.map +1 -1
  56. package/dist/esm/components/CnDetailPage/CnDetailHeaderChips.vue3.js.map +1 -1
  57. package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue.js +1 -1
  58. package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue2.js +2 -1
  59. package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue2.js.map +1 -1
  60. package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue3.js.map +1 -1
  61. package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue.js +1 -1
  62. package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue2.js +3 -1
  63. package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue2.js.map +1 -1
  64. package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue3.js.map +1 -1
  65. package/dist/esm/components/CnFileManager/CnFileManager.vue.js +1 -1
  66. package/dist/esm/components/CnFileManager/CnFileManager.vue2.js +3 -1
  67. package/dist/esm/components/CnFileManager/CnFileManager.vue2.js.map +1 -1
  68. package/dist/esm/components/CnFileManager/CnFileManager.vue3.js.map +1 -1
  69. package/dist/esm/components/CnFilePreview/CnFilePreview.vue.js +1 -1
  70. package/dist/esm/components/CnFilePreview/CnFilePreview.vue2.js +2 -1
  71. package/dist/esm/components/CnFilePreview/CnFilePreview.vue2.js.map +1 -1
  72. package/dist/esm/components/CnFilePreview/CnFilePreview.vue3.js.map +1 -1
  73. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
  74. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +49 -1
  75. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  76. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +3 -3
  77. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  78. package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue.js +1 -1
  79. package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue2.js +2 -1
  80. package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue2.js.map +1 -1
  81. package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue3.js.map +1 -1
  82. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +28 -5
  83. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  84. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  85. package/dist/esm/components/CnNotesCard/CnNotesCard.vue.js +1 -1
  86. package/dist/esm/components/CnNotesCard/CnNotesCard.vue2.js +2 -1
  87. package/dist/esm/components/CnNotesCard/CnNotesCard.vue2.js.map +1 -1
  88. package/dist/esm/components/CnNotesCard/CnNotesCard.vue3.js.map +1 -1
  89. package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue.js +1 -1
  90. package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue2.js +3 -2
  91. package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue2.js.map +1 -1
  92. package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue3.js.map +1 -1
  93. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue.js +1 -1
  94. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +28 -0
  95. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
  96. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js +82 -75
  97. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
  98. package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue.js +1 -1
  99. package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue2.js +5 -4
  100. package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue2.js.map +1 -1
  101. package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue3.js.map +1 -1
  102. package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue.js +1 -1
  103. package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue2.js +2 -1
  104. package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue2.js.map +1 -1
  105. package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue3.js.map +1 -1
  106. package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue.js +1 -1
  107. package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue2.js +2 -1
  108. package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue2.js.map +1 -1
  109. package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue3.js.map +1 -1
  110. package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue.js +1 -1
  111. package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js +2 -1
  112. package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js.map +1 -1
  113. package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue3.js.map +1 -1
  114. package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue.js +1 -1
  115. package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue2.js +2 -1
  116. package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue2.js.map +1 -1
  117. package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue3.js.map +1 -1
  118. package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue.js +1 -1
  119. package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue2.js +2 -1
  120. package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue2.js.map +1 -1
  121. package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue3.js.map +1 -1
  122. package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue.js +1 -1
  123. package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue2.js +2 -1
  124. package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue2.js.map +1 -1
  125. package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue3.js.map +1 -1
  126. package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue2.js +2 -0
  127. package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue2.js.map +1 -1
  128. package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue3.js +2 -2
  129. package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue3.js.map +1 -1
  130. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue.js +1 -1
  131. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue2.js +2 -1
  132. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue2.js.map +1 -1
  133. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue3.js.map +1 -1
  134. package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue.js +1 -1
  135. package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue2.js +2 -1
  136. package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue2.js.map +1 -1
  137. package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue3.js.map +1 -1
  138. package/dist/esm/components/CnTasksCard/CnTasksCard.vue.js +1 -1
  139. package/dist/esm/components/CnTasksCard/CnTasksCard.vue2.js +2 -1
  140. package/dist/esm/components/CnTasksCard/CnTasksCard.vue2.js.map +1 -1
  141. package/dist/esm/components/CnTasksCard/CnTasksCard.vue3.js.map +1 -1
  142. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +1 -1
  143. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +2 -1
  144. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -1
  145. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -1
  146. package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue.js +1 -1
  147. package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue2.js +2 -1
  148. package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue2.js.map +1 -1
  149. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue.js +1 -1
  150. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue2.js +2 -1
  151. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue2.js.map +1 -1
  152. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue3.js.map +1 -1
  153. package/dist/esm/dialogs/CnNoteHistoryDialog.vue.js +1 -1
  154. package/dist/esm/dialogs/CnNoteHistoryDialog.vue2.js +2 -1
  155. package/dist/esm/dialogs/CnNoteHistoryDialog.vue2.js.map +1 -1
  156. package/dist/esm/dialogs/CnNoteHistoryDialog.vue3.js.map +1 -1
  157. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue.js +1 -1
  158. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue2.js +3 -2
  159. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue2.js.map +1 -1
  160. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue3.js.map +1 -1
  161. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue.js +1 -1
  162. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue2.js +4 -3
  163. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue2.js.map +1 -1
  164. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue3.js.map +1 -1
  165. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue.js +1 -1
  166. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -2
  167. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
  168. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
  169. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue.js +1 -1
  170. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js +2 -1
  171. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js.map +1 -1
  172. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue3.js.map +1 -1
  173. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue.js +1 -1
  174. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue2.js +6 -5
  175. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue2.js.map +1 -1
  176. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue3.js.map +1 -1
  177. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue.js +1 -1
  178. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue2.js +2 -1
  179. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue2.js.map +1 -1
  180. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue3.js.map +1 -1
  181. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue.js +1 -1
  182. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js +2 -1
  183. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js.map +1 -1
  184. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js.map +1 -1
  185. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue.js +1 -1
  186. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +2 -1
  187. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
  188. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
  189. package/dist/esm/integrations/builtin/email/CnEmailCard.vue.js +1 -1
  190. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js +2 -1
  191. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js.map +1 -1
  192. package/dist/esm/integrations/builtin/email/CnEmailCard.vue3.js.map +1 -1
  193. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue.js +1 -1
  194. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js +2 -1
  195. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js.map +1 -1
  196. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js.map +1 -1
  197. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue.js +1 -1
  198. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue2.js +2 -1
  199. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue2.js.map +1 -1
  200. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue3.js.map +1 -1
  201. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue.js +1 -1
  202. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js +2 -1
  203. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js.map +1 -1
  204. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js.map +1 -1
  205. package/dist/esm/l10n/en.json.js +35 -2
  206. package/dist/esm/l10n/en.json.js.map +1 -1
  207. package/dist/esm/l10n/nl.json.js +38 -2
  208. package/dist/esm/l10n/nl.json.js.map +1 -1
  209. package/dist/esm/library-style.js +1 -1
  210. package/dist/esm/nextcloud-vue.css +994 -909
  211. package/dist/esm/store/useObjectStore.js +7 -2
  212. package/dist/esm/store/useObjectStore.js.map +1 -1
  213. package/dist/esm/utils/boardColumns.js +50 -1
  214. package/dist/esm/utils/boardColumns.js.map +1 -1
  215. package/dist/esm/utils/boardReferenceColumns.js +55 -3
  216. package/dist/esm/utils/boardReferenceColumns.js.map +1 -1
  217. package/dist/esm/utils/schema.js +5 -4
  218. package/dist/esm/utils/schema.js.map +1 -1
  219. package/dist/esm/utils/userLocale.js +30 -0
  220. package/dist/esm/utils/userLocale.js.map +1 -0
  221. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  222. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  223. package/dist/nextcloud-vue.cjs.js +837 -359
  224. package/dist/nextcloud-vue.cjs.js.map +2 -2
  225. package/dist/nextcloud-vue.css +994 -909
  226. package/l10n/en.json +35 -2
  227. package/l10n/nl.json +38 -2
  228. package/package.json +1 -1
  229. package/src/components/CnAdvancedFormDialog/CnMetadataTab.vue +3 -2
  230. package/src/components/CnAdvancedFormDialog/CnPropertyValueCell.vue +5 -4
  231. package/src/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue +2 -1
  232. package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +2 -1
  233. package/src/components/CnBoardView/CnBoardView.vue +189 -24
  234. package/src/components/CnCalendarEventPicker/CnCalendarEventPicker.vue +2 -1
  235. package/src/components/CnCalendarWidget/CnCalendarWidget.vue +2 -1
  236. package/src/components/CnChartWidget/CnChartWidget.vue +6 -5
  237. package/src/components/CnCollectivePagePicker/CnCollectivePagePicker.vue +2 -1
  238. package/src/components/CnConversationThread/CnConversationThread.vue +2 -1
  239. package/src/components/CnCountdownWidget/CnCountdownWidget.vue +2 -1
  240. package/src/components/CnDashboardPage/CnDashboardPage.vue +2 -1
  241. package/src/components/CnDataMatrix/CnDataMatrix.vue +2 -1
  242. package/src/components/CnDetailPage/CnDetailHeaderChips.vue +2 -1
  243. package/src/components/CnEmailPicker/CnEmailPicker.vue +2 -1
  244. package/src/components/CnFederationStatus/CnFederationStatus.vue +3 -1
  245. package/src/components/CnFileManager/CnFileManager.vue +2 -1
  246. package/src/components/CnFilePreview/CnFilePreview.vue +2 -1
  247. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +54 -6
  248. package/src/components/CnFollowToggle/CnFollowToggle.vue +2 -1
  249. package/src/components/CnIndexPage/CnIndexPage.vue +28 -4
  250. package/src/components/CnNotesCard/CnNotesCard.vue +2 -1
  251. package/src/components/CnObjectCalendar/CnObjectCalendar.vue +3 -2
  252. package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +36 -0
  253. package/src/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue +5 -4
  254. package/src/components/CnObjectSidebar/CnAuditTrailTab.vue +2 -1
  255. package/src/components/CnObjectSidebar/CnFlowTasksPanel.vue +2 -1
  256. package/src/components/CnObjectSidebar/CnNotesTab.vue +2 -1
  257. package/src/components/CnObjectSidebar/CnTasksTab.vue +2 -1
  258. package/src/components/CnPropertySourceField/CnPropertySourceField.vue +2 -1
  259. package/src/components/CnRoadmapItem/CnRoadmapItem.vue +2 -1
  260. package/src/components/CnSchemaFormDialog/CnSchemaFormDialog.vue +4 -2
  261. package/src/components/CnStatsBlock/CnStatsBlock.vue +2 -1
  262. package/src/components/CnSummaryAggregates/CnSummaryAggregates.vue +2 -1
  263. package/src/components/CnTasksCard/CnTasksCard.vue +2 -1
  264. package/src/components/CnTimelineWidget/CnTimelineWidget.vue +2 -1
  265. package/src/components/CnTranslatedBadge/CnTranslatedBadge.vue +2 -1
  266. package/src/components/CnVersionHistory/CnVersionHistory.vue +2 -1
  267. package/src/css/board.css +40 -0
  268. package/src/dialogs/CnNoteHistoryDialog.vue +2 -1
  269. package/src/integrations/builtin/activity/CnActivityCard.vue +3 -2
  270. package/src/integrations/builtin/activity/CnActivityTab.vue +4 -3
  271. package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +3 -2
  272. package/src/integrations/builtin/calendar/CnCalendarCard.vue +2 -1
  273. package/src/integrations/builtin/calendar/CnCalendarTab.vue +6 -5
  274. package/src/integrations/builtin/contactmoment/CnContactmomentCard.vue +2 -1
  275. package/src/integrations/builtin/cospend/CnCospendTab.vue +2 -1
  276. package/src/integrations/builtin/deck/CnDeckTab.vue +2 -1
  277. package/src/integrations/builtin/email/CnEmailCard.vue +2 -1
  278. package/src/integrations/builtin/field-inspection/CnFieldInspectionCard.vue +2 -1
  279. package/src/integrations/builtin/field-inspection/CnFieldInspectionTab.vue +2 -1
  280. package/src/integrations/builtin/photos/CnPhotosTab.vue +2 -1
  281. package/src/schemas/app-manifest-v2.schema.json +2 -1
  282. package/src/store/useObjectStore.js +7 -2
  283. package/src/utils/boardColumns.js +49 -0
  284. package/src/utils/boardReferenceColumns.js +54 -2
  285. package/src/utils/schema.js +5 -4
  286. package/src/utils/userLocale.js +26 -0
  287. package/src/utils/validateManifestV2.compiled.js +2 -2
@@ -88,6 +88,7 @@
88
88
  import { translate as t } from '@nextcloud/l10n'
89
89
  import { NcLoadingIcon } from '@nextcloud/vue'
90
90
  import { normalizeLook } from '../../composables/useLook.js'
91
+ import { userLocale } from '../../utils/userLocale.js'
91
92
 
92
93
  // The canonical KPI look, shared with CnStatWidget. Imported here so the
93
94
  // card is styled even when the consuming app has not pulled in the
@@ -372,7 +373,7 @@ export default {
372
373
  },
373
374
 
374
375
  formattedCount() {
375
- return this.count.toLocaleString()
376
+ return this.count.toLocaleString(userLocale())
376
377
  },
377
378
 
378
379
  /**
@@ -21,6 +21,7 @@
21
21
  <script>
22
22
  import { NcLoadingIcon } from '@nextcloud/vue'
23
23
  import { fetchAggregateValue } from '../../utils/fetchAggregate.js'
24
+ import { userLocale } from '../../utils/userLocale.js'
24
25
 
25
26
  /**
26
27
  * CnSummaryAggregates — declarative count/sum/avg stat chips for a
@@ -150,7 +151,7 @@ export default {
150
151
  return new Intl.NumberFormat(undefined, { style: 'currency', currency: 'EUR' }).format(num)
151
152
  }
152
153
  if (typeof raw === 'number') {
153
- return raw.toLocaleString()
154
+ return raw.toLocaleString(userLocale())
154
155
  }
155
156
  return raw
156
157
  },
@@ -97,6 +97,7 @@ import ProgressClock from 'vue-material-design-icons/ProgressClock.vue'
97
97
  import CnDetailCard from '../CnDetailCard/CnDetailCard.vue'
98
98
  import CnUserActionMenu from '../CnUserActionMenu/CnUserActionMenu.vue'
99
99
  import { buildHeaders, prefixUrl } from '../../utils/index.js'
100
+ import { userLocale } from '../../utils/userLocale.js'
100
101
 
101
102
  /**
102
103
  * CnTasksCard — Inline tasks widget for detail pages.
@@ -261,7 +262,7 @@ export default {
261
262
  return ''
262
263
  }
263
264
  try {
264
- return new Date(dateStr).toLocaleDateString(undefined, {
265
+ return new Date(dateStr).toLocaleDateString(userLocale(), {
265
266
  year: 'numeric',
266
267
  month: 'short',
267
268
  day: 'numeric',
@@ -54,6 +54,7 @@
54
54
  import { getLanguage, translate as t } from '@nextcloud/l10n'
55
55
  import { NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'
56
56
  import { auditEvents, fieldEvents, listEvents, relatedEvents, sortEvents, timelineEntryEvents } from '../../utils/timelineEvents.js'
57
+ import { userLocale } from '../../utils/userLocale.js'
57
58
 
58
59
  /**
59
60
  * CnTimelineWidget — an object's dated events in time order (`timeline`
@@ -296,7 +297,7 @@ export default {
296
297
  try {
297
298
  return new Intl.DateTimeFormat(locale, options).format(event.at)
298
299
  } catch {
299
- return event.at.toLocaleString()
300
+ return event.at.toLocaleString(userLocale())
300
301
  }
301
302
  },
302
303
 
@@ -28,6 +28,7 @@
28
28
 
29
29
  <script>
30
30
  import { translate as t } from '@nextcloud/l10n'
31
+ import { userLocale } from '../../utils/userLocale.js'
31
32
 
32
33
  /**
33
34
  * CnTranslatedBadge — surfaces OR's `_translationMeta.translatedFrom`
@@ -173,7 +174,7 @@ export default {
173
174
  try {
174
175
  const d = new Date(this.translatedAt)
175
176
  if (!Number.isNaN(d.getTime())) {
176
- return t('nextcloud-vue', 'Translated at {when}', { when: d.toLocaleString() })
177
+ return t('nextcloud-vue', 'Translated at {when}', { when: d.toLocaleString(userLocale()) })
177
178
  }
178
179
  } catch {
179
180
  // fall through to raw ISO
@@ -132,6 +132,7 @@ import CnDetailCard from '../CnDetailCard/CnDetailCard.vue'
132
132
  import { foldAuditTrailEntries } from '../../utils/auditTrailDiff.js'
133
133
  import { computeObjectDiff } from '../../utils/computeObjectDiff.js'
134
134
  import { buildHeaders } from '../../utils/index.js'
135
+ import { userLocale } from '../../utils/userLocale.js'
135
136
 
136
137
  /**
137
138
  * A single row rendered in the top-level diff table.
@@ -472,7 +473,7 @@ export default {
472
473
  if (Number.isNaN(d.getTime()) === true) {
473
474
  return String(raw)
474
475
  }
475
- return d.toLocaleString()
476
+ return d.toLocaleString(userLocale())
476
477
  },
477
478
  },
478
479
  }
package/src/css/board.css CHANGED
@@ -61,6 +61,12 @@
61
61
  font-weight: 400;
62
62
  }
63
63
 
64
+ /* A column at its limit: the count in the error colour; "full" is said in words too. */
65
+ .cn-board-view.cn-board-view--board .cn-board-view__badge.cn-board-view__badge--full {
66
+ color: var(--color-error-text, var(--color-error));
67
+ font-weight: 600;
68
+ }
69
+
64
70
  .cn-board-view.cn-board-view--board .cn-board-view__sum {
65
71
  font-size: 13px;
66
72
  color: var(--color-text-maxcontrast);
@@ -328,3 +334,37 @@
328
334
  font-size: 12px;
329
335
  color: var(--color-text-maxcontrast);
330
336
  }
337
+
338
+ /* A blocked target with the host's reason: the reason on its own line under the name. */
339
+ .cn-board-view.cn-board-view--board .cn-board-view__menu-item.cn-board-view__menu-item--reason {
340
+ flex-wrap: wrap;
341
+ max-width: 320px;
342
+ padding-block: 6px;
343
+ }
344
+
345
+ .cn-board-view .cn-board-view__menu-reason {
346
+ flex-basis: 100%;
347
+ font-size: 12px;
348
+ line-height: 1.4;
349
+ color: var(--color-text-maxcontrast);
350
+ }
351
+
352
+ /* While a card is dragged: why it cannot land in this column, under the header.
353
+ The rest of the column fades; the reason stays at full contrast. */
354
+ .cn-board-view .cn-board-view__column-reason {
355
+ margin: 0 0 8px;
356
+ padding: 6px 8px;
357
+ border-radius: var(--border-radius);
358
+ background-color: var(--color-main-background);
359
+ font-size: 12px;
360
+ line-height: 1.4;
361
+ color: var(--color-main-text);
362
+ }
363
+
364
+ .cn-board-view .cn-board-view__column--unreachable.cn-board-view__column--reason {
365
+ opacity: 1;
366
+ }
367
+
368
+ .cn-board-view .cn-board-view__column--reason > :not(.cn-board-view__column-reason) {
369
+ opacity: 0.45;
370
+ }
@@ -78,6 +78,7 @@ import HistoryIcon from 'vue-material-design-icons/History.vue'
78
78
  import CnDialog from '../components/CnDialog/CnDialog.vue'
79
79
  import { dialogBoardMixin } from '../mixins/dialogBoard.js'
80
80
  import { buildHeaders, prefixUrl } from '../utils/index.js'
81
+ import { userLocale } from '../utils/userLocale.js'
81
82
 
82
83
  export default {
83
84
  name: 'CnNoteHistoryDialog',
@@ -193,7 +194,7 @@ export default {
193
194
  return ''
194
195
  }
195
196
  try {
196
- return new Date(dateStr).toLocaleString(undefined, {
197
+ return new Date(dateStr).toLocaleString(userLocale(), {
197
198
  year: 'numeric',
198
199
  month: 'short',
199
200
  day: 'numeric',
@@ -112,6 +112,7 @@ import Timeline from 'vue-material-design-icons/Timeline.vue'
112
112
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
113
113
  import CnVisibilityChip from '../../../components/CnVisibilityChip/CnVisibilityChip.vue'
114
114
  import { buildHeaders, prefixUrl } from '../../../utils/index.js'
115
+ import { userLocale } from '../../../utils/userLocale.js'
115
116
 
116
117
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
117
118
  const COMPACT_LIMIT = 4
@@ -297,7 +298,7 @@ export default {
297
298
  return t('nextcloud-vue', 'Yesterday')
298
299
  }
299
300
  try {
300
- return date.toLocaleDateString(undefined, { weekday: 'short', day: 'numeric', month: 'short' })
301
+ return date.toLocaleDateString(userLocale(), { weekday: 'short', day: 'numeric', month: 'short' })
301
302
  } catch {
302
303
  return date.toISOString().split('T')[0]
303
304
  }
@@ -309,7 +310,7 @@ export default {
309
310
  return ''
310
311
  }
311
312
  try {
312
- return ts.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })
313
+ return ts.toLocaleTimeString(userLocale(), { hour: '2-digit', minute: '2-digit' })
313
314
  } catch {
314
315
  return ts.toISOString().split('T')[1].slice(0, 5)
315
316
  }
@@ -319,6 +319,7 @@ import Timeline from 'vue-material-design-icons/Timeline.vue'
319
319
  import CnVisibilityChip from '../../../components/CnVisibilityChip/CnVisibilityChip.vue'
320
320
  import { normalizeLook } from '../../../composables/useLook.js'
321
321
  import { buildHeaders, prefixUrl } from '../../../utils/index.js'
322
+ import { userLocale } from '../../../utils/userLocale.js'
322
323
  import { ACTIVITY_FEED_KINDS, exportBody, feedPath, feedQuery, isReadRow, parseFeed } from './activityFeedWire.js'
323
324
 
324
325
  const DEFAULT_PAGE_SIZE = 25
@@ -643,7 +644,7 @@ export default {
643
644
  return t('nextcloud-vue', 'Yesterday')
644
645
  }
645
646
  try {
646
- return date.toLocaleDateString(undefined, { weekday: 'short', day: 'numeric', month: 'short' })
647
+ return date.toLocaleDateString(userLocale(), { weekday: 'short', day: 'numeric', month: 'short' })
647
648
  } catch {
648
649
  return date.toISOString().split('T')[0]
649
650
  }
@@ -655,7 +656,7 @@ export default {
655
656
  return ''
656
657
  }
657
658
  try {
658
- return ts.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })
659
+ return ts.toLocaleTimeString(userLocale(), { hour: '2-digit', minute: '2-digit' })
659
660
  } catch {
660
661
  return ts.toISOString().split('T')[1].slice(0, 5)
661
662
  }
@@ -703,7 +704,7 @@ export default {
703
704
  let when = ''
704
705
  if (ts !== null) {
705
706
  try {
706
- when = ts.toLocaleString(undefined, { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })
707
+ when = ts.toLocaleString(userLocale(), { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })
707
708
  } catch {
708
709
  when = ts.toISOString().replace('T', ' ').slice(0, 16)
709
710
  }
@@ -177,6 +177,7 @@ import CnAnalyticsReportCreate from '../../../components/CnAnalyticsReportCreate
177
177
  import CnAnalyticsReportPicker from '../../../components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue'
178
178
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
179
179
  import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
180
+ import { userLocale } from '../../../utils/userLocale.js'
180
181
 
181
182
  /**
182
183
  * CnAnalyticsTab — bespoke dataset list for the `analytics` integration.
@@ -394,7 +395,7 @@ export default {
394
395
  const num = Number(raw)
395
396
  if (Number.isFinite(num) && String(raw).trim() !== '') {
396
397
  try {
397
- return num.toLocaleString()
398
+ return num.toLocaleString(userLocale())
398
399
  } catch {
399
400
  return String(num)
400
401
  }
@@ -436,7 +437,7 @@ export default {
436
437
  if (Number.isNaN(d.getTime())) {
437
438
  return String(value)
438
439
  }
439
- return d.toLocaleDateString(undefined, { dateStyle: 'medium' })
440
+ return d.toLocaleDateString(userLocale(), { dateStyle: 'medium' })
440
441
  } catch {
441
442
  return String(value)
442
443
  }
@@ -107,6 +107,7 @@ import CalendarCheck from 'vue-material-design-icons/CalendarCheck.vue'
107
107
  import CalendarClock from 'vue-material-design-icons/CalendarClock.vue'
108
108
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
109
109
  import { buildHeaders, prefixUrl } from '../../../utils/index.js'
110
+ import { userLocale } from '../../../utils/userLocale.js'
110
111
 
111
112
  /**
112
113
  * CnCalendarCard — surface-aware compact widget for the calendar
@@ -323,7 +324,7 @@ export default {
323
324
  const opts = this.surface === 'single-entity'
324
325
  ? { dateStyle: 'medium' }
325
326
  : { dateStyle: 'medium', timeStyle: 'short' }
326
- return d.toLocaleString(undefined, opts)
327
+ return d.toLocaleString(userLocale(), opts)
327
328
  } catch {
328
329
  return String(value)
329
330
  }
@@ -240,6 +240,7 @@ import CnCalendarEventCreate from '../../../components/CnCalendarEventCreate/CnC
240
240
  import CnCalendarEventPicker from '../../../components/CnCalendarEventPicker/CnCalendarEventPicker.vue'
241
241
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
242
242
  import { buildHeaders, prefixUrl } from '../../../utils/index.js'
243
+ import { userLocale } from '../../../utils/userLocale.js'
243
244
 
244
245
  const MAX_AVATARS = 3
245
246
 
@@ -524,7 +525,7 @@ export default {
524
525
  if (!d) {
525
526
  return '—'
526
527
  }
527
- return d.toLocaleDateString(undefined, { month: 'short' })
528
+ return d.toLocaleDateString(userLocale(), { month: 'short' })
528
529
  },
529
530
 
530
531
  dayOf(ev) {
@@ -541,16 +542,16 @@ export default {
541
542
  return ev.dtstart ? String(ev.dtstart) : t('nextcloud-vue', 'Time not set')
542
543
  }
543
544
  const end = this.parseDate(ev.dtend)
544
- const dateLabel = start.toLocaleDateString(undefined, { weekday: 'short', day: 'numeric', month: 'short' })
545
+ const dateLabel = start.toLocaleDateString(userLocale(), { weekday: 'short', day: 'numeric', month: 'short' })
545
546
  const timeOpts = { hour: '2-digit', minute: '2-digit' }
546
- const startTime = start.toLocaleTimeString(undefined, timeOpts)
547
+ const startTime = start.toLocaleTimeString(userLocale(), timeOpts)
547
548
  if (end) {
548
549
  const sameDay = start.toDateString() === end.toDateString()
549
- const endTime = end.toLocaleTimeString(undefined, timeOpts)
550
+ const endTime = end.toLocaleTimeString(userLocale(), timeOpts)
550
551
  if (sameDay) {
551
552
  return `${dateLabel} · ${startTime} – ${endTime}`
552
553
  }
553
- const endDateLabel = end.toLocaleDateString(undefined, { day: 'numeric', month: 'short' })
554
+ const endDateLabel = end.toLocaleDateString(userLocale(), { day: 'numeric', month: 'short' })
554
555
  return `${dateLabel} ${startTime} – ${endDateLabel} ${endTime}`
555
556
  }
556
557
  return `${dateLabel} · ${startTime}`
@@ -61,6 +61,7 @@ import { NcLoadingIcon } from '@nextcloud/vue'
61
61
  import PhoneOutline from 'vue-material-design-icons/PhoneOutline.vue'
62
62
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
63
63
  import { prefixUrl } from '../../../utils/index.js'
64
+ import { userLocale } from '../../../utils/userLocale.js'
64
65
 
65
66
  export default {
66
67
  name: 'CnContactmomentCard',
@@ -182,7 +183,7 @@ export default {
182
183
  */
183
184
  formatWhen(value) {
184
185
  const d = new Date(value)
185
- return isNaN(d.getTime()) ? value : d.toLocaleString()
186
+ return isNaN(d.getTime()) ? value : d.toLocaleString(userLocale())
186
187
  },
187
188
  },
188
189
  }
@@ -175,6 +175,7 @@ import CnCospendCreate from '../../../components/CnCospendCreate/CnCospendCreate
175
175
  import CnCospendPicker from '../../../components/CnCospendPicker/CnCospendPicker.vue'
176
176
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
177
177
  import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
178
+ import { userLocale } from '../../../utils/userLocale.js'
178
179
 
179
180
  /**
180
181
  * CnCospendTab — bespoke sidebar tab for the `cospend` integration.
@@ -495,7 +496,7 @@ export default {
495
496
  if (Number.isNaN(date.getTime())) {
496
497
  return ''
497
498
  }
498
- return date.toLocaleDateString(undefined, { dateStyle: 'medium' })
499
+ return date.toLocaleDateString(userLocale(), { dateStyle: 'medium' })
499
500
  },
500
501
 
501
502
  /**
@@ -168,6 +168,7 @@ import CnDeckCardCreate from '../../../components/CnDeckCardCreate/CnDeckCardCre
168
168
  import CnDeckCardPicker from '../../../components/CnDeckCardPicker/CnDeckCardPicker.vue'
169
169
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
170
170
  import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
171
+ import { userLocale } from '../../../utils/userLocale.js'
171
172
 
172
173
  /** Maximum assignee avatars shown before collapsing the rest into a +N overflow badge. */
173
174
  const MAX_VISIBLE_ASSIGNEES = 3
@@ -427,7 +428,7 @@ export default {
427
428
  if (Number.isNaN(date.getTime())) {
428
429
  return ''
429
430
  }
430
- return date.toLocaleDateString(undefined, { dateStyle: 'medium' })
431
+ return date.toLocaleDateString(userLocale(), { dateStyle: 'medium' })
431
432
  },
432
433
 
433
434
  /**
@@ -68,6 +68,7 @@ import { markRaw } from 'vue'
68
68
  import Email from 'vue-material-design-icons/Email.vue'
69
69
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
70
70
  import { buildHeaders, prefixUrl } from '../../../utils/index.js'
71
+ import { userLocale } from '../../../utils/userLocale.js'
71
72
 
72
73
  /**
73
74
  * CnEmailCard — compact widget for the `email` integration leaf.
@@ -279,7 +280,7 @@ export default {
279
280
  if (Number.isNaN(d.getTime()) === true) {
280
281
  return String(raw)
281
282
  }
282
- return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })
283
+ return d.toLocaleDateString(userLocale(), { year: 'numeric', month: 'short', day: 'numeric' })
283
284
  },
284
285
 
285
286
  // Thread deep-link into NC Mail; undefined when the row lacks ids.
@@ -164,6 +164,7 @@ import { NcButton, NcEmptyContent, NcLoadingIcon } from '@nextcloud/vue'
164
164
  import ClipboardCheckOutline from 'vue-material-design-icons/ClipboardCheckOutline.vue'
165
165
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
166
166
  import CnOfflineQueue from '../../../components/CnOfflineQueue/index.js'
167
+ import { userLocale } from '../../../utils/userLocale.js'
167
168
  import { buildChecklistSubmission } from '../../offline/checklistSubmission.js'
168
169
  import { checklistProgress, classifyGps, normaliseChecklistTemplate, syncIndicator, validateChecklistAnswers } from '../../offline/fieldCollectionHelpers.js'
169
170
  import {
@@ -379,7 +380,7 @@ export default {
379
380
  if (!iso) {
380
381
  return ''
381
382
  }
382
- return new Date(iso).toLocaleString()
383
+ return new Date(iso).toLocaleString(userLocale())
383
384
  },
384
385
 
385
386
  errorFor(questionId) {
@@ -86,6 +86,7 @@ import { NcButton, NcLoadingIcon } from '@nextcloud/vue'
86
86
  import ClipboardCheckOutline from 'vue-material-design-icons/ClipboardCheckOutline.vue'
87
87
  import Sync from 'vue-material-design-icons/Sync.vue'
88
88
  import CnOfflineQueue from '../../../components/CnOfflineQueue/index.js'
89
+ import { userLocale } from '../../../utils/userLocale.js'
89
90
  import { syncIndicator } from '../../offline/fieldCollectionHelpers.js'
90
91
  import {
91
92
  countPending,
@@ -186,7 +187,7 @@ export default {
186
187
  return ''
187
188
  }
188
189
  const moment = new Date(syncedAt)
189
- return Number.isNaN(moment.getTime()) ? '' : moment.toLocaleString()
190
+ return Number.isNaN(moment.getTime()) ? '' : moment.toLocaleString(userLocale())
190
191
  },
191
192
 
192
193
  /**
@@ -154,6 +154,7 @@ import Plus from 'vue-material-design-icons/Plus.vue'
154
154
  import CnPhotoAlbumCreate from '../../../components/CnPhotoAlbumCreate/CnPhotoAlbumCreate.vue'
155
155
  import CnPhotoAlbumPicker from '../../../components/CnPhotoAlbumPicker/CnPhotoAlbumPicker.vue'
156
156
  import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
157
+ import { userLocale } from '../../../utils/userLocale.js'
157
158
 
158
159
  /**
159
160
  * CnPhotosTab — bespoke album grid for the `photos` integration.
@@ -317,7 +318,7 @@ export default {
317
318
  if (Number.isNaN(d.getTime())) {
318
319
  return String(value)
319
320
  }
320
- return d.toLocaleDateString(undefined, { dateStyle: 'medium' })
321
+ return d.toLocaleDateString(userLocale(), { dateStyle: 'medium' })
321
322
  } catch {
322
323
  return String(value)
323
324
  }
@@ -3,7 +3,7 @@
3
3
  "$id": "https://raw.githubusercontent.com/ConductionNL/nextcloud-vue/main/src/schemas/app-manifest-v2.schema.json",
4
4
  "title": "Conduction App Manifest v2",
5
5
  "description": "v2 schema for the JSON-driven page and navigation manifest consumed by @conduction/nextcloud-vue. Introduces a uniform widgets[] array on every page type with a per-slot grid coordinate system, a typed actions[] discriminator, and the required $schema field for version detection. v1 manifests continue to validate against app-manifest.schema.json (unchanged).",
6
- "version": "2.99.0",
6
+ "version": "2.100.0",
7
7
  "type": "object",
8
8
  "required": ["$schema", "version"],
9
9
  "allOf": [
@@ -1176,6 +1176,7 @@
1176
1176
  "orderField": { "type": "string", "description": "The referenced row's numeric field the columns are ordered by." },
1177
1177
  "colorField": { "type": "string", "description": "The referenced row's field that holds the column's dot colour (a badge variant or a CSS colour)." },
1178
1178
  "filter": { "type": "object", "description": "Equality filters on the referenced rows, e.g. `{ \"isFinal\": false }` to leave out end states.", "additionalProperties": { "type": ["string", "number", "boolean"] } },
1179
+ "capacityField": { "type": "string", "minLength": 1, "description": "board-column-capacity (2.100.0): the referenced row's numeric field that holds the column's limit. The header reads \"count / capacity\" and turns full at the limit, and a move into a full row is refused before it is written (the server still guards). A column merged from several rows shows no limit, but each row's own limit still refuses a move into it. A row without a number above 0 has no limit." },
1179
1180
  "mergeBy": { "type": "string", "description": "Merge referenced rows with the same value of this field into one column (statuses of every case type by `name`). A drop then writes the row of the card's own parent (`narrowBy`), and is refused when that parent has none." },
1180
1181
  "narrowBy": {
1181
1182
  "type": "object",
@@ -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
 
@@ -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.
@@ -154,6 +170,7 @@ export function buildBoardColumns({
154
170
  key: stage.key,
155
171
  label: stage.label,
156
172
  color: stage.color,
173
+ capacity: stage.capacity ?? null,
157
174
  cards: [],
158
175
  count: 0,
159
176
  }))
@@ -177,3 +194,35 @@ export function buildBoardColumns({
177
194
 
178
195
  return { columns, usable: true }
179
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
+ }
@@ -27,6 +27,7 @@
27
27
  * Pure apart from `fetchReferenceObjects`: no store, no Vue.
28
28
  */
29
29
 
30
+ import { capacityValue } from './boardColumns.js'
30
31
  import { buildHeaders, buildQueryString, prefixUrl } from './headers.js'
31
32
  import { readPath } from './readPath.js'
32
33
  import { schemaRefSlug } from './schemaRefSlug.js'
@@ -124,7 +125,9 @@ export function referenceTargetOf(source, { register = '', property = null } = {
124
125
  * @param {string} [options.mergeBy] The row field whose equal values make one column.
125
126
  * @param {{field: string, rowField: string}|null} [options.narrowBy] The parent link.
126
127
  * @param {string} [options.narrowValue] The parent the board is narrowed to, '' for all.
127
- * @return {{states: Array<{key: string, label: string, color: string}>, keyByValue: Map<string, string>, refsByKey: Map<string, Array<object>>}} The stages.
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.
128
131
  * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-columns-can-be-the-rows-a-field-references
129
132
  */
130
133
  export function buildReferenceStages({
@@ -135,6 +138,7 @@ export function buildReferenceStages({
135
138
  mergeBy = '',
136
139
  narrowBy = null,
137
140
  narrowValue = '',
141
+ capacityField = '',
138
142
  } = {}) {
139
143
  const list = (Array.isArray(refs) ? refs : []).filter((ref) => ref && typeof ref === 'object' && refIdOf(ref) !== '')
140
144
  const narrowed = narrowBy && narrowBy.field && narrowValue !== ''
@@ -161,13 +165,61 @@ export function buildReferenceStages({
161
165
  if (!refsByKey.has(key)) {
162
166
  refsByKey.set(key, [])
163
167
  const color = colorField ? readPath(ref, colorField) : ref.color
164
- states.push({ key, label, color: typeof color === 'string' ? 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)
165
173
  }
166
174
  refsByKey.get(key).push(ref)
167
175
  }
176
+ for (const state of states) {
177
+ if (capacityField && refsByKey.get(state.key).length > 1) {
178
+ state.capacity = null
179
+ }
180
+ }
168
181
  return { states, keyByValue, refsByKey }
169
182
  }
170
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
+
171
223
  /**
172
224
  * The stages of a field with no referenced schema (a user id): the values
173
225
  * present on the rows, by label, then one column for no value.