@conduction/nextcloud-vue 2.56.0-beta.3 → 2.56.0-beta.5

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 (314) hide show
  1. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +12 -2
  2. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +1 -2
  4. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
  5. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
  6. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +0 -3
  7. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
  8. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
  9. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +1 -2
  10. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
  11. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +21 -1
  12. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  13. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +1 -1
  14. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  15. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +12 -5
  16. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
  17. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +2 -1
  18. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
  19. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js +9 -1
  20. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js.map +1 -1
  21. package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js.map +1 -1
  22. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js +6 -1
  23. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js.map +1 -1
  24. package/dist/esm/components/CnContextMenu/CnContextMenu.vue3.js.map +1 -1
  25. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +116 -15
  26. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  27. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +27 -14
  28. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  29. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js +13 -6
  30. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js.map +1 -1
  31. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js +2 -0
  32. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js.map +1 -1
  33. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +29 -1
  34. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  35. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  36. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
  37. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js +1 -2
  38. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
  39. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +3 -1
  40. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  41. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +17 -17
  42. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  43. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js +4 -21
  44. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js.map +1 -1
  45. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue3.js.map +1 -1
  46. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js +0 -13
  47. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js.map +1 -1
  48. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js +8 -8
  49. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js.map +1 -1
  50. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue2.js.map +1 -1
  51. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js +3 -2
  52. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js.map +1 -1
  53. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +67 -13
  54. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  55. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +15 -8
  56. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  57. package/dist/esm/components/CnIndexPage/manifestActionDispatch.js +31 -11
  58. package/dist/esm/components/CnIndexPage/manifestActionDispatch.js.map +1 -1
  59. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue2.js.map +1 -1
  60. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js +1 -2
  61. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js.map +1 -1
  62. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue2.js.map +1 -1
  63. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js +0 -1
  64. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js.map +1 -1
  65. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js +2 -17
  66. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js.map +1 -1
  67. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue3.js.map +1 -1
  68. package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js +35 -11
  69. package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js.map +1 -1
  70. package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js +3 -2
  71. package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js.map +1 -1
  72. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js +23 -5
  73. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js.map +1 -1
  74. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js +1 -1
  75. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js.map +1 -1
  76. package/dist/esm/components/CnObjectList/CnObjectList.vue2.js +19 -3
  77. package/dist/esm/components/CnObjectList/CnObjectList.vue2.js.map +1 -1
  78. package/dist/esm/components/CnObjectList/CnObjectList.vue3.js.map +1 -1
  79. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +45 -15
  80. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  81. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -2
  82. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  83. package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js +24 -6
  84. package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js.map +1 -1
  85. package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js +1 -1
  86. package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js.map +1 -1
  87. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  88. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +0 -1
  89. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  90. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
  91. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js +4 -2
  92. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
  93. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js +7 -2
  94. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js.map +1 -1
  95. package/dist/esm/components/CnRowActions/CnRowActions.vue3.js.map +1 -1
  96. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +49 -5
  97. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
  98. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +1 -1
  99. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
  100. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js +5 -3
  101. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js.map +1 -1
  102. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue3.js.map +1 -1
  103. package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
  104. package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
  105. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js +3 -1
  106. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js.map +1 -1
  107. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js +1 -0
  108. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js.map +1 -1
  109. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js +3 -1
  110. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js.map +1 -1
  111. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue3.js.map +1 -1
  112. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -1
  113. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
  114. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js +2 -4
  115. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
  116. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js +6 -0
  117. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js.map +1 -1
  118. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js +68 -53
  119. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js.map +1 -1
  120. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js +17 -0
  121. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js.map +1 -1
  122. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js +21 -19
  123. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js.map +1 -1
  124. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js +3 -1
  125. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js.map +1 -1
  126. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue3.js.map +1 -1
  127. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js +3 -1
  128. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js.map +1 -1
  129. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js +2 -4
  130. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js.map +1 -1
  131. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js +2 -1
  132. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js.map +1 -1
  133. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue3.js.map +1 -1
  134. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js +2 -1
  135. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js.map +1 -1
  136. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js +1 -2
  137. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js.map +1 -1
  138. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js +2 -1
  139. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js.map +1 -1
  140. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js.map +1 -1
  141. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +2 -1
  142. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
  143. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js +1 -2
  144. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
  145. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js.map +1 -1
  146. package/dist/esm/integrations/builtin/email/CnEmailCard.vue3.js.map +1 -1
  147. package/dist/esm/integrations/builtin/email/CnEmailTab.vue2.js.map +1 -1
  148. package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js +1 -2
  149. package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js.map +1 -1
  150. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js +2 -1
  151. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js.map +1 -1
  152. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue3.js.map +1 -1
  153. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js +2 -1
  154. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js.map +1 -1
  155. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js +1 -2
  156. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js.map +1 -1
  157. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js +3 -1
  158. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js.map +1 -1
  159. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue3.js.map +1 -1
  160. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js +3 -1
  161. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js.map +1 -1
  162. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js +2 -4
  163. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js.map +1 -1
  164. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js +3 -1
  165. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js.map +1 -1
  166. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue3.js.map +1 -1
  167. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js +3 -1
  168. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js.map +1 -1
  169. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js +2 -4
  170. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js.map +1 -1
  171. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js +3 -1
  172. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js.map +1 -1
  173. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue3.js.map +1 -1
  174. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js +3 -1
  175. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js.map +1 -1
  176. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js +2 -4
  177. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js.map +1 -1
  178. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js +2 -1
  179. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js.map +1 -1
  180. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue3.js.map +1 -1
  181. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js +2 -1
  182. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js.map +1 -1
  183. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js +1 -2
  184. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js.map +1 -1
  185. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js +2 -1
  186. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js.map +1 -1
  187. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue3.js.map +1 -1
  188. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js +2 -1
  189. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js.map +1 -1
  190. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js +1 -2
  191. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js.map +1 -1
  192. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue2.js.map +1 -1
  193. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js +3 -6
  194. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js.map +1 -1
  195. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js +3 -1
  196. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js.map +1 -1
  197. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue3.js.map +1 -1
  198. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js +3 -1
  199. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js.map +1 -1
  200. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js +2 -4
  201. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js.map +1 -1
  202. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js +2 -1
  203. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js.map +1 -1
  204. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue3.js.map +1 -1
  205. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js +2 -1
  206. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js.map +1 -1
  207. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js +1 -2
  208. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js.map +1 -1
  209. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js +4 -1
  210. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js.map +1 -1
  211. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue3.js.map +1 -1
  212. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js +6 -3
  213. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js.map +1 -1
  214. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js +2 -4
  215. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js.map +1 -1
  216. package/dist/esm/l10n/en.json.js +2 -0
  217. package/dist/esm/l10n/en.json.js.map +1 -1
  218. package/dist/esm/l10n/nl.json.js +2 -0
  219. package/dist/esm/l10n/nl.json.js.map +1 -1
  220. package/dist/esm/nextcloud-vue.css +78 -7
  221. package/dist/esm/utils/actionLink.js +5 -0
  222. package/dist/esm/utils/actionLink.js.map +1 -1
  223. package/dist/esm/utils/actionsDispatcher.js +16 -1
  224. package/dist/esm/utils/actionsDispatcher.js.map +1 -1
  225. package/dist/esm/utils/linkNavigation.js +6 -3
  226. package/dist/esm/utils/linkNavigation.js.map +1 -1
  227. package/dist/esm/utils/rowAuxClick.js +30 -5
  228. package/dist/esm/utils/rowAuxClick.js.map +1 -1
  229. package/dist/esm/utils/safeHref.js +18 -3
  230. package/dist/esm/utils/safeHref.js.map +1 -1
  231. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  232. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  233. package/dist/nextcloud-vue.cjs.js +885 -393
  234. package/dist/nextcloud-vue.cjs.js.map +2 -2
  235. package/dist/nextcloud-vue.css +78 -7
  236. package/l10n/en.json +2 -0
  237. package/l10n/nl.json +2 -0
  238. package/package.json +1 -1
  239. package/src/components/CnActionsBar/CnActionsBar.vue +14 -5
  240. package/src/components/CnActionsMenu/CnActionsMenu.vue +0 -3
  241. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +1 -2
  242. package/src/components/CnAppRoot/CnAppRoot.vue +31 -2
  243. package/src/components/CnBoardView/CnBoardView.vue +13 -5
  244. package/src/components/CnCardGrid/CnCardGrid.vue +9 -1
  245. package/src/components/CnContextMenu/CnContextMenu.vue +6 -1
  246. package/src/components/CnDataTable/CnDataTable.md +1 -1
  247. package/src/components/CnDataTable/CnDataTable.vue +131 -17
  248. package/src/components/CnDateAxisView/CnDateAxisView.vue +15 -6
  249. package/src/components/CnDetailPage/CnDetailPage.md +1 -1
  250. package/src/components/CnDetailPage/CnDetailPage.vue +29 -1
  251. package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +1 -2
  252. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +5 -3
  253. package/src/components/CnFilesWidget/CnFilesWidget.vue +4 -21
  254. package/src/components/CnFlowRunsWidget/CnFlowRunsWidget.vue +8 -21
  255. package/src/components/CnFlowsPage/CnFlowsPage.vue +2 -1
  256. package/src/components/CnIndexPage/CnIndexPage.vue +75 -14
  257. package/src/components/CnIndexPage/manifestActionDispatch.js +31 -11
  258. package/src/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue +1 -2
  259. package/src/components/CnInteractionFormWidget/CnInteractionFormWidget.vue +0 -1
  260. package/src/components/CnLinkButtonWidget/CnLinkButtonWidget.vue +2 -17
  261. package/src/components/CnLogsPage/CnLogsPage.vue +37 -12
  262. package/src/components/CnObjectCard/CnObjectCard.vue +24 -6
  263. package/src/components/CnObjectList/CnObjectList.vue +19 -3
  264. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +47 -15
  265. package/src/components/CnObjectRow/CnObjectRow.vue +25 -7
  266. package/src/components/CnObjectSidebar/CnFilesTab.vue +0 -1
  267. package/src/components/CnPageRenderer/CnPageRenderer.vue +2 -0
  268. package/src/components/CnRowActions/CnRowActions.vue +7 -2
  269. package/src/components/CnSetupWizard/CnSetupWizard.vue +57 -6
  270. package/src/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue +5 -3
  271. package/src/components/CnTabs/CnTabs.vue +7 -3
  272. package/src/components/CnTasksWidget/CnTasksWidget.vue +4 -1
  273. package/src/css/table.css +26 -0
  274. package/src/integrations/builtin/analytics/CnAnalyticsCard.vue +3 -2
  275. package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +5 -6
  276. package/src/integrations/builtin/bookmarks/CnBookmarksCard.vue +12 -1
  277. package/src/integrations/builtin/bookmarks/CnBookmarksTab.vue +23 -6
  278. package/src/integrations/builtin/bookmarks/__tests__/CnBookmarksTab.spec.js +7 -2
  279. package/src/integrations/builtin/collectives/CnCollectivesCard.vue +3 -2
  280. package/src/integrations/builtin/collectives/CnCollectivesTab.vue +5 -6
  281. package/src/integrations/builtin/cospend/CnCospendCard.vue +2 -2
  282. package/src/integrations/builtin/cospend/CnCospendTab.vue +3 -4
  283. package/src/integrations/builtin/deck/CnDeckCard.vue +2 -2
  284. package/src/integrations/builtin/deck/CnDeckTab.vue +3 -4
  285. package/src/integrations/builtin/email/CnEmailCard.vue +6 -2
  286. package/src/integrations/builtin/email/CnEmailTab.vue +7 -4
  287. package/src/integrations/builtin/flow/CnFlowCard.vue +2 -2
  288. package/src/integrations/builtin/flow/CnFlowTab.vue +3 -4
  289. package/src/integrations/builtin/forms/CnFormsCard.vue +3 -2
  290. package/src/integrations/builtin/forms/CnFormsTab.vue +5 -6
  291. package/src/integrations/builtin/maps/CnMapsCard.vue +3 -2
  292. package/src/integrations/builtin/maps/CnMapsTab.vue +5 -6
  293. package/src/integrations/builtin/maps/__tests__/CnMapsTab.spec.js +9 -0
  294. package/src/integrations/builtin/openproject/CnOpenprojectCard.vue +3 -2
  295. package/src/integrations/builtin/openproject/CnOpenprojectTab.vue +5 -6
  296. package/src/integrations/builtin/photos/CnPhotosCard.vue +2 -2
  297. package/src/integrations/builtin/photos/CnPhotosTab.vue +3 -4
  298. package/src/integrations/builtin/polls/CnPollsCard.vue +2 -2
  299. package/src/integrations/builtin/polls/CnPollsTab.vue +3 -4
  300. package/src/integrations/builtin/shares/CnSharesTab.vue +3 -6
  301. package/src/integrations/builtin/talk/CnTalkCard.vue +3 -2
  302. package/src/integrations/builtin/talk/CnTalkTab.vue +5 -6
  303. package/src/integrations/builtin/time-tracker/CnTimeTrackerCard.vue +2 -2
  304. package/src/integrations/builtin/time-tracker/CnTimeTrackerTab.vue +3 -4
  305. package/src/integrations/builtin/xwiki/CnXwikiCard.vue +4 -2
  306. package/src/integrations/builtin/xwiki/CnXwikiTab.vue +7 -7
  307. package/src/integrations/builtin/xwiki/__tests__/CnXwikiTab.spec.js +9 -0
  308. package/src/schemas/app-manifest-v2.schema.json +2 -1
  309. package/src/utils/actionLink.js +5 -0
  310. package/src/utils/actionsDispatcher.js +15 -0
  311. package/src/utils/linkNavigation.js +6 -3
  312. package/src/utils/rowAuxClick.js +29 -4
  313. package/src/utils/safeHref.js +18 -3
  314. package/src/utils/validateManifestV2.compiled.js +2 -2
