@conduction/nextcloud-vue 2.85.0 → 2.87.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) 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 +30 -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/CnTabsWidget/CnTabsWidget.vue.js +1 -1
  139. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +36 -0
  140. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  141. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +55 -40
  142. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  143. package/dist/esm/components/CnTasksCard/CnTasksCard.vue.js +1 -1
  144. package/dist/esm/components/CnTasksCard/CnTasksCard.vue2.js +2 -1
  145. package/dist/esm/components/CnTasksCard/CnTasksCard.vue2.js.map +1 -1
  146. package/dist/esm/components/CnTasksCard/CnTasksCard.vue3.js.map +1 -1
  147. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +1 -1
  148. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +2 -1
  149. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -1
  150. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -1
  151. package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue.js +1 -1
  152. package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue2.js +2 -1
  153. package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue2.js.map +1 -1
  154. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue.js +1 -1
  155. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue2.js +2 -1
  156. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue2.js.map +1 -1
  157. package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue3.js.map +1 -1
  158. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue.js +1 -1
  159. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +3 -26
  160. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
  161. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
  162. package/dist/esm/dialogs/CnNoteHistoryDialog.vue.js +1 -1
  163. package/dist/esm/dialogs/CnNoteHistoryDialog.vue2.js +2 -1
  164. package/dist/esm/dialogs/CnNoteHistoryDialog.vue2.js.map +1 -1
  165. package/dist/esm/dialogs/CnNoteHistoryDialog.vue3.js.map +1 -1
  166. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue.js +1 -1
  167. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue2.js +3 -2
  168. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue2.js.map +1 -1
  169. package/dist/esm/integrations/builtin/activity/CnActivityCard.vue3.js.map +1 -1
  170. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue.js +1 -1
  171. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue2.js +4 -3
  172. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue2.js.map +1 -1
  173. package/dist/esm/integrations/builtin/activity/CnActivityTab.vue3.js.map +1 -1
  174. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue.js +1 -1
  175. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -2
  176. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
  177. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
  178. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue.js +1 -1
  179. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js +2 -1
  180. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js.map +1 -1
  181. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue3.js.map +1 -1
  182. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue.js +1 -1
  183. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue2.js +6 -5
  184. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue2.js.map +1 -1
  185. package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue3.js.map +1 -1
  186. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue.js +1 -1
  187. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue2.js +2 -1
  188. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue2.js.map +1 -1
  189. package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue3.js.map +1 -1
  190. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue.js +1 -1
  191. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js +2 -1
  192. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js.map +1 -1
  193. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js.map +1 -1
  194. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue.js +1 -1
  195. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +2 -1
  196. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
  197. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
  198. package/dist/esm/integrations/builtin/email/CnEmailCard.vue.js +1 -1
  199. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js +2 -1
  200. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js.map +1 -1
  201. package/dist/esm/integrations/builtin/email/CnEmailCard.vue3.js.map +1 -1
  202. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue.js +1 -1
  203. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js +2 -1
  204. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js.map +1 -1
  205. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js.map +1 -1
  206. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue.js +1 -1
  207. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue2.js +2 -1
  208. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue2.js.map +1 -1
  209. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue3.js.map +1 -1
  210. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue.js +1 -1
  211. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js +2 -1
  212. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js.map +1 -1
  213. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js.map +1 -1
  214. package/dist/esm/l10n/en.json.js +35 -2
  215. package/dist/esm/l10n/en.json.js.map +1 -1
  216. package/dist/esm/l10n/nl.json.js +38 -2
  217. package/dist/esm/l10n/nl.json.js.map +1 -1
  218. package/dist/esm/library-style.js +1 -1
  219. package/dist/esm/nextcloud-vue.css +1068 -962
  220. package/dist/esm/store/useObjectStore.js +7 -2
  221. package/dist/esm/store/useObjectStore.js.map +1 -1
  222. package/dist/esm/utils/boardColumns.js +50 -1
  223. package/dist/esm/utils/boardColumns.js.map +1 -1
  224. package/dist/esm/utils/boardReferenceColumns.js +115 -4
  225. package/dist/esm/utils/boardReferenceColumns.js.map +1 -1
  226. package/dist/esm/utils/contentHeaderLink.js +48 -1
  227. package/dist/esm/utils/contentHeaderLink.js.map +1 -1
  228. package/dist/esm/utils/schema.js +5 -4
  229. package/dist/esm/utils/schema.js.map +1 -1
  230. package/dist/esm/utils/userLocale.js +30 -0
  231. package/dist/esm/utils/userLocale.js.map +1 -0
  232. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  233. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  234. package/dist/nextcloud-vue.cjs.js +1088 -476
  235. package/dist/nextcloud-vue.cjs.js.map +2 -2
  236. package/dist/nextcloud-vue.css +1068 -962
  237. package/l10n/en.json +35 -2
  238. package/l10n/nl.json +38 -2
  239. package/package.json +1 -1
  240. package/src/components/CnAdvancedFormDialog/CnMetadataTab.vue +3 -2
  241. package/src/components/CnAdvancedFormDialog/CnPropertyValueCell.vue +5 -4
  242. package/src/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue +2 -1
  243. package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +2 -1
  244. package/src/components/CnBoardView/CnBoardView.vue +189 -24
  245. package/src/components/CnCalendarEventPicker/CnCalendarEventPicker.vue +2 -1
  246. package/src/components/CnCalendarWidget/CnCalendarWidget.vue +2 -1
  247. package/src/components/CnChartWidget/CnChartWidget.vue +6 -5
  248. package/src/components/CnCollectivePagePicker/CnCollectivePagePicker.vue +2 -1
  249. package/src/components/CnConversationThread/CnConversationThread.vue +2 -1
  250. package/src/components/CnCountdownWidget/CnCountdownWidget.vue +2 -1
  251. package/src/components/CnDashboardPage/CnDashboardPage.vue +2 -1
  252. package/src/components/CnDataMatrix/CnDataMatrix.vue +2 -1
  253. package/src/components/CnDetailPage/CnDetailHeaderChips.vue +2 -1
  254. package/src/components/CnEmailPicker/CnEmailPicker.vue +2 -1
  255. package/src/components/CnFederationStatus/CnFederationStatus.vue +3 -1
  256. package/src/components/CnFileManager/CnFileManager.vue +2 -1
  257. package/src/components/CnFilePreview/CnFilePreview.vue +2 -1
  258. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +54 -6
  259. package/src/components/CnFollowToggle/CnFollowToggle.vue +2 -1
  260. package/src/components/CnIndexPage/CnIndexPage.vue +30 -4
  261. package/src/components/CnNotesCard/CnNotesCard.vue +2 -1
  262. package/src/components/CnObjectCalendar/CnObjectCalendar.vue +3 -2
  263. package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +36 -0
  264. package/src/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue +5 -4
  265. package/src/components/CnObjectSidebar/CnAuditTrailTab.vue +2 -1
  266. package/src/components/CnObjectSidebar/CnFlowTasksPanel.vue +2 -1
  267. package/src/components/CnObjectSidebar/CnNotesTab.vue +2 -1
  268. package/src/components/CnObjectSidebar/CnTasksTab.vue +2 -1
  269. package/src/components/CnPropertySourceField/CnPropertySourceField.vue +2 -1
  270. package/src/components/CnRoadmapItem/CnRoadmapItem.vue +2 -1
  271. package/src/components/CnSchemaFormDialog/CnSchemaFormDialog.vue +4 -2
  272. package/src/components/CnStatsBlock/CnStatsBlock.vue +2 -1
  273. package/src/components/CnSummaryAggregates/CnSummaryAggregates.vue +2 -1
  274. package/src/components/CnTabsWidget/CnTabsWidget.vue +71 -0
  275. package/src/components/CnTasksCard/CnTasksCard.vue +2 -1
  276. package/src/components/CnTimelineWidget/CnTimelineWidget.vue +2 -1
  277. package/src/components/CnTranslatedBadge/CnTranslatedBadge.vue +2 -1
  278. package/src/components/CnVersionHistory/CnVersionHistory.vue +2 -1
  279. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +3 -26
  280. package/src/css/board.css +40 -0
  281. package/src/dialogs/CnNoteHistoryDialog.vue +2 -1
  282. package/src/integrations/builtin/activity/CnActivityCard.vue +3 -2
  283. package/src/integrations/builtin/activity/CnActivityTab.vue +4 -3
  284. package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +3 -2
  285. package/src/integrations/builtin/calendar/CnCalendarCard.vue +2 -1
  286. package/src/integrations/builtin/calendar/CnCalendarTab.vue +6 -5
  287. package/src/integrations/builtin/contactmoment/CnContactmomentCard.vue +2 -1
  288. package/src/integrations/builtin/cospend/CnCospendTab.vue +2 -1
  289. package/src/integrations/builtin/deck/CnDeckTab.vue +2 -1
  290. package/src/integrations/builtin/email/CnEmailCard.vue +2 -1
  291. package/src/integrations/builtin/field-inspection/CnFieldInspectionCard.vue +2 -1
  292. package/src/integrations/builtin/field-inspection/CnFieldInspectionTab.vue +2 -1
  293. package/src/integrations/builtin/photos/CnPhotosTab.vue +2 -1
  294. package/src/schemas/app-manifest-v2.schema.json +4 -1
  295. package/src/store/useObjectStore.js +7 -2
  296. package/src/utils/boardColumns.js +49 -0
  297. package/src/utils/boardReferenceColumns.js +114 -3
  298. package/src/utils/contentHeaderLink.js +47 -0
  299. package/src/utils/schema.js +5 -4
  300. package/src/utils/userLocale.js +26 -0
  301. package/src/utils/validateManifestV2.compiled.js +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"CnActivityCard.vue3.js","sources":["../../../../../src/integrations/builtin/activity/CnActivityCard.vue?vue&type=template&id=ebdd405c&lang.js"],"sourcesContent":["<!--\n CnActivityCard — bespoke surface-aware widget for the `activity` integration.\n\n Replaces the generic CnIntegrationCard for the `activity` leaf. Branches\n on `surface` per AD-19:\n - user-dashboard / app-dashboard : headline count of activity events\n (with a \"today\" sub-count) + most-recent line summarising the\n latest event (actor + verb + time).\n - detail-page : compact chronological feed grouped\n by day (mirrors the tab layout at a smaller scale).\n - single-entity : chip with type icon + actor +\n subject (referenceType: 'activity').\n\n Pulls rows from the same OR pluggable-integration sub-resource as\n CnActivityTab; for `single-entity` the optional `value` prop addresses\n a single event by id (matching CnIntegrationCard's fetchSingle\n contract).\n\n See `openregister/openspec/changes/integration-activity/` for the spec\n delta and ADR-019 (registry mechanism), AD-19 (surface fallback).\n-->\n<template>\n\t<CnDetailCard :title=\"cardTitle\" :icon=\"cardIcon\" :collapsible=\"collapsible\">\n\t\t<NcLoadingIcon v-if=\"loading\" />\n\n\t\t<!-- single-entity surface: chip -->\n\t\t<template v-else-if=\"surface === 'single-entity'\">\n\t\t\t<span v-if=\"entity\" class=\"cn-activity-card__chip\" :title=\"subjectFor(entity)\">\n\t\t\t\t<component :is=\"iconFor(entity)\" :size=\"14\" />\n\t\t\t\t<span class=\"cn-activity-card__chip-label\">\n\t\t\t\t\t<span class=\"cn-activity-card__chip-actor\">{{ actorFor(entity) }}</span>\n\t\t\t\t\t<span class=\"cn-activity-card__chip-sep\">·</span>\n\t\t\t\t\t<span class=\"cn-activity-card__chip-subject\">{{ subjectFor(entity) }}</span>\n\t\t\t\t</span>\n\t\t\t</span>\n\t\t\t<span v-else class=\"cn-activity-card__empty\">{{ emptyLabel }}</span>\n\t\t</template>\n\n\t\t<!-- dashboard surfaces: headline count + most-recent line -->\n\t\t<template v-else-if=\"surface === 'user-dashboard' || surface === 'app-dashboard'\">\n\t\t\t<div v-if=\"degraded\" class=\"cn-activity-card__empty\">\n\t\t\t\t{{ degraded }}\n\t\t\t</div>\n\t\t\t<div v-else-if=\"entries.length === 0\" class=\"cn-activity-card__empty\">\n\t\t\t\t{{ emptyLabel }}\n\t\t\t</div>\n\t\t\t<div v-else class=\"cn-activity-card__headline\">\n\t\t\t\t<div class=\"cn-activity-card__headline-line\">\n\t\t\t\t\t<strong>{{ headlineLabel }}</strong>\n\t\t\t\t</div>\n\t\t\t\t<div v-if=\"mostRecent\" class=\"cn-activity-card__headline-recent\">\n\t\t\t\t\t<component :is=\"iconFor(mostRecent)\" :size=\"14\" />\n\t\t\t\t\t<span class=\"cn-activity-card__headline-actor\">{{ actorFor(mostRecent) }}</span>\n\t\t\t\t\t<span class=\"cn-activity-card__chip-sep\">·</span>\n\t\t\t\t\t<span class=\"cn-activity-card__headline-subject\">{{ subjectFor(mostRecent) }}</span>\n\t\t\t\t\t<span class=\"cn-activity-card__chip-sep\">·</span>\n\t\t\t\t\t<span class=\"cn-activity-card__headline-time\">{{ relativeTime(mostRecent) }}</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<!-- detail-page surface: compact timeline -->\n\t\t<template v-else>\n\t\t\t<div v-if=\"degraded\" class=\"cn-activity-card__empty\">\n\t\t\t\t{{ degraded }}\n\t\t\t</div>\n\t\t\t<div v-else-if=\"entries.length === 0\" class=\"cn-activity-card__empty\">\n\t\t\t\t{{ emptyLabel }}\n\t\t\t</div>\n\t\t\t<div v-else class=\"cn-activity-card__timeline\">\n\t\t\t\t<section\n\t\t\t\t\tv-for=\"day in groupedByDay\"\n\t\t\t\t\t:key=\"day.key\"\n\t\t\t\t\tclass=\"cn-activity-card__day\">\n\t\t\t\t\t<header class=\"cn-activity-card__day-header\">\n\t\t\t\t\t\t<CalendarOutline :size=\"14\" />\n\t\t\t\t\t\t<span>{{ day.label }}</span>\n\t\t\t\t\t\t<span class=\"cn-activity-card__day-count\">{{ day.rows.length }}</span>\n\t\t\t\t\t</header>\n\t\t\t\t\t<ul class=\"cn-activity-card__list\">\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tv-for=\"entry in day.rows.slice(0, COMPACT_LIMIT)\"\n\t\t\t\t\t\t\t:key=\"entryKey(entry)\"\n\t\t\t\t\t\t\tclass=\"cn-activity-card__row\">\n\t\t\t\t\t\t\t<component :is=\"iconFor(entry)\" :size=\"14\" />\n\t\t\t\t\t\t\t<div class=\"cn-activity-card__row-main\">\n\t\t\t\t\t\t\t\t<span class=\"cn-activity-card__row-subject\">{{ subjectFor(entry) }}</span>\n\t\t\t\t\t\t\t\t<span class=\"cn-activity-card__row-meta\">\n\t\t\t\t\t\t\t\t\t{{ actorFor(entry) }} · {{ relativeTime(entry) }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<CnVisibilityChip v-if=\"showVisibility\" :visibility=\"entry.visibility\" />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t</template>\n\t</CnDetailCard>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcLoadingIcon } from '@nextcloud/vue'\nimport AccountOutline from 'vue-material-design-icons/AccountOutline.vue'\nimport CalendarClockOutline from 'vue-material-design-icons/CalendarClockOutline.vue'\nimport CalendarOutline from 'vue-material-design-icons/CalendarOutline.vue'\nimport CommentTextOutline from 'vue-material-design-icons/CommentTextOutline.vue'\nimport FileOutline from 'vue-material-design-icons/FileOutline.vue'\nimport ShareVariantOutline from 'vue-material-design-icons/ShareVariantOutline.vue'\nimport TagOutline from 'vue-material-design-icons/TagOutline.vue'\nimport Timeline from 'vue-material-design-icons/Timeline.vue'\nimport CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'\nimport CnVisibilityChip from '../../../components/CnVisibilityChip/CnVisibilityChip.vue'\nimport { buildHeaders, prefixUrl } from '../../../utils/index.js'\n\nconst VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']\nconst COMPACT_LIMIT = 4\n\n/**\n * CnActivityCard — bespoke surface-aware widget for the `activity` integration.\n *\n * Renders activity events across all four surfaces. See the file-level\n * docblock for surface-by-surface behaviour.\n */\nexport default {\n\tname: 'CnActivityCard',\n\n\tcomponents: {\n\t\tCnDetailCard,\n\t\tCnVisibilityChip,\n\t\tNcLoadingIcon,\n\t\tCalendarOutline,\n\t\tTimeline,\n\t\tFileOutline,\n\t\tAccountOutline,\n\t\tCommentTextOutline,\n\t\tShareVariantOutline,\n\t\tTagOutline,\n\t\tCalendarClockOutline,\n\t},\n\n\tprops: {\n\t\t/** Show a visibility chip (internal or public) on each row of the detail-page feed. Off by default. */\n\t\tshowVisibility: { type: Boolean, default: false },\n\t\t/** Stable integration id (forwarded from the registry — always `'activity'`). */\n\t\tintegrationId: { type: String, default: 'activity' },\n\t\t/** OpenRegister register id (slug or uuid). */\n\t\tregister: { type: String, required: true },\n\t\t/** OpenRegister schema id (slug or uuid). */\n\t\tschema: { type: String, required: true },\n\t\t/** Parent object id. */\n\t\tobjectId: { type: String, required: true },\n\t\t/** Rendering surface (AD-19). */\n\t\tsurface: {\n\t\t\ttype: String,\n\t\t\tdefault: 'detail-page',\n\t\t\tvalidator: (s) => VALID_SURFACES.includes(s),\n\t\t},\n\n\t\t/** Optional single-entity reference (event id). */\n\t\tvalue: { type: [String, Number], default: '' },\n\t\t/** Pre-translated card title. */\n\t\ttitle: { type: String, default: () => t('nextcloud-vue', 'Activity') },\n\t\t/** Optional Material Design Icon component. */\n\t\ticon: { type: Object, default: () => Timeline },\n\t\t/** Base API URL. */\n\t\tapiBase: { type: String, default: '/apps/openregister/api' },\n\t\t/** Whether the card body is collapsible. */\n\t\tcollapsible: { type: Boolean, default: true },\n\t\t/** Compact-feed page size for dashboard / detail surfaces. */\n\t\tpageSize: { type: Number, default: 12 },\n\t\t/** Pre-translated empty-state label. */\n\t\temptyLabel: { type: String, default: () => t('nextcloud-vue', 'No activity yet for this object') },\n\t\t/** Pre-translated unavailable label. */\n\t\tunavailableLabel: { type: String, default: () => t('nextcloud-vue', 'NC Activity is currently unavailable.') },\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\tentity: null,\n\t\t\tloading: false,\n\t\t\tdegraded: '',\n\t\t\ttotal: 0,\n\t\t\tCOMPACT_LIMIT,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tcardTitle() {\n\t\t\treturn this.title || this.integrationId\n\t\t},\n\n\t\tcardIcon() {\n\t\t\treturn this.icon\n\t\t},\n\n\t\ttodayCount() {\n\t\t\tconst now = new Date()\n\t\t\tconst start = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime()\n\t\t\tlet count = 0\n\t\t\tfor (const entry of this.entries) {\n\t\t\t\tconst ts = this.timestampFor(entry)\n\t\t\t\tif (ts !== null && ts.getTime() >= start) {\n\t\t\t\t\tcount += 1\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn count\n\t\t},\n\n\t\theadlineLabel() {\n\t\t\tif (this.todayCount > 0) {\n\t\t\t\treturn t('nextcloud-vue', '{n} today', { n: this.todayCount })\n\t\t\t}\n\t\t\tconst total = this.total > 0 ? this.total : this.entries.length\n\t\t\treturn t('nextcloud-vue', '{n} events', { n: total })\n\t\t},\n\n\t\tmostRecent() {\n\t\t\tif (this.entries.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\t// Provider sorts DESC; rely on first row.\n\t\t\treturn this.entries[0]\n\t\t},\n\n\t\tgroupedByDay() {\n\t\t\tconst groups = new Map()\n\t\t\tfor (const entry of this.entries) {\n\t\t\t\tconst ts = this.timestampFor(entry)\n\t\t\t\tconst key = this.dayKey(ts)\n\t\t\t\tif (groups.has(key) === false) {\n\t\t\t\t\tgroups.set(key, { key, label: this.dayLabel(ts), rows: [] })\n\t\t\t\t}\n\t\t\t\tgroups.get(key).rows.push(entry)\n\t\t\t}\n\t\t\treturn [...groups.values()]\n\t\t},\n\t},\n\n\twatch: {\n\t\tobjectId: { immediate: true, handler() {\n\t\t\tthis.fetch()\n\t\t} },\n\n\t\tsurface() {\n\t\t\tthis.fetch()\n\t\t},\n\n\t\tvalue() {\n\t\t\tif (this.surface === 'single-entity') {\n\t\t\t\tthis.fetchSingle()\n\t\t\t}\n\t\t},\n\t},\n\n\tmethods: {\n\t\tbaseUrl() {\n\t\t\treturn `${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/integrations/${this.integrationId}`\n\t\t},\n\n\t\tentryKey(entry) {\n\t\t\treturn entry.id ?? entry.activity_id ?? entry.activityId ?? ''\n\t\t},\n\n\t\ttimestampFor(entry) {\n\t\t\tconst raw = entry.timestamp ?? entry.datetime ?? entry.created ?? entry.creationDateTime ?? null\n\t\t\tif (raw === null || raw === undefined || raw === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (typeof raw === 'number' && raw < 1e12) {\n\t\t\t\treturn new Date(raw * 1000)\n\t\t\t}\n\t\t\tconst parsed = new Date(raw)\n\t\t\treturn Number.isNaN(parsed.getTime()) ? null : parsed\n\t\t},\n\n\t\tdayKey(date) {\n\t\t\tif (date === null) {\n\t\t\t\treturn 'unknown'\n\t\t\t}\n\t\t\treturn `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`\n\t\t},\n\n\t\tdayLabel(date) {\n\t\t\tif (date === null) {\n\t\t\t\treturn t('nextcloud-vue', 'Earlier')\n\t\t\t}\n\t\t\tconst now = new Date()\n\t\t\tconst today = new Date(now.getFullYear(), now.getMonth(), now.getDate())\n\t\t\tconst yesterday = new Date(today.getTime() - 86400000)\n\t\t\tconst start = new Date(date.getFullYear(), date.getMonth(), date.getDate())\n\t\t\tif (start.getTime() === today.getTime()) {\n\t\t\t\treturn t('nextcloud-vue', 'Today')\n\t\t\t}\n\t\t\tif (start.getTime() === yesterday.getTime()) {\n\t\t\t\treturn t('nextcloud-vue', 'Yesterday')\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn date.toLocaleDateString(undefined, { weekday: 'short', day: 'numeric', month: 'short' })\n\t\t\t} catch {\n\t\t\t\treturn date.toISOString().split('T')[0]\n\t\t\t}\n\t\t},\n\n\t\trelativeTime(entry) {\n\t\t\tconst ts = this.timestampFor(entry)\n\t\t\tif (ts === null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn ts.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })\n\t\t\t} catch {\n\t\t\t\treturn ts.toISOString().split('T')[1].slice(0, 5)\n\t\t\t}\n\t\t},\n\n\t\tsubjectFor(entry) {\n\t\t\treturn entry.subject_rich ?? entry.subjectRich ?? entry.subject ?? entry.title ?? ''\n\t\t},\n\n\t\tactorFor(entry) {\n\t\t\treturn entry.actor_id ?? entry.actorDisplayName ?? entry.user ?? entry.affecteduser ?? t('nextcloud-vue', 'System')\n\t\t},\n\n\t\ticonFor(entry) {\n\t\t\tconst type = String(entry.type ?? '').toLowerCase()\n\t\t\tif (type.includes('file') || type.includes('upload') || type.includes('change')) {\n\t\t\t\treturn 'FileOutline'\n\t\t\t}\n\t\t\tif (type.includes('comment')) {\n\t\t\t\treturn 'CommentTextOutline'\n\t\t\t}\n\t\t\tif (type.includes('share')) {\n\t\t\t\treturn 'ShareVariantOutline'\n\t\t\t}\n\t\t\tif (type.includes('tag')) {\n\t\t\t\treturn 'TagOutline'\n\t\t\t}\n\t\t\tif (type.includes('calendar') || type.includes('event')) {\n\t\t\t\treturn 'CalendarClockOutline'\n\t\t\t}\n\t\t\tif (type.includes('user') || type.includes('account')) {\n\t\t\t\treturn 'AccountOutline'\n\t\t\t}\n\t\t\treturn 'Timeline'\n\t\t},\n\n\t\tfetch() {\n\t\t\tif (this.surface === 'single-entity') {\n\t\t\t\tthis.fetchSingle()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.fetchList()\n\t\t},\n\n\t\tasync fetchList() {\n\t\t\tif (!this.register || !this.schema || !this.objectId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\tthis.degraded = ''\n\t\t\ttry {\n\t\t\t\tconst params = new URLSearchParams({ limit: String(this.pageSize) })\n\t\t\t\tconst response = await fetch(prefixUrl(`${this.baseUrl()}?${params.toString()}`), { headers: buildHeaders() })\n\t\t\t\tif (response.ok) {\n\t\t\t\t\tconst data = await response.json()\n\t\t\t\t\tthis.entries = data.results || data.items || (Array.isArray(data) ? data : []) || []\n\t\t\t\t\tthis.total = Number(data.total ?? 0)\n\t\t\t\t} else if (response.status === 503) {\n\t\t\t\t\tthis.entries = []\n\t\t\t\t\tthis.degraded = this.unavailableLabel\n\t\t\t\t} else {\n\t\t\t\t\tthis.entries = []\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error('[CnActivityCard] failed to fetch activity', err)\n\t\t\t\tthis.entries = []\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\tasync fetchSingle() {\n\t\t\tif (this.value === '' || this.value === null || this.value === undefined\n\t\t\t\t|| !this.register || !this.schema || !this.objectId) {\n\t\t\t\tthis.entity = null\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\tthis.degraded = ''\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(prefixUrl(`${this.baseUrl()}/${encodeURIComponent(String(this.value))}`), { headers: buildHeaders() })\n\t\t\t\tif (response.ok) {\n\t\t\t\t\tthis.entity = await response.json()\n\t\t\t\t} else if (response.status === 503) {\n\t\t\t\t\tthis.entity = null\n\t\t\t\t\tthis.degraded = this.unavailableLabel\n\t\t\t\t} else {\n\t\t\t\t\tthis.entity = null\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error('[CnActivityCard] failed to fetch single event', err)\n\t\t\t\tthis.entity = null\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-activity-card__empty {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.9em;\n\tpadding: 8px 0;\n}\n\n.cn-activity-card__headline {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n\n.cn-activity-card__headline-line {\n\tfont-size: 1.05em;\n\tcolor: var(--color-main-text);\n}\n\n.cn-activity-card__headline-recent {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tfont-size: 0.9em;\n\tcolor: var(--color-text-maxcontrast);\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.cn-activity-card__headline-actor {\n\tfont-weight: 500;\n}\n\n.cn-activity-card__headline-subject {\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n.cn-activity-card__chip {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 4px 8px;\n\tborder-radius: 12px;\n\tbackground: var(--color-background-hover);\n\tfont-size: 0.9em;\n\tmax-width: 100%;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n.cn-activity-card__chip-label {\n\tdisplay: inline-flex;\n\tgap: 4px;\n\tcolor: var(--color-main-text);\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.cn-activity-card__chip-actor {\n\tfont-weight: 500;\n}\n\n.cn-activity-card__chip-sep {\n\topacity: 0.6;\n}\n\n.cn-activity-card__chip-subject {\n\tcolor: var(--color-text-maxcontrast);\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n.cn-activity-card__day {\n\tmargin-bottom: 10px;\n}\n\n.cn-activity-card__day-header {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 4px 0;\n\tfont-size: 0.8em;\n\tfont-weight: 600;\n\tcolor: var(--color-text-maxcontrast);\n\tborder-bottom: 1px solid var(--color-border);\n}\n\n.cn-activity-card__day-count {\n\tmargin-left: auto;\n\tfont-weight: normal;\n\tfont-size: 0.8em;\n\tpadding: 1px 6px;\n\tborder-radius: 9px;\n\tbackground: var(--color-background-hover);\n}\n\n.cn-activity-card__list {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.cn-activity-card__row {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 6px;\n\tpadding: 6px 0;\n}\n\n.cn-activity-card__row-main {\n\tflex: 1;\n\tmin-width: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.cn-activity-card__row-subject {\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\tcolor: var(--color-main-text);\n\tfont-size: 0.95em;\n}\n\n.cn-activity-card__row-meta {\n\tfont-size: 0.8em;\n\tcolor: var(--color-text-maxcontrast);\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n</style>\n"],"names":["_createBlock","_createElementBlock","_Fragment","_openBlock","_resolveDynamicComponent","_createElementVNode","_toDisplayString","_createVNode"],"mappings":"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"}
