@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
@@ -78,6 +78,7 @@ import { resolveObjectOpType } from '../../utils/actionsDispatcher.js'
78
78
  import { resolveObjectTokenContext } from '../../utils/detailObjectContext.js'
79
79
  import { safeCurrencyCode } from '../../utils/formatMetric.js'
80
80
  import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
81
+ import { userLocale } from '../../utils/userLocale.js'
81
82
 
82
83
  /**
83
84
  * Nice-ceiling ladder. Deliberately fine-grained: a coarse one (1 / 2 / 5 / 10)
@@ -1636,16 +1637,16 @@ export default {
1636
1637
  const year = d.getFullYear() === thisYear ? {} : { year: 'numeric' }
1637
1638
  switch (String(interval || '').toLowerCase()) {
1638
1639
  case 'minute':
1639
- return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })
1640
+ return d.toLocaleString(userLocale(), { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })
1640
1641
  case 'hour':
1641
- return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit' })
1642
+ return d.toLocaleString(userLocale(), { month: 'short', day: 'numeric', hour: '2-digit' })
1642
1643
  case 'day':
1643
1644
  case 'week':
1644
- return d.toLocaleDateString(undefined, { day: 'numeric', month: 'short', ...year })
1645
+ return d.toLocaleDateString(userLocale(), { day: 'numeric', month: 'short', ...year })
1645
1646
  case 'year':
1646
- return d.toLocaleDateString(undefined, { year: 'numeric' })
1647
+ return d.toLocaleDateString(userLocale(), { year: 'numeric' })
1647
1648
  default:
1648
- return d.toLocaleDateString(undefined, { month: 'short', year: '2-digit' })
1649
+ return d.toLocaleDateString(userLocale(), { month: 'short', year: '2-digit' })
1649
1650
  }
1650
1651
  },
1651
1652
 
@@ -112,6 +112,7 @@ import { translate as t } from '@nextcloud/l10n'
112
112
  import { NcButton, NcDialog, NcEmptyContent, NcLoadingIcon, NcNoteCard, NcSelect, NcTextField } from '@nextcloud/vue'
113
113
  import BookOpenPageVariant from 'vue-material-design-icons/BookOpenPageVariant.vue'
114
114
  import { buildHeaders, prefixUrl } from '../../utils/index.js'
115
+ import { userLocale } from '../../utils/userLocale.js'
115
116
 
116
117
  export default {
117
118
  name: 'CnCollectivePagePicker',
@@ -267,7 +268,7 @@ export default {
267
268
  if (Number.isNaN(d.getTime())) {
268
269
  return ''
269
270
  }
270
- return d.toLocaleDateString(undefined, { dateStyle: 'medium' })
271
+ return d.toLocaleDateString(userLocale(), { dateStyle: 'medium' })
271
272
  },
272
273
 
273
274
  confirm() {
@@ -86,6 +86,7 @@ import axios from '@nextcloud/axios'
86
86
  import { translate as t } from '@nextcloud/l10n'
87
87
  import { NcButton } from '@nextcloud/vue'
88
88
  import { prefixUrl } from '../../utils/headers.js'
89
+ import { userLocale } from '../../utils/userLocale.js'
89
90
 
90
91
  let conversationThreadUid = 0
91
92
 
@@ -299,7 +300,7 @@ export default {
299
300
  if (!looksLikeDate || Number.isNaN(date.getTime())) {
300
301
  return { label: String(value), datetime: '' }
301
302
  }
302
- const label = date.toLocaleString(undefined, { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })
303
+ const label = date.toLocaleString(userLocale(), { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })
303
304
  return { label, datetime: date.toISOString() }
304
305
  },
305
306
 
@@ -29,6 +29,7 @@ import { inject } from 'vue'
29
29
  import CnWidgetIcon from '../CnWidgetGrid/CnWidgetIcon.vue'
30
30
  import { getByPath } from '../../composables/useEndpointSource.js'
31
31
  import { resolveObjectTokenContext } from '../../utils/detailObjectContext.js'
32
+ import { userLocale } from '../../utils/userLocale.js'
32
33
 
33
34
  const MS_PER_DAY = 24 * 60 * 60 * 1000
34
35
 
@@ -248,7 +249,7 @@ export default {
248
249
  if (!this.targetDate || this.content?.showDate === false) {
249
250
  return ''
250
251
  }
251
- return this.targetDate.toLocaleDateString(undefined, { day: 'numeric', month: 'long', year: 'numeric' })
252
+ return this.targetDate.toLocaleDateString(userLocale(), { day: 'numeric', month: 'long', year: 'numeric' })
252
253
  },
253
254
 
254
255
  /**
@@ -395,6 +395,7 @@
395
395
  <CnStatsBlockWidget
396
396
  v-bind="getStatsBlockProps(item)"
397
397
  :title="getWidgetTitle(item)"
398
+ :eyebrow="getWidgetEyebrow(item)"
398
399
  :data-source="getWidgetDataSource(item)" />
399
400
  </CnWidgetWrapper>
400
401
  <CnWidgetWrapper
@@ -420,7 +421,7 @@
420
421
  :is="registryRenderer(item)"
421
422
  :widgetId="item.widgetId"
422
423
  :content="registryWidgetBindings(item)"
423
- v-bind="registryWidgetBindings(item)"
424
+ v-bind="{ ...registryWidgetBindings(item), ...containerBindings(item) }"
424
425
  @header="onWidgetHeader(item, $event)" />
425
426
  </CnWidgetWrapper>
426
427
  <CnWidgetWrapper
@@ -433,6 +434,7 @@
433
434
  <CnWidgetWrapper
434
435
  v-else
435
436
  :title="getWidgetTitle(item)"
437
+ :eyebrow="getWidgetEyebrow(item)"
436
438
  :showTitle="false"
437
439
  :showRefresh="false">
438
440
  <div class="cn-dashboard-page__unknown">
@@ -494,6 +496,7 @@
494
496
  <CnWidgetWrapper
495
497
  v-if="missingRequiredApp(item)"
496
498
  :title="getWidgetTitle(item)"
499
+ :eyebrow="getWidgetEyebrow(item)"
497
500
  :showTitle="widgetShowTitle(item)">
498
501
  <!-- Compact on purpose: a two-row tile is about 150px, less
499
502
  a title row. NcEmptyContent's 64px icon, 20px name,
@@ -532,6 +535,7 @@
532
535
  <CnWidgetWrapper
533
536
  :widgetId="item.widgetId"
534
537
  :title="getWidgetTitle(item)"
538
+ :eyebrow="getWidgetEyebrow(item)"
535
539
  :iconUrl="getWidgetIconUrl(item)"
536
540
  :iconClass="getWidgetIconClass(item)"
537
541
  :showTitle="widgetShowTitle(item)"
@@ -613,6 +617,7 @@
613
617
  :widgetId="item.widgetId"
614
618
  :class="{ 'cn-dashboard-page__chart-fit': isChartFitted(item) }"
615
619
  :title="getWidgetTitle(item)"
620
+ :eyebrow="getWidgetEyebrow(item)"
616
621
  :iconUrl="getWidgetIconUrl(item)"
617
622
  :iconClass="getWidgetIconClass(item)"
618
623
  :showTitle="widgetShowTitle(item)"
@@ -691,6 +696,7 @@
691
696
  <CnWidgetWrapper
692
697
  :widgetId="item.widgetId"
693
698
  :title="getWidgetTitle(item)"
699
+ :eyebrow="getWidgetEyebrow(item)"
694
700
  :iconUrl="getWidgetIconUrl(item)"
695
701
  :iconClass="getWidgetIconClass(item)"
696
702
  :showTitle="widgetShowTitle(item)"
@@ -718,6 +724,7 @@
718
724
  <CnWidgetWrapper
719
725
  :widgetId="item.widgetId"
720
726
  :title="getWidgetTitle(item)"
727
+ :eyebrow="getWidgetEyebrow(item)"
721
728
  :iconUrl="getWidgetIconUrl(item)"
722
729
  :iconClass="getWidgetIconClass(item)"
723
730
  :showTitle="widgetShowTitle(item)"
@@ -757,6 +764,7 @@
757
764
  <CnWidgetWrapper
758
765
  :widgetId="item.widgetId"
759
766
  :title="getWidgetTitle(item)"
767
+ :eyebrow="getWidgetEyebrow(item)"
760
768
  :iconUrl="getWidgetIconUrl(item)"
761
769
  :iconClass="getWidgetIconClass(item)"
762
770
  :showTitle="widgetShowTitle(item)"
@@ -782,6 +790,7 @@
782
790
  <CnWidgetWrapper
783
791
  :widgetId="item.widgetId"
784
792
  :title="getWidgetTitle(item)"
793
+ :eyebrow="getWidgetEyebrow(item)"
785
794
  :showTitle="widgetShowTitle(item)"
786
795
  :showActions="widgetShowActions(item)"
787
796
  :showRefresh="getWidgetShowRefresh(item)"
@@ -873,7 +882,7 @@
873
882
  :is="registryRenderer(item)"
874
883
  :widgetId="item.widgetId"
875
884
  :content="registryWidgetBindings(item)"
876
- v-bind="registryWidgetBindings(item)"
885
+ v-bind="{ ...registryWidgetBindings(item), ...containerBindings(item) }"
877
886
  @header="onWidgetHeader(item, $event)" />
878
887
  </CnWidgetWrapper>
879
888
  </template>
@@ -882,6 +891,7 @@
882
891
  <CnWidgetWrapper
883
892
  v-else
884
893
  :title="getWidgetTitle(item)"
894
+ :eyebrow="getWidgetEyebrow(item)"
885
895
  :showTitle="widgetShowTitle(item)"
886
896
  :showRefresh="false">
887
897
  <div class="cn-dashboard-page__unknown">
@@ -974,6 +984,7 @@ import { pageViews } from '../../mixins/pageViews.js'
974
984
  import { mergeUserLayout, resolveUserLayoutApi } from '../../store/plugins/dashboardLayouts.js'
975
985
  import { isAppInstalled } from '../../utils/appInstalled.js'
976
986
  import { contentHeaderLink } from '../../utils/contentHeaderLink.js'
987
+ import { userLocale } from '../../utils/userLocale.js'
977
988
  import { compareVisibleWhen, evaluateWorkspaceCondition, isWorkspaceCondition, readVisibleWhenValue } from '../../utils/visibleWhen.js'
978
989
  import { canonicalWidgetType } from '../../utils/widgetTypeAliases.js'
979
990
  import { CnActionButtons } from '../CnActionButtons/index.js'
@@ -2863,7 +2874,7 @@ export default {
2863
2874
  if (!d) {
2864
2875
  return ''
2865
2876
  }
2866
- return d.toLocaleDateString(undefined, {
2877
+ return d.toLocaleDateString(userLocale(), {
2867
2878
  day: 'numeric',
2868
2879
  month: 'short',
2869
2880
  ...(needsYear ? { year: 'numeric' } : {}),
@@ -2944,6 +2955,7 @@ export default {
2944
2955
  return {
2945
2956
  widgetId: item.widgetId,
2946
2957
  title: this.getWidgetTitle(item),
2958
+ eyebrow: this.getWidgetEyebrow(item),
2947
2959
  showTitle: this.widgetShowTitle(item),
2948
2960
  showActions: this.widgetShowActions(item),
2949
2961
  showRefresh: this.getWidgetShowRefresh(item),
@@ -3630,6 +3642,35 @@ export default {
3630
3642
  return outcome ? { ...content, conditionOutcome: outcome } : content
3631
3643
  },
3632
3644
 
3645
+ /**
3646
+ * What a container widget (registry `container`, such as `tabs`) needs
3647
+ * beside its content: the page's widget definitions, so its tabs find
3648
+ * the widgets they name, and the consumer registry for custom child
3649
+ * types. Empty for every other widget, so a leaf gets no extra
3650
+ * attributes on its root.
3651
+ *
3652
+ * @param {object} item Layout item.
3653
+ * @return {object} The extra bindings.
3654
+ * @spec openspec/changes/dashboard-tabs-children/specs/dashboard-page/spec.md#requirement-a-tabs-widget-on-a-dashboard-renders-the-widgets-its-tabs-name
3655
+ */
3656
+ containerBindings(item) {
3657
+ const def = this.getWidgetDef(item.widgetId)
3658
+ if (!def || !def.type) {
3659
+ return {}
3660
+ }
3661
+ const entry = getWidgetTypeEntry(def.type) || getWidgetTypeEntry(canonicalWidgetType(def.type))
3662
+ if (!entry || entry.container !== true) {
3663
+ return {}
3664
+ }
3665
+ const own = Array.isArray(this.widgets) ? this.widgets.filter(Boolean) : []
3666
+ const fromView = this.activeView && Array.isArray(this.activeView.widgets) ? this.activeView.widgets.filter(Boolean) : []
3667
+ return {
3668
+ availableWidgets: [...own, ...fromView],
3669
+ cnRegistry: this.cnRegistry || {},
3670
+ surface: this.surface,
3671
+ }
3672
+ },
3673
+
3633
3674
  /**
3634
3675
  * A widget's content with the board's quiet collection footer: in the
3635
3676
  * board look a dashboard that drops the widget Actions menu
@@ -4002,6 +4043,21 @@ export default {
4002
4043
  this.showWidgetConfig = false
4003
4044
  },
4004
4045
 
4046
+ /**
4047
+ * The line above a widget's title (`eyebrow` on the widget
4048
+ * definition: "Saldo per week" above "Prognose 13 weken"), through the
4049
+ * host translate, or '' for none.
4050
+ *
4051
+ * @param {object} item Layout item.
4052
+ * @return {string}
4053
+ * @spec openspec/changes/widget-title-eyebrow/specs/dashboard-page/spec.md#requirement-a-widget-card-can-carry-a-line-above-its-title
4054
+ */
4055
+ getWidgetEyebrow(item) {
4056
+ const def = this.getWidgetDef(item.widgetId)
4057
+ const eyebrow = def && typeof def.eyebrow === 'string' ? def.eyebrow : ''
4058
+ return eyebrow ? this.effectiveTranslate(eyebrow) : ''
4059
+ },
4060
+
4005
4061
  /**
4006
4062
  * The widget's title as AUTHORED — the untranslated manifest source
4007
4063
  * string — resolved by widget id rather than by item, so a descendant
@@ -83,6 +83,7 @@
83
83
  </template>
84
84
 
85
85
  <script>
86
+ import { userLocale } from '../../utils/userLocale.js'
86
87
  /**
87
88
  * CnDataMatrix — Inline-edit data grid for matrix-shaped data
88
89
  * (rows × columns). Each cell is click-to-edit; commits emit
@@ -239,7 +240,7 @@ export default {
239
240
  if (!Number.isFinite(n)) {
240
241
  return value
241
242
  }
242
- return n.toLocaleString()
243
+ return n.toLocaleString(userLocale())
243
244
  }
244
245
  return value
245
246
  },
@@ -58,6 +58,7 @@ import { useObjectStore } from '../../store/useObjectStore.js'
58
58
  import { resolveObjectOpType } from '../../utils/actionsDispatcher.js'
59
59
  import { isEmptyChipValue, isPastDate, normalizeHeaderFields, pickRefLabel, variantForColor } from '../../utils/headerFieldChips.js'
60
60
  import { schemaRefSlug } from '../../utils/schemaRefSlug.js'
61
+ import { userLocale } from '../../utils/userLocale.js'
61
62
 
62
63
  const DAY_MS = 86400000
63
64
 
@@ -239,7 +240,7 @@ export default {
239
240
  try {
240
241
  return new Intl.RelativeTimeFormat(this.locale(), { numeric: 'auto' }).format(days, 'day')
241
242
  } catch {
242
- return new Date(time).toLocaleDateString()
243
+ return new Date(time).toLocaleDateString(userLocale())
243
244
  }
244
245
  },
245
246
 
@@ -460,4 +460,4 @@ When the schema-driven fetch answers 404 the page shows a not-found state whose
460
460
 
461
461
  ### The board look
462
462
 
463
- `look` (String, default `''`): `nextcloud` or `board`; empty takes the app's look. `headerMeta` (String): the meta line on row 2 of the board header, a field template such as `via {channel}` (manifest `config.headerMeta`). `tabsLabel` (String): the accessible name of the tab list (manifest `config.tabsLabel`). `identifierField` (String): the field named in the last line of the History side card (manifest `config.identifierField`). See `docs/components/cn-detail-page.md`.
463
+ `look` (String, default `''`): `nextcloud` or `board`; empty takes the app's look. `headerMeta` (String): the meta line on row 2 of the board header, a field template such as `via {channel}` (manifest `config.headerMeta`). `tabsLabel` (String): the accessible name of the tab list (manifest `config.tabsLabel`). `identifierField` (String): the field named in the last line of the History side card (manifest `config.identifierField`). `titleField` (String): the record field the header names the record by, such as an invoice number (manifest `config.titleField`); an empty value falls back to the display name. See `docs/components/cn-detail-page.md`.
@@ -2664,6 +2664,19 @@ export default {
2664
2664
  type: String,
2665
2665
  default: '',
2666
2666
  },
2667
+
2668
+ /**
2669
+ * The record field the header names the record by (manifest
2670
+ * `config.titleField`, a dotted path such as `number`), as an invoice
2671
+ * page names the invoice number. An empty value falls back to the
2672
+ * display name. Empty (the default) changes nothing.
2673
+ *
2674
+ * @spec openspec/changes/detail-title-field/specs/detail-page/spec.md#requirement-a-detail-page-can-name-the-record-by-a-field
2675
+ */
2676
+ titleField: {
2677
+ type: String,
2678
+ default: '',
2679
+ },
2667
2680
  },