@@ -139,12 +139,13 @@
139
139
  :data-testid-row-id="row[rowKey]"
140
140
  :class="[
141
141
  isSelected(row) ? 'cn-table-row--selected' : '',
142
+ rowLinks[String(row[rowKey])] ? 'cn-table-row--linked' : '',
142
143
  rowClass ? rowClass(row) : '',
143
144
  ]"
144
- @mousedown="onPointerDown"
145
+ @mousedown="onRowMouseDown"
145
146
  @click="onRowClick(row, $event)"
146
147
  @auxclick="onRowAuxClick(row, $event)"
147
- @contextmenu.prevent="onRowContextMenu(row, $event)">
148
+ @contextmenu="onRowContextMenu(row, $event)">
148
149
  <!-- Checkbox -->
149
150
  <td v-if="selectable"
150
151
  class="cn-table-col--checkbox"
@@ -168,6 +169,18 @@
168
169
  :class="[col.class || '', col.cellClass || '', cellClass ? cellClass(row, col) : '']"
169
170
  :style="col.width ? { maxWidth: col.width } : {}"
170
171
  @mouseenter="titleWhenClipped">
172
+ <!-- A row with a `rowClickRoute` is a real link: this anchor
173
+ is stretched over the whole row by CSS, so hovering shows
174
+ the URL, a middle or ctrl click opens a new tab natively,
175
+ and the row is reachable with Tab. The row's own click
176
+ handlers treat it as a nested control and leave it be. -->
177
+ <a v-if="colIndex === 0 && rowLinks[String(row[rowKey])]"
178
+ class="cn-table-row__link"
179
+ :href="rowLinks[String(row[rowKey])].href"
180
+ :aria-label="rowLinkLabel(row, col)"
181
+ draggable="false"
182
+ data-testid="cn-row-link"
183
+ @click="onRowLinkClick(row, $event)" />
171
184
  <!-- The padlock rides the FIRST data cell, beside whatever
