@conduction/nextcloud-vue 2.56.0-beta.4 → 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 (300) 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/CnBoardView/CnBoardView.vue2.js +12 -5
  12. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
  13. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +2 -1
  14. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
  15. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js +9 -1
  16. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js.map +1 -1
  17. package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js.map +1 -1
  18. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js +6 -1
  19. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js.map +1 -1
  20. package/dist/esm/components/CnContextMenu/CnContextMenu.vue3.js.map +1 -1
  21. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +116 -15
  22. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  23. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +27 -14
  24. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  25. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js +13 -6
  26. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js.map +1 -1
  27. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js +2 -0
  28. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js.map +1 -1
  29. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +29 -1
  30. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  31. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  32. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
  33. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js +1 -2
  34. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
  35. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +3 -1
  36. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  37. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +17 -17
  38. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  39. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js +4 -21
  40. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js.map +1 -1
  41. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue3.js.map +1 -1
  42. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js +0 -13
  43. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js.map +1 -1
  44. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js +8 -8
  45. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js.map +1 -1
  46. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue2.js.map +1 -1
  47. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js +3 -2
  48. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js.map +1 -1
  49. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +67 -13
  50. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  51. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +15 -8
  52. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  53. package/dist/esm/components/CnIndexPage/manifestActionDispatch.js +31 -11
  54. package/dist/esm/components/CnIndexPage/manifestActionDispatch.js.map +1 -1
  55. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue2.js.map +1 -1
  56. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js +1 -2
  57. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js.map +1 -1
  58. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue2.js.map +1 -1
  59. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js +0 -1
  60. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js.map +1 -1
  61. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js +2 -17
  62. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js.map +1 -1
  63. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue3.js.map +1 -1
  64. package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js +35 -11
  65. package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js.map +1 -1
  66. package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js +3 -2
  67. package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js.map +1 -1
  68. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js +23 -5
  69. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js.map +1 -1
  70. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js +1 -1
  71. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js.map +1 -1
  72. package/dist/esm/components/CnObjectList/CnObjectList.vue2.js +19 -3
  73. package/dist/esm/components/CnObjectList/CnObjectList.vue2.js.map +1 -1
  74. package/dist/esm/components/CnObjectList/CnObjectList.vue3.js.map +1 -1
  75. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +45 -15
  76. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  77. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -2
  78. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  79. package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js +24 -6
  80. package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js.map +1 -1
  81. package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js +1 -1
  82. package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js.map +1 -1
  83. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  84. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +0 -1
  85. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  86. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
  87. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js +4 -2
  88. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
  89. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js +7 -2
  90. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js.map +1 -1
  91. package/dist/esm/components/CnRowActions/CnRowActions.vue3.js.map +1 -1
  92. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js +5 -3
  93. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js.map +1 -1
  94. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue3.js.map +1 -1
  95. package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
  96. package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
  97. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js +3 -1
  98. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js.map +1 -1
  99. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js +1 -0
  100. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js.map +1 -1
  101. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js +3 -1
  102. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js.map +1 -1
  103. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue3.js.map +1 -1
  104. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -1
  105. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
  106. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js +2 -4
  107. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
  108. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js +6 -0
  109. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js.map +1 -1
  110. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js +68 -53
  111. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js.map +1 -1
  112. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js +17 -0
  113. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js.map +1 -1
  114. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js +21 -19
  115. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js.map +1 -1
  116. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js +3 -1
  117. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js.map +1 -1
  118. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue3.js.map +1 -1
  119. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js +3 -1
  120. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js.map +1 -1
  121. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js +2 -4
  122. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js.map +1 -1
  123. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js +2 -1
  124. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js.map +1 -1
  125. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue3.js.map +1 -1
  126. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js +2 -1
  127. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js.map +1 -1
  128. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js +1 -2
  129. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js.map +1 -1
  130. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js +2 -1
  131. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js.map +1 -1
  132. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js.map +1 -1
  133. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +2 -1
  134. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
  135. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js +1 -2
  136. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
  137. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js.map +1 -1
  138. package/dist/esm/integrations/builtin/email/CnEmailCard.vue3.js.map +1 -1
  139. package/dist/esm/integrations/builtin/email/CnEmailTab.vue2.js.map +1 -1
  140. package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js +1 -2
  141. package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js.map +1 -1
  142. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js +2 -1
  143. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js.map +1 -1
  144. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue3.js.map +1 -1
  145. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js +2 -1
  146. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js.map +1 -1
  147. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js +1 -2
  148. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js.map +1 -1
  149. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js +3 -1
  150. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js.map +1 -1
  151. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue3.js.map +1 -1
  152. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js +3 -1
  153. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js.map +1 -1
  154. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js +2 -4
  155. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js.map +1 -1
  156. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js +3 -1
  157. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js.map +1 -1
  158. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue3.js.map +1 -1
  159. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js +3 -1
  160. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js.map +1 -1
  161. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js +2 -4
  162. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js.map +1 -1
  163. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js +3 -1
  164. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js.map +1 -1
  165. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue3.js.map +1 -1
  166. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js +3 -1
  167. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js.map +1 -1
  168. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js +2 -4
  169. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js.map +1 -1
  170. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js +2 -1
  171. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js.map +1 -1
  172. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue3.js.map +1 -1
  173. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js +2 -1
  174. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js.map +1 -1
  175. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js +1 -2
  176. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js.map +1 -1
  177. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js +2 -1
  178. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js.map +1 -1
  179. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue3.js.map +1 -1
  180. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js +2 -1
  181. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js.map +1 -1
  182. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js +1 -2
  183. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js.map +1 -1
  184. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue2.js.map +1 -1
  185. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js +3 -6
  186. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js.map +1 -1
  187. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js +3 -1
  188. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js.map +1 -1
  189. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue3.js.map +1 -1
  190. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js +3 -1
  191. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js.map +1 -1
  192. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js +2 -4
  193. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js.map +1 -1
  194. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js +2 -1
  195. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js.map +1 -1
  196. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue3.js.map +1 -1
  197. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js +2 -1
  198. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js.map +1 -1
  199. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js +1 -2
  200. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js.map +1 -1
  201. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js +4 -1
  202. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js.map +1 -1
  203. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue3.js.map +1 -1
  204. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js +6 -3
  205. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js.map +1 -1
  206. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js +2 -4
  207. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js.map +1 -1
  208. package/dist/esm/l10n/en.json.js +1 -0
  209. package/dist/esm/l10n/en.json.js.map +1 -1
  210. package/dist/esm/l10n/nl.json.js +1 -0
  211. package/dist/esm/l10n/nl.json.js.map +1 -1
  212. package/dist/esm/nextcloud-vue.css +71 -7
  213. package/dist/esm/utils/actionLink.js +5 -0
  214. package/dist/esm/utils/actionLink.js.map +1 -1
  215. package/dist/esm/utils/actionsDispatcher.js +16 -1
  216. package/dist/esm/utils/actionsDispatcher.js.map +1 -1
  217. package/dist/esm/utils/linkNavigation.js +6 -3
  218. package/dist/esm/utils/linkNavigation.js.map +1 -1
  219. package/dist/esm/utils/rowAuxClick.js +30 -5
  220. package/dist/esm/utils/rowAuxClick.js.map +1 -1
  221. package/dist/esm/utils/safeHref.js +18 -3
  222. package/dist/esm/utils/safeHref.js.map +1 -1
  223. package/dist/nextcloud-vue.cjs.js +809 -383
  224. package/dist/nextcloud-vue.cjs.js.map +2 -2
  225. package/dist/nextcloud-vue.css +71 -7
  226. package/l10n/en.json +1 -0
  227. package/l10n/nl.json +1 -0
  228. package/package.json +1 -1
  229. package/src/components/CnActionsBar/CnActionsBar.vue +14 -5
  230. package/src/components/CnActionsMenu/CnActionsMenu.vue +0 -3
  231. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +1 -2
  232. package/src/components/CnBoardView/CnBoardView.vue +13 -5
  233. package/src/components/CnCardGrid/CnCardGrid.vue +9 -1
  234. package/src/components/CnContextMenu/CnContextMenu.vue +6 -1
  235. package/src/components/CnDataTable/CnDataTable.md +1 -1
  236. package/src/components/CnDataTable/CnDataTable.vue +131 -17
  237. package/src/components/CnDateAxisView/CnDateAxisView.vue +15 -6
  238. package/src/components/CnDetailPage/CnDetailPage.md +1 -1
  239. package/src/components/CnDetailPage/CnDetailPage.vue +29 -1
  240. package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +1 -2
  241. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +5 -3
  242. package/src/components/CnFilesWidget/CnFilesWidget.vue +4 -21
  243. package/src/components/CnFlowRunsWidget/CnFlowRunsWidget.vue +8 -21
  244. package/src/components/CnFlowsPage/CnFlowsPage.vue +2 -1
  245. package/src/components/CnIndexPage/CnIndexPage.vue +75 -14
  246. package/src/components/CnIndexPage/manifestActionDispatch.js +31 -11
  247. package/src/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue +1 -2
  248. package/src/components/CnInteractionFormWidget/CnInteractionFormWidget.vue +0 -1
  249. package/src/components/CnLinkButtonWidget/CnLinkButtonWidget.vue +2 -17
  250. package/src/components/CnLogsPage/CnLogsPage.vue +37 -12
  251. package/src/components/CnObjectCard/CnObjectCard.vue +24 -6
  252. package/src/components/CnObjectList/CnObjectList.vue +19 -3
  253. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +47 -15
  254. package/src/components/CnObjectRow/CnObjectRow.vue +25 -7
  255. package/src/components/CnObjectSidebar/CnFilesTab.vue +0 -1
  256. package/src/components/CnPageRenderer/CnPageRenderer.vue +2 -0
  257. package/src/components/CnRowActions/CnRowActions.vue +7 -2
  258. package/src/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue +5 -3
  259. package/src/components/CnTabs/CnTabs.vue +7 -3
  260. package/src/components/CnTasksWidget/CnTasksWidget.vue +4 -1
  261. package/src/css/table.css +26 -0
  262. package/src/integrations/builtin/analytics/CnAnalyticsCard.vue +3 -2
  263. package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +5 -6
  264. package/src/integrations/builtin/bookmarks/CnBookmarksCard.vue +12 -1
  265. package/src/integrations/builtin/bookmarks/CnBookmarksTab.vue +23 -6
  266. package/src/integrations/builtin/bookmarks/__tests__/CnBookmarksTab.spec.js +7 -2
  267. package/src/integrations/builtin/collectives/CnCollectivesCard.vue +3 -2
  268. package/src/integrations/builtin/collectives/CnCollectivesTab.vue +5 -6
  269. package/src/integrations/builtin/cospend/CnCospendCard.vue +2 -2
  270. package/src/integrations/builtin/cospend/CnCospendTab.vue +3 -4
  271. package/src/integrations/builtin/deck/CnDeckCard.vue +2 -2
  272. package/src/integrations/builtin/deck/CnDeckTab.vue +3 -4
  273. package/src/integrations/builtin/email/CnEmailCard.vue +6 -2
  274. package/src/integrations/builtin/email/CnEmailTab.vue +7 -4
  275. package/src/integrations/builtin/flow/CnFlowCard.vue +2 -2
  276. package/src/integrations/builtin/flow/CnFlowTab.vue +3 -4
  277. package/src/integrations/builtin/forms/CnFormsCard.vue +3 -2
  278. package/src/integrations/builtin/forms/CnFormsTab.vue +5 -6
  279. package/src/integrations/builtin/maps/CnMapsCard.vue +3 -2
  280. package/src/integrations/builtin/maps/CnMapsTab.vue +5 -6
  281. package/src/integrations/builtin/maps/__tests__/CnMapsTab.spec.js +9 -0
  282. package/src/integrations/builtin/openproject/CnOpenprojectCard.vue +3 -2
  283. package/src/integrations/builtin/openproject/CnOpenprojectTab.vue +5 -6
  284. package/src/integrations/builtin/photos/CnPhotosCard.vue +2 -2
  285. package/src/integrations/builtin/photos/CnPhotosTab.vue +3 -4
  286. package/src/integrations/builtin/polls/CnPollsCard.vue +2 -2
  287. package/src/integrations/builtin/polls/CnPollsTab.vue +3 -4
  288. package/src/integrations/builtin/shares/CnSharesTab.vue +3 -6
  289. package/src/integrations/builtin/talk/CnTalkCard.vue +3 -2
  290. package/src/integrations/builtin/talk/CnTalkTab.vue +5 -6
  291. package/src/integrations/builtin/time-tracker/CnTimeTrackerCard.vue +2 -2
  292. package/src/integrations/builtin/time-tracker/CnTimeTrackerTab.vue +3 -4
  293. package/src/integrations/builtin/xwiki/CnXwikiCard.vue +4 -2
  294. package/src/integrations/builtin/xwiki/CnXwikiTab.vue +7 -7
  295. package/src/integrations/builtin/xwiki/__tests__/CnXwikiTab.spec.js +9 -0
  296. package/src/utils/actionLink.js +5 -0
  297. package/src/utils/actionsDispatcher.js +15 -0
  298. package/src/utils/linkNavigation.js +6 -3
  299. package/src/utils/rowAuxClick.js +29 -4
  300. package/src/utils/safeHref.js +18 -3
