@conduction/nextcloud-vue 2.58.0 → 2.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +12 -2
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +1 -2
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +0 -3
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +1 -2
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +12 -5
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +2 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js +9 -1
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js.map +1 -1
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js.map +1 -1
- package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js +6 -1
- package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js.map +1 -1
- package/dist/esm/components/CnContextMenu/CnContextMenu.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +116 -15
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +27 -14
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js +13 -6
- package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js.map +1 -1
- package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js +2 -0
- package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +29 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js +1 -2
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +3 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +17 -17
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js +4 -21
- package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js +0 -13
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js +8 -8
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue2.js.map +1 -1
- package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js +3 -2
- package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +67 -13
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +15 -8
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/manifestActionDispatch.js +31 -11
- package/dist/esm/components/CnIndexPage/manifestActionDispatch.js.map +1 -1
- package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue2.js.map +1 -1
- package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js +1 -2
- package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js.map +1 -1
- package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js +0 -1
- package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js +2 -17
- package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js +35 -11
- package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js.map +1 -1
- package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js +3 -2
- package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js +23 -5
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js +1 -1
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectList/CnObjectList.vue2.js +19 -3
- package/dist/esm/components/CnObjectList/CnObjectList.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectList/CnObjectList.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +45 -15
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -2
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js +24 -6
- package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js +1 -1
- package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +0 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js +4 -2
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js +100 -3
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnRowActions/CnRowActions.vue2.js +7 -2
- package/dist/esm/components/CnRowActions/CnRowActions.vue2.js.map +1 -1
- package/dist/esm/components/CnRowActions/CnRowActions.vue3.js.map +1 -1
- package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js +5 -3
- package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js +3 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js +1 -0
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js +6 -0
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js +68 -53
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js +17 -0
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js +21 -19
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/email/CnEmailCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/email/CnEmailTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/flow/CnFlowCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/forms/CnFormsCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/maps/CnMapsCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/polls/CnPollsCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/shares/CnSharesTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js +3 -6
- package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/talk/CnTalkCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js +4 -1
- package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js +6 -3
- package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js.map +1 -1
- package/dist/esm/l10n/en.json.js +1 -0
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +1 -0
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +71 -7
- package/dist/esm/utils/actionLink.js +5 -0
- package/dist/esm/utils/actionLink.js.map +1 -1
- package/dist/esm/utils/actionsDispatcher.js +16 -1
- package/dist/esm/utils/actionsDispatcher.js.map +1 -1
- package/dist/esm/utils/linkNavigation.js +6 -3
- package/dist/esm/utils/linkNavigation.js.map +1 -1
- package/dist/esm/utils/rowAuxClick.js +30 -5
- package/dist/esm/utils/rowAuxClick.js.map +1 -1
- package/dist/esm/utils/safeHref.js +18 -3
- package/dist/esm/utils/safeHref.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +909 -386
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +71 -7
- package/l10n/en.json +1 -0
- package/l10n/nl.json +1 -0
- package/package.json +1 -1
- package/src/components/CnActionsBar/CnActionsBar.vue +14 -5
- package/src/components/CnActionsMenu/CnActionsMenu.vue +0 -3
- package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +1 -2
- package/src/components/CnBoardView/CnBoardView.vue +13 -5
- package/src/components/CnCardGrid/CnCardGrid.vue +9 -1
- package/src/components/CnContextMenu/CnContextMenu.vue +6 -1
- package/src/components/CnDataTable/CnDataTable.md +1 -1
- package/src/components/CnDataTable/CnDataTable.vue +131 -17
- package/src/components/CnDateAxisView/CnDateAxisView.vue +15 -6
- package/src/components/CnDetailPage/CnDetailPage.md +1 -1
- package/src/components/CnDetailPage/CnDetailPage.vue +29 -1
- package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +1 -2
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +5 -3
- package/src/components/CnFilesWidget/CnFilesWidget.vue +4 -21
- package/src/components/CnFlowRunsWidget/CnFlowRunsWidget.vue +8 -21
- package/src/components/CnFlowsPage/CnFlowsPage.vue +2 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +75 -14
- package/src/components/CnIndexPage/manifestActionDispatch.js +31 -11
- package/src/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue +1 -2
- package/src/components/CnInteractionFormWidget/CnInteractionFormWidget.vue +0 -1
- package/src/components/CnLinkButtonWidget/CnLinkButtonWidget.vue +2 -17
- package/src/components/CnLogsPage/CnLogsPage.vue +37 -12
- package/src/components/CnObjectCard/CnObjectCard.vue +24 -6
- package/src/components/CnObjectList/CnObjectList.vue +19 -3
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +47 -15
- package/src/components/CnObjectRow/CnObjectRow.vue +25 -7
- package/src/components/CnObjectSidebar/CnFilesTab.vue +0 -1
- package/src/components/CnPageRenderer/CnPageRenderer.vue +2 -0
- package/src/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue +100 -3
- package/src/components/CnRowActions/CnRowActions.vue +7 -2
- package/src/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue +5 -3
- package/src/components/CnTabs/CnTabs.vue +7 -3
- package/src/components/CnTasksWidget/CnTasksWidget.vue +4 -1
- package/src/css/table.css +26 -0
- package/src/integrations/builtin/analytics/CnAnalyticsCard.vue +3 -2
- package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +5 -6
- package/src/integrations/builtin/bookmarks/CnBookmarksCard.vue +12 -1
- package/src/integrations/builtin/bookmarks/CnBookmarksTab.vue +23 -6
- package/src/integrations/builtin/bookmarks/__tests__/CnBookmarksTab.spec.js +7 -2
- package/src/integrations/builtin/collectives/CnCollectivesCard.vue +3 -2
- package/src/integrations/builtin/collectives/CnCollectivesTab.vue +5 -6
- package/src/integrations/builtin/cospend/CnCospendCard.vue +2 -2
- package/src/integrations/builtin/cospend/CnCospendTab.vue +3 -4
- package/src/integrations/builtin/deck/CnDeckCard.vue +2 -2
- package/src/integrations/builtin/deck/CnDeckTab.vue +3 -4
- package/src/integrations/builtin/email/CnEmailCard.vue +6 -2
- package/src/integrations/builtin/email/CnEmailTab.vue +7 -4
- package/src/integrations/builtin/flow/CnFlowCard.vue +2 -2
- package/src/integrations/builtin/flow/CnFlowTab.vue +3 -4
- package/src/integrations/builtin/forms/CnFormsCard.vue +3 -2
- package/src/integrations/builtin/forms/CnFormsTab.vue +5 -6
- package/src/integrations/builtin/maps/CnMapsCard.vue +3 -2
- package/src/integrations/builtin/maps/CnMapsTab.vue +5 -6
- package/src/integrations/builtin/maps/__tests__/CnMapsTab.spec.js +9 -0
- package/src/integrations/builtin/openproject/CnOpenprojectCard.vue +3 -2
- package/src/integrations/builtin/openproject/CnOpenprojectTab.vue +5 -6
- package/src/integrations/builtin/photos/CnPhotosCard.vue +2 -2
- package/src/integrations/builtin/photos/CnPhotosTab.vue +3 -4
- package/src/integrations/builtin/polls/CnPollsCard.vue +2 -2
- package/src/integrations/builtin/polls/CnPollsTab.vue +3 -4
- package/src/integrations/builtin/shares/CnSharesTab.vue +3 -6
- package/src/integrations/builtin/talk/CnTalkCard.vue +3 -2
- package/src/integrations/builtin/talk/CnTalkTab.vue +5 -6
- package/src/integrations/builtin/time-tracker/CnTimeTrackerCard.vue +2 -2
- package/src/integrations/builtin/time-tracker/CnTimeTrackerTab.vue +3 -4
- package/src/integrations/builtin/xwiki/CnXwikiCard.vue +4 -2
- package/src/integrations/builtin/xwiki/CnXwikiTab.vue +7 -7
- package/src/integrations/builtin/xwiki/__tests__/CnXwikiTab.spec.js +9 -0
- package/src/utils/actionLink.js +5 -0
- package/src/utils/actionsDispatcher.js +15 -0
- package/src/utils/linkNavigation.js +6 -3
- package/src/utils/rowAuxClick.js +29 -4
- package/src/utils/safeHref.js +18 -3
|
@@ -89,7 +89,8 @@
|
|
|
89
89
|
:sortKeys="effectiveSortKeys"
|
|
90
90
|
:emptyText="emptyText"
|
|
91
91
|
@sort="onSort"
|
|
92
|
-
@rowClick="onRowClick"
|
|
92
|
+
@rowClick="onRowClick"
|
|
93
|
+
@rowAuxClick="onRowAuxClick">
|
|
93
94
|
<template
|
|
94
95
|
v-for="col in slotColumns"
|
|
95
96
|
#[`column-${col}`]="{ row, value }">
|
|
@@ -484,14 +485,21 @@ export default {
|
|
|
484
485
|
*/
|
|
485
486
|
'action',
|
|
486
487
|
/**
|
|
487
|
-
* @event row-click Emitted when a log row's body is clicked or
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
488
|
+
* @event row-click Emitted when a log row's body is clicked, whether or
|
|
489
|
+
* not `rowDetail` opened the detail dialog — so a host can navigate
|
|
490
|
+
* instead of (or as well as) showing the dialog. Payload: `(row, event)`,
|
|
491
|
+
* the second being the native click event. A middle click emits
|
|
492
|
+
* `row-aux-click` instead.
|
|
492
493
|
* @type {object}
|
|
493
494
|
*/
|
|
494
495
|
'row-click',
|
|
496
|
+
/**
|
|
497
|
+
* @event row-aux-click Emitted when a log row's body is middle-clicked,
|
|
498
|
+
* for opening it in a new tab. Payload: `(row, event)`, the second being
|
|
499
|
+
* the native auxclick event.
|
|
500
|
+
* @type {object}
|
|
501
|
+
*/
|
|
502
|
+
'row-aux-click',
|
|
495
503
|
],
|
|
496
504
|
|
|
497
505
|
setup(props) {
|
|
@@ -994,26 +1002,43 @@ export default {
|
|
|
994
1002
|
/**
|
|
995
1003
|
* Handle a row-body click: navigate to `rowRoute` when one is declared,
|
|
996
1004
|
* else open the detail dialog when `rowDetail` is set. Always re-emits
|
|
997
|
-
* so a host can do its own thing regardless. A ctrl/cmd/shift
|
|
998
|
-
*
|
|
999
|
-
* dialog.
|
|
1005
|
+
* so a host can do its own thing regardless. A ctrl/cmd/shift click
|
|
1006
|
+
* opens `rowRoute` in a new tab.
|
|
1000
1007
|
*
|
|
1001
1008
|
* @param {object} row The clicked log entry.
|
|
1002
|
-
* @param {MouseEvent} [event] The originating click
|
|
1009
|
+
* @param {MouseEvent} [event] The originating click event.
|
|
1003
1010
|
*/
|
|
1004
1011
|
onRowClick(row, event) {
|
|
1005
1012
|
if (this.rowRoute) {
|
|
1006
1013
|
markNewTabHandled(event, openRowTarget(event, { name: this.rowRoute, params: { id: row?.[this.rowKey] } }, this.$router))
|
|
1007
|
-
} else if (this.rowDetail
|
|
1014
|
+
} else if (this.rowDetail) {
|
|
1008
1015
|
this.detailRow = row
|
|
1009
1016
|
}
|
|
1010
1017
|
/**
|
|
1011
|
-
* @event row-click Emitted when a log row's body is clicked
|
|
1018
|
+
* @event row-click Emitted when a log row's body is clicked. Payload: `(row, event)` — the log entry and the native click event.
|
|
1012
1019
|
* @type {object}
|
|
1013
1020
|
*/
|
|
1014
1021
|
this.$emit('row-click', row, event)
|
|
1015
1022
|
},
|
|
1016
1023
|
|
|
1024
|
+
/**
|
|
1025
|
+
* Handle a row-body middle click: open `rowRoute` in a new tab, never
|
|
1026
|
+
* the detail dialog, and emit `row-aux-click` rather than `row-click`.
|
|
1027
|
+
*
|
|
1028
|
+
* @param {object} row The clicked log entry.
|
|
1029
|
+
* @param {MouseEvent} event The originating auxclick event.
|
|
1030
|
+
*/
|
|
1031
|
+
onRowAuxClick(row, event) {
|
|
1032
|
+
if (this.rowRoute) {
|
|
1033
|
+
markNewTabHandled(event, openRowTarget(event, { name: this.rowRoute, params: { id: row?.[this.rowKey] } }, this.$router))
|
|
1034
|
+
}
|
|
1035
|
+
/**
|
|
1036
|
+
* @event row-aux-click Emitted when a log row's body is middle-clicked. Payload: `(row, event)` — the log entry and the native auxclick event.
|
|
1037
|
+
* @type {object}
|
|
1038
|
+
*/
|
|
1039
|
+
this.$emit('row-aux-click', row, event)
|
|
1040
|
+
},
|
|
1041
|
+
|
|
1017
1042
|
/** Close the row-detail dialog. */
|
|
1018
1043
|
closeDetail() {
|
|
1019
1044
|
this.detailRow = null
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div
|
|
3
3
|
class="cn-object-card"
|
|
4
4
|
:class="{ 'cn-object-card--selected': selected }"
|
|
5
|
-
@mousedown="
|
|
5
|
+
@mousedown="onCardMouseDown"
|
|
6
6
|
@click="onCardClick($event)"
|
|
7
7
|
@auxclick="onCardAuxClick($event)">
|
|
8
8
|
<!-- Selection checkbox -->
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
import { NcCheckboxRadioSwitch } from '@nextcloud/vue'
|
|
77
77
|
import { useClickDragGuard } from '../../composables/useClickDragGuard.js'
|
|
78
78
|
import { resolveImageUrl } from '../../utils/resolveImageUrl.js'
|
|
79
|
-
import { isRowMiddleClick } from '../../utils/rowAuxClick.js'
|
|
79
|
+
import { isRowMiddleClick, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'
|
|
80
80
|
import { formatValue } from '../../utils/schema.js'
|
|
81
81
|
import { CnCellRenderer } from '../CnCellRenderer/index.js'
|
|
82
82
|
import { CnLockIndicator } from '../CnLockIndicator/index.js'
|
|
@@ -161,7 +161,7 @@ export default {
|
|
|
161
161
|
},
|
|
162
162
|
},
|
|
163
163
|
|
|
164
|
-
emits: ['click', 'select'],
|
|
164
|
+
emits: ['click', 'select', 'aux-click'],
|
|
165
165
|
|
|
166
166
|
setup() {
|
|
167
167
|
// Tell a deliberate card click apart from a text-selection drag.
|
|
@@ -287,14 +287,28 @@ export default {
|
|
|
287
287
|
return
|
|
288
288
|
}
|
|
289
289
|
/**
|
|
290
|
-
* @event click Emitted when a non-selectable (or `clickToView`) card is clicked
|
|
290
|
+
* @event click Emitted when a non-selectable (or `clickToView`) card is clicked. Payload: `(object, event)` — the card's object and the native click event, for opening it in a new tab on a ctrl/cmd/shift click. A middle click emits `aux-click` instead. Selectable cards emit `select`; they also emit `click` (deprecated) when a `click` listener is present, so migrate selectable consumers to `@select`.
|
|
291
291
|
* @type {object} The card's object.
|
|
292
292
|
*/
|
|
293
293
|
this.$emit('click', this.object, event)
|
|
294
294
|
},
|
|
295
295
|
|
|
296
296
|
/**
|
|
297
|
-
* Card
|
|
297
|
+
* Card mousedown: record the press for the drag guard, and on a card a
|
|
298
|
+
* middle click opens, keep the browser from starting autoscroll.
|
|
299
|
+
*
|
|
300
|
+
* @param {MouseEvent} event The mousedown event.
|
|
301
|
+
*/
|
|
302
|
+
onCardMouseDown(event) {
|
|
303
|
+
this.onPointerDown(event)
|
|
304
|
+
if (!this.selectable || this.clickToView) {
|
|
305
|
+
preventMiddleClickAutoscroll(event)
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Card-body middle click: emits `aux-click`, not `click`, so an existing
|
|
311
|
+
* `click` listener that navigates never moves the current tab away.
|
|
298
312
|
* Ignored on a select-on-click card, on nested controls and on drags.
|
|
299
313
|
*
|
|
300
314
|
* @param {MouseEvent} event The auxclick event.
|
|
@@ -306,7 +320,11 @@ export default {
|
|
|
306
320
|
if (this.selectable && !this.clickToView) {
|
|
307
321
|
return
|
|
308
322
|
}
|
|
309
|
-
|
|
323
|
+
/**
|
|
324
|
+
* @event aux-click Emitted when a non-selectable (or `clickToView`) card is middle-clicked, for opening it in a new tab (see `openRowTarget`). Payload: `(object, event)` — the card's object and the native auxclick event.
|
|
325
|
+
* @type {object} The card's object.
|
|
326
|
+
*/
|
|
327
|
+
this.$emit('aux-click', this.object, event)
|
|
310
328
|
},
|
|
311
329
|
},
|
|
312
330
|
}
|
|
@@ -163,7 +163,7 @@ export default {
|
|
|
163
163
|
},
|
|
164
164
|
},
|
|
165
165
|
|
|
166
|
-
emits: ['click', 'select'],
|
|
166
|
+
emits: ['click', 'select', 'aux-click'],
|
|
167
167
|
|
|
168
168
|
computed: {
|
|
169
169
|
/**
|
|
@@ -194,6 +194,7 @@ export default {
|
|
|
194
194
|
const listeners = { select: () => this.toggleSelect(object) }
|
|
195
195
|
if (!this.selectable) {
|
|
196
196
|
listeners.click = (_row, event) => this.emitClick(object, event)
|
|
197
|
+
listeners['aux-click'] = (_row, event) => this.emitAuxClick(object, event)
|
|
197
198
|
}
|
|
198
199
|
return listeners
|
|
199
200
|
},
|
|
@@ -202,16 +203,31 @@ export default {
|
|
|
202
203
|
* Emit `click` for a non-selectable row (navigation).
|
|
203
204
|
*
|
|
204
205
|
* @param {object} object The clicked row's object.
|
|
205
|
-
* @param {MouseEvent} [event] The native click
|
|
206
|
+
* @param {MouseEvent} [event] The native click event.
|
|
206
207
|
*/
|
|
207
208
|
emitClick(object, event) {
|
|
208
209
|
/**
|
|
209
|
-
* @event click Emitted when a non-selectable row is clicked
|
|
210
|
+
* @event click Emitted when a non-selectable row is clicked (navigation). Payload: `(object, event)` — the row's object and the native click event, for opening it in a new tab on a ctrl/cmd/shift click. A middle click emits `aux-click` instead.
|
|
210
211
|
* @type {object} The clicked row's object.
|
|
211
212
|
*/
|
|
212
213
|
this.$emit('click', object, event)
|
|
213
214
|
},
|
|
214
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Emit `aux-click` for a middle click on a non-selectable row, kept off
|
|
218
|
+
* `click` so a navigating listener never moves the current tab away.
|
|
219
|
+
*
|
|
220
|
+
* @param {object} object The clicked row's object.
|
|
221
|
+
* @param {MouseEvent} event The native auxclick event.
|
|
222
|
+
*/
|
|
223
|
+
emitAuxClick(object, event) {
|
|
224
|
+
/**
|
|
225
|
+
* @event aux-click Emitted when a non-selectable row is middle-clicked, for opening it in a new tab (see `openRowTarget`). Payload: `(object, event)` — the row's object and the native auxclick event.
|
|
226
|
+
* @type {object} The clicked row's object.
|
|
227
|
+
*/
|
|
228
|
+
this.$emit('aux-click', object, event)
|
|
229
|
+
},
|
|
230
|
+
|
|
215
231
|
toggleSelect(object) {
|
|
216
232
|
const id = object[this.rowKey]
|
|
217
233
|
const newIds = this.isSelected(object)
|
|
@@ -152,6 +152,7 @@
|
|
|
152
152
|
:sortOrder="localSort.dir || 'asc'"
|
|
153
153
|
borderless
|
|
154
154
|
@rowClick="onRowClick"
|
|
155
|
+
@rowAuxClick="onRowAuxClick"
|
|
155
156
|
@select="onSelect"
|
|
156
157
|
@sort="onSort">
|
|
157
158
|
<template v-if="mappedRowActions.length > 0" #row-actions="{ row }">
|
|
@@ -172,6 +173,7 @@
|
|
|
172
173
|
:sortOrder="localSort.dir || 'asc'"
|
|
173
174
|
borderless
|
|
174
175
|
@rowClick="onRowClick"
|
|
176
|
+
@rowAuxClick="onRowAuxClick"
|
|
175
177
|
@select="onSelect"
|
|
176
178
|
@sort="onSort">
|
|
177
179
|
<!-- Declarative per-row actions (`content.rowActions`).
|
|
@@ -286,7 +288,7 @@ import CnFkResolveCell from '../CnFkResolveCell/CnFkResolveCell.vue'
|
|
|
286
288
|
import CnFormDialog from '../CnFormDialog/CnFormDialog.vue'
|
|
287
289
|
import CnPagination from '../CnPagination/CnPagination.vue'
|
|
288
290
|
import CnWidgetEmptyState from '../CnWidgetEmptyState/CnWidgetEmptyState.vue'
|
|
289
|
-
import { actionLink, dispatchAction } from '../../utils/actionsDispatcher.js'
|
|
291
|
+
import { actionLink, dispatchAction, hasActionTargetTokens } from '../../utils/actionsDispatcher.js'
|
|
290
292
|
import { followLinkClick, openRowTarget, resolveHref } from '../../utils/linkNavigation.js'
|
|
291
293
|
import { objectFieldValue } from '../../utils/objectName.js'
|
|
292
294
|
import { dropOptionalUnresolved, hasUnresolvedTokens, resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
@@ -421,7 +423,7 @@ export default {
|
|
|
421
423
|
},
|
|
422
424
|
},
|
|
423
425
|
|
|
424
|
-
emits: ['created', 'row-click', 'view-all', 'files-dropped'],
|
|
426
|
+
emits: ['created', 'row-click', 'row-aux-click', 'view-all', 'files-dropped'],
|
|
425
427
|
|
|
426
428
|
data() {
|
|
427
429
|
return {
|
|
@@ -1414,29 +1416,60 @@ export default {
|
|
|
1414
1416
|
|
|
1415
1417
|
/**
|
|
1416
1418
|
* Navigate to a configured detail route on row click (when `rowRoute`
|
|
1417
|
-
* is set and a router is available); a ctrl/cmd/shift
|
|
1418
|
-
*
|
|
1419
|
+
* is set and a router is available); a ctrl/cmd/shift click opens it
|
|
1420
|
+
* in a new tab.
|
|
1419
1421
|
*
|
|
1420
1422
|
* @param {object} row The clicked object row.
|
|
1421
|
-
* @param {MouseEvent} [event] The originating click
|
|
1423
|
+
* @param {MouseEvent} [event] The originating click event.
|
|
1422
1424
|
* @return {void}
|
|
1423
1425
|
*/
|
|
1424
1426
|
onRowClick(row, event) {
|
|
1425
|
-
|
|
1426
|
-
const id = row && (row.id || (row['@self'] && row['@self'].id))
|
|
1427
|
-
if (route && id && this.$router) {
|
|
1428
|
-
markNewTabHandled(event, openRowTarget(event, { name: route, params: { id } }, this.$router))
|
|
1429
|
-
}
|
|
1427
|
+
this.openRowRoute(row, event)
|
|
1430
1428
|
/**
|
|
1431
1429
|
* @event row-click Emitted with the clicked object (for hosts that
|
|
1432
|
-
* want to handle navigation themselves)
|
|
1433
|
-
*
|
|
1434
|
-
*
|
|
1430
|
+
* want to handle navigation themselves). Payload: `(row, event)`, the
|
|
1431
|
+
* second being the native click event. A middle click emits
|
|
1432
|
+
* `row-aux-click` instead.
|
|
1435
1433
|
* @type {object}
|
|
1436
1434
|
*/
|
|
1437
1435
|
this.$emit('row-click', row, event)
|
|
1438
1436
|
},
|
|
1439
1437
|
|
|
1438
|
+
/**
|
|
1439
|
+
* A row middle click: opens the configured detail route in a new tab
|
|
1440
|
+
* and emits `row-aux-click`, not `row-click`.
|
|
1441
|
+
*
|
|
1442
|
+
* @param {object} row The clicked object row.
|
|
1443
|
+
* @param {MouseEvent} event The originating auxclick event.
|
|
1444
|
+
* @return {void}
|
|
1445
|
+
*/
|
|
1446
|
+
onRowAuxClick(row, event) {
|
|
1447
|
+
this.openRowRoute(row, event)
|
|
1448
|
+
/**
|
|
1449
|
+
* @event row-aux-click Emitted with the middle-clicked object, for
|
|
1450
|
+
* opening it in a new tab. Payload: `(row, event)`, the second being
|
|
1451
|
+
* the native auxclick event.
|
|
1452
|
+
* @type {object}
|
|
1453
|
+
*/
|
|
1454
|
+
this.$emit('row-aux-click', row, event)
|
|
1455
|
+
},
|
|
1456
|
+
|
|
1457
|
+
/**
|
|
1458
|
+
* Open `content.rowRoute` for a row: in place, or in a new tab on a
|
|
1459
|
+
* ctrl/cmd/shift or middle click.
|
|
1460
|
+
*
|
|
1461
|
+
* @param {object} row The clicked object row.
|
|
1462
|
+
* @param {MouseEvent} [event] The originating event.
|
|
1463
|
+
* @return {void}
|
|
1464
|
+
*/
|
|
1465
|
+
openRowRoute(row, event) {
|
|
1466
|
+
const route = this.content.rowRoute
|
|
1467
|
+
const id = row && (row.id || (row['@self'] && row['@self'].id))
|
|
1468
|
+
if (route && id && this.$router) {
|
|
1469
|
+
markNewTabHandled(event, openRowTarget(event, { name: route, params: { id } }, this.$router))
|
|
1470
|
+
}
|
|
1471
|
+
},
|
|
1472
|
+
|
|
1440
1473
|
/**
|
|
1441
1474
|
* Dispatch one declared row action. A `handler` action gets the row
|
|
1442
1475
|
* appended as its last argument, the same convention CnWidgetObjectTable
|
|
@@ -1465,8 +1498,7 @@ export default {
|
|
|
1465
1498
|
* @return {object} `{ href, linkTarget }`, `{ to }`, or `{}`.
|
|
1466
1499
|
*/
|
|
1467
1500
|
rowActionLink(action) {
|
|
1468
|
-
|
|
1469
|
-
if (/[@{]/.test(target)) {
|
|
1501
|
+
if (hasActionTargetTokens(action.target)) {
|
|
1470
1502
|
return {}
|
|
1471
1503
|
}
|
|
1472
1504
|
const link = actionLink(action, { router: this.$router || null })
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div
|
|
3
3
|
class="cn-object-row"
|
|
4
4
|
:class="{ 'cn-object-row--selected': selected }"
|
|
5
|
-
@mousedown="
|
|
5
|
+
@mousedown="onRowMouseDown"
|
|
6
6
|
@click="onRowClick($event)"
|
|
7
7
|
@auxclick="onRowAuxClick($event)">
|
|
8
8
|
<!-- Selection checkbox -->
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
import { NcCheckboxRadioSwitch } from '@nextcloud/vue'
|
|
69
69
|
import { useClickDragGuard } from '../../composables/useClickDragGuard.js'
|
|
70
70
|
import { resolveImageUrl } from '../../utils/resolveImageUrl.js'
|
|
71
|
-
import { isRowMiddleClick } from '../../utils/rowAuxClick.js'
|
|
71
|
+
import { isRowMiddleClick, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'
|
|
72
72
|
import { CnIcon } from '../CnIcon/index.js'
|
|
73
73
|
import { CnStatusBadge } from '../CnStatusBadge/index.js'
|
|
74
74
|
|
|
@@ -146,7 +146,7 @@ export default {
|
|
|
146
146
|
// again from `$emit('click', object)` — twice per click, with different
|
|
147
147
|
// payloads. Declaring the names here removes them from `$attrs`, which is
|
|
148
148
|
// also what stops VTU v2 recording the native DOM event into `emitted()`.
|
|
149
|
-
emits: ['select', 'click'],
|
|
149
|
+
emits: ['select', 'click', 'aux-click'],
|
|
150
150
|
|
|
151
151
|
setup() {
|
|
152
152
|
// Tell a deliberate row click apart from a text-selection drag.
|
|
@@ -237,15 +237,29 @@ export default {
|
|
|
237
237
|
return
|
|
238
238
|
}
|
|
239
239
|
/**
|
|
240
|
-
* @event click Emitted when a non-selectable row is clicked
|
|
240
|
+
* @event click Emitted when a non-selectable row is clicked (navigation). Payload: `(object, event)` — the row's object and the native click event, for opening it in a new tab on a ctrl/cmd/shift click. A middle click emits `aux-click` instead.
|
|
241
241
|
* @type {object} The row's object.
|
|
242
242
|
*/
|
|
243
243
|
this.$emit('click', this.object, event)
|
|
244
244
|
},
|
|
245
245
|
|
|
246
246
|
/**
|
|
247
|
-
* Row
|
|
248
|
-
* non-selectable row.
|
|
247
|
+
* Row mousedown: record the press for the drag guard, and on a
|
|
248
|
+
* non-selectable row keep a middle press from starting autoscroll.
|
|
249
|
+
*
|
|
250
|
+
* @param {MouseEvent} event The mousedown event.
|
|
251
|
+
*/
|
|
252
|
+
onRowMouseDown(event) {
|
|
253
|
+
this.onPointerDown(event)
|
|
254
|
+
if (!this.selectable) {
|
|
255
|
+
preventMiddleClickAutoscroll(event)
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Row-body middle click on a non-selectable row: emits `aux-click`, not
|
|
261
|
+
* `click`, so an existing `click` listener that navigates never moves
|
|
262
|
+
* the current tab away.
|
|
249
263
|
*
|
|
250
264
|
* @param {MouseEvent} event The auxclick event.
|
|
251
265
|
*/
|
|
@@ -253,7 +267,11 @@ export default {
|
|
|
253
267
|
if (this.selectable || !isRowMiddleClick(event)) {
|
|
254
268
|
return
|
|
255
269
|
}
|
|
256
|
-
|
|
270
|
+
/**
|
|
271
|
+
* @event aux-click Emitted when a non-selectable row is middle-clicked, for opening it in a new tab (see `openRowTarget`). Payload: `(object, event)` — the row's object and the native auxclick event.
|
|
272
|
+
* @type {object} The row's object.
|
|
273
|
+
*/
|
|
274
|
+
this.$emit('aux-click', this.object, event)
|
|
257
275
|
},
|
|
258
276
|
},
|
|
259
277
|
}
|
|
@@ -128,6 +128,7 @@
|
|
|
128
128
|
v-bind="{ ...$attrs, ...resolvedProps }"
|
|
129
129
|
@view="onRowOpen"
|
|
130
130
|
@rowClick="onRowOpen"
|
|
131
|
+
@rowAuxClick="onRowOpen"
|
|
131
132
|
@editOpen="onRowOpen"
|
|
132
133
|
@configure="showConfigModal = true">
|
|
133
134
|
<!-- This `<template v-for>` defines dynamic SLOTS, not a
|
|
@@ -203,6 +204,7 @@
|
|
|
203
204
|
v-bind="{ ...$attrs, ...resolvedProps }"
|
|
204
205
|
@view="onRowOpen"
|
|
205
206
|
@rowClick="onRowOpen"
|
|
207
|
+
@rowAuxClick="onRowOpen"
|
|
206
208
|
@editOpen="onRowOpen"
|
|
207
209
|
@configure="showConfigModal = true">
|
|
208
210
|
<!-- Dynamic slot definition, not a rendered list — see the note on
|
|
@@ -322,6 +322,26 @@ const CORE_TABS = ['files', 'notes', 'tags', 'tasks', 'auditTrail', 'shares']
|
|
|
322
322
|
/** One-time guard so the legacy-path deprecation warning logs only once. */
|
|
323
323
|
let legacyWarned = false
|
|
324
324
|
|
|
325
|
+
/**
|
|
326
|
+
* Schema titles by numeric schema id, shared by every widget on the page so a
|
|
327
|
+
* schema is asked for once. OpenRegister's `/uses` and `/used` answer
|
|
328
|
+
* `@self.schema` as that id ("120"), which is not a word anyone can read.
|
|
329
|
+
*
|
|
330
|
+
* @type {Map<string, Promise<string>>}
|
|
331
|
+
*/
|
|
332
|
+
const schemaTitleCache = new Map()
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Whether a value is a bare number, the way OpenRegister names a schema by id.
|
|
336
|
+
*
|
|
337
|
+
* @param {string|number|undefined|null} value The value.
|
|
338
|
+
* @return {boolean}
|
|
339
|
+
*/
|
|
340
|
+
function isNumericId(value) {
|
|
341
|
+
return (typeof value === 'number' && Number.isFinite(value))
|
|
342
|
+
|| (typeof value === 'string' && /^\d+$/.test(value.trim()))
|
|
343
|
+
}
|
|
344
|
+
|
|
325
345
|
/**
|
|
326
346
|
* Leaf groups surfaced by the aggregated `/relations` endpoint, in tab order.
|
|
327
347
|
* `responseKey` is the key in the `/relations` payload; `integrationId` is the
|
|
@@ -404,6 +424,14 @@ export default {
|
|
|
404
424
|
NcEmptyContent,
|
|
405
425
|
},
|
|
406
426
|
|
|
427
|
+
inject: {
|
|
428
|
+
/**
|
|
429
|
+
* The host app's translator (CnAppRoot provides it), so a schema title
|
|
430
|
+
* reads in the app's language. Without it a title reads as stored.
|
|
431
|
+
*/
|
|
432
|
+
cnTranslate: { default: () => (key) => key },
|
|
433
|
+
},
|
|
434
|
+
|
|
407
435
|
props: {
|
|
408
436
|
/** Widget title shown in the header. */
|
|
409
437
|
title: {
|
|
@@ -667,6 +695,8 @@ export default {
|
|
|
667
695
|
* @type {HTMLInputElement|null}
|
|
668
696
|
*/
|
|
669
697
|
fileInputEl: null,
|
|
698
|
+
/** Schema titles by numeric schema id, for object rows. */
|
|
699
|
+
schemaTitles: {},
|
|
670
700
|
/** Whether any section/tab is currently fetching. */
|
|
671
701
|
loading: false,
|
|
672
702
|
/** True once the first fetch has completed (gates the empty state). */
|
|
@@ -1359,9 +1389,74 @@ export default {
|
|
|
1359
1389
|
self.name,
|
|
1360
1390
|
raw.summary,
|
|
1361
1391
|
raw.description,
|
|
1362
|
-
].find((v) => typeof v === 'string' && v.trim() && !isUuid(v))
|
|
1363
|
-
|
|
1364
|
-
|
|
1392
|
+
].find((v) => typeof v === 'string' && v.trim() && !isUuid(v))
|
|
1393
|
+
|| [raw.givenName, raw.familyName].filter((v) => typeof v === 'string' && v.trim()).join(' ')
|
|
1394
|
+
// OpenRegister names the schema by numeric id: show its title, never the number.
|
|
1395
|
+
const schema = this.schemaName(self.schema || raw.schema)
|
|
1396
|
+
const finalLabel = label || schema || String(id)
|
|
1397
|
+
return { id, label: finalLabel, meta: schema === finalLabel ? '' : schema, raw }
|
|
1398
|
+
},
|
|
1399
|
+
|
|
1400
|
+
/**
|
|
1401
|
+
* How a row names its schema: the translated title for a numeric id
|
|
1402
|
+
* (empty until it is read, or when it cannot be), a slug as it is.
|
|
1403
|
+
*
|
|
1404
|
+
* @param {string|number|undefined|null} schema - `@self.schema` of the related object.
|
|
1405
|
+
* @return {string}
|
|
1406
|
+
*/
|
|
1407
|
+
schemaName(schema) {
|
|
1408
|
+
if (isNumericId(schema)) {
|
|
1409
|
+
const title = this.schemaTitles[String(schema).trim()]
|
|
1410
|
+
return title ? this.cnTranslate(title) : ''
|
|
1411
|
+
}
|
|
1412
|
+
return typeof schema === 'string' ? schema : ''
|
|
1413
|
+
},
|
|
1414
|
+
|
|
1415
|
+
/**
|
|
1416
|
+
* Read the titles of the numeric schema ids in these envelopes once,
|
|
1417
|
+
* before the rows are built, so no row shows a number first.
|
|
1418
|
+
*
|
|
1419
|
+
* @param {Array<object|null>} envelopes - The `{ results }` payloads.
|
|
1420
|
+
* @return {Promise<void>}
|
|
1421
|
+
*/
|
|
1422
|
+
async resolveSchemaTitles(envelopes) {
|
|
1423
|
+
const ids = new Set()
|
|
1424
|
+
for (const envelope of envelopes) {
|
|
1425
|
+
for (const raw of ((envelope && envelope.results) || [])) {
|
|
1426
|
+
const schema = (raw && (raw['@self'] || {}).schema) ?? (raw && raw.schema)
|
|
1427
|
+
if (isNumericId(schema)) {
|
|
1428
|
+
ids.add(String(schema).trim())
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
const titles = { ...this.schemaTitles }
|
|
1433
|
+
await Promise.all([...ids].filter((id) => !(id in titles)).map(async (id) => {
|
|
1434
|
+
if (!schemaTitleCache.has(id)) {
|
|
1435
|
+
schemaTitleCache.set(id, this.fetchSchemaTitle(id))
|
|
1436
|
+
}
|
|
1437
|
+
titles[id] = await schemaTitleCache.get(id)
|
|
1438
|
+
}))
|
|
1439
|
+
this.schemaTitles = titles
|
|
1440
|
+
},
|
|
1441
|
+
|
|
1442
|
+
/**
|
|
1443
|
+
* GET one schema's title; '' when it cannot be read.
|
|
1444
|
+
*
|
|
1445
|
+
* @param {string} id - The numeric schema id.
|
|
1446
|
+
* @return {Promise<string>}
|
|
1447
|
+
*/
|
|
1448
|
+
async fetchSchemaTitle(id) {
|
|
1449
|
+
try {
|
|
1450
|
+
const response = await fetch(generateUrl('/apps/openregister/api/schemas/{id}', { id }), { method: 'GET', headers: buildHeaders() })
|
|
1451
|
+
if (!response.ok) {
|
|
1452
|
+
return ''
|
|
1453
|
+
}
|
|
1454
|
+
const schema = await response.json()
|
|
1455
|
+
const title = schema && (schema.title || schema.slug)
|
|
1456
|
+
return typeof title === 'string' ? title : ''
|
|
1457
|
+
} catch {
|
|
1458
|
+
return ''
|
|
1459
|
+
}
|
|
1365
1460
|
},
|
|
1366
1461
|
|
|
1367
1462
|
/**
|
|
@@ -1465,6 +1560,7 @@ export default {
|
|
|
1465
1560
|
const groups = []
|
|
1466
1561
|
|
|
1467
1562
|
if (this.showObjects) {
|
|
1563
|
+
await this.resolveSchemaTitles([uses, used, contracts])
|
|
1468
1564
|
const objectItems = this.mergeObjectResults([uses, used, contracts])
|
|
1469
1565
|
groups.push({ key: 'objects', label: this.objectsLabel, icon: 'FileTreeOutline', integrationId: '', items: objectItems, total: objectItems.length })
|
|
1470
1566
|
}
|
|
@@ -1590,6 +1686,7 @@ export default {
|
|
|
1590
1686
|
calls.push(store.fetchContracts(type, id))
|
|
1591
1687
|
}
|
|
1592
1688
|
const groups = await Promise.all(calls)
|
|
1689
|
+
await this.resolveSchemaTitles(groups.map((results) => ({ results: results || [] })))
|
|
1593
1690
|
const seen = new Set()
|
|
1594
1691
|
const merged = []
|
|
1595
1692
|
for (const group of groups) {
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
<script>
|
|
42
42
|
import { NcActionButton, NcActionLink, NcActions } from '@nextcloud/vue'
|
|
43
43
|
import { followItemActionLink, resolveItemActionLink } from '../../utils/actionLink.js'
|
|
44
|
+
import { isModifiedClick } from '../../utils/linkNavigation.js'
|
|
44
45
|
import { evaluateVisibleWhenLocal, isLocallyDecidableVisibleWhen } from '../../utils/visibleWhen.js'
|
|
45
46
|
import { CnIcon } from '../CnIcon/index.js'
|
|
46
47
|
|
|
@@ -215,16 +216,20 @@ export default {
|
|
|
215
216
|
/**
|
|
216
217
|
* A link entry was clicked: route a plain in-app click, leave the rest to
|
|
217
218
|
* the browser, and emit `action` as a button would. The `handler` is not
|
|
218
|
-
* called, since navigating is what the link already does.
|
|
219
|
+
* called, since navigating is what the link already does. A modified
|
|
220
|
+
* click opens a new tab, so nothing is emitted in this one.
|
|
219
221
|
*
|
|
220
222
|
* @param {object} action The action definition.
|
|
221
223
|
* @param {object} link The resolved link.
|
|
222
224
|
* @param {MouseEvent} event The click event.
|
|
223
225
|
*/
|
|
224
226
|
onLinkAction(action, link, event) {
|
|
227
|
+
if (isModifiedClick(event)) {
|
|
228
|
+
return
|
|
229
|
+
}
|
|
225
230
|
followItemActionLink(event, link, this.$router)
|
|
226
231
|
/**
|
|
227
|
-
* @event action User picked an entry. Payload: the action's label and the row. A button entry has already run its `handler`; a link entry navigates instead.
|
|
232
|
+
* @event action User picked an entry. Payload: the action's label and the row. A button entry has already run its `handler`; a link entry navigates instead, and a modified (new-tab) click on a link emits nothing.
|
|
228
233
|
* @type {{ action: string, row: object|null }}
|
|
229
234
|
*/
|
|
230
235
|
this.$emit('action', { action: action.label, row: this.row })
|
|
@@ -145,7 +145,8 @@ const DEBOUNCE_MS = 200
|
|
|
145
145
|
* Data origin (decoupling seam): all data flows through a consumer-supplied
|
|
146
146
|
* `dataSource` prop OR the `cnSpendAnalyticsSource` injection — an object
|
|
147
147
|
* exposing `fetchSummary(args)`, `fetchVendorCommitments(args)`,
|
|
148
|
-
* `fetchNarrative(args)`, and optionally `resolveDeepLink(app, kind, id)
|
|
148
|
+
* `fetchNarrative(args)`, and optionally `resolveDeepLink(app, kind, id)`
|
|
149
|
+
* (pure and synchronous: it runs for every row on every render). The
|
|
149
150
|
* renderer imports NO financeq / procest / launchpad service module and never
|
|
150
151
|
* calls axios itself; the consuming app (typically over GraphQL) owns the
|
|
151
152
|
* transport. The `requires.graphql` hint lives only in the registry entry, not
|
|
@@ -182,8 +183,9 @@ export default {
|
|
|
182
183
|
* Consumer-supplied data source overriding the
|
|
183
184
|
* `cnSpendAnalyticsSource` injection. Must expose `fetchSummary`,
|
|
184
185
|
* `fetchVendorCommitments`, and `fetchNarrative`; may expose
|
|
185
|
-
* `resolveDeepLink
|
|
186
|
-
*
|
|
186
|
+
* `resolveDeepLink`, which must be pure and synchronous, since it is
|
|
187
|
+
* called for every row on every render. When `null` the injection
|
|
188
|
+
* (then the empty state) is used.
|
|
187
189
|
*
|
|
188
190
|
* @type {object|null}
|
|
189
191
|
*/
|
|
@@ -467,7 +467,11 @@ export default defineComponent({
|
|
|
467
467
|
}
|
|
468
468
|
|
|
469
469
|
/* A fade over the clipped edge, only on the side that hides tabs. Stops a
|
|
470
|
-
pixel above the bar's rule so the rule keeps its full colour.
|
|
470
|
+
pixel above the bar's rule so the rule keeps its full colour.
|
|
471
|
+
|
|
472
|
+
z-index 2 so the fades outrank a lifted tab: CnTabsWidget puts the open tab
|
|
473
|
+
at 1, and a tie goes to DOM order, which would draw that tab over the start
|
|
474
|
+
fade (it precedes the tabs) while the end fade still covered it. */
|
|
471
475
|
.cn-tabs__strip::before,
|
|
472
476
|
.cn-tabs__strip::after {
|
|
473
477
|
content: '';
|
|
@@ -476,7 +480,7 @@ export default defineComponent({
|
|
|
476
480
|
pointer-events: none;
|
|
477
481
|
position: absolute;
|
|
478
482
|
width: 56px;
|
|
479
|
-
z-index:
|
|
483
|
+
z-index: 2;
|
|
480
484
|
}
|
|
481
485
|
|
|
482
486
|
.cn-tabs__strip::before {
|
|
@@ -513,7 +517,7 @@ export default defineComponent({
|
|
|
513
517
|
padding: 0;
|
|
514
518
|
position: absolute;
|
|
515
519
|
width: 28px;
|
|
516
|
-
z-index:
|
|
520
|
+
z-index: 3;
|
|
517
521
|
}
|
|
518
522
|
|
|
519
523
|
/* Nextcloud's `button:hover` rule would otherwise fill the chevron. */
|