2668
2681
 
2669
2682
  emits: [
@@ -4102,10 +4115,10 @@ export default {
4102
4115
  },
4103
4116
 
4104
4117
  /**
4105
- * The resolved record's human display name, drawn from the loaded
4106
- * object via the same fallback chain the relation resolver uses:
4107
- * `@self.name` → `name` / `title` / `displayName` → `firstName
4108
- * lastName`. Empty string while the object is still loading or when no
4118
+ * The resolved record's human display name: the `titleField` value
4119
+ * when the page names one and it is filled, else the same fallback
4120
+ * chain the relation resolver uses: `@self.name` → `name` / `title` /
4121
+ * `displayName` → `firstName lastName`. Empty string while the object is still loading or when no
4109
4122
  * name-like field exists (a raw id is never used as a name — ADR-062).
4110
4123
  *
4111
4124
  * @return {string}
@@ -4115,6 +4128,12 @@ export default {
4115
4128
  if (!obj || typeof obj !== 'object') {
4116
4129
  return ''
4117
4130
  }
4131
+ if (this.titleField) {
4132
+ const named = stageOf(obj, this.titleField)
4133
+ if (named !== '') {
4134
+ return named
4135
+ }
4136
+ }
4118
4137
  const self = obj['@self'] || {}
4119
4138
  const id = this.objectId !== null && this.objectId !== undefined ? String(this.objectId) : ''
4120
4139
  const candidates = [self.name, self.title, obj.name, obj.title, obj.displayName]
@@ -725,7 +725,9 @@ export default {
725
725
  if (this.widget && this.widget.type === 'files' && !(this.cnRegistry && this.cnRegistry.files) && this.register && this.schema) {
726
726
  return CnObjectFilesWidget
727
727
  }
728
- return resolveRegistryRenderer(this.widget, this.cnRegistry)
728
+ // Inside a dashboard's tabs the dashboard's resolution holds.
729
+ const onDashboard = this.surface === 'app-dashboard' || this.surface === 'user-dashboard'
730
+ return resolveRegistryRenderer(this.widget, this.cnRegistry, { typeAsWritten: onDashboard })
729
731
  },
730
732
 
731
733
  /**
@@ -171,6 +171,7 @@ import { NcButton, NcDialog, NcEmptyContent, NcLoadingIcon, NcNoteCard, NcTextFi
171
171
  import EmailOutline from 'vue-material-design-icons/EmailOutline.vue'
172
172
  import FolderOutline from 'vue-material-design-icons/FolderOutline.vue'
173
173
  import { buildHeaders, prefixUrl } from '../../utils/index.js'
174
+ import { userLocale } from '../../utils/userLocale.js'
174
175
 
175
176
  export default {
176
177
  name: 'CnEmailPicker',
@@ -404,7 +405,7 @@ export default {
404
405
  if (Number.isNaN(d.getTime())) {
405
406
  return String(raw)
406
407
  }
407
- return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })
408
+ return d.toLocaleDateString(userLocale(), { year: 'numeric', month: 'short', day: 'numeric' })
408
409
  },
409
410
  },
410
411
  }
@@ -145,6 +145,7 @@ import { dispatchAction } from '../../utils/actionsDispatcher.js'
145
145
  import { isBadgeVariant } from '../../utils/badgeVariants.js'
146
146
  import { formatBoardDate } from '../../utils/boardDate.js'
147
147
  import { parseDateValue } from '../../utils/dateVariant.js'
148
+ import { formatMoney, unwrapAppConfig } from '../../utils/formatMetric.js'
148
149
  import { readPath } from '../../utils/readPath.js'
149
150
  import { hasUnresolvedDeepTokens, resolveDeepTokens } from '../../utils/resolveFilterTokens.js'
150
151
 
@@ -246,6 +247,8 @@ export default {
246
247
  cnTranslate: { default: () => (key) => key },
247
248
  cnObjectContext: { default: null },
248
249
  cnWorkspaceContext: { default: null },
250
+ /** The page's app config; its `currency` is the reporting currency a money value falls back to. */
251
+ cnAppConfig: { default: null },
249
252
  /** Pre-bound action dispatcher of CnPageRenderer, for `action` / `headerAction`. */
250
253
  cnDispatchAction: { default: null },
251
254
  },