@@ -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>
@@ -451,6 +451,7 @@
451
451
  @sort="onSortEvent"
452
452
  @select="onSelect"
453
453
  @rowClick="onRowClick"
454
+ @rowAuxClick="onRowAuxClick"
454
455
  @rowContextMenu="onRowContextMenu">
455
456
  <!-- Pass through column slots -->
456
457
  <template
@@ -548,6 +549,7 @@
548
549
  :runTransition="runTransition"
549
550
  :paged="isPaged"
550
551
  @cardClick="onRowClick"
552
+ @cardAuxClick="onRowAuxClick"
551
553
  @moved="onBoardMoved" />
552
554
 
553
555
  <!--
@@ -563,7 +565,8 @@
563
565
  :laneField="dateAxis.laneField || ''"
564
566
  :labelField="dateAxis.labelField || ''"
565
567
  :rowKey="rowKey"
566
- @rowClick="onRowClick" />
568
+ @rowClick="onRowClick"
569
+ @rowAuxClick="onRowAuxClick" />
567
570
 
568
571
  <!-- List view -->
569
572
  <CnObjectList
@@ -576,6 +579,7 @@
576
579
  :rowKey="rowKey"
577
580
  :emptyText="emptyText"
578
581
  @click="onRowClick"
582
+ @auxClick="onRowAuxClick"
579
583
  @select="onSelect">
