@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
@@ -75,8 +75,7 @@
75
75
  <NcButton
76
76
  variant="primary"
77
77
  :href="cospendAppUrl"
78
- target="_blank"
79
- rel="noopener noreferrer">
78
+ target="_blank">
80
79
  <template #icon>
81
80
  <CurrencyEur :size="20" />
82
81
  </template>
@@ -175,7 +174,7 @@ import Plus from 'vue-material-design-icons/Plus.vue'
175
174
  import CnCospendCreate from '../../../components/CnCospendCreate/CnCospendCreate.vue'
176
175
  import CnCospendPicker from '../../../components/CnCospendPicker/CnCospendPicker.vue'
177
176
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
178
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
177
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
179
178
 
180
179
  /**
181
180
  * CnCospendTab — bespoke sidebar tab for the `cospend` integration.
@@ -389,7 +388,7 @@ export default {
389
388
  },
390
389
 
391
390
  rowUrl(row) {
392
- if (row.url) {
391
+ if (row.url && safeHref(row.url) !== '#') {
393
392
  return row.url
394
393
  }
395
394
  const projectId = row.projectId ?? row.project_id ?? row.data?.projectid ?? row.data?.project_id ?? null
@@ -110,7 +110,7 @@ import { translatePlural as n, translate as t } from '@nextcloud/l10n'
110
110
  import { NcLoadingIcon } from '@nextcloud/vue'
111
111
  import ViewColumnOutline from 'vue-material-design-icons/ViewColumnOutline.vue'
112
112
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
113
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
113
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
114
114
 
115
115
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
116
116
 
@@ -276,7 +276,7 @@ export default {
276
276
  },
277
277
 
278
278
  cardUrl(card) {
279
- if (card.url) {
279
+ if (card.url && safeHref(card.url) !== '#') {
280
280
  return card.url
281
281
  }
282
282
  const boardId = card.boardId ?? card.board?.id ?? ''
@@ -58,8 +58,7 @@
58
58
  <NcButton
59
59
  variant="primary"
60
60
  :href="deckAppUrl"
61
- target="_blank"
62
- rel="noopener noreferrer">
61
+ target="_blank">
63
62
  <template #icon>
64
63
  <ViewColumnOutline :size="20" />
65
64
  </template>
@@ -168,7 +167,7 @@ import ViewColumnOutline from 'vue-material-design-icons/ViewColumnOutline.vue'
168
167
  import CnDeckCardCreate from '../../../components/CnDeckCardCreate/CnDeckCardCreate.vue'
169
168
  import CnDeckCardPicker from '../../../components/CnDeckCardPicker/CnDeckCardPicker.vue'
170
169
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
171
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
170
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
172
171
 
173
172
  /** Maximum assignee avatars shown before collapsing the rest into a +N overflow badge. */
174
173
  const MAX_VISIBLE_ASSIGNEES = 3
@@ -353,7 +352,7 @@ export default {
353
352
  },
354
353
 