1
+ {"version":3,"file":"CnActivityCard.vue3.js","sources":["../../../../../src/integrations/builtin/activity/CnActivityCard.vue?vue&type=template&id=287c17fa&lang.js"],"sourcesContent":["<!--\n CnActivityCard — bespoke surface-aware widget for the `activity` integration.\n\n Replaces the generic CnIntegrationCard for the `activity` leaf. Branches\n on `surface` per AD-19:\n - user-dashboard / app-dashboard : headline count of activity events\n (with a \"today\" sub-count) + most-recent line summarising the\n latest event (actor + verb + time).\n - detail-page : compact chronological feed grouped\n by day (mirrors the tab layout at a smaller scale).\n - single-entity : chip with type icon + actor +\n subject (referenceType: 'activity').\n\n Pulls rows from the same OR pluggable-integration sub-resource as\n CnActivityTab; for `single-entity` the optional `value` prop addresses\n a single event by id (matching CnIntegrationCard's fetchSingle\n contract).\n\n See `openregister/openspec/changes/integration-activity/` for the spec\n delta and ADR-019 (registry mechanism), AD-19 (surface fallback).\n-->\n<template>\n\t<CnDetailCard :title=\"cardTitle\" :icon=\"cardIcon\" :collapsible=\"collapsible\">\n\t\t<NcLoadingIcon v-if=\"loading\" />\n\n\t\t<!-- single-entity surface: chip -->\n\t\t<template v-else-if=\"surface === 'single-entity'\">\n\t\t\t<span v-if=\"entity\" class=\"cn-activity-card__chip\" :title=\"subjectFor(entity)\">\n\t\t\t\t<component :is=\"iconFor(entity)\" :size=\"14\" />\n\t\t\t\t<span class=\"cn-activity-card__chip-label\">\n\t\t\t\t\t<span class=\"cn-activity-card__chip-actor\">{{ actorFor(entity) }}</span>\n\t\t\t\t\t<span class=\"cn-activity-card__chip-sep\">·</span>\n\t\t\t\t\t<span class=\"cn-activity-card__chip-subject\">{{ subjectFor(entity) }}</span>\n\t\t\t\t</span>\n\t\t\t</span>\n\t\t\t<span v-else class=\"cn-activity-card__empty\">{{ emptyLabel }}</span>\n\t\t</template>\n\n\t\t<!-- dashboard surfaces: headline count + most-recent line -->\n\t\t<template v-else-if=\"surface === 'user-dashboard' || surface === 'app-dashboard'\">\n\t\t\t<div v-if=\"degraded\" class=\"cn-activity-card__empty\">\n\t\t\t\t{{ degraded }}\n\t\t\t</div>\n\t\t\t<div v-else-if=\"entries.length === 0\" class=\"cn-activity-card__empty\">\n\t\t\t\t{{ emptyLabel }}\n\t\t\t</div>\n\t\t\t<div v-else class=\"cn-activity-card__headline\">\n\t\t\t\t<div class=\"cn-activity-card__headline-line\">\n\t\t\t\t\t<strong>{{ headlineLabel }}</strong>\n\t\t\t\t</div>\n\t\t\t\t<div v-if=\"mostRecent\" class=\"cn-activity-card__headline-recent\">\n\t\t\t\t\t<component :is=\"iconFor(mostRecent)\" :size=\"14\" />\n\t\t\t\t\t<span class=\"cn-activity-card__headline-actor\">{{ actorFor(mostRecent) }}</span>\n\t\t\t\t\t<span class=\"cn-activity-card__chip-sep\">·</span>\n\t\t\t\t\t<span class=\"cn-activity-card__headline-subject\">{{ subjectFor(mostRecent) }}</span>\n\t\t\t\t\t<span class=\"cn-activity-card__chip-sep\">·</span>\n\t\t\t\t\t<span class=\"cn-activity-card__headline-time\">{{ relativeTime(mostRecent) }}</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<!-- detail-page surface: compact timeline -->\n\t\t<template v-else>\n\t\t\t<div v-if=\"degraded\" class=\"cn-activity-card__empty\">\n\t\t\t\t{{ degraded }}\n\t\t\t</div>\n\t\t\t<div v-else-if=\"entries.length === 0\" class=\"cn-activity-card__empty\">\n\t\t\t\t{{ emptyLabel }}\n\t\t\t</div>\n\t\t\t<div v-else class=\"cn-activity-card__timeline\">\n\t\t\t\t<section\n\t\t\t\t\tv-for=\"day in groupedByDay\"\n\t\t\t\t\t:key=\"day.key\"\n\t\t\t\t\tclass=\"cn-activity-card__day\">\n\t\t\t\t\t<header class=\"cn-activity-card__day-header\">\n\t\t\t\t\t\t<CalendarOutline :size=\"14\" />\n\t\t\t\t\t\t<span>{{ day.label }}</span>\n\t\t\t\t\t\t<span class=\"cn-activity-card__day-count\">{{ day.rows.length }}</span>\n\t\t\t\t\t</header>\n\t\t\t\t\t<ul class=\"cn-activity-card__list\">\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tv-for=\"entry in day.rows.slice(0, COMPACT_LIMIT)\"\n\t\t\t\t\t\t\t:key=\"entryKey(entry)\"\n\t\t\t\t\t\t\tclass=\"cn-activity-card__row\">\n\t\t\t\t\t\t\t<component :is=\"iconFor(entry)\" :size=\"14\" />\n\t\t\t\t\t\t\t<div class=\"cn-activity-card__row-main\">\n\t\t\t\t\t\t\t\t<span class=\"cn-activity-card__row-subject\">{{ subjectFor(entry) }}</span>\n\t\t\t\t\t\t\t\t<span class=\"cn-activity-card__row-meta\">\n\t\t\t\t\t\t\t\t\t{{ actorFor(entry) }} · {{ relativeTime(entry) }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<CnVisibilityChip v-if=\"showVisibility\" :visibility=\"entry.visibility\" />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t</template>\n\t</CnDetailCard>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcLoadingIcon } from '@nextcloud/vue'\nimport AccountOutline from 'vue-material-design-icons/AccountOutline.vue'\nimport CalendarClockOutline from 'vue-material-design-icons/CalendarClockOutline.vue'\nimport CalendarOutline from 'vue-material-design-icons/CalendarOutline.vue'\nimport CommentTextOutline from 'vue-material-design-icons/CommentTextOutline.vue'\nimport FileOutline from 'vue-material-design-icons/FileOutline.vue'\nimport ShareVariantOutline from 'vue-material-design-icons/ShareVariantOutline.vue'\nimport TagOutline from 'vue-material-design-icons/TagOutline.vue'\nimport Timeline from 'vue-material-design-icons/Timeline.vue'\nimport CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'\nimport CnVisibilityChip from '../../../components/CnVisibilityChip/CnVisibilityChip.vue'\nimport { buildHeaders, prefixUrl } from '../../../utils/index.js'\nimport { userLocale } from '../../../utils/userLocale.js'\n\nconst VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']\nconst COMPACT_LIMIT = 4\n\n/**\n * CnActivityCard — bespoke surface-aware widget for the `activity` integration.\n *\n * Renders activity events across all four surfaces. See the file-level\n * docblock for surface-by-surface behaviour.\n */\nexport default {\n\tname: 'CnActivityCard',\n\n\tcomponents: {\n\t\tCnDetailCard,\n\t\tCnVisibilityChip,\n\t\tNcLoadingIcon,\n\t\tCalendarOutline,\n\t\tTimeline,\n\t\tFileOutline,\n\t\tAccountOutline,\n\t\tCommentTextOutline,\n\t\tShareVariantOutline,\n\t\tTagOutline,\n\t\tCalendarClockOutline,\n\t},\n\n\tprops: {\n\t\t/** Show a visibility chip (internal or public) on each row of the detail-page feed. Off by default. */\n\t\tshowVisibility: { type: Boolean, default: false },\n\t\t/** Stable integration id (forwarded from the registry — always `'activity'`). */\n\t\tintegrationId: { type: String, default: 'activity' },\n\t\t/** OpenRegister register id (slug or uuid). */\n\t\tregister: { type: String, required: true },\n\t\t/** OpenRegister schema id (slug or uuid). */\n\t\tschema: { type: String, required: true },\n\t\t/** Parent object id. */\n\t\tobjectId: { type: String, required: true },\n\t\t/** Rendering surface (AD-19). */\n\t\tsurface: {\n\t\t\ttype: String,\n\t\t\tdefault: 'detail-page',\n\t\t\tvalidator: (s) => VALID_SURFACES.includes(s),\n\t\t},\n\n\t\t/** Optional single-entity reference (event id). */\n\t\tvalue: { type: [String, Number], default: '' },\n\t\t/** Pre-translated card title. */\n\t\ttitle: { type: String, default: () => t('nextcloud-vue', 'Activity') },\n\t\t/** Optional Material Design Icon component. */\n\t\ticon: { type: Object, default: () => Timeline },\n\t\t/** Base API URL. */\n\t\tapiBase: { type: String, default: '/apps/openregister/api' },\n\t\t/** Whether the card body is collapsible. */\n\t\tcollapsible: { type: Boolean, default: true },\n\t\t/** Compact-feed page size for dashboard / detail surfaces. */\n\t\tpageSize: { type: Number, default: 12 },\n\t\t/** Pre-translated empty-state label. */\n\t\temptyLabel: { type: String, default: () => t('nextcloud-vue', 'No activity yet for this object') },\n\t\t/** Pre-translated unavailable label. */\n\t\tunavailableLabel: { type: String, default: () => t('nextcloud-vue', 'NC Activity is currently unavailable.') },\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\tentity: null,\n\t\t\tloading: false,\n\t\t\tdegraded: '',\n\t\t\ttotal: 0,\n\t\t\tCOMPACT_LIMIT,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tcardTitle() {\n\t\t\treturn this.title || this.integrationId\n\t\t},\n\n\t\tcardIcon() {\n\t\t\treturn this.icon\n\t\t},\n\n\t\ttodayCount() {\n\t\t\tconst now = new Date()\n\t\t\tconst start = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime()\n\t\t\tlet count = 0\n\t\t\tfor (const entry of this.entries) {\n\t\t\t\tconst ts = this.timestampFor(entry)\n\t\t\t\tif (ts !== null && ts.getTime() >= start) {\n\t\t\t\t\tcount += 1\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn count\n\t\t},\n\n\t\theadlineLabel() {\n\t\t\tif (this.todayCount > 0) {\n\t\t\t\treturn t('nextcloud-vue', '{n} today', { n: this.todayCount })\n\t\t\t}\n\t\t\tconst total = this.total > 0 ? this.total : this.entries.length\n\t\t\treturn t('nextcloud-vue', '{n} events', { n: total })\n\t\t},\n\n\t\tmostRecent() {\n\t\t\tif (this.entries.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\t// Provider sorts DESC; rely on first row.\n\t\t\treturn this.entries[0]\n\t\t},\n\n\t\tgroupedByDay() {\n\t\t\tconst groups = new Map()\n\t\t\tfor (const entry of this.entries) {\n\t\t\t\tconst ts = this.timestampFor(entry)\n\t\t\t\tconst key = this.dayKey(ts)\n\t\t\t\tif (groups.has(key) === false) {\n\t\t\t\t\tgroups.set(key, { key, label: this.dayLabel(ts), rows: [] })\n\t\t\t\t}\n\t\t\t\tgroups.get(key).rows.push(entry)\n\t\t\t}\n\t\t\treturn [...groups.values()]\n\t\t},\n\t},\n\n\twatch: {\n\t\tobjectId: { immediate: true, handler() {\n\t\t\tthis.fetch()\n\t\t} },\n\n\t\tsurface() {\n\t\t\tthis.fetch()\n\t\t},\n\n\t\tvalue() {\n\t\t\tif (this.surface === 'single-entity') {\n\t\t\t\tthis.fetchSingle()\n\t\t\t}\n\t\t},\n\t},\n\n\tmethods: {\n\t\tbaseUrl() {\n\t\t\treturn `${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/integrations/${this.integrationId}`\n\t\t},\n\n\t\tentryKey(entry) {\n\t\t\treturn entry.id ?? entry.activity_id ?? entry.activityId ?? ''\n\t\t},\n\n\t\ttimestampFor(entry) {\n\t\t\tconst raw = entry.timestamp ?? entry.datetime ?? entry.created ?? entry.creationDateTime ?? null\n\t\t\tif (raw === null || raw === undefined || raw === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (typeof raw === 'number' && raw < 1e12) {\n\t\t\t\treturn new Date(raw * 1000)\n\t\t\t}\n\t\t\tconst parsed = new Date(raw)\n\t\t\treturn Number.isNaN(parsed.getTime()) ? null : parsed\n\t\t},\n\n\t\tdayKey(date) {\n\t\t\tif (date === null) {\n\t\t\t\treturn 'unknown'\n\t\t\t}\n\t\t\treturn `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`\n\t\t},\n\n\t\tdayLabel(date) {\n\t\t\tif (date === null) {\n\t\t\t\treturn t('nextcloud-vue', 'Earlier')\n\t\t\t}\n\t\t\tconst now = new Date()\n\t\t\tconst today = new Date(now.getFullYear(), now.getMonth(), now.getDate())\n\t\t\tconst yesterday = new Date(today.getTime() - 86400000)\n\t\t\tconst start = new Date(date.getFullYear(), date.getMonth(), date.getDate())\n\t\t\tif (start.getTime() === today.getTime()) {\n\t\t\t\treturn t('nextcloud-vue', 'Today')\n\t\t\t}\n\t\t\tif (start.getTime() === yesterday.getTime()) {\n\t\t\t\treturn t('nextcloud-vue', 'Yesterday')\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn date.toLocaleDateString(userLocale(), { weekday: 'short', day: 'numeric', month: 'short' })\n\t\t\t} catch {\n\t\t\t\treturn date.toISOString().split('T')[0]\n\t\t\t}\n\t\t},\n\n\t\trelativeTime(entry) {\n\t\t\tconst ts = this.timestampFor(entry)\n\t\t\tif (ts === null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn ts.toLocaleTimeString(userLocale(), { hour: '2-digit', minute: '2-digit' })\n\t\t\t} catch {\n\t\t\t\treturn ts.toISOString().split('T')[1].slice(0, 5)\n\t\t\t}\n\t\t},\n\n\t\tsubjectFor(entry) {\n\t\t\treturn entry.subject_rich ?? entry.subjectRich ?? entry.subject ?? entry.title ?? ''\n\t\t},\n\n\t\tactorFor(entry) {\n\t\t\treturn entry.actor_id ?? entry.actorDisplayName ?? entry.user ?? entry.affecteduser ?? t('nextcloud-vue', 'System')\n\t\t},\n\n\t\ticonFor(entry) {\n\t\t\tconst type = String(entry.type ?? '').toLowerCase()\n\t\t\tif (type.includes('file') || type.includes('upload') || type.includes('change')) {\n\t\t\t\treturn 'FileOutline'\n\t\t\t}\n\t\t\tif (type.includes('comment')) {\n\t\t\t\treturn 'CommentTextOutline'\n\t\t\t}\n\t\t\tif (type.includes('share')) {\n\t\t\t\treturn 'ShareVariantOutline'\n\t\t\t}\n\t\t\tif (type.includes('tag')) {\n\t\t\t\treturn 'TagOutline'\n\t\t\t}\n\t\t\tif (type.includes('calendar') || type.includes('event')) {\n\t\t\t\treturn 'CalendarClockOutline'\n\t\t\t}\n\t\t\tif (type.includes('user') || type.includes('account')) {\n\t\t\t\treturn 'AccountOutline'\n\t\t\t}\n\t\t\treturn 'Timeline'\n\t\t},\n\n\t\tfetch() {\n\t\t\tif (this.surface === 'single-entity') {\n\t\t\t\tthis.fetchSingle()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.fetchList()\n\t\t},\n\n\t\tasync fetchList() {\n\t\t\tif (!this.register || !this.schema || !this.objectId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\tthis.degraded = ''\n\t\t\ttry {\n\t\t\t\tconst params = new URLSearchParams({ limit: String(this.pageSize) })\n\t\t\t\tconst response = await fetch(prefixUrl(`${this.baseUrl()}?${params.toString()}`), { headers: buildHeaders() })\n\t\t\t\tif (response.ok) {\n\t\t\t\t\tconst data = await response.json()\n\t\t\t\t\tthis.entries = data.results || data.items || (Array.isArray(data) ? data : []) || []\n\t\t\t\t\tthis.total = Number(data.total ?? 0)\n\t\t\t\t} else if (response.status === 503) {\n\t\t\t\t\tthis.entries = []\n\t\t\t\t\tthis.degraded = this.unavailableLabel\n\t\t\t\t} else {\n\t\t\t\t\tthis.entries = []\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error('[CnActivityCard] failed to fetch activity', err)\n\t\t\t\tthis.entries = []\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\tasync fetchSingle() {\n\t\t\tif (this.value === '' || this.value === null || this.value === undefined\n\t\t\t\t|| !this.register || !this.schema || !this.objectId) {\n\t\t\t\tthis.entity = null\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\tthis.degraded = ''\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(prefixUrl(`${this.baseUrl()}/${encodeURIComponent(String(this.value))}`), { headers: buildHeaders() })\n\t\t\t\tif (response.ok) {\n\t\t\t\t\tthis.entity = await response.json()\n\t\t\t\t} else if (response.status === 503) {\n\t\t\t\t\tthis.entity = null\n\t\t\t\t\tthis.degraded = this.unavailableLabel\n\t\t\t\t} else {\n\t\t\t\t\tthis.entity = null\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error('[CnActivityCard] failed to fetch single event', err)\n\t\t\t\tthis.entity = null\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-activity-card__empty {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.9em;\n\tpadding: 8px 0;\n}\n\n.cn-activity-card__headline {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n\n.cn-activity-card__headline-line {\n\tfont-size: 1.05em;\n\tcolor: var(--color-main-text);\n}\n\n.cn-activity-card__headline-recent {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tfont-size: 0.9em;\n\tcolor: var(--color-text-maxcontrast);\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.cn-activity-card__headline-actor {\n\tfont-weight: 500;\n}\n\n.cn-activity-card__headline-subject {\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n.cn-activity-card__chip {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 4px 8px;\n\tborder-radius: 12px;\n\tbackground: var(--color-background-hover);\n\tfont-size: 0.9em;\n\tmax-width: 100%;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n.cn-activity-card__chip-label {\n\tdisplay: inline-flex;\n\tgap: 4px;\n\tcolor: var(--color-main-text);\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.cn-activity-card__chip-actor {\n\tfont-weight: 500;\n}\n\n.cn-activity-card__chip-sep {\n\topacity: 0.6;\n}\n\n.cn-activity-card__chip-subject {\n\tcolor: var(--color-text-maxcontrast);\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n.cn-activity-card__day {\n\tmargin-bottom: 10px;\n}\n\n.cn-activity-card__day-header {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 4px 0;\n\tfont-size: 0.8em;\n\tfont-weight: 600;\n\tcolor: var(--color-text-maxcontrast);\n\tborder-bottom: 1px solid var(--color-border);\n}\n\n.cn-activity-card__day-count {\n\tmargin-left: auto;\n\tfont-weight: normal;\n\tfont-size: 0.8em;\n\tpadding: 1px 6px;\n\tborder-radius: 9px;\n\tbackground: var(--color-background-hover);\n}\n\n.cn-activity-card__list {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.cn-activity-card__row {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 6px;\n\tpadding: 6px 0;\n}\n\n.cn-activity-card__row-main {\n\tflex: 1;\n\tmin-width: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.cn-activity-card__row-subject {\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\tcolor: var(--color-main-text);\n\tfont-size: 0.95em;\n}\n\n.cn-activity-card__row-meta {\n\tfont-size: 0.8em;\n\tcolor: var(--color-text-maxcontrast);\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n</style>\n"],"names":["_createBlock","_createElementBlock","_Fragment","_openBlock","_resolveDynamicComponent","_createElementVNode","_toDisplayString","_createVNode"],"mappings":"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"}
@@ -2,7 +2,7 @@ import script from './CnActivityTab.vue2.js';
2
2
  import { render } from './CnActivityTab.vue3.js';