@@ -260,7 +263,7 @@ export default {
260
263
  * A part may be `{ text }`, a constant; a `line` or `text` entry without `path` or `parts` shows its `text`.
261
264
  * `resolve: { register, schema, labelField? }` on an entry or a part turns a value that is a reference (an id, or a list of ids) into the label of the referenced object (`labelField`, else `title`, then `name`): the case type or status of a task shows its name, not its uuid. The ids are fetched once per register and schema through the object store and shared by every facts widget on the page; the entry stays empty until its label is known, and when no label can be read. A resolved value works as a pill too: `map` is applied to the resolved label, and `variantMap` / `colorMap` look the tone up by the value of `resolve.toneField` on the referenced object when that is set (a status named by its `name`, coloured by its `state`), then by the resolved label, then by the stored value.
262
265
  * - `action` — an action drawn as a button under the facts; `headerAction` — one drawn in the card header (reported through the `header` event).
263
- * `format` is `text` (default), `date` (board short date), `date-long` (always with the year) or `list` (an array joined by ", ", each item read at `itemPath`).
266
+ * `format` is `text` (default), `date` (board short date), `date-long` (always with the year), `list` (an array joined by ", ", each item read at `itemPath`) or `currency` (a money amount in the reader's language, "€ 1.234,50": the code in `currency`, else the record's `currencyField`, else the app's reporting currency, else EUR; `decimals` defaults to 2).
264
267
  * `map` turns a raw value into a label (translated). `parts` (on a `line`) lists paths, or `{ path, label?, format? }`, joined by `separator` (default " · "); empty parts are dropped.
265
268
  * - `source` — `{ register, schema, id }` or `{ url }`; omitted = the current object.
266
269
  * - `link` — `{ label, route? | href? }` at the foot.
@@ -900,7 +903,7 @@ export default {
900
903
  */
901
904
  valueOf(record, field) {
902
905
  const raw = readPath(record, field.path)
903
- return this.format(raw, field)
906
+ return this.format(raw, field, record)
904
907
  },
905
908
 
906
909
  /**
@@ -919,7 +922,7 @@ export default {
919
922
  if (!spec.path && typeof spec.text === 'string') {
920
923
  return this.tr(spec.text)
921
924
  }
922
- const value = this.format(readPath(record, spec.path), spec)
925
+ const value = this.format(readPath(record, spec.path), spec, record)
923
926
  if (value === '') {
924
927
  return ''
925
928
  }
@@ -933,10 +936,12 @@ export default {
933
936
  * Format a raw value.
934
937
  *
935
938
  * @param {unknown} raw The value.
936
- * @param {object} spec `{ format?, map?, itemPath? }`.
939
+ * @param {object} spec `{ format?, map?, itemPath?, currency?, currencyField?, decimals? }`.
940
+ * @param {object|null} [record] The object shown, which `currencyField` reads.
937
941
  * @return {string} The text, '' when empty.
942
+ * @spec openspec/changes/facts-currency-format/specs/facts-widget/spec.md#requirement-a-facts-entry-can-show-a-money-amount
938
943
  */
939
- format(raw, spec) {
944
+ format(raw, spec, record = null) {
940
945
  if (raw === null || raw === undefined || raw === '') {
941
946
  return ''
942
947
  }
@@ -961,6 +966,14 @@ export default {
961
966
  ? formatBoardDate(date, new Date(date.getFullYear() + 1, 0, 1))
962
967
  : formatBoardDate(date)
963
968
  }
969
+ if (format === 'currency') {
970
+ const money = formatMoney(raw, { currency: spec.currency, currencyField: spec.currencyField, decimals: spec.decimals }, record, unwrapAppConfig(this.cnAppConfig))
971
+ if (money !== '') {
972
+ return money
973
+ }
974
+ // Not a number: shown as written, never as "[object Object]".
975
+ return typeof raw === 'object' ? '' : String(raw)
976
+ }
964
977
  if (typeof raw === 'object') {
965
978
  const label = raw.title || raw.name || raw.label || raw.displayName
966
979
  return typeof label === 'string' ? label : ''
@@ -81,6 +81,8 @@
81
81
  </template>
82
82
 
83
83
  <script>
84
+ import { userLocale } from '../../utils/userLocale.js'
85
+
84
86
  // The canonical KPI scale (`--cn-kpi-*`) lives in one stylesheet. Imported
85
87
  // here as well as from css/index.css so the tokens resolve even when the
86
88
  // consuming app pulls in components individually.
@@ -242,7 +244,7 @@ export default {
242
244
  if (Number.isNaN(d.getTime())) {
243
245
  return iso
244
246
  }
245
- return d.toLocaleString()
247
+ return d.toLocaleString(userLocale())
246
248
  } catch {
247
249
  return iso
248
250
  }
@@ -80,6 +80,7 @@
80
80
  </template>
81
81
 
82
82
  <script>
83
+ import { userLocale } from '../../utils/userLocale.js'
83
84
  /**
84
85
  * CnFileManager — File list widget with drag-drop upload, per-file
85
86
  * actions, and a click-emit for preview / detail.
@@ -223,7 +224,7 @@ export default {
223
224
  if (Number.isNaN(d.getTime())) {
224
225
  return iso
225
226
  }
226
- return d.toLocaleString()
227
+ return d.toLocaleString(userLocale())
227
228
  } catch {
228
229
  return iso
229
230
  }
@@ -72,6 +72,7 @@ import { NcButton, NcDialog, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'
72
72
  import { fileContentUrl, previewKindOf } from '../../composables/useFileOpener.js'
73
73
  import { buildHeaders, prefixUrl } from '../../utils/index.js'
74
74
  import { parseDelimited } from '../../utils/parseDelimited.js'
75
+ import { userLocale } from '../../utils/userLocale.js'
75
76
 
76
77
  /**
77
78
  * CnFilePreview — an in-page preview of a data file the Nextcloud Viewer does
@@ -203,7 +204,7 @@ export default {
203
204
  if (estimate > shown) {
204
205
  return t('nextcloud-vue', 'Showing the first {shown} of about {total} rows', {
205
206
  shown,
206
- total: estimate.toLocaleString(),
207
+ total: estimate.toLocaleString(userLocale()),
207
208
  })
208
209
  }
209
210
  return t('nextcloud-vue', 'Showing the first {shown} rows', { shown })
@@ -110,7 +110,7 @@
110
110
  <template #icon>
111
111
  <CnIcon :name="action.icon || 'Plus'" :size="20" />
112
112
  </template>
113
- {{ action.label }}
113
+ {{ hostLabel(action) }}
114
114
  </NcActionButton>
115
115
  </NcActions>
116
116
  <!-- A plain upload as its own button, when the host names it
@@ -193,7 +193,7 @@
193
193
  <template #icon>
194
194
  <CnIcon :name="action.icon || 'CheckboxMultipleMarkedOutline'" :size="20" />
195
195
  </template>
196
- {{ action.label }}
196
+ {{ hostLabel(action) }}
197
197
  </NcButton>
198
198
  <NcButton variant="tertiary"
199
199
  data-testid="cn-files-browser-bulk-clear"
@@ -366,7 +366,7 @@
366
366
  <template #icon>
367
367
  <CnIcon :name="action.icon || 'FileDocumentEditOutline'" :size="20" />
368
368
  </template>
369
- {{ action.label }}
369
+ {{ hostLabel(action) }}
370
370
  </NcActionButton>
371
371
  </template>
372
372
  <NcActionSeparator v-if="actionsFor(node).length > 0 || (!isFolder(node) && hostActionsFor(node).length > 0)" />
@@ -583,8 +583,6 @@
583
583
  <script>
584
584
  import { getCurrentUser } from '@nextcloud/auth'
585
585
  import axios from '@nextcloud/axios'
586
- import { FileType, formatFileSize, getFileActions, getNewFileMenuEntries, sortNodes, View } from '@nextcloud/files'
587
- import { getClient, getDefaultPropfind, getRemoteURL, getRootPath, resultToNode } from '@nextcloud/files/dav'
588
586
  /**
589
587
  * CnFilesBrowser — a folder of Nextcloud files, on any page, built from the
590
588
  * Files app's own primitives rather than a copy of its screen.
@@ -623,6 +621,9 @@ import { getClient, getDefaultPropfind, getRemoteURL, getRootPath, resultToNode
623
621
  * copy read `window._nc_fileactions`, which the server's plugins never write,
624
622
  * and saw nothing while the page held thirty actions.
625
623
  */
624
+ import { subscribe, unsubscribe } from '@nextcloud/event-bus'
625
+ import { FileType, formatFileSize, getFileActions, getNewFileMenuEntries, sortNodes, View } from '@nextcloud/files'
626
+ import { getClient, getDefaultPropfind, getRemoteURL, getRootPath, resultToNode } from '@nextcloud/files/dav'
626
627
  import { translatePlural as n, translate as t } from '@nextcloud/l10n'
627
628
  import { generateUrl } from '@nextcloud/router'
628
629
  import { NcActionButton, NcActionCheckbox, NcActionLink, NcActions, NcActionSeparator, NcBreadcrumb, NcBreadcrumbs, NcButton, NcDateTime, NcDialog, NcIconSvgWrapper, NcLoadingIcon, NcProgressBar, NcTextField } from '@nextcloud/vue'
@@ -660,6 +661,12 @@ let uploadSeq = 0
660
661
  /** A folder glyph, the icon the Files app's View constructor requires. */
661
662
  const VIEW_ICON = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg>'
662
663
 
664
+ // Event-bus channels that mean the open folder may have changed: the page's
665
+ // Refresh signal, and the node events the Files app's actions and uploader emit.
666
+ const FOLDER_CHANGED_CHANNELS = ['cn:page:refresh', 'files:node:created', 'files:node:deleted', 'files:node:updated', 'files:node:moved']
667
+
668
+ const FOLDER_CHANGED_DEBOUNCE_MS = 300
669
+
663
670
  export default {
664
671
  name: 'CnFilesBrowser',
665
672
 
@@ -696,6 +703,10 @@ export default {
696
703
  // The page's pre-bound action runner (CnPageRenderer provides it);
697
704
  // absent outside a page tree, in which case the bare dispatcher runs.
698
705
  cnDispatchAction: { default: null },
706
+ // The host app's translate function (CnAppRoot provides it). A row
707
+ // action or column the manifest declares is authored in English as
708
+ // the catalogue key, and read through this in the user's language.
709
+ cnTranslate: { default: () => (key) => key },
699
710
  },
700
711
 
701
712
  props: {
@@ -1356,6 +1367,19 @@ export default {
1356
1367
  mounted() {
1357
1368
  this.loadColumnChoice()
1358
1369
  this.refresh()
1370
+ // Another surface on the page changed the folder: the page's Refresh,
1371
+ // a dialog that filed a document, or a Files action whose work ends
1372
+ // after its own call returned (the delete confirmation, an upload).
1373
+ for (const channel of FOLDER_CHANGED_CHANNELS) {
1374
+ subscribe(channel, this.onFolderChanged)
1375
+ }
1376
+ },
1377
+
1378
+ beforeUnmount() {
1379
+ for (const channel of FOLDER_CHANGED_CHANNELS) {
1380
+ unsubscribe(channel, this.onFolderChanged)
1381
+ }
1382
+ clearTimeout(this._folderChangedTimer)
1359
1383
  },
1360
1384
 
1361
1385
  methods: {
@@ -1643,6 +1667,30 @@ export default {
1643
1667
  * @param {object} node The node.
1644
1668
  * @return {string} The label.
1645
1669
  */
1670
+ /**
1671
+ * A host action's label in the user's language.
1672
+ *
1673
+ * @spec openspec/changes/files-browser-hears-the-page/specs/files-browser/spec.md#requirement-a-declared-row-action-reads-in-the-users-language
1674
+ * @param {object} action The manifest-declared action.
1675
+ * @return {string} The label.
1676
+ */
1677
+ hostLabel(action) {
1678
+ return this.cnTranslate(String(action?.label ?? ''))
1679
+ },
1680
+
1681
+ /**
1682
+ * Re-read the folder once after a burst of change signals. One upload
1683
+ * of ten files answers ten `files:node:created`, and one PROPFIND
1684
+ * covers them all.
1685
+ *
1686
+ * @spec openspec/changes/files-browser-hears-the-page/specs/files-browser/spec.md#requirement-the-files-browser-re-reads-when-the-page-says-files-changed
1687
+ * @return {void}
1688
+ */
1689
+ onFolderChanged() {
1690
+ clearTimeout(this._folderChangedTimer)
1691
+ this._folderChangedTimer = setTimeout(() => this.refresh(), FOLDER_CHANGED_DEBOUNCE_MS)
1692
+ },
1693
+
1646
1694
  labelOf(action, node) {
1647
1695
  try {
1648
1696
  return action.displayName(this.contextFor(node))
@@ -2034,7 +2082,7 @@ export default {
2034
2082
  */
2035
2083
  columnLabel(column) {
2036
2084
  if (column && typeof column.label === 'string' && column.label !== '') {
2037
- return column.label
2085
+ return this.cnTranslate(column.label)
2038
2086
  }
2039
2087
  return this.builtInColumnLabels[column && column.key] || (column && column.key) || ''
2040
2088
  },
@@ -108,6 +108,7 @@ import EyeOutline from 'vue-material-design-icons/EyeOutline.vue'
108
108
  import { patchStoredSelf } from '../../utils/patchStoredSelf.js'
109
109
  import { listWatchers, setWatcher, setWatching } from '../../utils/recordInteractions.js'
110
110
  import { searchNextcloudUsers } from '../../utils/userAutocomplete.js'
111
+ import { userLocale } from '../../utils/userLocale.js'
111
112
 
112
113
  /**
113
114
  * CnFollowToggle — the one Follow control of a record: a Follow toggle bound to
@@ -298,7 +299,7 @@ export default {
298
299
  const d = new Date(created)
299
300
  return Number.isNaN(d.getTime())
300
301
  ? ''
301
- : t('nextcloud-vue', 'Since {date}', { date: d.toLocaleDateString() })
302
+ : t('nextcloud-vue', 'Since {date}', { date: d.toLocaleDateString(userLocale()) })
302
303
  },
303
304
 
304
305
  removeFollowerLabel(watcher) {