172
185
  names the row. Deliberately OUTSIDE the #column-<key>
173
186
  slot: a consumer overriding that column's rendering is
@@ -274,9 +287,9 @@ import { translate as t } from '@nextcloud/l10n'
274
287
  import { generateUrl } from '@nextcloud/router'
275
288
  import { NcCheckboxRadioSwitch, NcLoadingIcon } from '@nextcloud/vue'
276
289
  import { useClickDragGuard } from '../../composables/useClickDragGuard.js'
277
- import { openRowTarget } from '../../utils/linkNavigation.js'
290
+ import { followLinkClick, openRowTarget, resolveHref } from '../../utils/linkNavigation.js'
278
291
  import { nextSortState } from '../../utils/multiColumnSort.js'
279
- import { isNewTabHandled, isRowMiddleClick, markNewTabHandled } from '../../utils/rowAuxClick.js'
292
+ import { isNewTabClick, isNewTabHandled, isRowMiddleClick, markNewTabHandled, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'
280
293
  import { DEFAULT_ROW_INDICATOR_CAP, resolveRowIndicators } from '../../utils/rowIndicators.js'
281
294
  import { columnsFromSchema } from '../../utils/schema.js'
282
295
  import { CnCellRenderer } from '../CnCellRenderer/index.js'
@@ -692,9 +705,11 @@ export default {
692
705
 
693
706
  /**
694
707
  * Convenience navigation (folded from CnTableWidget): a function that
695
- * receives the clicked row and returns a vue-router route to push. When
696
- * set, a row click navigates there (the `row-click` event still fires);
697
- * a ctrl/cmd/shift or middle click opens it in a new tab.
708
+ * receives a row and returns the vue-router route it opens. When set,
709
+ * each row renders as a real link to that route, stretched over the
710
+ * row: a click navigates there (the `row-click` event still fires), and
711
+ * a ctrl/cmd/shift or middle click opens it in a new tab. A table whose
712
+ * row click selects (`selectable` without `rowClickToView`) gets no link.
698
713
  *
699
714
  * @type {((row: object) => object)|null}
700
715
  */
@@ -717,7 +732,7 @@ export default {
717
732
  },
718
733
  },
719
734
 
720
- emits: ['row-click', 'row-context-menu', 'select', 'select-all', 'sort', 'view-all'],
735
+ emits: ['row-click', 'row-aux-click', 'row-context-menu', 'select', 'select-all', 'sort', 'view-all'],
721
736
 
722
737
  setup() {
723
738
  // Tell a deliberate row click apart from a text-selection drag.
@@ -867,6 +882,32 @@ export default {
867
882
  *
868
883
  * @return {Array<{key: string, order: 'asc'|'desc'}>}
869
884
  */
885
+ /**
886
+ * The link each row opens, keyed by row key: the `rowClickRoute`
887
+ * location and its href. Empty when rows have no route, or when a row
888
+ * click selects instead of navigating.
889
+ *
890
+ * @return {{[key: string]: {target: object, href: string}}}
891
+ */
892
+ rowLinks() {
893
+ const links = {}
894
+ if (!this.rowClickRoute || !this.$router || (this.selectable && !this.rowClickToView)) {
895
+ return links
896
+ }
897
+ for (const row of this.effectiveRows) {
898
+ const route = this.rowClickRoute(row)
899
+ if (!route) {
900
+ continue
901
+ }
902
+ const target = typeof route === 'string' ? { path: route } : route
903
+ const href = resolveHref(target, this.$router)
904
+ if (href) {
905
+ links[String(row[this.rowKey])] = { target, href }
906
+ }
907
+ }
908
+ return links
909
+ },
910
+
870
911
  effectiveSortKeys() {
871
912
  if (this.sortKeys && this.sortKeys.length > 0) {
872
913
  return this.sortKeys
@@ -1343,9 +1384,23 @@ export default {
1343
1384
  },
1344
1385
 
1345
1386
  /**
1346
- * Row-body middle click: emits `row-click` like a click, so the host
1347
- * (or `rowClickRoute`) can open the row in a new tab. Ignored for other
1348
- * buttons, nested controls, drags and select-on-click tables.
1387
+ * Row mousedown: record the press for the drag guard, and on a row a
1388
+ * middle click opens, keep the browser from starting autoscroll.
1389
+ *
1390
+ * @param {MouseEvent} event The mousedown event.
1391
+ */
1392
+ onRowMouseDown(event) {
1393
+ this.onPointerDown(event)
1394
+ if (!this.selectable || this.rowClickToView) {
1395
+ preventMiddleClickAutoscroll(event)
1396
+ }
1397
+ },
1398
+
1399
+ /**
1400
+ * Row-body middle click: emits `row-aux-click`, not `row-click`, so an
1401
+ * existing `row-click` listener that navigates never moves the current
1402
+ * tab away; `rowClickRoute` still opens the row in a new tab. Ignored
1403
+ * for other buttons, nested controls, drags and select-on-click tables.
1349
1404
  *
1350
1405
  * @param {object} row The clicked row object
1351
1406
  * @param {MouseEvent} event The originating auxclick event.
@@ -1357,23 +1412,39 @@ export default {
1357
1412
  if (this.selectable && !this.rowClickToView) {
1358
1413
  return
1359
1414
  }
1360
- this.emitRowClick(row, event)
1415
+ /**
1416
+ * @event row-aux-click Emitted on a row-body middle click, under the same conditions as `row-click`, so a host can open the row in a new tab (see `openRowTarget`). Payload: `(row, event)` — the clicked row object and the native auxclick event.
1417
+ * @type {object} The clicked row object.
1418
+ */
1419
+ this.$emit('row-aux-click', row, event)
1420
+ this.followRowClickRoute(row, event)
1361
1421
  },
1362
1422
 
1363
1423
  /**
1364
1424
  * Emit `row-click` and follow `rowClickRoute` when set.
1365
1425
  *
1366
1426
  * @param {object} row The clicked row object
1367
- * @param {MouseEvent} [event] The originating click or auxclick event.
1427
+ * @param {MouseEvent} [event] The originating click event.
1368
1428
  */
1369
1429
  emitRowClick(row, event) {
1370
1430
  /**
1371
- * @event row-click Emitted on a row-body click for navigation, and on a middle click (auxclick). Fires when `selectable` is false, OR when `rowClickToView` is set (selection then happens via the checkbox column). Payload: `(row, event)` — the clicked row object and the native click/auxclick event, so a host can open the row in a new tab on a ctrl/cmd/shift or middle click (see `openRowTarget`).
1431
+ * @event row-click Emitted on a row-body click for navigation. Fires when `selectable` is false, OR when `rowClickToView` is set (selection then happens via the checkbox column). Payload: `(row, event)` — the clicked row object and the native click event, so a host can open the row in a new tab on a ctrl/cmd/shift click (see `openRowTarget`). A middle click emits `row-aux-click` instead.
1372
1432
  * @type {object} The clicked row object.
1373
1433
  */
1374
1434
  this.$emit('row-click', row, event)
1375
- // A ctrl/cmd/shift or middle click opens the route in a new tab,
1376
- // unless a row-click listener already did.
1435
+ this.followRowClickRoute(row, event)
1436
+ },
1437
+
1438
+ /**
1439
+ * Follow `rowClickRoute` for a row click: in place, or in a new tab on
1440
+ * a ctrl/cmd/shift or middle click.
1441
+ *
1442
+ * @param {object} row The clicked row object
1443
+ * @param {MouseEvent} [event] The originating click or auxclick event.
1444
+ */
1445
+ followRowClickRoute(row, event) {
1446
+ // A new-tab click opens the route in a new tab, unless a listener
1447
+ // already did.
1377
1448
  if (this.rowClickRoute && this.$router && !isNewTabHandled(event)) {
1378
1449
  const route = this.rowClickRoute(row)
1379
1450
  if (route) {
@@ -1382,14 +1453,57 @@ export default {
1382
1453
  }
1383
1454
  },
1384
1455
 
1456
+ /**
1457
+ * A plain or alt click on a row link routes in place; a new-tab click
1458
+ * is left to the browser, which opens the href itself.
1459
+ *
1460
+ * @param {object} row The row the link belongs to.
1461
+ * @param {MouseEvent} event The click event.
1462
+ */
1463
+ onRowLinkClick(row, event) {
1464
+ const link = this.rowLinks[String(row[this.rowKey])]
1465
+ if (!link) {
1466
+ return
1467
+ }
1468
+ // Alt-click on a link downloads it; a row opens like a plain click.
1469
+ if (event.altKey && !isNewTabClick(event) && !event.defaultPrevented) {
1470
+ event.preventDefault()
1471
+ this.$router.push(link.target).catch(() => {})
1472
+ return
1473
+ }
1474
+ followLinkClick(event, link.target, this.$router)
1475
+ },
1476
+
1477
+ /**
1478
+ * The row link's accessible name: the row's first cell when it holds
1479
+ * plain text, else a generic name.
1480
+ *
1481
+ * @param {object} row The row.
1482
+ * @param {object} col The first data column.
1483
+ * @return {string}
1484
+ */
1485
+ rowLinkLabel(row, col) {
1486
+ const value = this.cellValue(row, col)
1487
+ if (['string', 'number'].includes(typeof value) && String(value).trim() !== '') {
1488
+ return String(value)
1489
+ }
1490
+ return t('nextcloud-vue', 'Open row')
1491
+ },
1492
+
1385
1493
  /**
1386
1494
  * Row right-click: forward the row + originating event so a host can
1387
- * open a context menu (the browser default is prevented).
1495
+ * open a context menu. The browser menu is prevented, except on a row
1496
+ * link when no host listens, so its link actions stay available.
1388
1497
  *
1389
1498
  * @param {object} row The right-clicked row object.
1390
1499
  * @param {MouseEvent} event The originating contextmenu event.
1391
1500
  */
1392
1501
  onRowContextMenu(row, event) {
1502
+ const fromRowLink = event.target?.closest?.('.cn-table-row__link')
1503
+ // `$.vnode.props`, not `$attrs`: a declared emit is stripped from `$attrs`.
1504
+ if (!fromRowLink || this.$.vnode.props?.onRowContextMenu) {
1505
+ event.preventDefault()
1506
+ }
1393
1507
  /**
1394
1508
  * @event row-context-menu Emitted on a row right-click (contextmenu) for hosts that render a context menu.
1395
1509
  * @type {{ row: object, event: MouseEvent }}
@@ -35,6 +35,7 @@
35
35
  :style="barStyle(bar)"
36
36
  :aria-label="barLabel(bar)"
37
37
  @click="openRow(bar.row, $event)"
38
+ @mousedown="preventMiddleClickAutoscroll"
38
39
  @auxclick="onAuxClick(bar.row, $event)">
39
40
  {{ barText(bar) }}
40
41
  </button>
@@ -61,6 +62,7 @@
61
62
  :data-row-id="rowKeyOf(row)"
62
63
  :aria-label="unplannedLabelFor(row)"
63
64
  @click="openRow(row, $event)"
65
+ @mousedown="preventMiddleClickAutoscroll"
64
66
  @auxclick="onAuxClick(row, $event)">
65
67
  {{ nameOf(row) }}
66
68
  </button>
@@ -72,7 +74,7 @@
72
74
  <script>
73
75
  import { translate as t } from '@nextcloud/l10n'
74
76
  import { buildDateAxisLanes } from '../../utils/dateAxisLanes.js'
75
- import { isRowMiddleClick } from '../../utils/rowAuxClick.js'
77
+ import { isRowMiddleClick, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'
76
78
 
77
79
  /**
78
80
  * CnDateAxisView — the index page's rows on a time scale.
@@ -133,7 +135,7 @@ export default {
133
135
  },
134
136
  },
135
137
 
136
- emits: ['row-click'],
138
+ emits: ['row-click', 'row-aux-click'],
137
139
 
138
140
  computed: {
139
141
  /** @return {object} The layout. */
@@ -176,23 +178,27 @@ export default {
176
178
  methods: {
177
179
  t,
178
180
 
181
+ preventMiddleClickAutoscroll,
182
+
179
183
  /**
180
184
  * Open one record. Both the bar on the axis and the label of an
181
185
  * undated row come through here, so the two paths cannot drift.
182
186
  *
183
187
  * @param {object} row The record the reader picked.
184
- * @param {MouseEvent} [event] The click or middle-click event.
188
+ * @param {MouseEvent} [event] The click event.
185
189
  * @return {void} Nothing.
186
190
  */
187
191
  openRow(row, event) {
188
192
  /**
189
- * @event row-click Emitted when a reader opens a record, from its bar on the axis or from the label of an undated row, on a click or a middle click. Payload: `(row, event)` — the row and the native click/auxclick event, so the host can open it in a new tab on a ctrl/cmd/shift or middle click.
193
+ * @event row-click Emitted when a reader opens a record, from its bar on the axis or from the label of an undated row. Payload: `(row, event)` — the row and the native click event, so the host can open it in a new tab on a ctrl/cmd/shift click. A middle click emits `row-aux-click` instead.
190
194
  */
191
195
  this.$emit('row-click', row, event)
192
196
  },
193
197
 
194
198
  /**
195
- * Middle click on a bar: open the record like a click would.
199
+ * Middle click on a bar or an undated row's label: emits
200
+ * `row-aux-click`, not `row-click`, so an existing listener that
201
+ * navigates never moves the current tab away.
196
202
  *
197
203
  * @param {object} row The record the reader picked.
198
204
  * @param {MouseEvent} event The auxclick event.
@@ -200,7 +206,10 @@ export default {
200
206
  */
201
207
  onAuxClick(row, event) {
202
208
  if (isRowMiddleClick(event)) {
203
- this.openRow(row, event)
209
+ /**
210
+ * @event row-aux-click Emitted when a reader middle-clicks a record's bar or undated-row label, for opening it in a new tab (see `openRowTarget`). Payload: `(row, event)` — the row and the native auxclick event.
211
+ */
212
+ this.$emit('row-aux-click', row, event)
204
213
  }
205
214
  },
206
215
 
@@ -394,7 +394,7 @@ CnDetailPage consumes the same `actions[].handler` contract as CnIndexPage. When
394
394
  | `relatedCollections` | Array | `[]` | Declarative related-object list sections below the body; each `{ title?, register, schema, filter?, columns?, sort?, limit?, rowRoute? }` renders a `CnObjectListWidget` scoped to this object via `@objectId`. Emits `@related-row-click`. See docs `cn-related-collections.md`. |
395
395
  | `summaryAggregates` | Array | `[]` | Declarative cross-schema count/sum/avg chips in the header; each `{ label, register, schema, metric?, field?, filter?, format? }` scoped to this object. See docs `cn-summary-aggregates.md`. |
396
396
  | `relationLinks` | Array | `[]` | Declarative relation-link actions; each `{ label?, register, schema, fkField, labelField?, allowCreate?, title?, selectLabel? }` opens a search-and-link modal that patches a FK on this object. Emits `@relation-linked`. See docs `cn-relation-link-modal.md`. |
397
- | `bodyWidgets` | Array | `[]` | Declarative IN-BODY sections; each `{ id?, component, title?, props?, placement?, colSpan? }` renders a registered host-app component as a titled body section (NOT the sidebar) with token-resolved props (`@objectId` / `@object.<field>` / `@workspace.<key>`) and the object context provided on `cnSectionContext`. `placement` = `before-body`/`after-data`/`after-related`/`end`. No sidebar tab required. See docs `cn-body-sections.md`. |
397
+ | `bodyWidgets` | Array | `[]` | Declarative IN-BODY sections; each `{ id?, component, title?, props?, placement?, colSpan? }` renders a registered host-app component as a titled body section (NOT the sidebar) with token-resolved props (`@objectId` / `@object.<field>` / `@workspace.<key>`) and the object context provided on `cnSectionContext`, whose `setObject(object)` shows an object a section saved without a re-fetch. `placement` = `before-body`/`after-data`/`after-related`/`end`. No sidebar tab required. See docs `cn-body-sections.md`. |
398
398
 
399
399
  ## Header actions menu
400
400
 
@@ -2885,8 +2885,9 @@ export default {
2885
2885
  * (`@objectId` / `@object.<field>` / `@workspace.<key>`) AND provided on
2886
2886
  * `cnSectionContext` for host section components that inject. Mirrors the
2887
2887
  * `cnObjectContext` ref the abstract list/stat widgets already read.
2888
+ * `setObject(object)` shows an object a section saved without a re-fetch.
2888
2889
  *
2889
- * @return {{objectId: (string|null), object: (object|null), register: string, schema: string}}
2890
+ * @return {{objectId: (string|null), object: (object|null), register: string, schema: string, setObject: function(object): void}}
2890
2891
  */
2891
2892
  sectionContext() {
2892
2893
  const resolved = this.resolvedSidebar || {}
@@ -2896,6 +2897,7 @@ export default {
2896
2897
  register: resolved.register || this.register || this.sidebarProps?.register || '',
2897
2898
  schema: resolved.schema || this.schema || this.resolvedObjectType || this.sidebarProps?.schema || '',
2898
2899
  config: this.cnAppConfigRef,
2900
+ setObject: (object) => this.setCurrentObject(object),
2899
2901
  }
2900
2902
  },
2901
2903
  },
@@ -3392,6 +3394,32 @@ export default {
3392
3394
  this.$emit('related-row-click', payload)
3393
3395
  },
3394
3396
 
3397
+ /**
3398
+ * Replace the page's object in the store cache, for a section that saved
3399
+ * it and holds the saved version. An object with another id is ignored.
3400
+ *
3401
+ * @param {object} object The saved object.
3402
+ */
3403
+ setCurrentObject(object) {
3404
+ const store = this.effectiveObjectStore
3405
+ const type = this.resolvedObjectType
3406
+ if (!store || !type || !this.objectId || !object) {
3407
+ // eslint-disable-next-line no-console -- tells the integrating section its save is not shown
3408
+ console.warn('[CnDetailPage] setObject ignored: the page has no object store, type or id')
3409
+ return
3410
+ }
3411
+ const id = object.id ?? object['@self']?.id
3412
+ if (id !== undefined && id !== null && String(id) !== String(this.objectId)) {
3413
+ // eslint-disable-next-line no-console -- tells the integrating section its save is not shown
3414
+ console.warn(`[CnDetailPage] setObject ignored: object ${id} is not the page's object ${this.objectId}`)
3415
+ return
3416
+ }
3417
+ store.objects = {
3418
+ ...store.objects,
3419
+ [type]: { ...(store.objects?.[type] || {}), [this.objectId]: object },
3420
+ }
3421
+ },
3422
+
3395
3423
  /**
3396
3424
  * Schema-driven fetch entry point — no-op outside the
3397
3425
  * `register`+`schema`+`objectId` mode. Registers the type on
@@ -29,8 +29,7 @@
29
29
  v-if="resolvedSuggestUrl"
30
30
  variant="primary"
31
31
  :href="resolvedSuggestUrl"
32
- target="_blank"
33
- rel="noopener noreferrer">
32
+ target="_blank">
34
33
  <template #icon>
35
34
  <Plus :size="20" />
36
35
  </template>
@@ -180,6 +180,7 @@
180
180
  data-testid="cn-files-browser-row"
181
181
  :data-name="node.basename"
182
182
  @click="onRowClick(node, $event)"
183
+ @mousedown="preventMiddleClickAutoscroll"
183
184
  @auxclick="onRowAuxClick(node, $event)">
184
185
  <td class="cn-files-browser__col-icon">
185
186
  <img
@@ -258,7 +259,6 @@
258
259
  v-if="node.fileid"
259
260
  :href="permalink(node)"
260
261
  target="_blank"
261
- rel="noopener noreferrer"
262
262
  :closeAfterClick="true">
263
263
  <template #icon>
264
264
  <OpenInNew :size="20" />
@@ -278,6 +278,7 @@
278
278
  data-testid="cn-files-browser-linked-row"
279
279
  :data-name="item.name"
280
280
  @click="openLinked(item)"
281
+ @mousedown="preventMiddleClickAutoscroll"
281
282
  @auxclick="onLinkedAuxClick(item, $event)">
282
283
  <td class="cn-files-browser__col-icon">
283
284
  <img
@@ -316,7 +317,6 @@
316
317
  v-if="item.href"
317
318
  :href="item.href"
318
319
  target="_blank"
319
- rel="noopener noreferrer"
320
320
  :closeAfterClick="true"
321
321
  data-testid="cn-files-browser-linked-open">
322
322
  <template #icon>
@@ -473,7 +473,7 @@ import CnCellRenderer from '../CnCellRenderer/CnCellRenderer.vue'
473
473
  import CnIcon from '../CnIcon/CnIcon.vue'
474
474
  import { readUserPreference, writeUserPreference } from '../../composables/useUserPreferences.js'
475
475
  import { dispatchAction } from '../../utils/actionsDispatcher.js'
476
- import { isNewTabClick, isRowMiddleClick } from '../../utils/rowAuxClick.js'
476
+ import { isNewTabClick, isRowMiddleClick, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'
477
477
  import { ACTIONS_NEEDING_THE_FILES_PAGE, crumbsFor, joinPath } from './filesBrowser.js'
478
478
  import {
479
479
  attributePropertiesFor,
@@ -898,6 +898,8 @@ export default {
898
898
  methods: {
899
899
  t,
900
900
 
901
+ preventMiddleClickAutoscroll,
902
+
901
903
  /**
902
904
  * Hold the file input element from its function ref.
903
905
  *
@@ -725,18 +725,14 @@ export default {
725
725
  },
726
726
 
727
727
  /**
728
- * Handle a row click — descend into folders, open files in the Files app.
728
+ * Handle a folder row click by descending into it. A file row is a
729
+ * real link to the Files app and never reaches this.
729
730
  *
730
- * @param {object} item the clicked item.
731
+ * @param {object} item the clicked folder item.
731
732
  * @return {void}
732
733
  */
733
734
  onItemClick(item) {
734
- if (item.isFolder) {
735
- const next = this.joinPath(this.currentSubPath, item.name)
736
- this.navigateTo(next)
737
- } else {
738
- this.openFileInFilesApp(item.fileId)
739
- }
735
+ this.navigateTo(this.joinPath(this.currentSubPath, item.name))
740
736
  },
741
737
 
742
738
  /**
@@ -779,19 +775,6 @@ export default {
779
775
  return `${trimmedBase}/${trimmedName}`
780
776
  },
781
777
 
782
- /**
783
- * Deep-link a file into the Nextcloud Files app in a new tab.
784
- *
785
- * @param {number|string} fileId the Nextcloud file id.
786
- * @return {void}
787
- */
788
- openFileInFilesApp(fileId) {
789
- const url = this.fileUrl(fileId)
790
- if (url) {
791
- window.open(url, '_blank', 'noopener,noreferrer')
792
- }
793
- },
794
-
795
778
  /**
796
779
  * The Files-app permalink for a file.
797
780
  *
@@ -31,15 +31,15 @@
31
31
  </p>
32
32
  <ul v-else class="cn-flow-runs-widget__list">
33
33
  <li
34
- v-for="run in rows"
35
- :key="run.uuid"
34
+ v-for="(run, index) in rows"
35
+ :key="run.uuid || `row-${index}`"
36
36
  class="cn-flow-runs-widget__row"
37
37
  :class="{ 'cn-flow-runs-widget__row--linked': isLinked }"
38
38
  :data-status="run.status">
39
39
  <component
40
- :is="runHrefs[run.uuid] ? 'a' : 'div'"
40
+ :is="runHref(run) ? 'a' : 'div'"
41
41
  class="cn-flow-runs-widget__row-content"
42
- :href="runHrefs[run.uuid] || undefined"
42
+ :href="runHref(run) || undefined"
43
43
  @click="onRowClick($event, run)">
44
44
  <span
45
45
  class="cn-flow-runs-widget__dot"
@@ -70,15 +70,15 @@
70
70
  </p>
71
71
  <ul v-else class="cn-flow-runs-widget__list">
72
72
  <li
73
- v-for="run in completedRows"
74
- :key="run.uuid"
73
+ v-for="(run, index) in completedRows"
74
+ :key="run.uuid || `completed-${index}`"
75
75
  class="cn-flow-runs-widget__row cn-flow-runs-widget__row--terminal"
76
76
  :class="{ 'cn-flow-runs-widget__row--linked': isLinked }"
77
77
  :data-status="run.status">
78
78
  <component
79
- :is="runHrefs[run.uuid] ? 'a' : 'div'"
79
+ :is="runHref(run) ? 'a' : 'div'"
80
80
  class="cn-flow-runs-widget__row-content"
81
- :href="runHrefs[run.uuid] || undefined"
81
+ :href="runHref(run) || undefined"
82
82
  @click="onRowClick($event, run)">
83
83
  <span
84
84
  class="cn-flow-runs-widget__dot cn-flow-runs-widget__dot--terminal"
@@ -362,19 +362,6 @@ export default {
362
362
  },
363
363
 
364
364
  computed: {
365
- /**
366
- * Each run's link href by uuid, resolved once per render.
367
- *
368
- * @return {{[uuid: string]: string}}
369
- */
370
- runHrefs() {
371
- const out = {}
372
- for (const run of [...this.rows, ...this.completedRows]) {
373
- out[run.uuid] = this.runHref(run)
374
- }
375
- return out
376
- },
377
-
378
365
  /**
379
366
  * Effective translate function: the explicit prop, then the injected
380
367
  * host one, then `@nextcloud/l10n` under the library's own app id.
@@ -13,7 +13,8 @@
13
13
  :showEditAction="false"
14
14
  :actions="rowActions"
15
15
  rowClickToView
16
- @rowClick="openFlow">
16
+ @rowClick="openFlow"
17
+ @rowAuxClick="openFlow">
17
18
  <template #header-actions>
18
19
  <NcButton variant="primary" :to="newFlowRoute">
19
20
  <template #icon>