3
3
 
4
4
  script.render = render;
5
- script.__scopeId = "data-v-9e1507d2";
5
+ script.__scopeId = "data-v-bf3b0e7c";
6
6
  const __sfc_main = script;
7
7
 
8
8
  export { __sfc_main as default };
@@ -12,6 +12,7 @@ import TagOutline from 'vue-material-design-icons/TagOutline.vue';
12
12
  import Timeline from 'vue-material-design-icons/Timeline.vue';
13
13
  import __sfc_main from '../../../components/CnVisibilityChip/CnVisibilityChip.vue.js';
14
14
  import { normalizeLook } from '../../../composables/useLook.js';
15
+ import { userLocale } from '../../../utils/userLocale.js';
15
16
  import { ACTIVITY_FEED_KINDS, isReadRow, feedPath, feedQuery, exportBody, parseFeed } from './activityFeedWire.js';
16
17
  import { prefixUrl, buildHeaders } from '../../../utils/headers.js';
17
18
 
@@ -337,7 +338,7 @@ var script = {
337
338
  return translate('nextcloud-vue', 'Yesterday')
338
339
  }
339
340
  try {
340
- return date.toLocaleDateString(undefined, { weekday: 'short', day: 'numeric', month: 'short' })
341
+ return date.toLocaleDateString(userLocale(), { weekday: 'short', day: 'numeric', month: 'short' })
341
342
  } catch {
342
343
  return date.toISOString().split('T')[0]
343
344
  }
@@ -349,7 +350,7 @@ var script = {
349
350
  return ''
350
351
  }
351
352
  try {
352
- return ts.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })
353
+ return ts.toLocaleTimeString(userLocale(), { hour: '2-digit', minute: '2-digit' })
353
354
  } catch {
354
355
  return ts.toISOString().split('T')[1].slice(0, 5)
355
356
  }