580
584
  <!--
581
585
  List-item slot resolution priority (highest first):
@@ -596,6 +600,7 @@
596
600
  :register="register"
597
601
  :selected="selected"
598
602
  @click="(...args) => onRowClick(object, args.find(isDomEvent))"
603
+ @mousedown="onCustomItemMouseDown"
599
604
  @auxclick="onCustomItemAuxClick(object, $event)"
600
605
  @select="onSelect(toggleIdInArray(internalSelectedIds, object[rowKey]))" />
601
606
  </template>
@@ -629,6 +634,7 @@
629
634
  :rowKey="rowKey"
630
635
  :emptyText="emptyText"
631
636
  @click="onRowClick"
637
+ @auxClick="onRowAuxClick"
632
638
  @select="onSelect">
633
639
  <!--
634
640
  Card slot resolution priority (highest first):
@@ -649,6 +655,7 @@
649
655
  :register="register"
650
656
  :selected="selected"
651
657
  @click="(...args) => onRowClick(object, args.find(isDomEvent))"
658
+ @mousedown="onCustomItemMouseDown"
652
659
  @auxclick="onCustomItemAuxClick(object, $event)"
653
660
  @select="onSelect(toggleIdInArray(internalSelectedIds, object[rowKey]))" />
654
661
  </template>