355
354
  cardUrl(card) {
356
- if (card.url) {
355
+ if (card.url && safeHref(card.url) !== '#') {
357
356
  return card.url
358
357
  }
359
358
  const boardId = card.boardId ?? card.board?.id ?? ''
@@ -321,7 +321,6 @@ export default {
321
321
  background: none;
322
322
  border: none;
323
323
  padding: 6px 0;
324
- cursor: pointer;
325
324
  text-align: left;
326
325
  color: inherit;
327
326
  font: inherit;
@@ -329,7 +328,12 @@ export default {
329
328
  box-sizing: border-box;
330
329
  }
331
330
 
332
- .cn-email-card__open:hover .cn-email-card__subject {
331
+ /* Only a row with Mail ids is a link; the rest must not look clickable. */
332
+ a.cn-email-card__open {
333
+ cursor: pointer;
334
+ }
335
+
336
+ a.cn-email-card__open:hover .cn-email-card__subject {
333
337
  color: var(--color-primary-element);
334
338
  }
335
339
 
@@ -27,8 +27,7 @@
27
27
  <NcButton
28
28
  variant="primary"
29
29
  :href="composeUrl"
30
- target="_blank"
31
- rel="noopener noreferrer">
30
+ target="_blank">
32
31
  <template #icon>
33
32
  <EmailEditOutline :size="18" />
34
33
  </template>
@@ -497,11 +496,15 @@ export default {
497
496
  border-radius: var(--border-radius-large, 8px);
498
497
  color: inherit;
499
498
  text-decoration: none;
500
- cursor: pointer;
501
499
  position: relative;
502
500
  }
503
501
 
504
- .cn-email-tab__row:hover {
502
+ /* Only a row with Mail ids is a link; the rest must not look clickable. */
503
+ a.cn-email-tab__row {
504
+ cursor: pointer;
505
+ }
506
+
507
+ a.cn-email-tab__row:hover {
505
508
  background-color: var(--color-background-hover);
506
509
  }
507
510
 
@@ -104,7 +104,7 @@ import { translatePlural as n, translate as t } from '@nextcloud/l10n'
104
104
  import { NcLoadingIcon } from '@nextcloud/vue'
105
105
  import SitemapOutline from 'vue-material-design-icons/SitemapOutline.vue'
106
106
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
107
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
107
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
108
108
 
109
109
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
110
110
  const COMPACT_LIMIT = 5
@@ -239,7 +239,7 @@ export default {
239
239
  },
240
240
 
241
241
  opUrl(op) {
242
- return op.url || this.flowSettingsUrl
242
+ return op.url && safeHref(op.url) !== '#' ? op.url : this.flowSettingsUrl
243
243
  },
244
244
 
245
245
  shortClass(className) {
@@ -58,8 +58,7 @@
58
58
  <NcButton
59
59
  variant="primary"
60
60
  :href="flowSettingsUrl"
61
- target="_blank"
62
- rel="noopener noreferrer">
61
+ target="_blank">
63
62
  <template #icon>
64
63
  <SitemapOutline :size="20" />
65
64
  </template>
@@ -139,7 +138,7 @@ import Plus from 'vue-material-design-icons/Plus.vue'
139
138
  import SitemapOutline from 'vue-material-design-icons/SitemapOutline.vue'
140
139
  import CnFlowOperationPicker from '../../../components/CnFlowOperationPicker/CnFlowOperationPicker.vue'
141
140
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
142
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
141
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
143
142
 
144
143
  /**
145
144
  * CnFlowTab — bespoke automation-rule list for the `flow` integration.
@@ -218,7 +217,7 @@ export default {
218
217
  },
219
218
 
220
219
  opUrl(op) {
221
- return op.url || this.flowSettingsUrl
220
+ return op.url && safeHref(op.url) !== '#' ? op.url : this.flowSettingsUrl
222
221
  },
223
222
 
224
223
  shortClass(className) {
@@ -100,7 +100,7 @@ import { translatePlural as n, translate as t } from '@nextcloud/l10n'
100
100
  import { NcLoadingIcon } from '@nextcloud/vue'
101
101
  import ClipboardText from 'vue-material-design-icons/ClipboardText.vue'
102
102
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
103
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
103
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
104
104
 
105
105
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
106
106
  const COMPACT_LIMIT = 5
@@ -289,8 +289,9 @@ export default {
289
289
  return form.title || form.id || t('nextcloud-vue', 'Untitled form')
290
290
  },
291
291
 
292
+ // A provider URL is used only when it is a safe scheme; else the app link.
292
293
  formUrl(form) {
293
- if (form.url) {
294
+ if (form.url && safeHref(form.url) !== '#') {
294
295
  return form.url
295
296
  }
296
297
  if (form.hash) {
@@ -67,8 +67,7 @@
67
67
  <NcButton
68
68
  variant="primary"
69
69
  :href="formsAppUrl"
70
- target="_blank"
71
- rel="noopener noreferrer">
70
+ target="_blank">
72
71
  <template #icon>
73
72
  <ClipboardText :size="20" />
74
73
  </template>
@@ -118,8 +117,7 @@
118
117
  <NcActionLink
119
118
  :closeAfterClick="true"
120
119
  :href="formUrl(form)"
121
- target="_blank"
122
- rel="noopener noreferrer">
120
+ target="_blank">
123
121
  <template #icon>
124
122
  <OpenInNew :size="20" />
125
123
  </template>
@@ -168,7 +166,7 @@ import Plus from 'vue-material-design-icons/Plus.vue'
168
166
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
169
167
  import CnFormCreate from './CnFormCreate.vue'
170
168
  import CnFormPicker from './CnFormPicker.vue'
171
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
169
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
172
170
 
173
171
  /**
174
172
  * CnFormsTab — bespoke linked-forms list for the Tier-2 `forms` leaf.
@@ -332,8 +330,9 @@ export default {
332
330
  return form.description || ''
333
331
  },
334
332
 
333
+ // A provider URL is used only when it is a safe scheme; else the app link.
335
334
  formUrl(form) {
336
- if (form.url) {
335
+ if (form.url && safeHref(form.url) !== '#') {
337
336
  return form.url
338
337
  }
339
338
  if (form.hash) {
@@ -125,7 +125,7 @@ import { translatePlural as n, translate as t } from '@nextcloud/l10n'
125
125
  import { NcLoadingIcon } from '@nextcloud/vue'
126
126
  import MapMarker from 'vue-material-design-icons/MapMarker.vue'
127
127
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
128
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
128
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
129
129
  import { stripMarker } from '../../utils/marker.js'
130
130
 
131
131
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
@@ -291,8 +291,9 @@ export default {
291
291
  return `${lat.toFixed(5)}, ${lng.toFixed(5)}`
292
292
  },
293
293
 
294
+ // A provider URL is used only when it is a safe scheme; else the app link.
294
295
  pointUrl(point) {
295
- if (typeof point.url === 'string' && point.url !== '') {
296
+ if (typeof point.url === 'string' && point.url !== '' && safeHref(point.url) !== '#') {
296
297
  return point.url
297
298
  }
298
299
  const lat = this.pointLat(point)
@@ -86,8 +86,7 @@
86
86
  <NcButton
87
87
  variant="primary"
88
88
  :href="mapsAppUrl"
89
- target="_blank"
90
- rel="noopener noreferrer">
89
+ target="_blank">
91
90
  <template #icon>
92
91
  <MapMarker :size="20" />
93
92
  </template>
@@ -146,8 +145,7 @@
146
145
  <NcActionLink
147
146
  :closeAfterClick="true"
148
147
  :href="pointUrl(point)"
149
- target="_blank"
150
- rel="noopener noreferrer">
148
+ target="_blank">
151
149
  <template #icon>
152
150
  <OpenInNew :size="20" />
153
151
  </template>
@@ -188,7 +186,7 @@ import OpenInNew from 'vue-material-design-icons/OpenInNew.vue'
188
186
  import Plus from 'vue-material-design-icons/Plus.vue'
189
187
  import CnMapPoiCreate from '../../../components/CnMapPoiCreate/CnMapPoiCreate.vue'
190
188
  import CnMapPoiPicker from '../../../components/CnMapPoiPicker/CnMapPoiPicker.vue'
191
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
189
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
192
190
  import { stripMarker } from '../../utils/marker.js'
193
191
 
194
192
  const COMMENT_MAX_CHARS = 160
@@ -389,8 +387,9 @@ export default {
389
387
  return `${lat.toFixed(5)}, ${lng.toFixed(5)}`
390
388
  },
391
389
 
390
+ // A provider URL is used only when it is a safe scheme; else the app link.
392
391
  pointUrl(point) {
393
- if (typeof point.url === 'string' && point.url !== '') {
392
+ if (typeof point.url === 'string' && point.url !== '' && safeHref(point.url) !== '#') {
394
393
  return point.url
395
394
  }
396
395
  if (this.pointHasCoords(point)) {
@@ -45,6 +45,15 @@ describe('CnMapsTab', () => {
45
45
  delete global.fetch
46
46
  })
47
47
 
48
+ it('links to the Maps app instead of a provider URL with an unsafe scheme', async () => {
49
+ global.fetch = jest.fn().mockResolvedValueOnce({ ok: true, status: 200, json: () => Promise.resolve({ results: [] }) })
50
+ const wrapper = mount(CnMapsTab, { propsData: { ...DEFAULT_PROPS } })
51
+ await flushPromises()
52
+ expect(wrapper.vm.pointUrl({ url: 'javascript:alert(1)' })).toBe('/index.php/apps/maps')
53
+ expect(wrapper.vm.pointUrl({ url: 'https://maps.example/p/1' })).toBe('https://maps.example/p/1')
54
+ wrapper.unmount()
55
+ })
56
+
48
57
  it('renders the empty state with an "Open Locations" CTA when no points', async () => {
49
58
  global.fetch = jest.fn().mockResolvedValueOnce({ ok: true, status: 200, json: () => Promise.resolve({ results: [] }) })
50
59
  const wrapper = mount(CnMapsTab, { propsData: { ...DEFAULT_PROPS } })
@@ -156,7 +156,7 @@ import Briefcase from 'vue-material-design-icons/Briefcase.vue'
156
156
  import CheckCircleOutline from 'vue-material-design-icons/CheckCircleOutline.vue'
157
157
  import LockOutline from 'vue-material-design-icons/LockOutline.vue'
158
158
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
159
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
159
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
160
160
 
161
161
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
162
162
 
@@ -338,7 +338,8 @@ export default {
338
338
  },
339
339
 
340
340
  wpUrl(wp) {
341
- return wp.url ?? wp._links?.self?.href ?? this.openprojectAppUrl
341
+ const url = wp.url ?? wp._links?.self?.href
342
+ return url && safeHref(url) !== '#' ? url : this.openprojectAppUrl
342
343
  },
343
344
 
344
345
  wpStatus(wp) {
@@ -85,8 +85,7 @@
85
85
  <NcButton
86
86
  variant="primary"
87
87
  :href="openconnectorUrl"
88
- target="_blank"
89
- rel="noopener noreferrer">
88
+ target="_blank">
90
89
  <template #icon>
91
90
  <CogOutline :size="20" />
92
91
  </template>
@@ -104,8 +103,7 @@
104
103
  <NcButton
105
104
  variant="secondary"
106
105
  :href="openprojectAppUrl"
107
- target="_blank"
108
- rel="noopener noreferrer">
106
+ target="_blank">
109
107
  <template #icon>
110
108
  <OpenInNew :size="20" />
111
109
  </template>
@@ -233,7 +231,7 @@ import StarFourPointsOutline from 'vue-material-design-icons/StarFourPointsOutli
233
231
  import CnOpenProjectCreate from '../../../components/CnOpenProjectCreate/CnOpenProjectCreate.vue'
234
232
  import CnOpenProjectPicker from '../../../components/CnOpenProjectPicker/CnOpenProjectPicker.vue'
235
233
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
236
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
234
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
237
235
 
238
236
  /**
239
237
  * CnOpenprojectTab — bespoke sidebar tab for the `openproject` integration.
@@ -549,7 +547,8 @@ export default {
549
547
  },
550
548
 
551
549
  wpUrl(wp) {
552
- return wp.url ?? wp._links?.self?.href ?? this.openprojectAppUrl
550
+ const url = wp.url ?? wp._links?.self?.href
551
+ return url && safeHref(url) !== '#' ? url : this.openprojectAppUrl
553
552
  },
554
553
 
555
554
  wpStatus(wp) {
@@ -128,7 +128,7 @@ import { NcLoadingIcon } from '@nextcloud/vue'
128
128
  import ImageIcon from 'vue-material-design-icons/Image.vue'
129
129
  import ImageMultiple from 'vue-material-design-icons/ImageMultiple.vue'
130
130
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
131
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
131
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
132
132
 
133
133
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
134
134
  const COMPACT_LIMIT = 4
@@ -265,7 +265,7 @@ export default {
265
265
  },
266
266
 
267
267
  albumUrl(album) {
268
- if (album && album.url) {
268
+ if (album && album.url && safeHref(album.url) !== '#') {
269
269
  return album.url
270
270
  }
271
271
  const name = this.albumName(album)
@@ -72,8 +72,7 @@
72
72
  <NcButton
73
73
  variant="primary"
74
74
  :href="photosAppUrl"
75
- target="_blank"
76
- rel="noopener noreferrer">
75
+ target="_blank">
77
76
  <template #icon>
78
77
  <ImageIcon :size="20" />
79
78
  </template>
@@ -154,7 +153,7 @@ import LinkVariant from 'vue-material-design-icons/LinkVariant.vue'
154
153
  import Plus from 'vue-material-design-icons/Plus.vue'
155
154
  import CnPhotoAlbumCreate from '../../../components/CnPhotoAlbumCreate/CnPhotoAlbumCreate.vue'
156
155
  import CnPhotoAlbumPicker from '../../../components/CnPhotoAlbumPicker/CnPhotoAlbumPicker.vue'
157
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
156
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
158
157
 
159
158
  /**
160
159
  * CnPhotosTab — bespoke album grid for the `photos` integration.
@@ -262,7 +261,7 @@ export default {
262
261
  },
263
262
 
264
263
  albumUrl(album) {
265
- if (album && album.url) {
264
+ if (album && album.url && safeHref(album.url) !== '#') {
266
265
  return album.url
267
266
  }
268
267
  const id = this.albumKey(album)
@@ -129,7 +129,7 @@ import FormatListChecks from 'vue-material-design-icons/FormatListChecks.vue'
129
129
  import Poll from 'vue-material-design-icons/Poll.vue'
130
130
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
131
131
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
132
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
132
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
133
133
  import { stripMarker } from '../../utils/marker.js'
134
134
 
135
135
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
@@ -266,7 +266,7 @@ export default {
266
266
  },
267
267
 
268
268
  pollUrl(poll) {
269
- if (poll.url) {
269
+ if (poll.url && safeHref(poll.url) !== '#') {
270
270
  return poll.url
271
271
  }
272
272
  const id = poll.id ?? ''
@@ -63,8 +63,7 @@
63
63
  <NcButton
64
64
  variant="primary"
65
65
  :href="pollsAppUrl"
66
- target="_blank"
67
- rel="noopener noreferrer">
66
+ target="_blank">
68
67
  <template #icon>
69
68
  <Poll :size="20" />
70
69
  </template>
@@ -179,7 +178,7 @@ import Poll from 'vue-material-design-icons/Poll.vue'
179
178
  import CnPollCreate from '../../../components/CnPollCreate/CnPollCreate.vue'
180
179
  import CnPollPicker from '../../../components/CnPollPicker/CnPollPicker.vue'
181
180
  import CnStatusBadge from '../../../components/CnStatusBadge/CnStatusBadge.vue'
182
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
181
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
183
182
  import { stripMarker } from '../../utils/marker.js'
184
183
 
185
184
  /**
@@ -365,7 +364,7 @@ export default {
365
364
  },
366
365
 
367
366
  pollUrl(poll) {
368
- if (poll.url) {
367
+ if (poll.url && safeHref(poll.url) !== '#') {
369
368
  return poll.url
370
369
  }
371
370
  const id = this.pollKey(poll)
@@ -50,8 +50,7 @@
50
50
  <NcButton
51
51
  variant="primary"
52
52
  :href="filesAppUrl"
53
- target="_blank"
54
- rel="noopener noreferrer">
53
+ target="_blank">
55
54
  <template #icon>
56
55
  <FolderOutline :size="20" />
57
56
  </template>
@@ -125,8 +124,7 @@
125
124
  <NcActionLink
126
125
  :closeAfterClick="true"
127
126
  :href="filesAppUrl"
128
- target="_blank"
129
- rel="noopener noreferrer">
127
+ target="_blank">
130
128
  <template #icon>
131
129
  <FolderOutline :size="20" />
132
130
  </template>
@@ -140,8 +138,7 @@
140
138
  <NcButton
141
139
  variant="tertiary"
142
140
  :href="filesAppUrl"
143
- target="_blank"
144
- rel="noopener noreferrer">
141
+ target="_blank">
145
142
  <template #icon>
146
143
  <FolderOutline :size="18" />
147
144
  </template>
@@ -111,7 +111,7 @@ import { translatePlural as n, translate as t } from '@nextcloud/l10n'
111
111
  import { NcAvatar, NcCounterBubble, NcLoadingIcon } from '@nextcloud/vue'
112
112
  import ChatOutline from 'vue-material-design-icons/ChatOutline.vue'
113
113
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
114
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
114
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
115
115
  import { stripMarker } from '../../utils/marker.js'
116
116
 
117
117
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
@@ -252,8 +252,9 @@ export default {
252
252
  return stripMarker(raw) || String(this.roomKey(room))
253
253
  },
254
254
 
255
+ // A provider URL is used only when it is a safe scheme; else the app link.
255
256
  roomUrl(room) {
256
- if (room.url) {
257
+ if (room.url && safeHref(room.url) !== '#') {
257
258
  return room.url
258
259
  }
259
260
  const token = room.token ?? room.id ?? ''
@@ -60,8 +60,7 @@
60
60
  <NcButton
61
61
  variant="primary"
62
62
  :href="talkAppUrl"
63
- target="_blank"
64
- rel="noopener noreferrer">
63
+ target="_blank">
65
64
  <template #icon>
66
65
  <ChatOutline :size="20" />
67
66
  </template>
@@ -107,8 +106,7 @@
107
106
  <NcActionLink
108
107
  :closeAfterClick="true"
109
108
  :href="roomUrl(room)"
110
- target="_blank"
111
- rel="noopener noreferrer">
109
+ target="_blank">
112
110
  <template #icon>
113
111
  <OpenInNew :size="20" />
114
112
  </template>
@@ -149,7 +147,7 @@ import OpenInNew from 'vue-material-design-icons/OpenInNew.vue'
149
147
  import Plus from 'vue-material-design-icons/Plus.vue'
150
148
  import CnTalkRoomCreate from '../../../components/CnTalkRoomCreate/CnTalkRoomCreate.vue'
151
149
  import CnTalkRoomPicker from '../../../components/CnTalkRoomPicker/CnTalkRoomPicker.vue'
152
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
150
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
153
151
  import { stripMarker } from '../../utils/marker.js'
154
152
 
155
153
  /**
@@ -247,8 +245,9 @@ export default {
247
245
  return stripMarker(raw) || String(this.roomKey(room))
248
246
  },
249
247
 
248
+ // A provider URL is used only when it is a safe scheme; else the app link.
250
249
  roomUrl(room) {
251
- if (room.url) {
250
+ if (room.url && safeHref(room.url) !== '#') {
252
251
  return room.url
253
252
  }
254
253
  const token = room.roomToken ?? room.token ?? room.id ?? ''
@@ -119,7 +119,7 @@ import { NcLoadingIcon } from '@nextcloud/vue'
119
119
  import Clock from 'vue-material-design-icons/Clock.vue'
120
120
  import Timer from 'vue-material-design-icons/Timer.vue'
121
121
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
122
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
122
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
123
123
 
124
124
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
125
125
 
@@ -307,7 +307,7 @@ export default {
307
307
  },
308
308
 
309
309
  rowUrl(row) {
310
- if (row.url) {
310
+ if (row.url && safeHref(row.url) !== '#') {
311
311
  return row.url
312
312
  }
313
313
  const kind = this.rowKind(row)
@@ -81,8 +81,7 @@
81
81
  <NcButton
82
82
  variant="primary"
83
83
  :href="timeTrackerAppUrl"
84
- target="_blank"
85
- rel="noopener noreferrer">
84
+ target="_blank">
86
85
  <template #icon>
87
86
  <Clock :size="20" />
88
87
  </template>
@@ -185,7 +184,7 @@ import Plus from 'vue-material-design-icons/Plus.vue'
185
184
  import Timer from 'vue-material-design-icons/Timer.vue'
186
185
  import CnTimeTrackerCreate from '../../../components/CnTimeTrackerCreate/CnTimeTrackerCreate.vue'
187
186
  import CnTimeTrackerPicker from '../../../components/CnTimeTrackerPicker/CnTimeTrackerPicker.vue'
188
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
187
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
189
188
 
190
189
  /**
191
190
  * CnTimeTrackerTab — bespoke sidebar tab for the `time-tracker`
@@ -361,7 +360,7 @@ export default {
361
360
  },
362
361
 
363
362
  rowUrl(row) {
364
- if (row.url) {
363
+ if (row.url && safeHref(row.url) !== '#') {
365
364
  return row.url
366
365
  }
367
366
  const kind = this.rowKind(row)
@@ -138,7 +138,7 @@ import { translatePlural as n, translate as t } from '@nextcloud/l10n'
138
138
  import { NcLoadingIcon } from '@nextcloud/vue'
139
139
  import FileDocumentMultiple from 'vue-material-design-icons/FileDocumentMultiple.vue'
140
140
  import CnDetailCard from '../../../components/CnDetailCard/CnDetailCard.vue'
141
- import { buildHeaders, prefixUrl } from '../../../utils/index.js'
141
+ import { buildHeaders, prefixUrl, safeHref } from '../../../utils/index.js'
142
142
 
143
143
  const VALID_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']
144
144
  const PREVIEW_MAX_CHARS = 500
@@ -303,8 +303,10 @@ export default {
303
303
  return String(page.title ?? page.page ?? page.reference ?? this.pageKey(page))
304
304
  },
305
305
 
306
+ // An unsafe scheme is treated like a missing URL.
306
307
  pageUrl(page) {
307
- return page.url ?? ''
308
+ const url = page.url ?? ''
309
+ return url && safeHref(url) !== '#' ? url : ''
308
310
  },
309
311
 
310
312
  breadcrumbLabel(page) {