@@ -397,7 +398,7 @@ var script = {
397
398
  let when = '';
398
399
  if (ts !== null) {
399
400
  try {
400
- when = ts.toLocaleString(undefined, { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });
401
+ when = ts.toLocaleString(userLocale(), { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });
401
402
  } catch {
402
403
  when = ts.toISOString().replace('T', ' ').slice(0, 16);
403
404
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CnActivityTab.vue2.js","sources":["../../../../../src/integrations/builtin/activity/CnActivityTab.vue"],"sourcesContent":["<!--\n CnActivityTab — bespoke sidebar tab for the `activity` integration.\n\n Reads OpenRegister's MERGED activity feed (audit trail, NC Activity, files,\n notes, mail) for the object, paged on the feed's time cursor, with a chip\n per kind (a kind with no rows still shows, reading 0), reads off by default\n (the reader's choice is remembered per user), a from/until date range and\n an export of what is on screen. The wire names are in `activityFeedWire.js`.\n A server without the merged feed (404/405/501) makes the tab fall back to\n the single-source mode described below, which `legacyFeed` also selects.\n\n Single-source mode: renders a chronological timeline of NC Activity events grouped by day,\n with a type icon + actor + subject text + relative timestamp per row.\n\n Tier-2 surface (read-only — NC Activity entries are core-generated):\n - Filter bar: type dropdown, actor dropdown, date-range segmented\n control (24h / 7d / 30d / all).\n - Cursor-based \"load more\" pagination.\n - NO picker, NO inline create (entries are not user-authored here).\n\n Talks to the OpenRegister Tier-2 activity endpoints:\n GET /api/objects/{register}/{schema}/{objectId}/activity\n ?type=&actor=&after=&limit=&cursor=\n GET /api/integrations/activity/types?object={r}/{s}/{id}\n GET /api/integrations/activity/actors?object={r}/{s}/{id}\n backed by `OCA\\OpenRegister\\Service\\ActivityFilterService`, which wraps\n the wave-5.3 `MarkerLookupTrait` carve-out (NC Activity's single string\n `subject` column is the `[or:{uuid}]` marker target) with the filters\n and cursor pagination above. The carve-out is intentionally preserved.\n\n Surface behaviour:\n - Empty state with neutral copy when no activity matches the filters.\n - Loading + 501/503 \"unavailable\" + generic error banner all match\n CnIntegrationTab's degradation patterns (AD-23).\n\n See `openregister/openspec/changes/integration-activity/` for the spec\n delta and ADR-019 (registry mechanism).\n-->\n<template>\n\t<div class=\"cn-sidebar-tab cn-activity-tab\" :class=\"{ 'cn-activity-tab--board': isBoard }\">\n\t\t<div v-if=\"degraded\" class=\"cn-activity-tab__banner\" role=\"alert\">\n\t\t\t<AlertCircleOutline :size=\"18\" />\n\t\t\t<span>{{ degraded }}</span>\n\t\t</div>\n\n\t\t<!-- The History panel's header in the board look: the title, what the\n\t\t list is, and the two buttons at its end. -->\n\t\t<div v-if=\"isBoard && !degraded\" class=\"cn-activity-tab__board-head\" data-testid=\"cn-activity-board-head\">\n\t\t\t<div class=\"cn-activity-tab__board-titles\">\n\t\t\t\t<h2 class=\"cn-activity-tab__board-title\">\n\t\t\t\t\t{{ historyTitle }}\n\t\t\t\t</h2>\n\t\t\t\t<p class=\"cn-activity-tab__board-subtitle\">\n\t\t\t\t\t{{ historySubtitle }}\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t\t<div class=\"cn-activity-tab__board-actions\">\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"showAddNote\"\n\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\tdata-testid=\"cn-activity-add-note\"\n\t\t\t\t\t@click=\"$emit('add-note')\">\n\t\t\t\t\t{{ addNoteLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"!legacy\"\n\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t:disabled=\"visibleEntries.length === 0 || exporting\"\n\t\t\t\t\tdata-testid=\"cn-activity-export\"\n\t\t\t\t\t@click=\"exportFeed\">\n\t\t\t\t\t{{ exportLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div v-if=\"!degraded\" class=\"cn-activity-tab__filters\">\n\t\t\t<!-- Merged feed: one chip per kind. A kind with no rows keeps its chip, reading 0: gone would say the kind does not exist on this object. -->\n\t\t\t<div\n\t\t\t\tv-if=\"!legacy\"\n\t\t\t\tclass=\"cn-activity-tab__kinds\"\n\t\t\t\trole=\"group\"\n\t\t\t\t:aria-label=\"kindsGroupLabel\"\n\t\t\t\tdata-testid=\"cn-activity-kinds\">\n\t\t\t\t<button\n\t\t\t\t\tv-for=\"kind in feedKinds\"\n\t\t\t\t\t:key=\"kind\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-activity-tab__kind\"\n\t\t\t\t\t:class=\"{ 'cn-activity-tab__kind--active': selectedKinds.includes(kind) }\"\n\t\t\t\t\t:aria-pressed=\"String(selectedKinds.includes(kind))\"\n\t\t\t\t\t:data-testid=\"`cn-activity-kind-${kind}`\"\n\t\t\t\t\t@click=\"toggleKind(kind)\">\n\t\t\t\t\t{{ kindLabel(kind) }}\n\t\t\t\t\t<span class=\"cn-activity-tab__kind-count\" :data-testid=\"`cn-activity-kind-count-${kind}`\">{{ kindCount(kind) }}</span>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div class=\"cn-activity-tab__filter-row\">\n\t\t\t\t<label v-if=\"legacy\" class=\"cn-activity-tab__filter\">\n\t\t\t\t\t<span class=\"cn-activity-tab__filter-label\">{{ typeLabel }}</span>\n\t\t\t\t\t<select\n\t\t\t\t\t\tv-model=\"selectedType\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__select\"\n\t\t\t\t\t\t@change=\"resetAndFetch\">\n\t\t\t\t\t\t<option value=\"\">{{ allTypesLabel }}</option>\n\t\t\t\t\t\t<option v-for=\"ty in types\" :key=\"ty\" :value=\"ty\">{{ ty }}</option>\n\t\t\t\t\t</select>\n\t\t\t\t</label>\n\t\t\t\t<label class=\"cn-activity-tab__filter\">\n\t\t\t\t\t<span class=\"cn-activity-tab__filter-label\">{{ actorLabel }}</span>\n\t\t\t\t\t<select\n\t\t\t\t\t\tv-model=\"selectedActor\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__select\"\n\t\t\t\t\t\t@change=\"resetAndFetch\">\n\t\t\t\t\t\t<option value=\"\">{{ allActorsLabel }}</option>\n\t\t\t\t\t\t<option v-for=\"ac in actors\" :key=\"ac\" :value=\"ac\">{{ ac }}</option>\n\t\t\t\t\t</select>\n\t\t\t\t</label>\n\t\t\t</div>\n\t\t\t<!-- Visibility filter (showVisibility): all, internal, public. A caller served the\n\t\t\t public view sees it fixed at public, with the reason. -->\n\t\t\t<div v-if=\"showVisibility\" class=\"cn-activity-tab__visibility\" data-testid=\"cn-activity-visibility\">\n\t\t\t\t<p v-if=\"publicViewOnly\" class=\"cn-activity-tab__visibility-fixed\" data-testid=\"cn-activity-visibility-fixed\">\n\t\t\t\t\t<CnVisibilityChip visibility=\"public\" />\n\t\t\t\t\t{{ publicOnlyLabel }}\n\t\t\t\t</p>\n\t\t\t\t<label v-else class=\"cn-activity-tab__filter\">\n\t\t\t\t\t<span class=\"cn-activity-tab__filter-label\">{{ visibilityLabel }}</span>\n\t\t\t\t\t<select\n\t\t\t\t\t\tv-model=\"selectedVisibility\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__select\"\n\t\t\t\t\t\tdata-testid=\"cn-activity-visibility-select\"\n\t\t\t\t\t\t@change=\"resetAndFetch\">\n\t\t\t\t\t\t<option value=\"\">{{ allVisibilityLabel }}</option>\n\t\t\t\t\t\t<option value=\"internal\">{{ internalLabel }}</option>\n\t\t\t\t\t\t<option value=\"public\">{{ publicLabel }}</option>\n\t\t\t\t\t</select>\n\t\t\t\t</label>\n\t\t\t</div>\n\t\t\t<label v-if=\"!legacy\" class=\"cn-activity-tab__reads\">\n\t\t\t\t<input\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t:checked=\"showReads\"\n\t\t\t\t\tdata-testid=\"cn-activity-reads\"\n\t\t\t\t\t@change=\"setShowReads($event.target.checked)\">\n\t\t\t\t{{ showReadsLabel }}\n\t\t\t</label>\n\t\t\t<div class=\"cn-activity-tab__range\" role=\"group\" :aria-label=\"rangeGroupLabel\">\n\t\t\t\t<button\n\t\t\t\t\tv-for=\"range in ranges\"\n\t\t\t\t\t:key=\"range.key\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-activity-tab__range-btn\"\n\t\t\t\t\t:class=\"{ 'cn-activity-tab__range-btn--active': selectedRange === range.key }\"\n\t\t\t\t\t@click=\"selectRange(range.key)\">\n\t\t\t\t\t{{ range.label }}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<!-- The range kept as a range: from and until, which is what the feed takes. -->\n\t\t\t<div v-if=\"!legacy\" class=\"cn-activity-tab__dates\">\n\t\t\t\t<label class=\"cn-activity-tab__filter\">\n\t\t\t\t\t<span class=\"cn-activity-tab__filter-label\">{{ fromLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__select\"\n\t\t\t\t\t\t:value=\"fromDate\"\n\t\t\t\t\t\tdata-testid=\"cn-activity-from\"\n\t\t\t\t\t\t@change=\"setDate('fromDate', $event.target.value)\">\n\t\t\t\t</label>\n\t\t\t\t<label class=\"cn-activity-tab__filter\">\n\t\t\t\t\t<span class=\"cn-activity-tab__filter-label\">{{ untilLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__select\"\n\t\t\t\t\t\t:value=\"untilDate\"\n\t\t\t\t\t\tdata-testid=\"cn-activity-until\"\n\t\t\t\t\t\t@change=\"setDate('untilDate', $event.target.value)\">\n\t\t\t\t</label>\n\t\t\t</div>\n\t\t\t<!-- The export is what is on screen: these rows and these filters, nothing re-queried. -->\n\t\t\t<NcButton\n\t\t\t\tv-if=\"!legacy && !isBoard\"\n\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t:disabled=\"visibleEntries.length === 0 || exporting\"\n\t\t\t\tdata-testid=\"cn-activity-export\"\n\t\t\t\t@click=\"exportFeed\">\n\t\t\t\t{{ exportLabel }}\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<NcLoadingIcon v-if=\"loading && entries.length === 0\" />\n\t\t<div v-else-if=\"error\" class=\"cn-activity-tab__error\" role=\"alert\">\n\t\t\t{{ error }}\n\t\t</div>\n\t\t<div v-else-if=\"visibleEntries.length === 0\" class=\"cn-sidebar-tab__empty cn-activity-tab__empty\">\n\t\t\t<Timeline :size=\"32\" class=\"cn-activity-tab__empty-icon\" />\n\t\t\t<p>{{ emptyLabel }}</p>\n\t\t</div>\n\t\t<!-- The board look draws the events as one rail: a 34px icon on a tint\n\t\t of its kind, a connector to the next event, the verb in bold, and a\n\t\t meta line of kind, who and when. -->\n\t\t<div v-else-if=\"isBoard\" class=\"cn-activity-tab__timeline cn-activity-tab__timeline--rail\">\n\t\t\t<ol class=\"cn-activity-tab__rail\" data-testid=\"cn-activity-rail\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"entry in visibleEntries\"\n\t\t\t\t\t:key=\"entryKey(entry)\"\n\t\t\t\t\tclass=\"cn-activity-tab__event\"\n\t\t\t\t\t:class=\"`cn-activity-tab__event--${entry.kind || 'activity'}`\"\n\t\t\t\t\tdata-testid=\"cn-activity-event\">\n\t\t\t\t\t<span class=\"cn-activity-tab__event-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t<component :is=\"iconFor(entry)\" :size=\"18\" />\n\t\t\t\t\t</span>\n\t\t\t\t\t<div class=\"cn-activity-tab__event-body\">\n\t\t\t\t\t\t<p class=\"cn-activity-tab__event-line\">\n\t\t\t\t\t\t\t<strong>{{ splitSubject(entry).verb }}</strong>{{ splitSubject(entry).rest }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p class=\"cn-activity-tab__event-meta\">\n\t\t\t\t\t\t\t{{ eventMeta(entry) }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<CnVisibilityChip v-if=\"showVisibility\" :visibility=\"entry.visibility\" />\n\t\t\t\t</li>\n\t\t\t</ol>\n\t\t\t<div v-if=\"hasMore\" class=\"cn-activity-tab__footer\">\n\t\t\t\t<NcButton\n\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t:wide=\"true\"\n\t\t\t\t\t:disabled=\"loadingMore\"\n\t\t\t\t\t@click=\"loadMore\">\n\t\t\t\t\t<template v-if=\"loadingMore\" #icon>\n\t\t\t\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ loadMoreLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</div>\n\t\t</div>\n\t\t<div v-else class=\"cn-activity-tab__timeline\">\n\t\t\t<section\n\t\t\t\tv-for=\"day in groupedByDay\"\n\t\t\t\t:key=\"day.key\"\n\t\t\t\tclass=\"cn-activity-tab__day\">\n\t\t\t\t<header class=\"cn-activity-tab__day-header\">\n\t\t\t\t\t<CalendarOutline :size=\"16\" />\n\t\t\t\t\t<span class=\"cn-activity-tab__day-label\">{{ day.label }}</span>\n\t\t\t\t\t<span class=\"cn-activity-tab__day-count\">{{ day.rows.length }}</span>\n\t\t\t\t</header>\n\t\t\t\t<ul class=\"cn-activity-tab__list\">\n\t\t\t\t\t<NcListItem\n\t\t\t\t\t\tv-for=\"entry in day.rows\"\n\t\t\t\t\t\t:key=\"entryKey(entry)\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__row\"\n\t\t\t\t\t\t:name=\"subjectFor(entry)\"\n\t\t\t\t\t\t:bold=\"false\"\n\t\t\t\t\t\t:compact=\"true\"\n\t\t\t\t\t\t:forceDisplayActions=\"false\">\n\t\t\t\t\t\t<template #name>\n\t\t\t\t\t\t\t<span class=\"cn-activity-tab__subject\">{{ subjectFor(entry) }}</span>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<span class=\"cn-activity-tab__avatar-wrap\">\n\t\t\t\t\t\t\t\t<NcAvatar\n\t\t\t\t\t\t\t\t\t:user=\"avatarUser(entry)\"\n\t\t\t\t\t\t\t\t\t:displayName=\"actorFor(entry)\"\n\t\t\t\t\t\t\t\t\t:size=\"36\"\n\t\t\t\t\t\t\t\t\t:disableMenu=\"true\"\n\t\t\t\t\t\t\t\t\t:disableTooltip=\"true\"\n\t\t\t\t\t\t\t\t\thideStatus />\n\t\t\t\t\t\t\t\t<span class=\"cn-activity-tab__type-badge\" :class=\"typeBadgeClass(entry)\">\n\t\t\t\t\t\t\t\t\t<component :is=\"iconFor(entry)\" :size=\"12\" />\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<template #subname>\n\t\t\t\t\t\t\t<span class=\"cn-activity-tab__subname\">\n\t\t\t\t\t\t\t\t<span class=\"cn-activity-tab__actor\">{{ actorFor(entry) }}</span>\n\t\t\t\t\t\t\t\t<CnVisibilityChip v-if=\"showVisibility\" :visibility=\"entry.visibility\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<template v-if=\"timestampMillis(entry)\" #details>\n\t\t\t\t\t\t\t<NcDateTime\n\t\t\t\t\t\t\t\tclass=\"cn-activity-tab__time\"\n\t\t\t\t\t\t\t\t:timestamp=\"timestampMillis(entry)\"\n\t\t\t\t\t\t\t\trelativeTime=\"short\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<template v-else #details>\n\t\t\t\t\t\t\t<span class=\"cn-activity-tab__time\">{{ relativeTime(entry) }}</span>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</NcListItem>\n\t\t\t\t</ul>\n\t\t\t</section>\n\t\t\t<div v-if=\"hasMore\" class=\"cn-activity-tab__footer\">\n\t\t\t\t<NcButton\n\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t:wide=\"true\"\n\t\t\t\t\t:disabled=\"loadingMore\"\n\t\t\t\t\t@click=\"loadMore\">\n\t\t\t\t\t<template v-if=\"loadingMore\" #icon>\n\t\t\t\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ loadMoreLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcAvatar, NcButton, NcDateTime, NcListItem, NcLoadingIcon } from '@nextcloud/vue'\nimport AccountOutline from 'vue-material-design-icons/AccountOutline.vue'\nimport AlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'\nimport CalendarClockOutline from 'vue-material-design-icons/CalendarClockOutline.vue'\nimport CalendarOutline from 'vue-material-design-icons/CalendarOutline.vue'\nimport CommentTextOutline from 'vue-material-design-icons/CommentTextOutline.vue'\nimport EmailOutline from 'vue-material-design-icons/EmailOutline.vue'\nimport FileOutline from 'vue-material-design-icons/FileOutline.vue'\nimport ShareVariantOutline from 'vue-material-design-icons/ShareVariantOutline.vue'\nimport TagOutline from 'vue-material-design-icons/TagOutline.vue'\nimport Timeline from 'vue-material-design-icons/Timeline.vue'\nimport CnVisibilityChip from '../../../components/CnVisibilityChip/CnVisibilityChip.vue'\nimport { normalizeLook } from '../../../composables/useLook.js'\nimport { buildHeaders, prefixUrl } from '../../../utils/index.js'\nimport { ACTIVITY_FEED_KINDS, exportBody, feedPath, feedQuery, isReadRow, parseFeed } from './activityFeedWire.js'\n\nconst DEFAULT_PAGE_SIZE = 25\nconst READS_PREFERENCE_KEY = 'activity.showReads'\nconst SECONDS_PER_DAY = 86400\n\n/**\n * CnActivityTab — bespoke chronological timeline for the `activity`\n * integration. Reads the merged feed (audit trail, NC Activity, files, notes,\n * mail) with a chip per kind, a reads toggle that is remembered per user, a\n * from/until range, an export of what is on screen, and cursor pagination on\n * the feed's time cursor. In `legacyFeed` mode (or against a server without\n * the merged feed) it reads the single-source Activity endpoint with type,\n * actor and date filters, as it did before.\n *\n * Renders activity entries grouped by day (today / yesterday / older\n * dates), with type icons, actor name, and a relative timestamp. Reads\n * from the OR Tier-2 activity endpoints; filters drive a fresh fetch,\n * \"load more\" walks the cursor returned by the backend.\n */\nexport default {\n\tname: 'CnActivityTab',\n\n\tcomponents: {\n\t\tCnVisibilityChip,\n\t\tNcAvatar,\n\t\tNcButton,\n\t\tNcDateTime,\n\t\tNcListItem,\n\t\tNcLoadingIcon,\n\t\tAlertCircleOutline,\n\t\tCalendarOutline,\n\t\tEmailOutline,\n\t\tTimeline,\n\t\tFileOutline,\n\t\tAccountOutline,\n\t\tCommentTextOutline,\n\t\tShareVariantOutline,\n\t\tTagOutline,\n\t\tCalendarClockOutline,\n\t},\n\n\tinject: {\n\t\t/** The per-user preference group from CnAppRoot, so \"show reads\" is remembered. */\n\t\tcnUserPreferences: { default: null },\n\t\t/** The app's look, provided by CnAppRoot or CnPageRenderer (`nextcloud` or `board`). */\n\t\tcnLook: { default: 'nextcloud' },\n\t},\n\n\tprops: {\n\n\t\t/** Stable integration id (forwarded from the registry — always `'activity'`). */\n\t\tintegrationId: { type: String, default: 'activity' },\n\n\t\t/** Parent object id. */\n\t\tobjectId: { type: String, required: true },\n\t\t/** OpenRegister register id (slug or uuid). */\n\t\tregister: { type: String, default: '' },\n\t\t/** OpenRegister schema id (slug or uuid). */\n\t\tschema: { type: String, default: '' },\n\t\t/** Base API URL. */\n\t\tapiBase: { type: String, default: '/apps/openregister/api' },\n\t\t/** Number of entries per fetch. */\n\t\tpageSize: { type: Number, default: DEFAULT_PAGE_SIZE },\n\t\t/**\n\t\t * Read the single-source NC Activity endpoint (type, actor, date-range\n\t\t * filters, no kinds, reads toggle or export) instead of the merged feed.\n\t\t * The tab also falls back to it by itself when the server has no merged feed.\n\t\t */\n\t\tlegacyFeed: { type: Boolean, default: false },\n\t\t/**\n\t\t * Show a visibility chip on each row and a visibility filter (all,\n\t\t * internal, public) that sends `visibility` on the fetch. Off by default,\n\t\t * so a host that passes nothing renders the feed as before.\n\t\t */\n\t\tshowVisibility: { type: Boolean, default: false },\n\t\t/**\n\t\t * The server serves this caller the public view only (no `update` on the\n\t\t * object): the filter is then fixed at public and says why, instead of\n\t\t * offering options that change nothing. The host passes it.\n\t\t */\n\t\tpublicViewOnly: { type: Boolean, default: false },\n\t\t/**\n\t\t * Offer an \"Add note\" button in the board look's History header. It\n\t\t * emits `add-note`; the host opens whatever composes the note. Off by\n\t\t * default, so no button points at nothing.\n\t\t */\n\t\tshowAddNote: { type: Boolean, default: false },\n\t\t/** Pre-translated empty-state label. */\n\t\temptyLabel: { type: String, default: () => t('nextcloud-vue', 'No activity yet for this object') },\n\t\t/** Pre-translated unavailable banner. */\n\t\tunavailableLabel: { type: String, default: () => t('nextcloud-vue', 'NC Activity is currently unavailable.') },\n\t\t/** Pre-translated load-more button label. */\n\t\tloadMoreLabel: { type: String, default: () => t('nextcloud-vue', 'Load more') },\n\t},\n\n\temits: ['exported', 'add-note'],\n\n\tdata() {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\ttypes: [],\n\t\t\tactors: [],\n\t\t\tselectedType: '',\n\t\t\tselectedActor: '',\n\t\t\tselectedVisibility: '',\n\t\t\tselectedRange: 'all',\n\t\t\t/** The single-source endpoint is in use: chosen by `legacyFeed`, or after the server had no merged feed. */\n\t\t\tlegacy: this.legacyFeed,\n\t\t\tfeedKinds: ACTIVITY_FEED_KINDS,\n\t\t\t/** Kinds the reader narrowed to; empty = all. */\n\t\t\tselectedKinds: [],\n\t\t\t/** Count per kind, as the feed returned it. */\n\t\t\tkindCounts: {},\n\t\t\t/** Read entries are shown. Off by default; the reader's choice is remembered per user. */\n\t\t\tshowReads: false,\n\t\t\tfromDate: '',\n\t\t\tuntilDate: '',\n\t\t\texporting: false,\n\t\t\tcursor: null,\n\t\t\tloading: false,\n\t\t\tloadingMore: false,\n\t\t\ttotal: 0,\n\t\t\terror: '',\n\t\t\tdegraded: '',\n\t\t\tvisibilityLabel: t('nextcloud-vue', 'Visibility'),\n\t\t\tallVisibilityLabel: t('nextcloud-vue', 'All entries'),\n\t\t\tinternalLabel: t('nextcloud-vue', 'Internal'),\n\t\t\tpublicLabel: t('nextcloud-vue', 'Public'),\n\t\t\tpublicOnlyLabel: t('nextcloud-vue', 'You see the public entries only.'),\n\t\t\ttypeLabel: t('nextcloud-vue', 'Type'),\n\t\t\tactorLabel: t('nextcloud-vue', 'Actor'),\n\t\t\tallTypesLabel: t('nextcloud-vue', 'All types'),\n\t\t\tallActorsLabel: t('nextcloud-vue', 'All actors'),\n\t\t\trangeGroupLabel: t('nextcloud-vue', 'Date range'),\n\t\t\tkindsGroupLabel: t('nextcloud-vue', 'Kinds of activity'),\n\t\t\tshowReadsLabel: t('nextcloud-vue', 'Show reads'),\n\t\t\tfromLabel: t('nextcloud-vue', 'From'),\n\t\t\tuntilLabel: t('nextcloud-vue', 'Until'),\n\t\t\texportLabel: t('nextcloud-vue', 'Export'),\n\t\t\taddNoteLabel: t('nextcloud-vue', 'Add note'),\n\t\t\thistoryTitle: t('nextcloud-vue', 'History'),\n\t\t\thistorySubtitle: t('nextcloud-vue', 'What happened, who did it and when, newest first'),\n\t\t\tranges: [\n\t\t\t\t{ key: '24h', label: t('nextcloud-vue', '24h') },\n\t\t\t\t{ key: '7d', label: t('nextcloud-vue', '7d') },\n\t\t\t\t{ key: '30d', label: t('nextcloud-vue', '30d') },\n\t\t\t\t{ key: 'all', label: t('nextcloud-vue', 'All') },\n\t\t\t],\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Whether the tab is drawn in the board look: the History header, the\n\t\t * filled kind chips and the event rail.\n\t\t *\n\t\t * @return {boolean} True in the board look.\n\t\t * @spec openspec/changes/screens-detail-page-parity/specs/detail-page-board-look/spec.md#requirement-history-is-the-last-tab\n\t\t */\n\t\tisBoard() {\n\t\t\treturn normalizeLook(this.cnLook) === 'board'\n\t\t},\n\n\t\thasMore() {\n\t\t\treturn this.cursor !== null\n\t\t},\n\n\t\t/**\n\t\t * Unix-epoch-seconds lower bound for the selected date range, or\n\t\t * null for \"all\".\n\t\t *\n\t\t * @return {?number} Lower-bound timestamp or null.\n\t\t */\n\t\tafterTimestamp() {\n\t\t\tconst days = { '24h': 1, '7d': 7, '30d': 30 }[this.selectedRange]\n\t\t\tif (!days) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn Math.floor(Date.now() / 1000) - (days * SECONDS_PER_DAY)\n\t\t},\n\n\t\t/**\n\t\t * The rows on screen: reads are left out unless the reader turned them on.\n\t\t * Only an audit row can be a read.\n\t\t *\n\t\t * @return {object[]} The rows.\n\t\t */\n\t\tvisibleEntries() {\n\t\t\tif (this.legacy || this.showReads) {\n\t\t\t\treturn this.entries\n\t\t\t}\n\t\t\treturn this.entries.filter((entry) => !isReadRow(entry))\n\t\t},\n\n\t\tgroupedByDay() {\n\t\t\tconst groups = new Map()\n\t\t\tfor (const entry of this.visibleEntries) {\n\t\t\t\tconst ts = this.timestampFor(entry)\n\t\t\t\tconst key = this.dayKey(ts)\n\t\t\t\tif (groups.has(key) === false) {\n\t\t\t\t\tgroups.set(key, { key, label: this.dayLabel(ts), rows: [] })\n\t\t\t\t}\n\t\t\t\tgroups.get(key).rows.push(entry)\n\t\t\t}\n\t\t\t// Preserve insertion order (entries assumed pre-sorted DESC by\n\t\t\t// the provider). Each day's rows likewise stay in the order\n\t\t\t// they were appended.\n\t\t\treturn [...groups.values()]\n\t\t},\n\t},\n\n\twatch: {\n\t\tobjectId: { immediate: true, handler(id) {\n\t\t\tif (id) {\n\t\t\t\tthis.bootstrap()\n\t\t\t}\n\t\t} },\n\n\t\tregister() {\n\t\t\tthis.bootstrap()\n\t\t},\n\n\t\tschema() {\n\t\t\tthis.bootstrap()\n\t\t},\n\t},\n\n\tmethods: {\n\t\tbaseUrl() {\n\t\t\tif (!this.legacy) {\n\t\t\t\treturn prefixUrl(feedPath(this.objectAddress()))\n\t\t\t}\n\t\t\treturn prefixUrl(`${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/activity`)\n\t\t},\n\n\t\tobjectAddress() {\n\t\t\treturn { apiBase: this.apiBase, register: this.register, schema: this.schema, objectId: this.objectId }\n\t\t},\n\n\t\t/** @return {object} The filters the tab is showing, in the feed's terms. */\n\t\tfeedFilters() {\n\t\t\treturn {\n\t\t\t\tkinds: this.selectedKinds,\n\t\t\t\tfrom: this.fromDate ? new Date(`${this.fromDate}T00:00:00`).toISOString() : '',\n\t\t\t\tuntil: this.untilDate ? new Date(`${this.untilDate}T23:59:59.999`).toISOString() : '',\n\t\t\t\treads: this.showReads,\n\t\t\t\tactor: this.selectedActor,\n\t\t\t\tvisibility: this.showVisibility ? (this.publicViewOnly ? 'public' : this.selectedVisibility) : '',\n\t\t\t\tlimit: this.pageSize,\n\t\t\t}\n\t\t},\n\n\t\tdropdownUrl(kind) {\n\t\t\tconst object = `${this.register}/${this.schema}/${this.objectId}`\n\t\t\treturn prefixUrl(`${this.apiBase}/integrations/activity/${kind}?object=${encodeURIComponent(object)}`)\n\t\t},\n\n\t\tbuildQuery() {\n\t\t\tif (!this.legacy) {\n\t\t\t\treturn feedQuery({ ...this.feedFilters(), cursor: this.cursor })\n\t\t\t}\n\t\t\tconst params = new URLSearchParams()\n\t\t\tparams.set('limit', String(this.pageSize))\n\t\t\tif (this.selectedType) {\n\t\t\t\tparams.set('type', this.selectedType)\n\t\t\t}\n\t\t\tif (this.selectedActor) {\n\t\t\t\tparams.set('actor', this.selectedActor)\n\t\t\t}\n\t\t\tif (this.showVisibility) {\n\t\t\t\tconst visibility = this.publicViewOnly ? 'public' : this.selectedVisibility\n\t\t\t\tif (visibility) {\n\t\t\t\t\tparams.set('visibility', visibility)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.afterTimestamp !== null) {\n\t\t\t\tparams.set('after', String(this.afterTimestamp))\n\t\t\t}\n\t\t\tif (this.cursor !== null) {\n\t\t\t\tparams.set('cursor', String(this.cursor))\n\t\t\t}\n\t\t\treturn params.toString()\n\t\t},\n\n\t\tentryKey(entry) {\n\t\t\treturn entry.id ?? entry.activity_id ?? entry.activityId ?? ''\n\t\t},\n\n\t\ttimestampFor(entry) {\n\t\t\tconst raw = entry.timestamp ?? entry.datetime ?? entry.time ?? entry.at ?? entry.created ?? entry.creationDateTime ?? null\n\t\t\tif (raw === null || raw === undefined || raw === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\t// NC Activity exposes Unix epoch seconds in `timestamp`.\n\t\t\tif (typeof raw === 'number' && raw < 1e12) {\n\t\t\t\treturn new Date(raw * 1000)\n\t\t\t}\n\t\t\tconst parsed = new Date(raw)\n\t\t\treturn Number.isNaN(parsed.getTime()) ? null : parsed\n\t\t},\n\n\t\tdayKey(date) {\n\t\t\tif (date === null) {\n\t\t\t\treturn 'unknown'\n\t\t\t}\n\t\t\treturn `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`\n\t\t},\n\n\t\tdayLabel(date) {\n\t\t\tif (date === null) {\n\t\t\t\treturn t('nextcloud-vue', 'Earlier')\n\t\t\t}\n\t\t\tconst now = new Date()\n\t\t\tconst today = new Date(now.getFullYear(), now.getMonth(), now.getDate())\n\t\t\tconst yesterday = new Date(today.getTime() - 86400000)\n\t\t\tconst start = new Date(date.getFullYear(), date.getMonth(), date.getDate())\n\t\t\tif (start.getTime() === today.getTime()) {\n\t\t\t\treturn t('nextcloud-vue', 'Today')\n\t\t\t}\n\t\t\tif (start.getTime() === yesterday.getTime()) {\n\t\t\t\treturn t('nextcloud-vue', 'Yesterday')\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn date.toLocaleDateString(undefined, { weekday: 'short', day: 'numeric', month: 'short' })\n\t\t\t} catch {\n\t\t\t\treturn date.toISOString().split('T')[0]\n\t\t\t}\n\t\t},\n\n\t\trelativeTime(entry) {\n\t\t\tconst ts = this.timestampFor(entry)\n\t\t\tif (ts === null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn ts.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })\n\t\t\t} catch {\n\t\t\t\treturn ts.toISOString().split('T')[1].slice(0, 5)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Resolve the entry timestamp as epoch-millisecond value for\n\t\t * NcDateTime, or 0 when unknown (callers branch on truthiness).\n\t\t *\n\t\t * @param {object} entry Activity row.\n\t\t * @return {number} Epoch milliseconds, or 0.\n\t\t */\n\t\ttimestampMillis(entry) {\n\t\t\tconst ts = this.timestampFor(entry)\n\t\t\treturn ts === null ? 0 : ts.getTime()\n\t\t},\n\n\t\t/**\n\t\t * Split an event's subject at its first colon: the verb (\"Document\n\t\t * reviewed\") is drawn bold, the rest as written. A subject without a\n\t\t * colon is all verb.\n\t\t *\n\t\t * @param {object} entry Activity row.\n\t\t * @return {{verb: string, rest: string}} The two parts.\n\t\t * @spec openspec/changes/screens-detail-page-parity/specs/detail-page-board-look/spec.md#requirement-history-is-the-last-tab\n\t\t */\n\t\tsplitSubject(entry) {\n\t\t\tconst subject = String(this.subjectFor(entry))\n\t\t\tconst at = subject.indexOf(':')\n\t\t\tif (at <= 0) {\n\t\t\t\treturn { verb: subject, rest: '' }\n\t\t\t}\n\t\t\treturn { verb: subject.slice(0, at + 1), rest: subject.slice(at + 1) }\n\t\t},\n\n\t\t/**\n\t\t * The meta line under an event: kind, who, when.\n\t\t *\n\t\t * @param {object} entry Activity row.\n\t\t * @return {string} For example \"Document · Pieter Jansen · 6 Oct, 15:40\".\n\t\t * @spec openspec/changes/screens-detail-page-parity/specs/detail-page-board-look/spec.md#requirement-history-is-the-last-tab\n\t\t */\n\t\teventMeta(entry) {\n\t\t\tconst ts = this.timestampFor(entry)\n\t\t\tlet when = ''\n\t\t\tif (ts !== null) {\n\t\t\t\ttry {\n\t\t\t\t\twhen = ts.toLocaleString(undefined, { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })\n\t\t\t\t} catch {\n\t\t\t\t\twhen = ts.toISOString().replace('T', ' ').slice(0, 16)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [this.kindLabel(entry.kind || 'activity'), this.actorFor(entry), when].filter((part) => part !== '').join(' \\u00b7 ')\n\t\t},\n\n\t\tsubjectFor(entry) {\n\t\t\treturn entry.subject_rich ?? entry.subjectRich ?? entry.subject ?? entry.summary ?? entry.title ?? ''\n\t\t},\n\n\t\tactorFor(entry) {\n\t\t\treturn entry.actor_id ?? entry.actorDisplayName ?? entry.actor ?? entry.user ?? entry.affecteduser ?? t('nextcloud-vue', 'System')\n\t\t},\n\n\t\t/**\n\t\t * NC user id to seed the actor avatar, when the entry carries a\n\t\t * real account id. Falls back to '' so NcAvatar renders initials\n\t\t * from the display name (e.g. the System pseudo-actor).\n\t\t *\n\t\t * @param {object} entry Activity row.\n\t\t * @return {string} NC user id, or ''.\n\t\t */\n\t\tavatarUser(entry) {\n\t\t\tconst id = entry.actor_id ?? entry.actor ?? entry.user ?? entry.affecteduser ?? ''\n\t\t\treturn typeof id === 'string' ? id : ''\n\t\t},\n\n\t\t/**\n\t\t * Modifier class colouring the small activity-type badge that\n\t\t * overlaps the actor avatar, grouping verbs into NC-Activity-like\n\t\t * families (file / comment / share / tag).\n\t\t *\n\t\t * @param {object} entry Activity row.\n\t\t * @return {string} BEM modifier class.\n\t\t */\n\t\ttypeBadgeClass(entry) {\n\t\t\tconst type = String(entry.type ?? '').toLowerCase()\n\t\t\tif (type.includes('comment')) {\n\t\t\t\treturn 'cn-activity-tab__type-badge--comment'\n\t\t\t}\n\t\t\tif (type.includes('share')) {\n\t\t\t\treturn 'cn-activity-tab__type-badge--share'\n\t\t\t}\n\t\t\tif (type.includes('tag')) {\n\t\t\t\treturn 'cn-activity-tab__type-badge--tag'\n\t\t\t}\n\t\t\treturn 'cn-activity-tab__type-badge--file'\n\t\t},\n\n\t\ticonFor(entry) {\n\t\t\tconst byKind = { file: 'FileOutline', note: 'CommentTextOutline', mail: 'EmailOutline', audit: 'Timeline', activity: 'Timeline' }[entry.kind]\n\t\t\tif (byKind) {\n\t\t\t\treturn byKind\n\t\t\t}\n\t\t\tconst type = String(entry.type ?? '').toLowerCase()\n\t\t\tif (type.includes('file') || type.includes('upload') || type.includes('change')) {\n\t\t\t\treturn 'FileOutline'\n\t\t\t}\n\t\t\tif (type.includes('comment')) {\n\t\t\t\treturn 'CommentTextOutline'\n\t\t\t}\n\t\t\tif (type.includes('share')) {\n\t\t\t\treturn 'ShareVariantOutline'\n\t\t\t}\n\t\t\tif (type.includes('tag')) {\n\t\t\t\treturn 'TagOutline'\n\t\t\t}\n\t\t\tif (type.includes('calendar') || type.includes('event')) {\n\t\t\t\treturn 'CalendarClockOutline'\n\t\t\t}\n\t\t\tif (type.includes('user') || type.includes('account')) {\n\t\t\t\treturn 'AccountOutline'\n\t\t\t}\n\t\t\treturn 'Timeline'\n\t\t},\n\n\t\tselectRange(key) {\n\t\t\tif (this.selectedRange === key) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.selectedRange = key\n\t\t\tif (!this.legacy) {\n\t\t\t\t// A preset is a from date; until stays open.\n\t\t\t\tconst days = { '24h': 1, '7d': 7, '30d': 30 }[key]\n\t\t\t\tthis.fromDate = days ? this.localDate(new Date(Date.now() - (days * SECONDS_PER_DAY * 1000))) : ''\n\t\t\t\tthis.untilDate = ''\n\t\t\t}\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\t/**\n\t\t * @param {Date} date A date.\n\t\t * @return {string} `YYYY-MM-DD` in local time.\n\t\t */\n\t\tlocalDate(date) {\n\t\t\tconst pad = (n) => String(n).padStart(2, '0')\n\t\t\treturn `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`\n\t\t},\n\n\t\t/**\n\t\t * @param {'fromDate'|'untilDate'} field Which end of the range.\n\t\t * @param {string} value `YYYY-MM-DD`, or '' to leave it open.\n\t\t * @return {void}\n\t\t */\n\t\tsetDate(field, value) {\n\t\t\tthis[field] = value\n\t\t\tthis.selectedRange = 'custom'\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\t/**\n\t\t * @param {string} kind A feed kind.\n\t\t * @return {string} Its label.\n\t\t */\n\t\tkindLabel(kind) {\n\t\t\treturn {\n\t\t\t\taudit: t('nextcloud-vue', 'Changes'),\n\t\t\t\tactivity: t('nextcloud-vue', 'Activity'),\n\t\t\t\tfile: t('nextcloud-vue', 'Files'),\n\t\t\t\tnote: t('nextcloud-vue', 'Notes'),\n\t\t\t\tmail: t('nextcloud-vue', 'Mail'),\n\t\t\t}[kind] || kind\n\t\t},\n\n\t\t/**\n\t\t * The count the feed returned for a kind. A kind with no rows reads 0\n\t\t * and keeps its chip.\n\t\t *\n\t\t * @param {string} kind A feed kind.\n\t\t * @return {number} The count.\n\t\t */\n\t\tkindCount(kind) {\n\t\t\treturn this.kindCounts[kind] ?? 0\n\t\t},\n\n\t\ttoggleKind(kind) {\n\t\t\tthis.selectedKinds = this.selectedKinds.includes(kind)\n\t\t\t\t? this.selectedKinds.filter((k) => k !== kind)\n\t\t\t\t: [...this.selectedKinds, kind]\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\t/**\n\t\t * Turn read entries on or off, and remember the choice for this user.\n\t\t *\n\t\t * @param {boolean} on Whether reads are shown.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync setShowReads(on) {\n\t\t\tthis.showReads = !!on\n\t\t\tconst write = this.cnUserPreferences && this.cnUserPreferences.write\n\t\t\ttry {\n\t\t\t\tif (typeof write === 'function') {\n\t\t\t\t\tawait write(READS_PREFERENCE_KEY, this.showReads)\n\t\t\t\t} else if (typeof localStorage !== 'undefined') {\n\t\t\t\t\tlocalStorage.setItem(`cn-pref:${READS_PREFERENCE_KEY}`, JSON.stringify(this.showReads))\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Not remembered; the toggle still works for this session.\n\t\t\t}\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\t/**\n\t\t * Read the reader's remembered choice for the reads toggle.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync loadShowReads() {\n\t\t\ttry {\n\t\t\t\tconst read = this.cnUserPreferences && this.cnUserPreferences.read\n\t\t\t\tif (typeof read === 'function') {\n\t\t\t\t\tthis.showReads = (await read(READS_PREFERENCE_KEY, false)) === true\n\t\t\t\t} else if (typeof localStorage !== 'undefined') {\n\t\t\t\t\tthis.showReads = JSON.parse(localStorage.getItem(`cn-pref:${READS_PREFERENCE_KEY}`) || 'false') === true\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tthis.showReads = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Export what is on screen: the rows shown and the filters that produced\n\t\t * them are sent to the feed's export; nothing is re-queried.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync exportFeed() {\n\t\t\tthis.exporting = true\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(`${this.baseUrl()}/export`, {\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: buildHeaders(),\n\t\t\t\t\tbody: JSON.stringify(exportBody(this.visibleEntries, this.feedFilters())),\n\t\t\t\t})\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`export failed (${response.status})`)\n\t\t\t\t}\n\t\t\t\tconst blob = new Blob([await response.text()], { type: 'text/csv;charset=utf-8' })\n\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\tconst link = document.createElement('a')\n\t\t\t\tlink.href = url\n\t\t\t\tlink.download = `activity-${this.objectId}.csv`\n\t\t\t\tdocument.body.appendChild(link)\n\t\t\t\tlink.click()\n\t\t\t\tlink.remove()\n\t\t\t\tURL.revokeObjectURL(url)\n\t\t\t\t/**\n\t\t\t\t * @event exported Emitted after the feed on screen was exported. Payload: the number of rows.\n\t\t\t\t * @type {number}\n\t\t\t\t */\n\t\t\t\tthis.$emit('exported', this.visibleEntries.length)\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error('[CnActivityTab] export failed', err)\n\t\t\t\tthis.error = t('nextcloud-vue', 'Could not export activity.')\n\t\t\t} finally {\n\t\t\t\tthis.exporting = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Full (re)load: refresh the dropdown sources, then fetch the\n\t\t * first filtered page.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbootstrap() {\n\t\t\tif (!this.register || !this.schema || !this.objectId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.fetchDropdowns()\n\t\t\tif (!this.legacy) {\n\t\t\t\tthis.loadShowReads().then(() => this.resetAndFetch())\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\tresetAndFetch() {\n\t\t\tthis.entries = []\n\t\t\tthis.cursor = null\n\t\t\tthis.total = 0\n\t\t\tthis.fetchEntries()\n\t\t},\n\n\t\t/** The server has no merged feed: read the single-source endpoint, as before. */\n\t\tfallBackToLegacy() {\n\t\t\tthis.legacy = true\n\t\t\tthis.selectedRange = 'all'\n\t\t\tthis.fromDate = ''\n\t\t\tthis.untilDate = ''\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\tasync fetchDropdowns() {\n\t\t\ttry {\n\t\t\t\tconst [typesRes, actorsRes] = await Promise.all([\n\t\t\t\t\tfetch(this.dropdownUrl('types'), { headers: buildHeaders() }),\n\t\t\t\t\tfetch(this.dropdownUrl('actors'), { headers: buildHeaders() }),\n\t\t\t\t])\n\t\t\t\tif (typesRes.ok) {\n\t\t\t\t\tconst data = await typesRes.json()\n\t\t\t\t\tthis.types = data.results || []\n\t\t\t\t}\n\t\t\t\tif (actorsRes.ok) {\n\t\t\t\t\tconst data = await actorsRes.json()\n\t\t\t\t\tthis.actors = data.results || []\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// Dropdown failure is non-fatal — filters just stay empty.\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error('[CnActivityTab] failed to fetch filter options', err)\n\t\t\t}\n\t\t},\n\n\t\tasync fetchEntries() {\n\t\t\tif (!this.register || !this.schema || !this.objectId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst isFirstPage = this.cursor === null\n\t\t\tif (isFirstPage) {\n\t\t\t\tthis.loading = true\n\t\t\t} else {\n\t\t\t\tthis.loadingMore = true\n\t\t\t}\n\t\t\tthis.error = ''\n\t\t\tthis.degraded = ''\n\t\t\tlet noFeed = false\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(`${this.baseUrl()}?${this.buildQuery()}`, { headers: buildHeaders() })\n\t\t\t\tif (!this.legacy && [404, 405, 501].includes(response.status)) {\n\t\t\t\t\t// No merged feed on this server: read the single-source endpoint instead.\n\t\t\t\t\tnoFeed = true\n\t\t\t\t} else if (response.ok && !this.legacy) {\n\t\t\t\t\tconst feed = parseFeed(await response.json())\n\t\t\t\t\tthis.entries = isFirstPage ? feed.rows : [...this.entries, ...feed.rows]\n\t\t\t\t\tthis.kindCounts = feed.counts\n\t\t\t\t\tthis.total = this.entries.length\n\t\t\t\t\tthis.cursor = feed.cursor\n\t\t\t\t} else if (response.ok) {\n\t\t\t\t\tconst data = await response.json()\n\t\t\t\t\tconst rows = data.results || data.items || (Array.isArray(data) ? data : []) || []\n\t\t\t\t\tthis.entries = isFirstPage ? rows : [...this.entries, ...rows]\n\t\t\t\t\tthis.total = Number(data.total ?? 0)\n\t\t\t\t\tconst next = data.nextCursor ?? null\n\t\t\t\t\tthis.cursor = (next === null || next === undefined) ? null : Number(next)\n\t\t\t\t} else if (response.status === 503 || response.status === 501) {\n\t\t\t\t\tif (isFirstPage) {\n\t\t\t\t\t\tthis.entries = []\n\t\t\t\t\t}\n\t\t\t\t\tthis.cursor = null\n\t\t\t\t\tthis.degraded = this.unavailableLabel\n\t\t\t\t} else {\n\t\t\t\t\tif (isFirstPage) {\n\t\t\t\t\t\tthis.entries = []\n\t\t\t\t\t}\n\t\t\t\t\tthis.cursor = null\n\t\t\t\t\tthis.error = t('nextcloud-vue', 'Could not load activity.')\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error('[CnActivityTab] failed to fetch activity', err)\n\t\t\t\tif (isFirstPage) {\n\t\t\t\t\tthis.entries = []\n\t\t\t\t}\n\t\t\t\tthis.cursor = null\n\t\t\t\tthis.error = t('nextcloud-vue', 'Could not load activity.')\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t\tthis.loadingMore = false\n\t\t\t}\n\t\t\tif (noFeed) {\n\t\t\t\tthis.fallBackToLegacy()\n\t\t\t}\n\t\t},\n\n\t\tloadMore() {\n\t\t\tif (this.cursor === null) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.fetchEntries()\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-activity-tab__banner {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 8px 10px;\n\tmargin-bottom: 10px;\n\tborder-radius: var(--border-radius);\n\tbackground: var(--color-warning, #e9a40f);\n\tcolor: var(--color-main-background);\n\tfont-size: 0.9em;\n}\n\n.cn-activity-tab__filters {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmargin-bottom: 12px;\n}\n\n.cn-activity-tab__filter-row {\n\tdisplay: flex;\n\tgap: 8px;\n}\n\n.cn-activity-tab__filter {\n\tflex: 1;\n\tmin-width: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n\n.cn-activity-tab__filter-label {\n\tfont-size: 0.78em;\n\tfont-weight: 600;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-activity-tab__select {\n\twidth: 100%;\n\tmin-height: 34px;\n\tpadding: 4px 6px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n}\n\n.cn-activity-tab__range {\n\tdisplay: flex;\n\tgap: 4px;\n}\n\n.cn-activity-tab__range-btn {\n\tflex: 1;\n\tpadding: 4px 0;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.82em;\n\tcursor: pointer;\n}\n\n.cn-activity-tab__range-btn--active {\n\tbackground: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n\tborder-color: var(--color-primary-element);\n}\n\n.cn-activity-tab__error {\n\tcolor: var(--color-error);\n\tfont-size: 0.9em;\n\tmargin: 4px 0 8px;\n}\n\n.cn-activity-tab__empty {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 16px 8px;\n\tcolor: var(--color-text-maxcontrast);\n\ttext-align: center;\n}\n\n.cn-activity-tab__empty-icon {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-activity-tab__day {\n\tmargin-bottom: 14px;\n}\n\n.cn-activity-tab__day-header {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 4px 0;\n\tfont-size: 0.85em;\n\tfont-weight: 600;\n\tcolor: var(--color-text-maxcontrast);\n\tborder-bottom: 1px solid var(--color-border);\n}\n\n.cn-activity-tab__day-label {\n\tflex: 1;\n}\n\n.cn-activity-tab__day-count {\n\tfont-weight: normal;\n\tfont-size: 0.85em;\n\tpadding: 1px 6px;\n\tborder-radius: 9px;\n\tbackground: var(--color-background-hover);\n}\n\n.cn-activity-tab__list {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n\n/* Actor avatar with an overlapping activity-type badge, mirroring the\n NC Activity feed's per-event glyph. */\n.cn-activity-tab__avatar-wrap {\n\tposition: relative;\n\tdisplay: inline-flex;\n\twidth: 36px;\n\theight: 36px;\n}\n\n.cn-activity-tab__type-badge {\n\tposition: absolute;\n\tright: -2px;\n\tbottom: -2px;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 16px;\n\theight: 16px;\n\tborder-radius: 50%;\n\tborder: 2px solid var(--color-main-background);\n\tcolor: var(--color-primary-element-text);\n\tbackground: var(--color-primary-element);\n}\n\n.cn-activity-tab__type-badge--comment {\n\tbackground: var(--color-success, #46ba61);\n}\n\n.cn-activity-tab__type-badge--share {\n\tbackground: var(--color-primary-element);\n}\n\n.cn-activity-tab__type-badge--tag {\n\tbackground: var(--color-warning, #e9a40f);\n}\n\n.cn-activity-tab__type-badge--file {\n\tbackground: var(--color-text-maxcontrast);\n}\n\n.cn-activity-tab__subject {\n\tcolor: var(--color-main-text);\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n.cn-activity-tab__subname {\n\tdisplay: block;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-activity-tab__actor {\n\tfont-weight: 500;\n}\n\n.cn-activity-tab__time {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.8em;\n\twhite-space: nowrap;\n}\n\n.cn-activity-tab__footer {\n\tmargin-top: 8px;\n}\n</style>\n"],"names":["CnVisibilityChip","t"],"mappings":"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"}
1
+ {"version":3,"file":"CnActivityTab.vue2.js","sources":["../../../../../src/integrations/builtin/activity/CnActivityTab.vue"],"sourcesContent":["<!--\n CnActivityTab — bespoke sidebar tab for the `activity` integration.\n\n Reads OpenRegister's MERGED activity feed (audit trail, NC Activity, files,\n notes, mail) for the object, paged on the feed's time cursor, with a chip\n per kind (a kind with no rows still shows, reading 0), reads off by default\n (the reader's choice is remembered per user), a from/until date range and\n an export of what is on screen. The wire names are in `activityFeedWire.js`.\n A server without the merged feed (404/405/501) makes the tab fall back to\n the single-source mode described below, which `legacyFeed` also selects.\n\n Single-source mode: renders a chronological timeline of NC Activity events grouped by day,\n with a type icon + actor + subject text + relative timestamp per row.\n\n Tier-2 surface (read-only — NC Activity entries are core-generated):\n - Filter bar: type dropdown, actor dropdown, date-range segmented\n control (24h / 7d / 30d / all).\n - Cursor-based \"load more\" pagination.\n - NO picker, NO inline create (entries are not user-authored here).\n\n Talks to the OpenRegister Tier-2 activity endpoints:\n GET /api/objects/{register}/{schema}/{objectId}/activity\n ?type=&actor=&after=&limit=&cursor=\n GET /api/integrations/activity/types?object={r}/{s}/{id}\n GET /api/integrations/activity/actors?object={r}/{s}/{id}\n backed by `OCA\\OpenRegister\\Service\\ActivityFilterService`, which wraps\n the wave-5.3 `MarkerLookupTrait` carve-out (NC Activity's single string\n `subject` column is the `[or:{uuid}]` marker target) with the filters\n and cursor pagination above. The carve-out is intentionally preserved.\n\n Surface behaviour:\n - Empty state with neutral copy when no activity matches the filters.\n - Loading + 501/503 \"unavailable\" + generic error banner all match\n CnIntegrationTab's degradation patterns (AD-23).\n\n See `openregister/openspec/changes/integration-activity/` for the spec\n delta and ADR-019 (registry mechanism).\n-->\n<template>\n\t<div class=\"cn-sidebar-tab cn-activity-tab\" :class=\"{ 'cn-activity-tab--board': isBoard }\">\n\t\t<div v-if=\"degraded\" class=\"cn-activity-tab__banner\" role=\"alert\">\n\t\t\t<AlertCircleOutline :size=\"18\" />\n\t\t\t<span>{{ degraded }}</span>\n\t\t</div>\n\n\t\t<!-- The History panel's header in the board look: the title, what the\n\t\t list is, and the two buttons at its end. -->\n\t\t<div v-if=\"isBoard && !degraded\" class=\"cn-activity-tab__board-head\" data-testid=\"cn-activity-board-head\">\n\t\t\t<div class=\"cn-activity-tab__board-titles\">\n\t\t\t\t<h2 class=\"cn-activity-tab__board-title\">\n\t\t\t\t\t{{ historyTitle }}\n\t\t\t\t</h2>\n\t\t\t\t<p class=\"cn-activity-tab__board-subtitle\">\n\t\t\t\t\t{{ historySubtitle }}\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t\t<div class=\"cn-activity-tab__board-actions\">\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"showAddNote\"\n\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\tdata-testid=\"cn-activity-add-note\"\n\t\t\t\t\t@click=\"$emit('add-note')\">\n\t\t\t\t\t{{ addNoteLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"!legacy\"\n\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t:disabled=\"visibleEntries.length === 0 || exporting\"\n\t\t\t\t\tdata-testid=\"cn-activity-export\"\n\t\t\t\t\t@click=\"exportFeed\">\n\t\t\t\t\t{{ exportLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div v-if=\"!degraded\" class=\"cn-activity-tab__filters\">\n\t\t\t<!-- Merged feed: one chip per kind. A kind with no rows keeps its chip, reading 0: gone would say the kind does not exist on this object. -->\n\t\t\t<div\n\t\t\t\tv-if=\"!legacy\"\n\t\t\t\tclass=\"cn-activity-tab__kinds\"\n\t\t\t\trole=\"group\"\n\t\t\t\t:aria-label=\"kindsGroupLabel\"\n\t\t\t\tdata-testid=\"cn-activity-kinds\">\n\t\t\t\t<button\n\t\t\t\t\tv-for=\"kind in feedKinds\"\n\t\t\t\t\t:key=\"kind\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-activity-tab__kind\"\n\t\t\t\t\t:class=\"{ 'cn-activity-tab__kind--active': selectedKinds.includes(kind) }\"\n\t\t\t\t\t:aria-pressed=\"String(selectedKinds.includes(kind))\"\n\t\t\t\t\t:data-testid=\"`cn-activity-kind-${kind}`\"\n\t\t\t\t\t@click=\"toggleKind(kind)\">\n\t\t\t\t\t{{ kindLabel(kind) }}\n\t\t\t\t\t<span class=\"cn-activity-tab__kind-count\" :data-testid=\"`cn-activity-kind-count-${kind}`\">{{ kindCount(kind) }}</span>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div class=\"cn-activity-tab__filter-row\">\n\t\t\t\t<label v-if=\"legacy\" class=\"cn-activity-tab__filter\">\n\t\t\t\t\t<span class=\"cn-activity-tab__filter-label\">{{ typeLabel }}</span>\n\t\t\t\t\t<select\n\t\t\t\t\t\tv-model=\"selectedType\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__select\"\n\t\t\t\t\t\t@change=\"resetAndFetch\">\n\t\t\t\t\t\t<option value=\"\">{{ allTypesLabel }}</option>\n\t\t\t\t\t\t<option v-for=\"ty in types\" :key=\"ty\" :value=\"ty\">{{ ty }}</option>\n\t\t\t\t\t</select>\n\t\t\t\t</label>\n\t\t\t\t<label class=\"cn-activity-tab__filter\">\n\t\t\t\t\t<span class=\"cn-activity-tab__filter-label\">{{ actorLabel }}</span>\n\t\t\t\t\t<select\n\t\t\t\t\t\tv-model=\"selectedActor\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__select\"\n\t\t\t\t\t\t@change=\"resetAndFetch\">\n\t\t\t\t\t\t<option value=\"\">{{ allActorsLabel }}</option>\n\t\t\t\t\t\t<option v-for=\"ac in actors\" :key=\"ac\" :value=\"ac\">{{ ac }}</option>\n\t\t\t\t\t</select>\n\t\t\t\t</label>\n\t\t\t</div>\n\t\t\t<!-- Visibility filter (showVisibility): all, internal, public. A caller served the\n\t\t\t public view sees it fixed at public, with the reason. -->\n\t\t\t<div v-if=\"showVisibility\" class=\"cn-activity-tab__visibility\" data-testid=\"cn-activity-visibility\">\n\t\t\t\t<p v-if=\"publicViewOnly\" class=\"cn-activity-tab__visibility-fixed\" data-testid=\"cn-activity-visibility-fixed\">\n\t\t\t\t\t<CnVisibilityChip visibility=\"public\" />\n\t\t\t\t\t{{ publicOnlyLabel }}\n\t\t\t\t</p>\n\t\t\t\t<label v-else class=\"cn-activity-tab__filter\">\n\t\t\t\t\t<span class=\"cn-activity-tab__filter-label\">{{ visibilityLabel }}</span>\n\t\t\t\t\t<select\n\t\t\t\t\t\tv-model=\"selectedVisibility\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__select\"\n\t\t\t\t\t\tdata-testid=\"cn-activity-visibility-select\"\n\t\t\t\t\t\t@change=\"resetAndFetch\">\n\t\t\t\t\t\t<option value=\"\">{{ allVisibilityLabel }}</option>\n\t\t\t\t\t\t<option value=\"internal\">{{ internalLabel }}</option>\n\t\t\t\t\t\t<option value=\"public\">{{ publicLabel }}</option>\n\t\t\t\t\t</select>\n\t\t\t\t</label>\n\t\t\t</div>\n\t\t\t<label v-if=\"!legacy\" class=\"cn-activity-tab__reads\">\n\t\t\t\t<input\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t:checked=\"showReads\"\n\t\t\t\t\tdata-testid=\"cn-activity-reads\"\n\t\t\t\t\t@change=\"setShowReads($event.target.checked)\">\n\t\t\t\t{{ showReadsLabel }}\n\t\t\t</label>\n\t\t\t<div class=\"cn-activity-tab__range\" role=\"group\" :aria-label=\"rangeGroupLabel\">\n\t\t\t\t<button\n\t\t\t\t\tv-for=\"range in ranges\"\n\t\t\t\t\t:key=\"range.key\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-activity-tab__range-btn\"\n\t\t\t\t\t:class=\"{ 'cn-activity-tab__range-btn--active': selectedRange === range.key }\"\n\t\t\t\t\t@click=\"selectRange(range.key)\">\n\t\t\t\t\t{{ range.label }}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<!-- The range kept as a range: from and until, which is what the feed takes. -->\n\t\t\t<div v-if=\"!legacy\" class=\"cn-activity-tab__dates\">\n\t\t\t\t<label class=\"cn-activity-tab__filter\">\n\t\t\t\t\t<span class=\"cn-activity-tab__filter-label\">{{ fromLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__select\"\n\t\t\t\t\t\t:value=\"fromDate\"\n\t\t\t\t\t\tdata-testid=\"cn-activity-from\"\n\t\t\t\t\t\t@change=\"setDate('fromDate', $event.target.value)\">\n\t\t\t\t</label>\n\t\t\t\t<label class=\"cn-activity-tab__filter\">\n\t\t\t\t\t<span class=\"cn-activity-tab__filter-label\">{{ untilLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__select\"\n\t\t\t\t\t\t:value=\"untilDate\"\n\t\t\t\t\t\tdata-testid=\"cn-activity-until\"\n\t\t\t\t\t\t@change=\"setDate('untilDate', $event.target.value)\">\n\t\t\t\t</label>\n\t\t\t</div>\n\t\t\t<!-- The export is what is on screen: these rows and these filters, nothing re-queried. -->\n\t\t\t<NcButton\n\t\t\t\tv-if=\"!legacy && !isBoard\"\n\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t:disabled=\"visibleEntries.length === 0 || exporting\"\n\t\t\t\tdata-testid=\"cn-activity-export\"\n\t\t\t\t@click=\"exportFeed\">\n\t\t\t\t{{ exportLabel }}\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<NcLoadingIcon v-if=\"loading && entries.length === 0\" />\n\t\t<div v-else-if=\"error\" class=\"cn-activity-tab__error\" role=\"alert\">\n\t\t\t{{ error }}\n\t\t</div>\n\t\t<div v-else-if=\"visibleEntries.length === 0\" class=\"cn-sidebar-tab__empty cn-activity-tab__empty\">\n\t\t\t<Timeline :size=\"32\" class=\"cn-activity-tab__empty-icon\" />\n\t\t\t<p>{{ emptyLabel }}</p>\n\t\t</div>\n\t\t<!-- The board look draws the events as one rail: a 34px icon on a tint\n\t\t of its kind, a connector to the next event, the verb in bold, and a\n\t\t meta line of kind, who and when. -->\n\t\t<div v-else-if=\"isBoard\" class=\"cn-activity-tab__timeline cn-activity-tab__timeline--rail\">\n\t\t\t<ol class=\"cn-activity-tab__rail\" data-testid=\"cn-activity-rail\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"entry in visibleEntries\"\n\t\t\t\t\t:key=\"entryKey(entry)\"\n\t\t\t\t\tclass=\"cn-activity-tab__event\"\n\t\t\t\t\t:class=\"`cn-activity-tab__event--${entry.kind || 'activity'}`\"\n\t\t\t\t\tdata-testid=\"cn-activity-event\">\n\t\t\t\t\t<span class=\"cn-activity-tab__event-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t<component :is=\"iconFor(entry)\" :size=\"18\" />\n\t\t\t\t\t</span>\n\t\t\t\t\t<div class=\"cn-activity-tab__event-body\">\n\t\t\t\t\t\t<p class=\"cn-activity-tab__event-line\">\n\t\t\t\t\t\t\t<strong>{{ splitSubject(entry).verb }}</strong>{{ splitSubject(entry).rest }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p class=\"cn-activity-tab__event-meta\">\n\t\t\t\t\t\t\t{{ eventMeta(entry) }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t<CnVisibilityChip v-if=\"showVisibility\" :visibility=\"entry.visibility\" />\n\t\t\t\t</li>\n\t\t\t</ol>\n\t\t\t<div v-if=\"hasMore\" class=\"cn-activity-tab__footer\">\n\t\t\t\t<NcButton\n\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t:wide=\"true\"\n\t\t\t\t\t:disabled=\"loadingMore\"\n\t\t\t\t\t@click=\"loadMore\">\n\t\t\t\t\t<template v-if=\"loadingMore\" #icon>\n\t\t\t\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ loadMoreLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</div>\n\t\t</div>\n\t\t<div v-else class=\"cn-activity-tab__timeline\">\n\t\t\t<section\n\t\t\t\tv-for=\"day in groupedByDay\"\n\t\t\t\t:key=\"day.key\"\n\t\t\t\tclass=\"cn-activity-tab__day\">\n\t\t\t\t<header class=\"cn-activity-tab__day-header\">\n\t\t\t\t\t<CalendarOutline :size=\"16\" />\n\t\t\t\t\t<span class=\"cn-activity-tab__day-label\">{{ day.label }}</span>\n\t\t\t\t\t<span class=\"cn-activity-tab__day-count\">{{ day.rows.length }}</span>\n\t\t\t\t</header>\n\t\t\t\t<ul class=\"cn-activity-tab__list\">\n\t\t\t\t\t<NcListItem\n\t\t\t\t\t\tv-for=\"entry in day.rows\"\n\t\t\t\t\t\t:key=\"entryKey(entry)\"\n\t\t\t\t\t\tclass=\"cn-activity-tab__row\"\n\t\t\t\t\t\t:name=\"subjectFor(entry)\"\n\t\t\t\t\t\t:bold=\"false\"\n\t\t\t\t\t\t:compact=\"true\"\n\t\t\t\t\t\t:forceDisplayActions=\"false\">\n\t\t\t\t\t\t<template #name>\n\t\t\t\t\t\t\t<span class=\"cn-activity-tab__subject\">{{ subjectFor(entry) }}</span>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<span class=\"cn-activity-tab__avatar-wrap\">\n\t\t\t\t\t\t\t\t<NcAvatar\n\t\t\t\t\t\t\t\t\t:user=\"avatarUser(entry)\"\n\t\t\t\t\t\t\t\t\t:displayName=\"actorFor(entry)\"\n\t\t\t\t\t\t\t\t\t:size=\"36\"\n\t\t\t\t\t\t\t\t\t:disableMenu=\"true\"\n\t\t\t\t\t\t\t\t\t:disableTooltip=\"true\"\n\t\t\t\t\t\t\t\t\thideStatus />\n\t\t\t\t\t\t\t\t<span class=\"cn-activity-tab__type-badge\" :class=\"typeBadgeClass(entry)\">\n\t\t\t\t\t\t\t\t\t<component :is=\"iconFor(entry)\" :size=\"12\" />\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<template #subname>\n\t\t\t\t\t\t\t<span class=\"cn-activity-tab__subname\">\n\t\t\t\t\t\t\t\t<span class=\"cn-activity-tab__actor\">{{ actorFor(entry) }}</span>\n\t\t\t\t\t\t\t\t<CnVisibilityChip v-if=\"showVisibility\" :visibility=\"entry.visibility\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<template v-if=\"timestampMillis(entry)\" #details>\n\t\t\t\t\t\t\t<NcDateTime\n\t\t\t\t\t\t\t\tclass=\"cn-activity-tab__time\"\n\t\t\t\t\t\t\t\t:timestamp=\"timestampMillis(entry)\"\n\t\t\t\t\t\t\t\trelativeTime=\"short\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<template v-else #details>\n\t\t\t\t\t\t\t<span class=\"cn-activity-tab__time\">{{ relativeTime(entry) }}</span>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</NcListItem>\n\t\t\t\t</ul>\n\t\t\t</section>\n\t\t\t<div v-if=\"hasMore\" class=\"cn-activity-tab__footer\">\n\t\t\t\t<NcButton\n\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t:wide=\"true\"\n\t\t\t\t\t:disabled=\"loadingMore\"\n\t\t\t\t\t@click=\"loadMore\">\n\t\t\t\t\t<template v-if=\"loadingMore\" #icon>\n\t\t\t\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ loadMoreLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcAvatar, NcButton, NcDateTime, NcListItem, NcLoadingIcon } from '@nextcloud/vue'\nimport AccountOutline from 'vue-material-design-icons/AccountOutline.vue'\nimport AlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'\nimport CalendarClockOutline from 'vue-material-design-icons/CalendarClockOutline.vue'\nimport CalendarOutline from 'vue-material-design-icons/CalendarOutline.vue'\nimport CommentTextOutline from 'vue-material-design-icons/CommentTextOutline.vue'\nimport EmailOutline from 'vue-material-design-icons/EmailOutline.vue'\nimport FileOutline from 'vue-material-design-icons/FileOutline.vue'\nimport ShareVariantOutline from 'vue-material-design-icons/ShareVariantOutline.vue'\nimport TagOutline from 'vue-material-design-icons/TagOutline.vue'\nimport Timeline from 'vue-material-design-icons/Timeline.vue'\nimport CnVisibilityChip from '../../../components/CnVisibilityChip/CnVisibilityChip.vue'\nimport { normalizeLook } from '../../../composables/useLook.js'\nimport { buildHeaders, prefixUrl } from '../../../utils/index.js'\nimport { userLocale } from '../../../utils/userLocale.js'\nimport { ACTIVITY_FEED_KINDS, exportBody, feedPath, feedQuery, isReadRow, parseFeed } from './activityFeedWire.js'\n\nconst DEFAULT_PAGE_SIZE = 25\nconst READS_PREFERENCE_KEY = 'activity.showReads'\nconst SECONDS_PER_DAY = 86400\n\n/**\n * CnActivityTab — bespoke chronological timeline for the `activity`\n * integration. Reads the merged feed (audit trail, NC Activity, files, notes,\n * mail) with a chip per kind, a reads toggle that is remembered per user, a\n * from/until range, an export of what is on screen, and cursor pagination on\n * the feed's time cursor. In `legacyFeed` mode (or against a server without\n * the merged feed) it reads the single-source Activity endpoint with type,\n * actor and date filters, as it did before.\n *\n * Renders activity entries grouped by day (today / yesterday / older\n * dates), with type icons, actor name, and a relative timestamp. Reads\n * from the OR Tier-2 activity endpoints; filters drive a fresh fetch,\n * \"load more\" walks the cursor returned by the backend.\n */\nexport default {\n\tname: 'CnActivityTab',\n\n\tcomponents: {\n\t\tCnVisibilityChip,\n\t\tNcAvatar,\n\t\tNcButton,\n\t\tNcDateTime,\n\t\tNcListItem,\n\t\tNcLoadingIcon,\n\t\tAlertCircleOutline,\n\t\tCalendarOutline,\n\t\tEmailOutline,\n\t\tTimeline,\n\t\tFileOutline,\n\t\tAccountOutline,\n\t\tCommentTextOutline,\n\t\tShareVariantOutline,\n\t\tTagOutline,\n\t\tCalendarClockOutline,\n\t},\n\n\tinject: {\n\t\t/** The per-user preference group from CnAppRoot, so \"show reads\" is remembered. */\n\t\tcnUserPreferences: { default: null },\n\t\t/** The app's look, provided by CnAppRoot or CnPageRenderer (`nextcloud` or `board`). */\n\t\tcnLook: { default: 'nextcloud' },\n\t},\n\n\tprops: {\n\n\t\t/** Stable integration id (forwarded from the registry — always `'activity'`). */\n\t\tintegrationId: { type: String, default: 'activity' },\n\n\t\t/** Parent object id. */\n\t\tobjectId: { type: String, required: true },\n\t\t/** OpenRegister register id (slug or uuid). */\n\t\tregister: { type: String, default: '' },\n\t\t/** OpenRegister schema id (slug or uuid). */\n\t\tschema: { type: String, default: '' },\n\t\t/** Base API URL. */\n\t\tapiBase: { type: String, default: '/apps/openregister/api' },\n\t\t/** Number of entries per fetch. */\n\t\tpageSize: { type: Number, default: DEFAULT_PAGE_SIZE },\n\t\t/**\n\t\t * Read the single-source NC Activity endpoint (type, actor, date-range\n\t\t * filters, no kinds, reads toggle or export) instead of the merged feed.\n\t\t * The tab also falls back to it by itself when the server has no merged feed.\n\t\t */\n\t\tlegacyFeed: { type: Boolean, default: false },\n\t\t/**\n\t\t * Show a visibility chip on each row and a visibility filter (all,\n\t\t * internal, public) that sends `visibility` on the fetch. Off by default,\n\t\t * so a host that passes nothing renders the feed as before.\n\t\t */\n\t\tshowVisibility: { type: Boolean, default: false },\n\t\t/**\n\t\t * The server serves this caller the public view only (no `update` on the\n\t\t * object): the filter is then fixed at public and says why, instead of\n\t\t * offering options that change nothing. The host passes it.\n\t\t */\n\t\tpublicViewOnly: { type: Boolean, default: false },\n\t\t/**\n\t\t * Offer an \"Add note\" button in the board look's History header. It\n\t\t * emits `add-note`; the host opens whatever composes the note. Off by\n\t\t * default, so no button points at nothing.\n\t\t */\n\t\tshowAddNote: { type: Boolean, default: false },\n\t\t/** Pre-translated empty-state label. */\n\t\temptyLabel: { type: String, default: () => t('nextcloud-vue', 'No activity yet for this object') },\n\t\t/** Pre-translated unavailable banner. */\n\t\tunavailableLabel: { type: String, default: () => t('nextcloud-vue', 'NC Activity is currently unavailable.') },\n\t\t/** Pre-translated load-more button label. */\n\t\tloadMoreLabel: { type: String, default: () => t('nextcloud-vue', 'Load more') },\n\t},\n\n\temits: ['exported', 'add-note'],\n\n\tdata() {\n\t\treturn {\n\t\t\tentries: [],\n\t\t\ttypes: [],\n\t\t\tactors: [],\n\t\t\tselectedType: '',\n\t\t\tselectedActor: '',\n\t\t\tselectedVisibility: '',\n\t\t\tselectedRange: 'all',\n\t\t\t/** The single-source endpoint is in use: chosen by `legacyFeed`, or after the server had no merged feed. */\n\t\t\tlegacy: this.legacyFeed,\n\t\t\tfeedKinds: ACTIVITY_FEED_KINDS,\n\t\t\t/** Kinds the reader narrowed to; empty = all. */\n\t\t\tselectedKinds: [],\n\t\t\t/** Count per kind, as the feed returned it. */\n\t\t\tkindCounts: {},\n\t\t\t/** Read entries are shown. Off by default; the reader's choice is remembered per user. */\n\t\t\tshowReads: false,\n\t\t\tfromDate: '',\n\t\t\tuntilDate: '',\n\t\t\texporting: false,\n\t\t\tcursor: null,\n\t\t\tloading: false,\n\t\t\tloadingMore: false,\n\t\t\ttotal: 0,\n\t\t\terror: '',\n\t\t\tdegraded: '',\n\t\t\tvisibilityLabel: t('nextcloud-vue', 'Visibility'),\n\t\t\tallVisibilityLabel: t('nextcloud-vue', 'All entries'),\n\t\t\tinternalLabel: t('nextcloud-vue', 'Internal'),\n\t\t\tpublicLabel: t('nextcloud-vue', 'Public'),\n\t\t\tpublicOnlyLabel: t('nextcloud-vue', 'You see the public entries only.'),\n\t\t\ttypeLabel: t('nextcloud-vue', 'Type'),\n\t\t\tactorLabel: t('nextcloud-vue', 'Actor'),\n\t\t\tallTypesLabel: t('nextcloud-vue', 'All types'),\n\t\t\tallActorsLabel: t('nextcloud-vue', 'All actors'),\n\t\t\trangeGroupLabel: t('nextcloud-vue', 'Date range'),\n\t\t\tkindsGroupLabel: t('nextcloud-vue', 'Kinds of activity'),\n\t\t\tshowReadsLabel: t('nextcloud-vue', 'Show reads'),\n\t\t\tfromLabel: t('nextcloud-vue', 'From'),\n\t\t\tuntilLabel: t('nextcloud-vue', 'Until'),\n\t\t\texportLabel: t('nextcloud-vue', 'Export'),\n\t\t\taddNoteLabel: t('nextcloud-vue', 'Add note'),\n\t\t\thistoryTitle: t('nextcloud-vue', 'History'),\n\t\t\thistorySubtitle: t('nextcloud-vue', 'What happened, who did it and when, newest first'),\n\t\t\tranges: [\n\t\t\t\t{ key: '24h', label: t('nextcloud-vue', '24h') },\n\t\t\t\t{ key: '7d', label: t('nextcloud-vue', '7d') },\n\t\t\t\t{ key: '30d', label: t('nextcloud-vue', '30d') },\n\t\t\t\t{ key: 'all', label: t('nextcloud-vue', 'All') },\n\t\t\t],\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Whether the tab is drawn in the board look: the History header, the\n\t\t * filled kind chips and the event rail.\n\t\t *\n\t\t * @return {boolean} True in the board look.\n\t\t * @spec openspec/changes/screens-detail-page-parity/specs/detail-page-board-look/spec.md#requirement-history-is-the-last-tab\n\t\t */\n\t\tisBoard() {\n\t\t\treturn normalizeLook(this.cnLook) === 'board'\n\t\t},\n\n\t\thasMore() {\n\t\t\treturn this.cursor !== null\n\t\t},\n\n\t\t/**\n\t\t * Unix-epoch-seconds lower bound for the selected date range, or\n\t\t * null for \"all\".\n\t\t *\n\t\t * @return {?number} Lower-bound timestamp or null.\n\t\t */\n\t\tafterTimestamp() {\n\t\t\tconst days = { '24h': 1, '7d': 7, '30d': 30 }[this.selectedRange]\n\t\t\tif (!days) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn Math.floor(Date.now() / 1000) - (days * SECONDS_PER_DAY)\n\t\t},\n\n\t\t/**\n\t\t * The rows on screen: reads are left out unless the reader turned them on.\n\t\t * Only an audit row can be a read.\n\t\t *\n\t\t * @return {object[]} The rows.\n\t\t */\n\t\tvisibleEntries() {\n\t\t\tif (this.legacy || this.showReads) {\n\t\t\t\treturn this.entries\n\t\t\t}\n\t\t\treturn this.entries.filter((entry) => !isReadRow(entry))\n\t\t},\n\n\t\tgroupedByDay() {\n\t\t\tconst groups = new Map()\n\t\t\tfor (const entry of this.visibleEntries) {\n\t\t\t\tconst ts = this.timestampFor(entry)\n\t\t\t\tconst key = this.dayKey(ts)\n\t\t\t\tif (groups.has(key) === false) {\n\t\t\t\t\tgroups.set(key, { key, label: this.dayLabel(ts), rows: [] })\n\t\t\t\t}\n\t\t\t\tgroups.get(key).rows.push(entry)\n\t\t\t}\n\t\t\t// Preserve insertion order (entries assumed pre-sorted DESC by\n\t\t\t// the provider). Each day's rows likewise stay in the order\n\t\t\t// they were appended.\n\t\t\treturn [...groups.values()]\n\t\t},\n\t},\n\n\twatch: {\n\t\tobjectId: { immediate: true, handler(id) {\n\t\t\tif (id) {\n\t\t\t\tthis.bootstrap()\n\t\t\t}\n\t\t} },\n\n\t\tregister() {\n\t\t\tthis.bootstrap()\n\t\t},\n\n\t\tschema() {\n\t\t\tthis.bootstrap()\n\t\t},\n\t},\n\n\tmethods: {\n\t\tbaseUrl() {\n\t\t\tif (!this.legacy) {\n\t\t\t\treturn prefixUrl(feedPath(this.objectAddress()))\n\t\t\t}\n\t\t\treturn prefixUrl(`${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/activity`)\n\t\t},\n\n\t\tobjectAddress() {\n\t\t\treturn { apiBase: this.apiBase, register: this.register, schema: this.schema, objectId: this.objectId }\n\t\t},\n\n\t\t/** @return {object} The filters the tab is showing, in the feed's terms. */\n\t\tfeedFilters() {\n\t\t\treturn {\n\t\t\t\tkinds: this.selectedKinds,\n\t\t\t\tfrom: this.fromDate ? new Date(`${this.fromDate}T00:00:00`).toISOString() : '',\n\t\t\t\tuntil: this.untilDate ? new Date(`${this.untilDate}T23:59:59.999`).toISOString() : '',\n\t\t\t\treads: this.showReads,\n\t\t\t\tactor: this.selectedActor,\n\t\t\t\tvisibility: this.showVisibility ? (this.publicViewOnly ? 'public' : this.selectedVisibility) : '',\n\t\t\t\tlimit: this.pageSize,\n\t\t\t}\n\t\t},\n\n\t\tdropdownUrl(kind) {\n\t\t\tconst object = `${this.register}/${this.schema}/${this.objectId}`\n\t\t\treturn prefixUrl(`${this.apiBase}/integrations/activity/${kind}?object=${encodeURIComponent(object)}`)\n\t\t},\n\n\t\tbuildQuery() {\n\t\t\tif (!this.legacy) {\n\t\t\t\treturn feedQuery({ ...this.feedFilters(), cursor: this.cursor })\n\t\t\t}\n\t\t\tconst params = new URLSearchParams()\n\t\t\tparams.set('limit', String(this.pageSize))\n\t\t\tif (this.selectedType) {\n\t\t\t\tparams.set('type', this.selectedType)\n\t\t\t}\n\t\t\tif (this.selectedActor) {\n\t\t\t\tparams.set('actor', this.selectedActor)\n\t\t\t}\n\t\t\tif (this.showVisibility) {\n\t\t\t\tconst visibility = this.publicViewOnly ? 'public' : this.selectedVisibility\n\t\t\t\tif (visibility) {\n\t\t\t\t\tparams.set('visibility', visibility)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.afterTimestamp !== null) {\n\t\t\t\tparams.set('after', String(this.afterTimestamp))\n\t\t\t}\n\t\t\tif (this.cursor !== null) {\n\t\t\t\tparams.set('cursor', String(this.cursor))\n\t\t\t}\n\t\t\treturn params.toString()\n\t\t},\n\n\t\tentryKey(entry) {\n\t\t\treturn entry.id ?? entry.activity_id ?? entry.activityId ?? ''\n\t\t},\n\n\t\ttimestampFor(entry) {\n\t\t\tconst raw = entry.timestamp ?? entry.datetime ?? entry.time ?? entry.at ?? entry.created ?? entry.creationDateTime ?? null\n\t\t\tif (raw === null || raw === undefined || raw === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\t// NC Activity exposes Unix epoch seconds in `timestamp`.\n\t\t\tif (typeof raw === 'number' && raw < 1e12) {\n\t\t\t\treturn new Date(raw * 1000)\n\t\t\t}\n\t\t\tconst parsed = new Date(raw)\n\t\t\treturn Number.isNaN(parsed.getTime()) ? null : parsed\n\t\t},\n\n\t\tdayKey(date) {\n\t\t\tif (date === null) {\n\t\t\t\treturn 'unknown'\n\t\t\t}\n\t\t\treturn `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`\n\t\t},\n\n\t\tdayLabel(date) {\n\t\t\tif (date === null) {\n\t\t\t\treturn t('nextcloud-vue', 'Earlier')\n\t\t\t}\n\t\t\tconst now = new Date()\n\t\t\tconst today = new Date(now.getFullYear(), now.getMonth(), now.getDate())\n\t\t\tconst yesterday = new Date(today.getTime() - 86400000)\n\t\t\tconst start = new Date(date.getFullYear(), date.getMonth(), date.getDate())\n\t\t\tif (start.getTime() === today.getTime()) {\n\t\t\t\treturn t('nextcloud-vue', 'Today')\n\t\t\t}\n\t\t\tif (start.getTime() === yesterday.getTime()) {\n\t\t\t\treturn t('nextcloud-vue', 'Yesterday')\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn date.toLocaleDateString(userLocale(), { weekday: 'short', day: 'numeric', month: 'short' })\n\t\t\t} catch {\n\t\t\t\treturn date.toISOString().split('T')[0]\n\t\t\t}\n\t\t},\n\n\t\trelativeTime(entry) {\n\t\t\tconst ts = this.timestampFor(entry)\n\t\t\tif (ts === null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn ts.toLocaleTimeString(userLocale(), { hour: '2-digit', minute: '2-digit' })\n\t\t\t} catch {\n\t\t\t\treturn ts.toISOString().split('T')[1].slice(0, 5)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Resolve the entry timestamp as epoch-millisecond value for\n\t\t * NcDateTime, or 0 when unknown (callers branch on truthiness).\n\t\t *\n\t\t * @param {object} entry Activity row.\n\t\t * @return {number} Epoch milliseconds, or 0.\n\t\t */\n\t\ttimestampMillis(entry) {\n\t\t\tconst ts = this.timestampFor(entry)\n\t\t\treturn ts === null ? 0 : ts.getTime()\n\t\t},\n\n\t\t/**\n\t\t * Split an event's subject at its first colon: the verb (\"Document\n\t\t * reviewed\") is drawn bold, the rest as written. A subject without a\n\t\t * colon is all verb.\n\t\t *\n\t\t * @param {object} entry Activity row.\n\t\t * @return {{verb: string, rest: string}} The two parts.\n\t\t * @spec openspec/changes/screens-detail-page-parity/specs/detail-page-board-look/spec.md#requirement-history-is-the-last-tab\n\t\t */\n\t\tsplitSubject(entry) {\n\t\t\tconst subject = String(this.subjectFor(entry))\n\t\t\tconst at = subject.indexOf(':')\n\t\t\tif (at <= 0) {\n\t\t\t\treturn { verb: subject, rest: '' }\n\t\t\t}\n\t\t\treturn { verb: subject.slice(0, at + 1), rest: subject.slice(at + 1) }\n\t\t},\n\n\t\t/**\n\t\t * The meta line under an event: kind, who, when.\n\t\t *\n\t\t * @param {object} entry Activity row.\n\t\t * @return {string} For example \"Document · Pieter Jansen · 6 Oct, 15:40\".\n\t\t * @spec openspec/changes/screens-detail-page-parity/specs/detail-page-board-look/spec.md#requirement-history-is-the-last-tab\n\t\t */\n\t\teventMeta(entry) {\n\t\t\tconst ts = this.timestampFor(entry)\n\t\t\tlet when = ''\n\t\t\tif (ts !== null) {\n\t\t\t\ttry {\n\t\t\t\t\twhen = ts.toLocaleString(userLocale(), { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })\n\t\t\t\t} catch {\n\t\t\t\t\twhen = ts.toISOString().replace('T', ' ').slice(0, 16)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [this.kindLabel(entry.kind || 'activity'), this.actorFor(entry), when].filter((part) => part !== '').join(' \\u00b7 ')\n\t\t},\n\n\t\tsubjectFor(entry) {\n\t\t\treturn entry.subject_rich ?? entry.subjectRich ?? entry.subject ?? entry.summary ?? entry.title ?? ''\n\t\t},\n\n\t\tactorFor(entry) {\n\t\t\treturn entry.actor_id ?? entry.actorDisplayName ?? entry.actor ?? entry.user ?? entry.affecteduser ?? t('nextcloud-vue', 'System')\n\t\t},\n\n\t\t/**\n\t\t * NC user id to seed the actor avatar, when the entry carries a\n\t\t * real account id. Falls back to '' so NcAvatar renders initials\n\t\t * from the display name (e.g. the System pseudo-actor).\n\t\t *\n\t\t * @param {object} entry Activity row.\n\t\t * @return {string} NC user id, or ''.\n\t\t */\n\t\tavatarUser(entry) {\n\t\t\tconst id = entry.actor_id ?? entry.actor ?? entry.user ?? entry.affecteduser ?? ''\n\t\t\treturn typeof id === 'string' ? id : ''\n\t\t},\n\n\t\t/**\n\t\t * Modifier class colouring the small activity-type badge that\n\t\t * overlaps the actor avatar, grouping verbs into NC-Activity-like\n\t\t * families (file / comment / share / tag).\n\t\t *\n\t\t * @param {object} entry Activity row.\n\t\t * @return {string} BEM modifier class.\n\t\t */\n\t\ttypeBadgeClass(entry) {\n\t\t\tconst type = String(entry.type ?? '').toLowerCase()\n\t\t\tif (type.includes('comment')) {\n\t\t\t\treturn 'cn-activity-tab__type-badge--comment'\n\t\t\t}\n\t\t\tif (type.includes('share')) {\n\t\t\t\treturn 'cn-activity-tab__type-badge--share'\n\t\t\t}\n\t\t\tif (type.includes('tag')) {\n\t\t\t\treturn 'cn-activity-tab__type-badge--tag'\n\t\t\t}\n\t\t\treturn 'cn-activity-tab__type-badge--file'\n\t\t},\n\n\t\ticonFor(entry) {\n\t\t\tconst byKind = { file: 'FileOutline', note: 'CommentTextOutline', mail: 'EmailOutline', audit: 'Timeline', activity: 'Timeline' }[entry.kind]\n\t\t\tif (byKind) {\n\t\t\t\treturn byKind\n\t\t\t}\n\t\t\tconst type = String(entry.type ?? '').toLowerCase()\n\t\t\tif (type.includes('file') || type.includes('upload') || type.includes('change')) {\n\t\t\t\treturn 'FileOutline'\n\t\t\t}\n\t\t\tif (type.includes('comment')) {\n\t\t\t\treturn 'CommentTextOutline'\n\t\t\t}\n\t\t\tif (type.includes('share')) {\n\t\t\t\treturn 'ShareVariantOutline'\n\t\t\t}\n\t\t\tif (type.includes('tag')) {\n\t\t\t\treturn 'TagOutline'\n\t\t\t}\n\t\t\tif (type.includes('calendar') || type.includes('event')) {\n\t\t\t\treturn 'CalendarClockOutline'\n\t\t\t}\n\t\t\tif (type.includes('user') || type.includes('account')) {\n\t\t\t\treturn 'AccountOutline'\n\t\t\t}\n\t\t\treturn 'Timeline'\n\t\t},\n\n\t\tselectRange(key) {\n\t\t\tif (this.selectedRange === key) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.selectedRange = key\n\t\t\tif (!this.legacy) {\n\t\t\t\t// A preset is a from date; until stays open.\n\t\t\t\tconst days = { '24h': 1, '7d': 7, '30d': 30 }[key]\n\t\t\t\tthis.fromDate = days ? this.localDate(new Date(Date.now() - (days * SECONDS_PER_DAY * 1000))) : ''\n\t\t\t\tthis.untilDate = ''\n\t\t\t}\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\t/**\n\t\t * @param {Date} date A date.\n\t\t * @return {string} `YYYY-MM-DD` in local time.\n\t\t */\n\t\tlocalDate(date) {\n\t\t\tconst pad = (n) => String(n).padStart(2, '0')\n\t\t\treturn `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`\n\t\t},\n\n\t\t/**\n\t\t * @param {'fromDate'|'untilDate'} field Which end of the range.\n\t\t * @param {string} value `YYYY-MM-DD`, or '' to leave it open.\n\t\t * @return {void}\n\t\t */\n\t\tsetDate(field, value) {\n\t\t\tthis[field] = value\n\t\t\tthis.selectedRange = 'custom'\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\t/**\n\t\t * @param {string} kind A feed kind.\n\t\t * @return {string} Its label.\n\t\t */\n\t\tkindLabel(kind) {\n\t\t\treturn {\n\t\t\t\taudit: t('nextcloud-vue', 'Changes'),\n\t\t\t\tactivity: t('nextcloud-vue', 'Activity'),\n\t\t\t\tfile: t('nextcloud-vue', 'Files'),\n\t\t\t\tnote: t('nextcloud-vue', 'Notes'),\n\t\t\t\tmail: t('nextcloud-vue', 'Mail'),\n\t\t\t}[kind] || kind\n\t\t},\n\n\t\t/**\n\t\t * The count the feed returned for a kind. A kind with no rows reads 0\n\t\t * and keeps its chip.\n\t\t *\n\t\t * @param {string} kind A feed kind.\n\t\t * @return {number} The count.\n\t\t */\n\t\tkindCount(kind) {\n\t\t\treturn this.kindCounts[kind] ?? 0\n\t\t},\n\n\t\ttoggleKind(kind) {\n\t\t\tthis.selectedKinds = this.selectedKinds.includes(kind)\n\t\t\t\t? this.selectedKinds.filter((k) => k !== kind)\n\t\t\t\t: [...this.selectedKinds, kind]\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\t/**\n\t\t * Turn read entries on or off, and remember the choice for this user.\n\t\t *\n\t\t * @param {boolean} on Whether reads are shown.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync setShowReads(on) {\n\t\t\tthis.showReads = !!on\n\t\t\tconst write = this.cnUserPreferences && this.cnUserPreferences.write\n\t\t\ttry {\n\t\t\t\tif (typeof write === 'function') {\n\t\t\t\t\tawait write(READS_PREFERENCE_KEY, this.showReads)\n\t\t\t\t} else if (typeof localStorage !== 'undefined') {\n\t\t\t\t\tlocalStorage.setItem(`cn-pref:${READS_PREFERENCE_KEY}`, JSON.stringify(this.showReads))\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Not remembered; the toggle still works for this session.\n\t\t\t}\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\t/**\n\t\t * Read the reader's remembered choice for the reads toggle.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync loadShowReads() {\n\t\t\ttry {\n\t\t\t\tconst read = this.cnUserPreferences && this.cnUserPreferences.read\n\t\t\t\tif (typeof read === 'function') {\n\t\t\t\t\tthis.showReads = (await read(READS_PREFERENCE_KEY, false)) === true\n\t\t\t\t} else if (typeof localStorage !== 'undefined') {\n\t\t\t\t\tthis.showReads = JSON.parse(localStorage.getItem(`cn-pref:${READS_PREFERENCE_KEY}`) || 'false') === true\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tthis.showReads = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Export what is on screen: the rows shown and the filters that produced\n\t\t * them are sent to the feed's export; nothing is re-queried.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync exportFeed() {\n\t\t\tthis.exporting = true\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(`${this.baseUrl()}/export`, {\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: buildHeaders(),\n\t\t\t\t\tbody: JSON.stringify(exportBody(this.visibleEntries, this.feedFilters())),\n\t\t\t\t})\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`export failed (${response.status})`)\n\t\t\t\t}\n\t\t\t\tconst blob = new Blob([await response.text()], { type: 'text/csv;charset=utf-8' })\n\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\tconst link = document.createElement('a')\n\t\t\t\tlink.href = url\n\t\t\t\tlink.download = `activity-${this.objectId}.csv`\n\t\t\t\tdocument.body.appendChild(link)\n\t\t\t\tlink.click()\n\t\t\t\tlink.remove()\n\t\t\t\tURL.revokeObjectURL(url)\n\t\t\t\t/**\n\t\t\t\t * @event exported Emitted after the feed on screen was exported. Payload: the number of rows.\n\t\t\t\t * @type {number}\n\t\t\t\t */\n\t\t\t\tthis.$emit('exported', this.visibleEntries.length)\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error('[CnActivityTab] export failed', err)\n\t\t\t\tthis.error = t('nextcloud-vue', 'Could not export activity.')\n\t\t\t} finally {\n\t\t\t\tthis.exporting = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Full (re)load: refresh the dropdown sources, then fetch the\n\t\t * first filtered page.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbootstrap() {\n\t\t\tif (!this.register || !this.schema || !this.objectId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.fetchDropdowns()\n\t\t\tif (!this.legacy) {\n\t\t\t\tthis.loadShowReads().then(() => this.resetAndFetch())\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\tresetAndFetch() {\n\t\t\tthis.entries = []\n\t\t\tthis.cursor = null\n\t\t\tthis.total = 0\n\t\t\tthis.fetchEntries()\n\t\t},\n\n\t\t/** The server has no merged feed: read the single-source endpoint, as before. */\n\t\tfallBackToLegacy() {\n\t\t\tthis.legacy = true\n\t\t\tthis.selectedRange = 'all'\n\t\t\tthis.fromDate = ''\n\t\t\tthis.untilDate = ''\n\t\t\tthis.resetAndFetch()\n\t\t},\n\n\t\tasync fetchDropdowns() {\n\t\t\ttry {\n\t\t\t\tconst [typesRes, actorsRes] = await Promise.all([\n\t\t\t\t\tfetch(this.dropdownUrl('types'), { headers: buildHeaders() }),\n\t\t\t\t\tfetch(this.dropdownUrl('actors'), { headers: buildHeaders() }),\n\t\t\t\t])\n\t\t\t\tif (typesRes.ok) {\n\t\t\t\t\tconst data = await typesRes.json()\n\t\t\t\t\tthis.types = data.results || []\n\t\t\t\t}\n\t\t\t\tif (actorsRes.ok) {\n\t\t\t\t\tconst data = await actorsRes.json()\n\t\t\t\t\tthis.actors = data.results || []\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// Dropdown failure is non-fatal — filters just stay empty.\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error('[CnActivityTab] failed to fetch filter options', err)\n\t\t\t}\n\t\t},\n\n\t\tasync fetchEntries() {\n\t\t\tif (!this.register || !this.schema || !this.objectId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst isFirstPage = this.cursor === null\n\t\t\tif (isFirstPage) {\n\t\t\t\tthis.loading = true\n\t\t\t} else {\n\t\t\t\tthis.loadingMore = true\n\t\t\t}\n\t\t\tthis.error = ''\n\t\t\tthis.degraded = ''\n\t\t\tlet noFeed = false\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(`${this.baseUrl()}?${this.buildQuery()}`, { headers: buildHeaders() })\n\t\t\t\tif (!this.legacy && [404, 405, 501].includes(response.status)) {\n\t\t\t\t\t// No merged feed on this server: read the single-source endpoint instead.\n\t\t\t\t\tnoFeed = true\n\t\t\t\t} else if (response.ok && !this.legacy) {\n\t\t\t\t\tconst feed = parseFeed(await response.json())\n\t\t\t\t\tthis.entries = isFirstPage ? feed.rows : [...this.entries, ...feed.rows]\n\t\t\t\t\tthis.kindCounts = feed.counts\n\t\t\t\t\tthis.total = this.entries.length\n\t\t\t\t\tthis.cursor = feed.cursor\n\t\t\t\t} else if (response.ok) {\n\t\t\t\t\tconst data = await response.json()\n\t\t\t\t\tconst rows = data.results || data.items || (Array.isArray(data) ? data : []) || []\n\t\t\t\t\tthis.entries = isFirstPage ? rows : [...this.entries, ...rows]\n\t\t\t\t\tthis.total = Number(data.total ?? 0)\n\t\t\t\t\tconst next = data.nextCursor ?? null\n\t\t\t\t\tthis.cursor = (next === null || next === undefined) ? null : Number(next)\n\t\t\t\t} else if (response.status === 503 || response.status === 501) {\n\t\t\t\t\tif (isFirstPage) {\n\t\t\t\t\t\tthis.entries = []\n\t\t\t\t\t}\n\t\t\t\t\tthis.cursor = null\n\t\t\t\t\tthis.degraded = this.unavailableLabel\n\t\t\t\t} else {\n\t\t\t\t\tif (isFirstPage) {\n\t\t\t\t\t\tthis.entries = []\n\t\t\t\t\t}\n\t\t\t\t\tthis.cursor = null\n\t\t\t\t\tthis.error = t('nextcloud-vue', 'Could not load activity.')\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error('[CnActivityTab] failed to fetch activity', err)\n\t\t\t\tif (isFirstPage) {\n\t\t\t\t\tthis.entries = []\n\t\t\t\t}\n\t\t\t\tthis.cursor = null\n\t\t\t\tthis.error = t('nextcloud-vue', 'Could not load activity.')\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t\tthis.loadingMore = false\n\t\t\t}\n\t\t\tif (noFeed) {\n\t\t\t\tthis.fallBackToLegacy()\n\t\t\t}\n\t\t},\n\n\t\tloadMore() {\n\t\t\tif (this.cursor === null) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.fetchEntries()\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-activity-tab__banner {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 8px 10px;\n\tmargin-bottom: 10px;\n\tborder-radius: var(--border-radius);\n\tbackground: var(--color-warning, #e9a40f);\n\tcolor: var(--color-main-background);\n\tfont-size: 0.9em;\n}\n\n.cn-activity-tab__filters {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmargin-bottom: 12px;\n}\n\n.cn-activity-tab__filter-row {\n\tdisplay: flex;\n\tgap: 8px;\n}\n\n.cn-activity-tab__filter {\n\tflex: 1;\n\tmin-width: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n\n.cn-activity-tab__filter-label {\n\tfont-size: 0.78em;\n\tfont-weight: 600;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-activity-tab__select {\n\twidth: 100%;\n\tmin-height: 34px;\n\tpadding: 4px 6px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n}\n\n.cn-activity-tab__range {\n\tdisplay: flex;\n\tgap: 4px;\n}\n\n.cn-activity-tab__range-btn {\n\tflex: 1;\n\tpadding: 4px 0;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.82em;\n\tcursor: pointer;\n}\n\n.cn-activity-tab__range-btn--active {\n\tbackground: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n\tborder-color: var(--color-primary-element);\n}\n\n.cn-activity-tab__error {\n\tcolor: var(--color-error);\n\tfont-size: 0.9em;\n\tmargin: 4px 0 8px;\n}\n\n.cn-activity-tab__empty {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 16px 8px;\n\tcolor: var(--color-text-maxcontrast);\n\ttext-align: center;\n}\n\n.cn-activity-tab__empty-icon {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-activity-tab__day {\n\tmargin-bottom: 14px;\n}\n\n.cn-activity-tab__day-header {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 4px 0;\n\tfont-size: 0.85em;\n\tfont-weight: 600;\n\tcolor: var(--color-text-maxcontrast);\n\tborder-bottom: 1px solid var(--color-border);\n}\n\n.cn-activity-tab__day-label {\n\tflex: 1;\n}\n\n.cn-activity-tab__day-count {\n\tfont-weight: normal;\n\tfont-size: 0.85em;\n\tpadding: 1px 6px;\n\tborder-radius: 9px;\n\tbackground: var(--color-background-hover);\n}\n\n.cn-activity-tab__list {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n\n/* Actor avatar with an overlapping activity-type badge, mirroring the\n NC Activity feed's per-event glyph. */\n.cn-activity-tab__avatar-wrap {\n\tposition: relative;\n\tdisplay: inline-flex;\n\twidth: 36px;\n\theight: 36px;\n}\n\n.cn-activity-tab__type-badge {\n\tposition: absolute;\n\tright: -2px;\n\tbottom: -2px;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 16px;\n\theight: 16px;\n\tborder-radius: 50%;\n\tborder: 2px solid var(--color-main-background);\n\tcolor: var(--color-primary-element-text);\n\tbackground: var(--color-primary-element);\n}\n\n.cn-activity-tab__type-badge--comment {\n\tbackground: var(--color-success, #46ba61);\n}\n\n.cn-activity-tab__type-badge--share {\n\tbackground: var(--color-primary-element);\n}\n\n.cn-activity-tab__type-badge--tag {\n\tbackground: var(--color-warning, #e9a40f);\n}\n\n.cn-activity-tab__type-badge--file {\n\tbackground: var(--color-text-maxcontrast);\n}\n\n.cn-activity-tab__subject {\n\tcolor: var(--color-main-text);\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n.cn-activity-tab__subname {\n\tdisplay: block;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-activity-tab__actor {\n\tfont-weight: 500;\n}\n\n.cn-activity-tab__time {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.8em;\n\twhite-space: nowrap;\n}\n\n.cn-activity-tab__footer {\n\tmargin-top: 8px;\n}\n</style>\n"],"names":["CnVisibilityChip","t"],"mappings":"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"}