@@ -781,7 +788,7 @@ import { LIST_SHORTCUTS, listPaletteCommands, shortcutFor } from '../../utils/li
781
788
  import { multiKeySort } from '../../utils/multiKeySort.js'
782
789
  import { resolveDeepTokens, resolveFilterValue } from '../../utils/resolveFilterTokens.js'
783
790
  import { availableRowActions, DEFAULT_ROW_ACTION_FIELD, refusalReasonFor, undeclaredRowActions } from '../../utils/rowActionAvailability.js'
784
- import { isNewTabClick, isRowMiddleClick, markNewTabHandled } from '../../utils/rowAuxClick.js'
791
+ import { isNewTabClick, isNewTabHandled, isRowMiddleClick, markNewTabHandled, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'
785
792
  import { DEFAULT_ROW_INDICATOR_CAP } from '../../utils/rowIndicators.js'
786
793
  import { buildRouteQueryFromViewState, buildViewCreatePayload, extractViewState, extractViewStateFromRouteQuery, savedViewScope, viewMatchesScope } from '../../utils/savedViewHelpers.js'
787
794
  import { columnsFromSchema } from '../../utils/schema.js'
@@ -995,7 +1002,8 @@ function namedFilterToQuery(values) {
995
1002
  * @event {object} mass-export — Mass export confirmed. Payload: { ids, format }
996
1003
  * @event {object} mass-import — Mass import confirmed. Payload: import data
997
1004
  * @event {void} refresh — Refresh button clicked
998
- * @event {object} row-click — Table row or card clicked or middle-clicked. Payload: (row, event) — the row object and the native click/auxclick event
1005
+ * @event {object} row-click — Table row or card clicked. Payload: (row, event) — the row object and the native click event
1006
+ * @event {object} row-aux-click — Table row or card middle-clicked. Payload: (row, event) — the row object and the native auxclick event
999
1007
  * @event {{ key: string, order: string }} sort — Column sort changed
1000
1008
  * @event {number} page-changed — Pagination page changed
1001
1009
  * @event {number} page-size-changed — Pagination page size changed
@@ -2568,6 +2576,7 @@ export default {
2568
2576
  'quick-filter-change',
2569
2577
  'refresh',
2570
2578
  'row-click',
2579
+ 'row-aux-click',
2571
2580
  'search',
2572
2581
  'select',
2573
2582
  'sort',
@@ -2810,6 +2819,9 @@ export default {
2810
2819
  * that is what Add does (no host `@add` listener) and the router can
2811
2820
  * resolve it. The bar then renders Add as a real link; null otherwise.
2812
2821
  *
2822
+ * `$.vnode.props` is not reactive, so an `add` listener attached or
2823
+ * removed after mount does not re-evaluate this.
2824
+ *
2813
2825
  * @return {string|object|null}
2814
2826
  */
2815
2827
  addLinkTo() {
@@ -5565,21 +5577,60 @@ export default {
5565
5577
  /**
5566
5578
  * Row/card click: toggles selection when `selectable` (covers the custom
5567
5579
  * `cardComponent` path), otherwise emits `row-click` for navigation. A
5568
- * ctrl/cmd/shift or middle click opens a named source's row in a new tab.
5580
+ * ctrl/cmd/shift click opens a named source's row in a new tab.
5569
5581
  *
5570
5582
  * The `@event` block below sits directly against its `$emit`, and must
5571
5583
  * stay there. vue-docgen binds an event's description to the emit it
5572
5584
  * IMMEDIATELY precedes.
5573
5585
  *
5574
5586
  * @param {object} row The clicked row object
5575
- * @param {MouseEvent|KeyboardEvent} [event] The originating click/auxclick event.
5587
+ * @param {MouseEvent|KeyboardEvent} [event] The originating click event.
5576
5588
  */
5577
5589
  onRowClick(row, event) {
5590
+ if (!this.routeClickedRow(row, event)) {
5591
+ return
5592
+ }
5593
+ /**
5594
+ * @event row-click Emitted on a row/card click for navigation. Fires when `selectable` is false, OR when `rowClickToView` is set and something can open the row (selection then happens via the checkbox). Payload: `(row, event)` — the clicked row and the native click event (absent for a keyboard shortcut or map marker), so a host can open the row in a new tab on a ctrl/cmd/shift click with `openRowTarget`. A middle click emits `row-aux-click` instead.
5595
+ * @type {object} The clicked row object.
5596
+ */
5597
+ this.$emit('row-click', ...(event ? [row, event] : [row]))
5598
+ },
5599
+
5600
+ /**
5601
+ * Row/card middle click: opens a named source's row in a new tab and
5602
+ * emits `row-aux-click`, not `row-click`, so a host whose `row-click`
5603
+ * listener navigates never moves the current tab away.
5604
+ *
5605
+ * @param {object} row The clicked row object
5606
+ * @param {MouseEvent} event The originating auxclick event.
5607
+ */
5608
+ onRowAuxClick(row, event) {
5609
+ if (!this.routeClickedRow(row, event)) {
5610
+ return
5611
+ }
5612
+ /**
5613
+ * @event row-aux-click Emitted on a row/card middle click, under the same conditions as `row-click`, so a host can open the row in a new tab with `openRowTarget`. Payload: `(row, event)` — the clicked row and the native auxclick event.
5614
+ * @type {object} The clicked row object.
5615
+ */
5616
+ this.$emit('row-aux-click', row, event)
5617
+ },
5618
+
5619
+ /**
5620
+ * The shared part of a row click and a middle click: on a selectable
5621
+ * page a plain click toggles selection instead, and a named source opens
5622
+ * its own row.
5623
+ *
5624
+ * @param {object} row The clicked row object
5625
+ * @param {MouseEvent|KeyboardEvent} [event] The originating event.
5626
+ * @return {boolean} Whether the click navigates, so the caller emits.
5627
+ */
5628
+ routeClickedRow(row, event) {
5578
5629
  if (this.selectable && !this.rowClickOpens) {
5579
5630
  if (!event || event.button === undefined || event.button === 0) {
5580
5631
  this.onSelect(this.toggleIdInArray(this.internalSelectedIds, row[this.rowKey]))
5581
5632
  }
5582
- return
5633
+ return false
5583
5634
  }
5584
5635
  // A named source knows where its rows live. Emitting only would leave
5585
5636
  // the click inert on a manifest page, which has no listener to bind —
@@ -5626,11 +5677,7 @@ export default {
5626
5677
  }
5627
5678
  }
5628
5679
  }
5629
- /**
5630
- * @event row-click Emitted on a row/card click (or middle click) for navigation. Fires when `selectable` is false, OR when `rowClickToView` is set and something can open the row (selection then happens via the checkbox). Payload: `(row, event)` — the clicked row and the native click/auxclick event (absent for a keyboard shortcut or map marker), so a host can open the row in a new tab on a ctrl/cmd/shift or middle click with `openRowTarget`.
5631
- * @type {object} The clicked row object.
5632
- */
5633
- this.$emit('row-click', ...(event ? [row, event] : [row]))
5680
+ return true
5634
5681
  },
5635
5682
 
5636
5683
  /**
@@ -5644,17 +5691,31 @@ export default {
5644
5691
  return typeof Event !== 'undefined' && value instanceof Event
5645
5692
  },
5646
5693
 
5694
+ /**
5695
+ * Mousedown on a custom list/card component's root: when a middle click
5696
+ * opens the row, keep the browser from starting autoscroll.
5697
+ *
5698
+ * @param {MouseEvent} event The mousedown event.
5699
+ * @return {void}
5700
+ */
5701
+ onCustomItemMouseDown(event) {
5702
+ if (!this.selectable || this.rowClickOpens) {
5703
+ preventMiddleClickAutoscroll(event)
5704
+ }
5705
+ },
5706
+
5647
5707
  /**
5648
5708
  * Middle click on a custom list/card component's root: open the row
5649
- * like a click would.
5709
+ * like a middle click on a built-in card would. Skipped when something
5710
+ * inside the component already opened it in a new tab.
5650
5711
  *
5651
5712
  * @param {object} row The component's row.
5652
5713
  * @param {MouseEvent} event The auxclick event.
5653
5714
  * @return {void}
5654
5715
  */
5655
5716
  onCustomItemAuxClick(row, event) {
5656
- if (isRowMiddleClick(event)) {
5657
- this.onRowClick(row, event)
5717
+ if (isRowMiddleClick(event) && !isNewTabHandled(event)) {
5718
+ this.onRowAuxClick(row, event)
5658
5719
  }
5659
5720
  },
5660
5721
 
@@ -37,19 +37,39 @@ function resolveRowToken(value, row) {
37
37
  }
38
38
 
39
39
  /**
40
- * The route params a `handler: "navigate"` action pushes for a row: the row id,
41
- * overridden by the declared `params` after the `{field}` token grammar. A
42
- * token naming a field the row lacks is dropped.
40
+ * The implicit `{ id }` param for a row, only when the named route declares
41
+ * `:id`: vue-router warns about (and drops) a param its path does not take.
42
+ * Without a router to ask, or for a route it does not know, the id is kept.
43
43
  *
44
- * @param {object} action Manifest action descriptor.
44
+ * @param {object} [router] The app's router.
45
+ * @param {string} name The route name.
45
46
  * @param {object} row The row.
46
47
  * @param {string} rowKey The row's id field.
48
+ * @return {object} `{ id }`, or an empty object.
49
+ */
50
+ function rowIdParam(router, name, row, rowKey) {
51
+ const routes = typeof router?.getRoutes === 'function' ? router.getRoutes() : null
52
+ const route = routes ? routes.find((r) => r.name === name) : null
53
+ if (route && !/:id\b/.test(route.path)) {
54
+ return {}
55
+ }
56
+ return { id: row?.[rowKey] }
57
+ }
58
+
59
+ /**
60
+ * The route params a `handler: "navigate"` action pushes for a row: the row id
61
+ * (when the route takes one), overridden by the declared `params` after the
62
+ * `{field}` token grammar. A token naming a field the row lacks is dropped.
63
+ *
64
+ * @param {object} action Manifest action descriptor.
65
+ * @param {object} row The row.
66
+ * @param {object} ctx Dispatch context (`rowKey`, `router`).
47
67
  * @param {boolean} warn Whether to warn about a dropped param.
48
68
  * @return {object} The params.
49
69
  */
50
- function navigateParams(action, row, rowKey, warn) {
70
+ function navigateParams(action, row, ctx, warn) {
51
71
  const declaredParams = (action.params && typeof action.params === 'object') ? action.params : null
52
- const params = { id: row?.[rowKey] }
72
+ const params = rowIdParam(ctx.router, action.route, row, ctx.rowKey)
53
73
  for (const [key, declared] of Object.entries(declaredParams || {})) {
54
74
  const { resolved, value } = resolveRowToken(declared, row)
55
75
  if (resolved) {
@@ -88,7 +108,7 @@ export function resolveActionTarget(action, row, ctx, warn = false) {
88
108
  return null
89
109
  }
90
110
  if (type === 'open-page') {
91
- return { target: { name: target, params: { id: row?.[ctx.rowKey] } }, external: false }
111
+ return { target: { name: target, params: rowIdParam(ctx.router, target, row, ctx.rowKey) }, external: false }
92
112
  }
93
113
  return { target, external: isExternalActionTarget(target) }
94
114
  }
@@ -96,7 +116,7 @@ export function resolveActionTarget(action, row, ctx, warn = false) {
96
116
  if (typeof action.route !== 'string' || action.route.length === 0) {
97
117
  return null
98
118
  }
99
- return { target: { name: action.route, params: navigateParams(action, row, ctx.rowKey, warn) }, external: false }
119
+ return { target: { name: action.route, params: navigateParams(action, row, ctx, warn) }, external: false }
100
120
  }
101
121
  return null
102
122
  }
@@ -115,8 +135,8 @@ export function resolveActionTarget(action, row, ctx, warn = false) {
115
135
  * - `open-modal` → not wired for index actions; falls back to `@action`.
116
136
  *
117
137
  * Handler dispatch (`type: 'handler'`, the default) reads `action.handler`:
118
- * - `navigate` → $router.push to `action.route` with `{ id: row[rowKey] }`,
119
- * merged with the `action.params` map (declared params win — so a
138
+ * - `navigate` → $router.push to `action.route` with `{ id: row[rowKey] }`
139
+ * (when the route declares `:id`), merged with the `action.params` map (declared params win — so a
120
140
  * "New X" action can navigate to a detail route with `{ id: "new" }`).
121
141
  * Param strings run the `{field}` row-token grammar: `"{id}"` resolves to
122
142
  * `row.id` (type preserved), `"item-{id}"` interpolates, and a brace-less
@@ -187,7 +207,7 @@ export function resolveActionHandler(action, ctx) {
187
207
  // `{field}` row-token grammar first — an unresolved token is dropped
188
208
  // rather than pushed as a literal `%7Bid%7D` path segment.
189
209
  return (row) => {
190
- ctx.router.push({ name: route, params: navigateParams(action, row, ctx.rowKey, true) })
210
+ ctx.router.push({ name: route, params: navigateParams(action, row, ctx, true) })
191
211
  }
192
212
  }
193
213
 
@@ -25,8 +25,7 @@
25
25
  <NcButton
26
26
  variant="primary"
27
27
  :href="docsUrl"
28
- target="_blank"
29
- rel="noopener">
28
+ target="_blank">
30
29
  <template #icon>
31
30
  <OpenInNew :size="18" />
32
31
  </template>
@@ -38,7 +38,6 @@
38
38
  variant="tertiary"
39
39
  :href="savedHref"
40
40
  target="_blank"
41
- rel="noopener noreferrer"
42
41
  data-testid="cn-interaction-form-open">
43
42
  <template #icon>
44
43
  <OpenInNew :size="20" />
@@ -420,10 +420,9 @@ export default {
420
420
  * @return {void}
421
421
  */
422
422
  dispatchAction({ actionType, url, value }) {
423
+ // An `external` entry with a URL is a real link (see linkAttrsFor);
424
+ // one without a URL has nothing to open.
423
425
  switch (actionType) {
424
- case ACTION_TYPES.EXTERNAL:
425
- this.handleExternal(url)
426
- break
427
426
  case ACTION_TYPES.INTERNAL:
428
427
  this.$emit('internal-action', url)
429
428
  break
@@ -434,20 +433,6 @@ export default {
434
433
  break
435
434
  }
436
435
  },
437
-
438
- /**
439
- * Open an external URL in a new tab; `noopener,noreferrer` prevents
440
- * the opened page reaching back via `window.opener`.
441
- *
442
- * @param {string} url the URL to open.
443
- * @return {void}
444
- */
445
- handleExternal(url) {
446
- if (typeof url !== 'string' || url === '') {
447
- return
448
- }
449
- window.open(url, '_blank', 'noopener,noreferrer')
450
- },
451
436
  },
452
437
  }
453
438
  </script>