@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.
- 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/CnAppRoot/CnAppRoot.vue2.js +21 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.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/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/CnSetupWizard/CnSetupWizard.vue2.js +49 -5
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.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 +2 -0
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +2 -0
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +78 -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/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +885 -393
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +78 -7
- package/l10n/en.json +2 -0
- package/l10n/nl.json +2 -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/CnAppRoot/CnAppRoot.vue +31 -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/CnRowActions/CnRowActions.vue +7 -2
- package/src/components/CnSetupWizard/CnSetupWizard.vue +57 -6
- 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/schemas/app-manifest-v2.schema.json +2 -1
- 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
- package/src/utils/validateManifestV2.compiled.js +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnDataTable.vue2.js","sources":["../../../../src/components/CnDataTable/CnDataTable.vue"],"sourcesContent":["<template>\n\t<div\n\t\tclass=\"cn-table-container\"\n\t\tdata-testid=\"cn-object-list\"\n\t\t:class=\"{\n\t\t\t'cn-table-container--scrollable': scrollable,\n\t\t\t'cn-table-container--borderless': borderless,\n\t\t\t'cn-table-container--fill': fillHeight,\n\t\t}\">\n\t\t<!-- Optional card header (folded from the retired CnTableWidget): a title\n\t\t + total-count badge. Only rendered when `title` is set; bare table\n\t\t usage is unchanged. -->\n\t\t<div v-if=\"title\" class=\"cn-data-table__header\">\n\t\t\t<h3 class=\"cn-data-table__title\">\n\t\t\t\t{{ title }}\n\t\t\t</h3>\n\t\t\t<span v-if=\"totalRowCount > 0\" class=\"cn-data-table__count\">\n\t\t\t\t{{ totalRowCount }}\n\t\t\t</span>\n\t\t</div>\n\n\t\t<!-- Loading State -->\n\t\t<div v-if=\"isLoading\" class=\"cn-table-loading\" data-testid=\"cn-object-list-loading\">\n\t\t\t<!-- Decorative: the adjacent <p> already carries the accessible\n\t\t\t name (loadingText), so the spinner is hidden from the\n\t\t\t accessibility tree rather than exposed as an unlabelled\n\t\t\t role=\"img\" (WCAG 1.1.1 / axe \"role-img-alt\"). -->\n\t\t\t<NcLoadingIcon :size=\"32\" aria-hidden=\"true\" />\n\t\t\t<p>{{ loadingText }}</p>\n\t\t</div>\n\n\t\t<!-- Table. The horizontal scroll lives on this wrapper, NOT on\n\t\t `.cn-table-container`: `overflow-x: auto` on the container coerces\n\t\t its `overflow-y` from `visible` to `auto` (CSS forbids mixing\n\t\t `visible` with a non-visible value), which silently made the\n\t\t container the nearest scrollport. The sticky footer then anchored\n\t\t to a container that never scrolls, so \"View all\" scrolled away with\n\t\t the rows instead of pinning to the bottom of the enclosing widget. -->\n\t\t<!-- The horizontal scrollport must be reachable by keyboard: a region\n\t\t that scrolls but cannot take focus gives a keyboard-only user no\n\t\t way to reach the columns past the fold (axe\n\t\t `scrollable-region-focusable`, serious; WCAG 2.1.1).\n\n\t\t Gated on ACTUAL overflow rather than applied unconditionally, for\n\t\t two reasons. A table that fits needs no scrolling, so a permanent\n\t\t tab stop would put every table in the fleet on the keyboard path\n\t\t for nothing. And the axe rule itself only applies to elements that\n\t\t really are scrollable, so the conditional attribute is present in\n\t\t exactly the cases the rule evaluates.\n\n\t\t `role=\"group\"`, NOT `role=\"region\"`: this element is nested inside\n\t\t `.cn-widget-wrapper__content[role=\"region\"]` on the dashboard-widget\n\t\t path, and a second landmark there would surface as a duplicate.\n\t\t `group` is nameable but is not a landmark. A name is required\n\t\t rather than optional — `aria-label` is PROHIBITED on a role-less\n\t\t generic element, so a bare `tabindex` div would trade this\n\t\t violation for `aria-prohibited-attr` plus an unlabelled mystery\n\t\t stop in the tab order. -->\n\t\t<div\n\t\t\tv-else\n\t\t\tref=\"scrollEl\"\n\t\t\tclass=\"cn-data-table__scroll\"\n\t\t\t:tabindex=\"isScrollable ? 0 : undefined\"\n\t\t\t:role=\"isScrollable ? 'group' : undefined\"\n\t\t\t:aria-label=\"isScrollable ? scrollRegionLabel : undefined\">\n\t\t\t<table\n\t\t\t\tclass=\"cn-data-table\"\n\t\t\t\t:class=\"{ 'cn-data-table--fixed': fixedLayout }\"\n\t\t\t\tdata-testid=\"cn-object-list-table\">\n\t\t\t\t<thead v-if=\"!hideHeader\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<!-- Checkbox column -->\n\t\t\t\t\t\t<th v-if=\"selectable\" class=\"cn-table-col--checkbox\">\n\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t:modelValue=\"allSelected\"\n\t\t\t\t\t\t\t\t:indeterminate=\"someSelected && !allSelected\"\n\t\t\t\t\t\t\t\t:aria-label=\"selectAllLabel\"\n\t\t\t\t\t\t\t\t@update:modelValue=\"toggleSelectAll\" />\n\t\t\t\t\t\t</th>\n\n\t\t\t\t\t\t<!-- Leading icon column (header is intentionally blank) -->\n\t\t\t\t\t\t<th v-if=\"rowIcon\" class=\"cn-table-col--icon\" />\n\n\t\t\t\t\t\t<!-- Data columns -->\n\t\t\t\t\t\t<th\n\t\t\t\t\t\t\tv-for=\"col in effectiveColumns\"\n\t\t\t\t\t\t\t:key=\"col.key\"\n\t\t\t\t\t\t\t:class=\"[\n\t\t\t\t\t\t\t\tcol.sortable ? 'cn-table-header--sortable' : '',\n\t\t\t\t\t\t\t\tcol.class || '',\n\t\t\t\t\t\t\t]\"\n\t\t\t\t\t\t\t:style=\"col.width ? { width: col.width } : {}\"\n\t\t\t\t\t\t\t:tabindex=\"col.sortable ? 0 : null\"\n\t\t\t\t\t\t\t:aria-sort=\"ariaSortFor(col)\"\n\t\t\t\t\t\t\t:title=\"translateLabel(col.description) || null\"\n\t\t\t\t\t\t\t@click=\"col.sortable ? onHeaderClick(col.key, $event) : null\"\n\t\t\t\t\t\t\t@keydown.enter=\"col.sortable ? onHeaderKeydown(col.key, $event) : null\">\n\t\t\t\t\t\t\t<span :class=\"col.description ? 'cn-table-header--described' : ''\">\n\t\t\t\t\t\t\t\t{{ translateLabel(col.label) }}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tv-if=\"col.sortable && sortKeyIndex(col.key) !== -1\"\n\t\t\t\t\t\t\t\tclass=\"cn-table-sort-indicator\">\n\t\t\t\t\t\t\t\t{{ effectiveSortKeys[sortKeyIndex(col.key)].order === 'asc' ? '▲' : '▼' }}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tv-if=\"col.sortable && effectiveSortKeys.length > 1 && sortKeyIndex(col.key) !== -1\"\n\t\t\t\t\t\t\t\tclass=\"cn-table-sort-badge\">\n\t\t\t\t\t\t\t\t{{ sortKeyIndex(col.key) + 1 }}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</th>\n\n\t\t\t\t\t\t<!-- Actions column -->\n\t\t\t\t\t\t<th v-if=\"$slots['row-actions']\" class=\"cn-table-col--actions\">\n\t\t\t\t\t\t\t<!-- @slot Header cell content above the row-actions column (blank by default). -->\n\t\t\t\t\t\t\t<slot name=\"actions-header\" />\n\t\t\t\t\t\t</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<!-- Empty state -->\n\t\t\t\t\t<tr v-if=\"effectiveRows.length === 0\" class=\"cn-table-empty\" data-testid=\"cn-object-list-empty\">\n\t\t\t\t\t\t<td :colspan=\"totalColumns\">\n\t\t\t\t\t\t\t<!-- @slot Empty-state content shown when there are no rows (defaults to `emptyText`). -->\n\t\t\t\t\t\t\t<slot name=\"empty\">\n\t\t\t\t\t\t\t\t{{ translateLabel(emptyText) }}\n\t\t\t\t\t\t\t</slot>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<!-- Data rows -->\n\t\t\t\t\t<tr\n\t\t\t\t\t\tv-for=\"row in effectiveRows\"\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:key=\"row[rowKey]\"\n\t\t\t\t\t\tclass=\"cn-table-row\"\n\t\t\t\t\t\tdata-testid=\"cn-object-row\"\n\t\t\t\t\t\t:data-testid-row-id=\"row[rowKey]\"\n\t\t\t\t\t\t:class=\"[\n\t\t\t\t\t\t\tisSelected(row) ? 'cn-table-row--selected' : '',\n\t\t\t\t\t\t\trowClass ? rowClass(row) : '',\n\t\t\t\t\t\t]\"\n\t\t\t\t\t\t@mousedown=\"onPointerDown\"\n\t\t\t\t\t\t@click=\"onRowClick(row, $event)\"\n\t\t\t\t\t\t@auxclick=\"onRowAuxClick(row, $event)\"\n\t\t\t\t\t\t@contextmenu.prevent=\"onRowContextMenu(row, $event)\">\n\t\t\t\t\t\t<!-- Checkbox -->\n\t\t\t\t\t\t<td v-if=\"selectable\"\n\t\t\t\t\t\t\tclass=\"cn-table-col--checkbox\"\n\t\t\t\t\t\t\t@click.stop\n\t\t\t\t\t\t\t@auxclick.stop>\n\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t:modelValue=\"isSelected(row)\"\n\t\t\t\t\t\t\t\t:aria-label=\"selectRowLabel\"\n\t\t\t\t\t\t\t\t@update:modelValue=\"toggleSelect(row)\" />\n\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t<!-- Leading icon -->\n\t\t\t\t\t\t<td v-if=\"rowIcon\" class=\"cn-table-col--icon\">\n\t\t\t\t\t\t\t<CnIcon :name=\"getRowIcon(row)\" :size=\"20\" />\n\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t<!-- Data cells -->\n\t\t\t\t\t\t<td\n\t\t\t\t\t\t\tv-for=\"(col, colIndex) in effectiveColumns\"\n\t\t\t\t\t\t\t:key=\"col.key\"\n\t\t\t\t\t\t\t:class=\"[col.class || '', col.cellClass || '', cellClass ? cellClass(row, col) : '']\"\n\t\t\t\t\t\t\t:style=\"col.width ? { maxWidth: col.width } : {}\"\n\t\t\t\t\t\t\t@mouseenter=\"titleWhenClipped\">\n\t\t\t\t\t\t\t<!-- The padlock rides the FIRST data cell, beside whatever\n\t\t\t\t\t\t\t names the row. Deliberately OUTSIDE the #column-<key>\n\t\t\t\t\t\t\t slot: a consumer overriding that column's rendering is\n\t\t\t\t\t\t\t customising their own data, not opting out of being told\n\t\t\t\t\t\t\t the record is locked. It renders nothing when unlocked,\n\t\t\t\t\t\t\t so an unlocked table is byte-for-byte what it was. -->\n\t\t\t\t\t\t\t<CnLockIndicator\n\t\t\t\t\t\t\t\tv-if=\"colIndex === 0\"\n\t\t\t\t\t\t\t\t:object=\"row\"\n\t\t\t\t\t\t\t\t:size=\"16\" />\n\t\t\t\t\t\t\t<!-- Declared state indicators ride the first data cell\n\t\t\t\t\t\t\t beside the padlock. Each one renders as an icon WITH a\n\t\t\t\t\t\t\t text alternative and a tooltip, never as colour alone,\n\t\t\t\t\t\t\t and an indicator the page did not declare cannot appear\n\t\t\t\t\t\t\t however the record is shaped. Past the cap the rest move\n\t\t\t\t\t\t\t into the row menu, because a row of nine icons is not a\n\t\t\t\t\t\t\t row anyone can triage at a glance. -->\n\t\t\t\t\t\t\t<span v-if=\"colIndex === 0 && indicatorsFor(row).shown.length > 0\"\n\t\t\t\t\t\t\t\tclass=\"cn-table-row-indicators\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-row-indicators\">\n\t\t\t\t\t\t\t\t<span v-for=\"indicator in indicatorsFor(row).shown\"\n\t\t\t\t\t\t\t\t\t:key=\"indicator.id || indicator.field\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-table-row-indicator\"\n\t\t\t\t\t\t\t\t\t:title=\"indicator.tooltip || indicator.text\"\n\t\t\t\t\t\t\t\t\t:data-testid=\"`cn-row-indicator-${indicator.id || indicator.field}`\">\n\t\t\t\t\t\t\t\t\t<CnIcon :name=\"indicator.icon || 'InformationOutline'\" :size=\"16\" />\n\t\t\t\t\t\t\t\t\t<span class=\"hidden-visually\">{{ indicator.text }}</span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<!-- @slot Per-column cell override (`#column-<key>`), scoped with { row, value }. Wins over CnCellRenderer. -->\n\t\t\t\t\t\t\t<slot :name=\"'column-' + col.key\" :row=\"row\" :value=\"cellValue(row, col)\">\n\t\t\t\t\t\t\t\t<!-- Every column renders through CnCellRenderer: it resolves\n\t\t\t\t\t\t\t col.formatter / col.widget against the injected registries\n\t\t\t\t\t\t\t (cnFormatters / cnCellWidgets), uses the schema property when\n\t\t\t\t\t\t\t one is available (else {}) for type-aware rendering, and\n\t\t\t\t\t\t\t falls back to formatValue(). Columns with `aggregate` get a\n\t\t\t\t\t\t\t count of related objects (see cellValue/loadAggregates). The\n\t\t\t\t\t\t\t #column-{key} slot still wins. -->\n\t\t\t\t\t\t\t\t<CnCellRenderer\n\t\t\t\t\t\t\t\t\t:value=\"cellValue(row, col)\"\n\t\t\t\t\t\t\t\t\t:property=\"columnProperty(col)\"\n\t\t\t\t\t\t\t\t\t:formatter=\"col.formatter || null\"\n\t\t\t\t\t\t\t\t\t:formatterOptions=\"col.formatterOptions || null\"\n\t\t\t\t\t\t\t\t\t:widget=\"col.widget || null\"\n\t\t\t\t\t\t\t\t\t:widgetProps=\"col.widgetProps || undefined\"\n\t\t\t\t\t\t\t\t\t:format=\"columnFormat(col)\"\n\t\t\t\t\t\t\t\t\t:row=\"row\"\n\t\t\t\t\t\t\t\t\t:rowKey=\"rowKey\" />\n\t\t\t\t\t\t\t</slot>\n\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t<!-- Row actions -->\n\t\t\t\t\t\t<td v-if=\"$slots['row-actions']\"\n\t\t\t\t\t\t\tclass=\"cn-table-col--actions\"\n\t\t\t\t\t\t\t:class=\"[cellClass ? cellClass(row, { key: 'actions' }) : '']\"\n\t\t\t\t\t\t\t@click.stop\n\t\t\t\t\t\t\t@auxclick.stop>\n\t\t\t\t\t\t\t<!-- @slot Per-row actions menu (e.g. a CnRowActions), scoped with { row }. Supplying it adds the trailing actions column. -->\n\t\t\t\t\t\t\t<slot name=\"row-actions\" :row=\"row\" />\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\n\t\t<!-- Optional footer. A `#footer` scoped slot lets a host render its own\n\t\t footer link (e.g. a \"+ New\" create action or an always-shown\n\t\t \"View all\") with its own click handler — useful when the widget runs\n\t\t outside a vue-router context (the built-in link uses $router). When\n\t\t no slot is given, the built-in \"View all\" control (folded from the\n\t\t retired CnTableWidget) is shown for a `limit`-ed subset.\n\n\t\t The control is a real link (with an href) when the router resolves\n\t\t `viewAllRoute` to a URL, and a real button otherwise. An `<a>`\n\t\t without an href has no link role and is not keyboard focusable\n\t\t (WCAG 2.1.1, 4.1.2), so it is never rendered. -->\n\t\t<div\n\t\t\tv-if=\"$slots.footer || (viewAllRoute && totalRowCount > effectiveRows.length)\"\n\t\t\tclass=\"cn-data-table__footer\">\n\t\t\t<!-- @slot Custom footer content, scoped with { total, shown } (defaults to the built-in \"View all\" link). -->\n\t\t\t<slot name=\"footer\" :total=\"totalRowCount\" :shown=\"effectiveRows.length\">\n\t\t\t\t<a\n\t\t\t\t\tv-if=\"viewAllHref\"\n\t\t\t\t\tclass=\"cn-data-table__view-all\"\n\t\t\t\t\t:href=\"viewAllHref\"\n\t\t\t\t\t@click=\"onViewAll\">\n\t\t\t\t\t{{ viewAllLabel }}\n\t\t\t\t</a>\n\t\t\t\t<button\n\t\t\t\t\tv-else\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-data-table__view-all\"\n\t\t\t\t\t@click=\"onViewAll\">\n\t\t\t\t\t{{ viewAllLabel }}\n\t\t\t\t</button>\n\t\t\t</slot>\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcCheckboxRadioSwitch, NcLoadingIcon } from '@nextcloud/vue'\nimport { useClickDragGuard } from '../../composables/useClickDragGuard.js'\nimport { openRowTarget } from '../../utils/linkNavigation.js'\nimport { nextSortState } from '../../utils/multiColumnSort.js'\nimport { isNewTabHandled, isRowMiddleClick, markNewTabHandled } from '../../utils/rowAuxClick.js'\nimport { DEFAULT_ROW_INDICATOR_CAP, resolveRowIndicators } from '../../utils/rowIndicators.js'\nimport { columnsFromSchema } from '../../utils/schema.js'\nimport { CnCellRenderer } from '../CnCellRenderer/index.js'\nimport { CnIcon } from '../CnIcon/index.js'\nimport { CnLockIndicator } from '../CnLockIndicator/index.js'\n\n// CnDataTable has no scoped styles of its own — its entire look lives in the\n// shared table stylesheet. Import it here so the table is styled even when the\n// consuming app does not pull in the library's global css/index.css.\nimport '../../css/table.css'\n\n/**\n * CnDataTable — Generic sortable data table for list views.\n *\n * Replaces the copy-pasted `<table class=\"viewTable\">` HTML pattern found in\n * every list view across OpenRegister, Pipelinq, and Dossiq. Supports sorting,\n * row selection, custom cell rendering via scoped slots, loading states,\n * and empty states.\n *\n * Sorting: a plain click on a sortable header is single-sort (cycle asc →\n * desc → cleared), unchanged from before. Shift+click (or Shift+Enter on a\n * focused header) appends the column as a secondary/tertiary sort key —\n * capped at 3 — with numbered priority badges (1, 2, 3) once more than one\n * key is active. Pass `sortKeys: [{key, order}, ...]` for multi-sort (falls\n * back to the legacy `sortKey`/`sortOrder` props when empty). The `sort`\n * event payload is extended, not replaced: `{key, order}` still mirrors the\n * primary key exactly as before; a new `keys` field carries the full\n * ordered list. See `src/utils/multiColumnSort.js` for the state machine.\n *\n * When a `schema` prop is provided, columns are auto-generated from schema\n * properties and cells render through CnCellRenderer for type-aware formatting\n * (dates, booleans, UUIDs, enums, etc.). Scoped slots still override individual\n * columns when needed.\n *\n * Manual columns (backwards compatible)\n * ```vue\n * <CnDataTable\n * :columns=\"[\n * { key: 'name', label: 'Name', sortable: true },\n * { key: 'email', label: 'Email' },\n * ]\"\n * :rows=\"clients\"\n * @row-click=\"openClient\" />\n * ```\n *\n * Schema-driven (auto columns)\n * ```vue\n * <CnDataTable :schema=\"schema\" :rows=\"objects\" />\n * ```\n *\n * Schema with overrides and custom cell\n * ```vue\n * <CnDataTable\n * :schema=\"schema\"\n * :exclude-columns=\"['description']\"\n * :column-overrides=\"{ status: { width: '200px' } }\"\n * :rows=\"objects\">\n * <template #column-status=\"{ row, value }\">\n * <QuickStatusDropdown :case-obj=\"row\" />\n * </template>\n * </CnDataTable>\n * ```\n */\nexport default {\n\tname: 'CnDataTable',\n\n\tcomponents: {\n\t\tNcLoadingIcon,\n\t\tNcCheckboxRadioSwitch,\n\t\tCnCellRenderer,\n\t\tCnIcon,\n\t\tCnLockIndicator,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Consumer translation function, provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id, e.g.\n\t\t * `t.bind(null, 'docudesk')`). Column headers come from schema\n\t\t * property titles, which are authored in English as the canonical\n\t\t * source (API predictability); the visible label is resolved through\n\t\t * this function so it follows the user's language, with the English\n\t\t * source key living in each app's l10n files. Defaults to identity\n\t\t * when the table is used standalone (no CnAppRoot ancestor).\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * Column definitions (manual mode).\n\t\t * Not required when `schema` is provided.\n\t\t * Each entry may be a full column object OR a bare string key; bare strings\n\t\t * are normalised to `{ key, label }` by `effectiveColumns` so manifest-driven\n\t\t * pages that pass `config.columns` as a string array work without extra mapping.\n\t\t *\n\t\t * `description` renders as the header cell's tooltip and marks the label with a\n\t\t * dotted underline, so a column whose meaning is not obvious from its name (a\n\t\t * maturity level, a computed score, a domain term) can explain itself where the\n\t\t * reader is looking. `columnsFromSchema` fills it from the JSON Schema property\n\t\t * description automatically, so schema-driven tables get it for free.\n\t\t *\n\t\t * @type {Array<{key: string, label: string, description: string, sortable: boolean, width: string, class: string, cellClass: string}|string>}\n\t\t */\n\t\tcolumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Optional leading icon shown at the start of every row. Either a static\n\t\t * MDI icon name (PascalCase, e.g. `'FileDocumentOutline'`) applied to all\n\t\t * rows, or a function `(row) => iconName` to vary it per row. The icon is\n\t\t * resolved through the shared CnIcon registry. Unset = no icon column.\n\t\t *\n\t\t * @type {string | ((row: object) => string) | null}\n\t\t */\n\t\trowIcon: {\n\t\t\ttype: [String, Function],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * State indicators a page declares for its rows. Each entry is\n\t\t * `{ id, field, equals?, in?, icon, text, tooltip? }`: `field` is a\n\t\t * dotted path on the row, the condition is `equals`, `in`, or plain\n\t\t * truthiness when neither is given, `icon` is a CnIcon name, and `text`\n\t\t * is the text alternative. An entry without `text` does not render,\n\t\t * because an icon with no text is colour and shape alone.\n\t\t *\n\t\t * The page declares which indicators exist. A record cannot add one the\n\t\t * page has not declared, however it is shaped. A page declaring none\n\t\t * renders its rows exactly as before.\n\t\t *\n\t\t * @type {Array<{id?: string, field: string, equals?: (string|number|boolean|null), in?: Array, icon?: string, text: string, tooltip?: string}>}\n\t\t */\n\t\trowIndicators: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * How many declared indicators render on the row itself. The rest are\n\t\t * available from `indicatorsFor(row).overflow` for the row menu.\n\t\t *\n\t\t * @type {number}\n\t\t */\n\t\trowIndicatorCap: {\n\t\t\ttype: Number,\n\t\t\tdefault: DEFAULT_ROW_INDICATOR_CAP,\n\t\t},\n\n\t\t/**\n\t\t * Schema object with `properties` field (schema-driven mode).\n\t\t * When provided, columns are auto-generated from schema properties.\n\t\t */\n\t\tschema: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Per-column overrides when using schema mode: { key: { width, label, sortable, ... } } */\n\t\tcolumnOverrides: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Column keys to exclude when using schema mode */\n\t\texcludeColumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Column keys to include when using schema mode (whitelist) */\n\t\tincludeColumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Row data array. Each row should have a unique identifier (see rowKey). */\n\t\trows: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Whether data is loading (shows loading spinner) */\n\t\tloading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Current sort column key */\n\t\tsortKey: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Current sort order: 'asc', 'desc', or null (no sort) */\n\t\tsortOrder: {\n\t\t\ttype: String,\n\t\t\tdefault: 'asc',\n\t\t\tvalidator: (v) => v === null || ['asc', 'desc'].includes(v),\n\t\t},\n\n\t\t/**\n\t\t * Ordered multi-column sort state: `[{ key, order }, ...]` (priority\n\t\t * order, 0 to 3 entries). Optional — when empty (the default), the\n\t\t * table falls back to the legacy `sortKey`/`sortOrder` props, so\n\t\t * single-sort hosts are completely unaffected. Shift+click a\n\t\t * sortable header to append/cycle a secondary or tertiary key (see\n\t\t * `src/utils/multiColumnSort.js`).\n\t\t *\n\t\t * @type {Array<{key: string, order: 'asc'|'desc'}>}\n\t\t */\n\t\tsortKeys: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Whether rows can be selected with checkboxes */\n\t\tselectable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Array of currently selected row IDs */\n\t\tselectedIds: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Property name used as unique row identifier */\n\t\trowKey: {\n\t\t\ttype: String,\n\t\t\tdefault: 'id',\n\t\t},\n\n\t\t/** Text shown when there are no rows */\n\t\temptyText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'No items found'),\n\t\t},\n\n\t\t/** Function returning CSS class(es) for a row: (row) => string|object */\n\t\trowClass: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Function returning CSS class(es) for a data cell: (row, col) => string|object */\n\t\tcellClass: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Whether to constrain table height and make it scrollable */\n\t\tscrollable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Text shown while loading */\n\t\tloadingText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Loading…'),\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for the select-all checkbox in the header row.\n\t\t * Used as the checkbox's `aria-label` so screen readers announce a\n\t\t * named control (WCAG 4.1.2). Defaults to the lib's translation of\n\t\t * \"Select all rows\".\n\t\t */\n\t\tselectAllLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Select all rows'),\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for a per-row select checkbox. Used as the\n\t\t * checkbox's `aria-label` so screen readers announce a named control\n\t\t * (WCAG 4.1.2). Defaults to the lib's translation of \"Select row\".\n\t\t */\n\t\tselectRowLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Select row'),\n\t\t},\n\n\t\t/**\n\t\t * Optional card title rendered in a header above the table. When set, the\n\t\t * table reads as a self-contained card (the container's own border/radius\n\t\t * is the card chrome). Folded in from the retired CnTableWidget.\n\t\t */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Drop the container's card chrome (border, radius, shadow) so the table\n\t\t * sits flush inside a parent that already provides a card (e.g. a\n\t\t * CnWidgetWrapper dashboard slot). Folded in from CnTableWidget.\n\t\t */\n\t\tborderless: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Fill the height of the parent (a flex-column card / widget content\n\t\t * area) so the optional `#footer` is pushed to the bottom instead of\n\t\t * floating directly under a short list. When the list is long enough to\n\t\t * overflow, the footer stays pinned via its sticky rule. No-op outside a\n\t\t * height-constrained parent. Opt-in so ordinary in-flow tables are\n\t\t * unaffected.\n\t\t */\n\t\tfillHeight: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Hide the column-header row (`<thead>`). Useful for compact dashboard\n\t\t * list widgets that want a plain bordered-row list without column labels.\n\t\t */\n\t\thideHeader: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Switch the table to `table-layout: fixed`, making each column's `width`\n\t\t * authoritative instead of a hint the browser may override. Opt in when a\n\t\t * column's content would otherwise dictate the layout — a long unbreakable\n\t\t * value (a PHP FQCN, a UUID) widens its column under the default auto\n\t\t * layout and can render past the cell box into its neighbour, while any\n\t\t * column left unsized soaks up all remaining width. Cells also break long\n\t\t * words rather than overflowing. Columns with no `width` share whatever\n\t\t * space is left, so size every column when you want exact control.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tfixedLayout: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Max number of rows to display. When the total exceeds it, only the first\n\t\t * `limit` render and the \"View all\" footer appears (with `viewAllRoute`).\n\t\t * 0 = show all. Folded in from CnTableWidget.\n\t\t */\n\t\tlimit: {\n\t\t\ttype: Number,\n\t\t\tdefault: 0,\n\t\t},\n\n\t\t/**\n\t\t * vue-router route object for the \"View all\" footer link. The footer only\n\t\t * shows when set AND the rows are a `limit`-ed subset. Folded in from CnTableWidget.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tviewAllRoute: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Pre-translated \"View all\" footer label. */\n\t\tviewAllLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'View all'),\n\t\t},\n\n\t\t/**\n\t\t * Self-fetch mode (folded from CnTableWidget): the OpenRegister register\n\t\t * id/slug. When `register` + `schemaId` are set and no `rows` are passed,\n\t\t * the table fetches `/apps/openregister/api/objects/{register}/{schemaId}`.\n\t\t *\n\t\t * @type {string|number|null}\n\t\t */\n\t\tregister: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Self-fetch mode (folded from CnTableWidget): the OpenRegister schema\n\t\t * id used together with `register`. (Distinct from the `schema` prop,\n\t\t * which is a JSON Schema object for column generation.)\n\t\t *\n\t\t * @type {string|number|null}\n\t\t */\n\t\tschemaId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Extra query parameters sent with the self-fetch request (register +\n\t\t * schemaId mode) — e.g. a resolved filter map, `_order[field]` ordering,\n\t\t * or `_limit`. Changing it re-triggers the self-fetch, so a host widget\n\t\t * (CnWidgetObjectTable's declarative `source`) can drive filtering and\n\t\t * ordering without re-implementing the fetch. Ignored when external\n\t\t * `rows` are supplied.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tfetchParams: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Convenience navigation (folded from CnTableWidget): a function that\n\t\t * receives the clicked row and returns a vue-router route to push. When\n\t\t * set, a row click navigates there (the `row-click` event still fires);\n\t\t * a ctrl/cmd/shift or middle click opens it in a new tab.\n\t\t *\n\t\t * @type {((row: object) => object)|null}\n\t\t */\n\t\trowClickRoute: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * When true, a row-body click emits `row-click` (for navigation) even\n\t\t * while `selectable` — selection then happens only via the checkbox\n\t\t * column. Lets \"click row = open, tick box = select\" coexist. Default\n\t\t * false keeps the legacy behaviour (selectable rows select on body click).\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\trowClickToView: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: ['row-click', 'row-context-menu', 'select', 'select-all', 'sort', 'view-all'],\n\n\tsetup() {\n\t\t// Tell a deliberate row click apart from a text-selection drag.\n\t\treturn useClickDragGuard()\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * Resolved aggregate-column values, keyed by `String(row[rowKey])`\n\t\t\t * then by column key. Populated by `loadAggregates()` for columns\n\t\t\t * that declare `aggregate` (see CnIndexPage's manifest config).\n\t\t\t *\n\t\t\t * @type {{[rowId: string]: {[colKey: string]: number}}}\n\t\t\t */\n\t\t\taggregateValues: {},\n\t\t\t/**\n\t\t\t * Whether the table currently overflows its scrollport horizontally.\n\t\t\t * Drives the keyboard tab stop on `.cn-data-table__scroll`; see the\n\t\t\t * comment on that element.\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t */\n\t\t\tisScrollable: false,\n\t\t\t/** True while a batch of aggregate-count requests is in flight. */\n\t\t\taggregateLoading: false,\n\t\t\t/** Monotonic id used to discard a stale aggregate batch when `rows` changes mid-flight. */\n\t\t\taggregateRequestId: 0,\n\t\t\t/** Rows fetched in self-fetch mode (register + schemaId). */\n\t\t\tfetchedRows: [],\n\t\t\t/** True while a self-fetch request is in flight. */\n\t\t\tselfFetchLoading: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Accessible name for the horizontal scrollport when it becomes a tab\n\t\t * stop. Prefers the table's own `title` so the announcement identifies\n\t\t * WHICH table the user has landed in — several can share a dashboard.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tscrollRegionLabel() {\n\t\t\treturn this.title\n\t\t\t\t? t('nextcloud-vue', '{title} — scrollable table', { title: this.title })\n\t\t\t\t: t('nextcloud-vue', 'Scrollable table')\n\t\t},\n\n\t\t/**\n\t\t * The row source: external `rows` when provided, else the self-fetched\n\t\t * rows (register + schemaId mode). External rows always win.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\tsourceRows() {\n\t\t\tif (this.rows && this.rows.length > 0) {\n\t\t\t\treturn this.rows\n\t\t\t}\n\t\t\tif (this.register !== null && this.register !== undefined && this.schemaId !== null && this.schemaId !== undefined) {\n\t\t\t\treturn this.fetchedRows\n\t\t\t}\n\t\t\treturn this.rows\n\t\t},\n\n\t\t/**\n\t\t * The rows actually rendered — `sourceRows` capped to `limit` (0 = all).\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\teffectiveRows() {\n\t\t\treturn this.limit > 0 ? this.sourceRows.slice(0, this.limit) : this.sourceRows\n\t\t},\n\n\t\t/**\n\t\t * Total row count before the `limit` cap (drives the count badge + the\n\t\t * \"View all\" footer condition).\n\t\t *\n\t\t * @return {number}\n\t\t */\n\t\ttotalRowCount() {\n\t\t\treturn this.sourceRows.length\n\t\t},\n\n\t\t/**\n\t\t * The URL the router resolves `viewAllRoute` to, or `null` when there is\n\t\t * no route or no router (a widget mounted outside a vue-router context).\n\t\t * Decides whether the \"View all\" footer renders as a link or a button.\n\t\t *\n\t\t * @return {string|null}\n\t\t */\n\t\tviewAllHref() {\n\t\t\tif (!this.viewAllRoute || !this.$router || typeof this.$router.resolve !== 'function') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst resolved = this.$router.resolve(this.viewAllRoute)\n\t\t\t\treturn (resolved && resolved.href) || null\n\t\t\t} catch {\n\t\t\t\treturn null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Whether to show the loading state — the external `loading` prop OR a\n\t\t * self-fetch in flight.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisLoading() {\n\t\t\treturn this.loading || this.selfFetchLoading\n\t\t},\n\n\t\t/**\n\t\t * Effective columns: schema-generated or manually provided.\n\t\t * Schema columns take precedence when schema is provided and no manual columns given.\n\t\t */\n\t\teffectiveColumns() {\n\t\t\tconst cols = (this.schema && this.columns.length === 0)\n\t\t\t\t? columnsFromSchema(this.schema, {\n\t\t\t\t\t\texclude: this.excludeColumns,\n\t\t\t\t\t\tinclude: this.includeColumns,\n\t\t\t\t\t\toverrides: this.columnOverrides,\n\t\t\t\t\t})\n\t\t\t\t: this.columns\n\t\t\tif (!(cols || []).some((c) => typeof c === 'string')) {\n\t\t\t\treturn cols || []\n\t\t\t}\n\t\t\tconst schemaCols = this.schema\n\t\t\t\t? columnsFromSchema(this.schema, { overrides: this.columnOverrides })\n\t\t\t\t: []\n\t\t\tconst byKey = new Map(schemaCols.map((c) => [c.key, c]))\n\t\t\treturn (cols || []).map((c) => {\n\t\t\t\tif (typeof c !== 'string') {\n\t\t\t\t\treturn c\n\t\t\t\t}\n\t\t\t\treturn byKey.get(c) || { key: c, label: c, sortable: true }\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The active ordered sort-key list: the `sortKeys` prop when non-empty,\n\t\t * else a single-entry list derived from the legacy `sortKey`/`sortOrder`\n\t\t * props (empty when neither is active). Every header/badge/aria-sort\n\t\t * computation reads this so single-sort hosts (no `sortKeys` passed)\n\t\t * render exactly as before.\n\t\t *\n\t\t * @return {Array<{key: string, order: 'asc'|'desc'}>}\n\t\t */\n\t\teffectiveSortKeys() {\n\t\t\tif (this.sortKeys && this.sortKeys.length > 0) {\n\t\t\t\treturn this.sortKeys\n\t\t\t}\n\t\t\tif (this.sortKey) {\n\t\t\t\treturn [{ key: this.sortKey, order: this.sortOrder || 'asc' }]\n\t\t\t}\n\t\t\treturn []\n\t\t},\n\n\t\ttotalColumns() {\n\t\t\tlet count = this.effectiveColumns.length\n\t\t\tif (this.selectable) {\n\t\t\t\tcount++\n\t\t\t}\n\t\t\tif (this.rowIcon) {\n\t\t\t\tcount++\n\t\t\t}\n\t\t\tif (this.$slots['row-actions']) {\n\t\t\t\tcount++\n\t\t\t}\n\t\t\treturn count\n\t\t},\n\n\t\t/**\n\t\t * Stable signature of the self-fetch inputs so the watcher refetches\n\t\t * only on a real change (register / schemaId / fetchParams).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tselfFetchKey() {\n\t\t\treturn JSON.stringify({\n\t\t\t\tregister: this.register,\n\t\t\t\tschemaId: this.schemaId,\n\t\t\t\tfetchParams: this.fetchParams || null,\n\t\t\t})\n\t\t},\n\n\t\tallSelected() {\n\t\t\treturn this.effectiveRows.length > 0\n\t\t\t\t&& this.effectiveRows.every((row) => this.selectedIds.includes(row[this.rowKey]))\n\t\t},\n\n\t\tsomeSelected() {\n\t\t\treturn this.effectiveRows.some((row) => this.selectedIds.includes(row[this.rowKey]))\n\t\t},\n\t},\n\n\twatch: {\n\t\trows: {\n\t\t\thandler() {\n\t\t\t\tthis.loadAggregates()\n\t\t\t},\n\t\t},\n\n\t\teffectiveColumns: {\n\t\t\thandler() {\n\t\t\t\tthis.loadAggregates()\n\t\t\t},\n\n\t\t\tdeep: false,\n\t\t},\n\n\t\t/**\n\t\t * Re-run the self-fetch when its inputs (register, schemaId, or the\n\t\t * host-driven `fetchParams`) change — a token-resolved filter (e.g.\n\t\t * `@workspace.*`) can change after mount. External rows still win.\n\t\t */\n\t\tselfFetchKey() {\n\t\t\tif ((!this.rows || this.rows.length === 0) && this.register !== null && this.register !== undefined && this.schemaId !== null && this.schemaId !== undefined) {\n\t\t\t\tthis.fetchData()\n\t\t\t}\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.loadAggregates()\n\t\t// Self-fetch mode: pull rows from OpenRegister when register + schemaId\n\t\t// are given and no external rows were passed (folded from CnTableWidget).\n\t\tif ((!this.rows || this.rows.length === 0) && this.register !== null && this.register !== undefined && this.schemaId !== null && this.schemaId !== undefined) {\n\t\t\tthis.fetchData()\n\t\t}\n\t\tthis.observeScrollOverflow()\n\t},\n\n\tupdated() {\n\t\t// Columns and rows can change after mount (self-fetch resolving, a\n\t\t// column toggled), and either can flip the table between fitting and\n\t\t// overflowing. ResizeObserver alone would miss a change that alters\n\t\t// content width without resizing the box.\n\t\tthis.measureScrollOverflow()\n\t},\n\n\tbeforeUnmount() {\n\t\tthis.disconnectScrollOverflow()\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * The declared indicators that apply to one row, split into the ones\n\t\t * that fit on the row and the ones that go to the row menu.\n\t\t *\n\t\t * @param {object} row The row.\n\t\t * @return {{shown: Array<object>, overflow: Array<object>}}\n\t\t * @spec openspec/changes/working-list-row-actions/specs/index-page/spec.md\n\t\t */\n\t\tindicatorsFor(row) {\n\t\t\treturn resolveRowIndicators(this.rowIndicators, row, this.rowIndicatorCap)\n\t\t},\n\n\t\t/**\n\t\t * Give a cell its full text on hover, and only when it is cut short.\n\t\t *\n\t\t * Cells are one line with an ellipsis, so a long value is readable only\n\t\t * as far as the column goes. A `title` on every cell would answer that,\n\t\t * and would also put a tooltip on the cells that need none — repeating\n\t\t * back what is already on screen.\n\t\t *\n\t\t * Read on ENTER rather than on render: `scrollWidth > clientWidth` forces\n\t\t * layout, and doing it per cell per paint would cost a reflow for a\n\t\t * tooltip almost none of them want. On enter it is one read of one cell,\n\t\t * and it is re-read every time, so a column resized since the last hover\n\t\t * answers for its new width rather than its old one.\n\t\t *\n\t\t * @param {MouseEvent} event The enter event.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\ttitleWhenClipped(event) {\n\t\t\tconst el = event.currentTarget\n\t\t\tif (!el) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// 1px of tolerance, as the scrollport check uses: sub-pixel rounding\n\t\t\t// otherwise reports a cell that visually fits as clipped.\n\t\t\tif (el.scrollWidth - el.clientWidth > 1) {\n\t\t\t\tel.setAttribute('title', (el.textContent || '').trim())\n\t\t\t} else {\n\t\t\t\tel.removeAttribute('title')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Start watching the scrollport for horizontal overflow.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tobserveScrollOverflow() {\n\t\t\tthis.measureScrollOverflow()\n\t\t\tif (typeof ResizeObserver === 'undefined') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis._scrollObserver = new ResizeObserver(() => this.measureScrollOverflow())\n\t\t\tconst el = this.$refs.scrollEl\n\t\t\tif (el) {\n\t\t\t\tthis._scrollObserver.observe(el)\n\t\t\t\t// The table itself, not just the port: a column widening pushes\n\t\t\t\t// the content past the fold without the port changing size.\n\t\t\t\tconst table = el.querySelector('table')\n\t\t\t\tif (table) {\n\t\t\t\t\tthis._scrollObserver.observe(table)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Recompute whether the scrollport overflows horizontally.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tmeasureScrollOverflow() {\n\t\t\tconst el = this.$refs.scrollEl\n\t\t\t// 1px of tolerance: sub-pixel layout rounding otherwise reports a\n\t\t\t// table that visually fits as scrollable, which would put a tab\n\t\t\t// stop on it for no reachable content.\n\t\t\tconst next = !!el && (el.scrollWidth - el.clientWidth) > 1\n\t\t\tif (next !== this.isScrollable) {\n\t\t\t\tthis.isScrollable = next\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Tear down the overflow observer.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tdisconnectScrollOverflow() {\n\t\t\tif (this._scrollObserver) {\n\t\t\t\tthis._scrollObserver.disconnect()\n\t\t\t\tthis._scrollObserver = null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Resolve a column header label through the consumer's translation\n\t\t * function. Column labels originate from schema property titles\n\t\t * (English canonical source); this makes the rendered header follow\n\t\t * the user's language when the host app provides `cnTranslate`, and\n\t\t * returns the label unchanged when it does not.\n\t\t *\n\t\t * @param {string} label The English source label (schema property title).\n\t\t * @return {string} The translated label, or the input unchanged.\n\t\t */\n\t\ttranslateLabel(label) {\n\t\t\tif (!label) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst fn = typeof this.cnTranslate === 'function' ? this.cnTranslate : (k) => k\n\t\t\treturn fn(label)\n\t\t},\n\n\t\t/**\n\t\t * Self-fetch rows from OpenRegister (register + schemaId mode). Best-effort:\n\t\t * any failure leaves the fetched rows empty. Folded from CnTableWidget.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync fetchData() {\n\t\t\tthis.selfFetchLoading = true\n\t\t\ttry {\n\t\t\t\tconst url = generateUrl('/apps/openregister/api/objects/{register}/{schemaId}', {\n\t\t\t\t\tregister: String(this.register),\n\t\t\t\t\tschemaId: String(this.schemaId),\n\t\t\t\t})\n\t\t\t\tconst { data } = await axios.get(url, {\n\t\t\t\t\theaders: { 'OCS-APIREQUEST': 'true' },\n\t\t\t\t\t...(this.fetchParams ? { params: this.fetchParams } : {}),\n\t\t\t\t})\n\t\t\t\tthis.fetchedRows = (data && data.results) || (Array.isArray(data) ? data : [])\n\t\t\t} catch {\n\t\t\t\tthis.fetchedRows = []\n\t\t\t} finally {\n\t\t\t\tthis.selfFetchLoading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Activate the \"View all\" footer control: emit `view-all`, then push\n\t\t * `viewAllRoute` through the router when there is one. A plain left\n\t\t * click on the link is handled in-app; a modified click (ctrl/cmd/\n\t\t * shift/middle) is left to the browser so \"open in new tab\" keeps\n\t\t * working on the real href.\n\t\t *\n\t\t * @param {MouseEvent} [event] The click event, when triggered by one.\n\t\t * @return {void}\n\t\t */\n\t\tonViewAll(event) {\n\t\t\tconst modified = Boolean(event && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.button))\n\t\t\tif (event && !modified) {\n\t\t\t\tevent.preventDefault()\n\t\t\t}\n\t\t\t/** @event view-all Emitted when the built-in \"View all\" footer control is activated. Payload: the `viewAllRoute` object. */\n\t\t\tthis.$emit('view-all', this.viewAllRoute)\n\t\t\tif (modified) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.viewAllRoute && this.$router) {\n\t\t\t\tthis.$router.push(this.viewAllRoute).catch(() => {})\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Resolve the leading-row icon name for a row. Returns the static\n\t\t * `rowIcon` string, or the result of the `rowIcon(row)` function.\n\t\t *\n\t\t * @param {object} row The row object.\n\t\t * @return {string} The MDI icon name (PascalCase).\n\t\t */\n\t\tgetRowIcon(row) {\n\t\t\treturn typeof this.rowIcon === 'function' ? this.rowIcon(row) : this.rowIcon\n\t\t},\n\n\t\t/**\n\t\t * Get a cell value from a row using dot-notation key.\n\t\t *\n\t\t * OpenRegister system/metadata fields (created, updated, owner, uri,\n\t\t * size, register, schema, ...) live under the object's `@self` block.\n\t\t * For a flat key we fall back to `@self` when the top level has no\n\t\t * value, so sidebar-enabled metadata columns resolve. Top-level fields\n\t\t * always win, keeping existing behaviour unchanged.\n\t\t *\n\t\t * @param {object} row The row data\n\t\t * @param {string} key The column key (supports dot notation: 'address.city')\n\t\t * @return {unknown} The cell value\n\t\t */\n\t\tgetCellValue(row, key) {\n\t\t\tif (typeof key !== 'string') {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tif (key.includes('.')) {\n\t\t\t\treturn key.split('.').reduce((obj, k) => obj?.[k], row)\n\t\t\t}\n\t\t\tif (row?.[key] === undefined && row?.['@self'] && typeof row['@self'] === 'object') {\n\t\t\t\treturn row['@self'][key]\n\t\t\t}\n\t\t\treturn row?.[key]\n\t\t},\n\n\t\t/**\n\t\t * Get the schema property definition for a column key, or `{}` when\n\t\t * there is no schema (manual mode) or no matching property. The result\n\t\t * is handed to `CnCellRenderer` for type-aware rendering; an empty\n\t\t * object makes it fall back to `formatValue()` (plain truncated text).\n\t\t *\n\t\t * @param {string} key Column key\n\t\t * @return {object} Property definition (possibly empty).\n\t\t */\n\t\tgetSchemaProperty(key) {\n\t\t\treturn this.schema?.properties?.[key] || {}\n\t\t},\n\n\t\t/**\n\t\t * Effective property definition handed to CnCellRenderer for a column:\n\t\t * the schema property augmented with the column's own `type`/`format`/\n\t\t * `enum`/`enumLabels` hints. Lets synthesized columns that have no\n\t\t * schema property (e.g. metadata fields with `format: 'date-time'` /\n\t\t * `'uri'`, or a dotted path into a reference this table was never\n\t\t * handed a `:schema` for at all) still get type-aware rendering.\n\t\t * `enumLabels` rides with `enum` rather than getting its own `if`\n\t\t * branch: a column can't usefully declare labels without also\n\t\t * declaring the codes they label.\n\t\t *\n\t\t * @param {object} col Column definition.\n\t\t * @return {object} Property definition for CnCellRenderer.\n\t\t */\n\t\tcolumnProperty(col) {\n\t\t\tconst base = this.getSchemaProperty(col.key)\n\t\t\tif (col && (col.format || col.type || col.enum)) {\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\t...(col.type ? { type: col.type } : {}),\n\t\t\t\t\t...(col.format ? { format: col.format } : {}),\n\t\t\t\t\t...(col.enum ? { enum: col.enum, enumLabels: col.enumLabels || base.enumLabels } : {}),\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn base\n\t\t},\n\n\t\t/**\n\t\t * Declarative cell-format spec handed to CnCellRenderer's `format` prop\n\t\t * (an object: `{ style, currency, decimals, ... }`). `col.format` is\n\t\t * overloaded — for schema-derived columns it is the schema format STRING\n\t\t * (`'date'`, `'uri'`, ...), which is NOT a declarative spec and drives\n\t\t * type-aware rendering via `columnProperty()` instead. Only forward an\n\t\t * object here, so a string schema-format no longer trips CnCellRenderer's\n\t\t * `Object`-typed `format` prop (Vue prop-type warning).\n\t\t *\n\t\t * @param {object} col Column definition.\n\t\t * @return {object|null} The declarative format spec, or null.\n\t\t */\n\t\tcolumnFormat(col) {\n\t\t\treturn (col && typeof col.format === 'object') ? col.format : null\n\t\t},\n\n\t\t/**\n\t\t * Value to render in a cell. For a column that declares `aggregate`\n\t\t * (a count of related objects), returns the cached count once\n\t\t * `loadAggregates()` has resolved it (or `'…'` while pending, `'—'`\n\t\t * if it failed / there's nothing to count). Otherwise the row's\n\t\t * property value via `getCellValue`.\n\t\t *\n\t\t * @param {object} row The row data.\n\t\t * @param {object} col The column definition.\n\t\t * @return {unknown} The value handed to the slot / CnCellRenderer.\n\t\t */\n\t\tcellValue(row, col) {\n\t\t\tif (col && col.aggregate) {\n\t\t\t\tconst cached = this.aggregateValues[String(row[this.rowKey])]\n\t\t\t\tconst v = cached ? cached[col.key] : undefined\n\t\t\t\tif (v === undefined) {\n\t\t\t\t\treturn this.aggregateLoading ? '…' : '—'\n\t\t\t\t}\n\t\t\t\treturn v\n\t\t\t}\n\t\t\treturn this.getCellValue(row, col.key)\n\t\t},\n\n\t\t/**\n\t\t * Interpolate a column's `aggregate.where` map for one row: any string\n\t\t * value of the form `\"@self.<path>\"` is replaced with\n\t\t * `getCellValue(row, path)`; everything else is passed through.\n\t\t *\n\t\t * @param {object} where The `aggregate.where` map (may be undefined).\n\t\t * @param {object} row The parent row.\n\t\t * @return {object} The resolved filter map.\n\t\t */\n\t\tresolveAggregateWhere(where, row) {\n\t\t\tconst out = {}\n\t\t\tfor (const [k, v] of Object.entries(where || {})) {\n\t\t\t\tif (typeof v === 'string' && v.startsWith('@self.')) {\n\t\t\t\t\tout[k] = this.getCellValue(row, v.slice('@self.'.length))\n\t\t\t\t} else {\n\t\t\t\t\tout[k] = v\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out\n\t\t},\n\n\t\t/**\n\t\t * For every column that declares `aggregate` (currently `op: \"count\"`),\n\t\t * issue one `_limit=0` count request per visible row against the related\n\t\t * OpenRegister collection and cache the totals in `aggregateValues`.\n\t\t * Batched with `Promise.all`; a per-request failure degrades that one\n\t\t * cell to `'—'` (logged), never the page. A monotonic request id\n\t\t * discards a stale batch when `rows` / columns change mid-flight.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync loadAggregates() {\n\t\t\tconst aggCols = this.effectiveColumns.filter((c) => c && c.aggregate && c.aggregate.op === 'count')\n\t\t\tif (aggCols.length === 0) {\n\t\t\t\tif (Object.keys(this.aggregateValues).length > 0) {\n\t\t\t\t\tthis.aggregateValues = {}\n\t\t\t\t}\n\t\t\t\tthis.aggregateLoading = false\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst id = ++this.aggregateRequestId\n\t\t\tthis.aggregateLoading = true\n\t\t\tconst next = {}\n\t\t\tconst jobs = []\n\t\t\tfor (const row of this.rows) {\n\t\t\t\tconst rowKey = String(row[this.rowKey])\n\t\t\t\tnext[rowKey] = {}\n\t\t\t\tfor (const col of aggCols) {\n\t\t\t\t\tconst agg = col.aggregate\n\t\t\t\t\tif (!agg.register || !agg.schema) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst where = this.resolveAggregateWhere(agg.where, row)\n\t\t\t\t\tjobs.push(axios.get(generateUrl(`/apps/openregister/api/objects/${agg.register}/${agg.schema}`), {\n\t\t\t\t\t\tparams: { ...where, _limit: 0 },\n\t\t\t\t\t})\n\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\tconst d = res && res.data\n\t\t\t\t\t\t\tnext[rowKey][col.key] = (d && (d.total ?? (Array.isArray(d.results) ? d.results.length : undefined))) ?? 0\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((e) => {\n\t\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\t\tconsole.warn(`[CnDataTable] aggregate \"${col.key}\" count failed for row ${rowKey}`, e)\n\t\t\t\t\t\t\tnext[rowKey][col.key] = undefined\n\t\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait Promise.all(jobs)\n\t\t\tif (id !== this.aggregateRequestId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.aggregateValues = next\n\t\t\tthis.aggregateLoading = false\n\t\t},\n\n\t\tisSelected(row) {\n\t\t\treturn this.selectedIds.includes(row[this.rowKey])\n\t\t},\n\n\t\t/**\n\t\t * Row-body click: toggles selection when `selectable` (ignoring drags),\n\t\t * otherwise emits `row-click` for navigation.\n\t\t *\n\t\t * @param {object} row The clicked row object\n\t\t * @param {MouseEvent} [event] The originating click event.\n\t\t */\n\t\tonRowClick(row, event) {\n\t\t\tif (this.wasDrag(event)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.selectable && !this.rowClickToView) {\n\t\t\t\tthis.toggleSelect(row)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitRowClick(row, event)\n\t\t},\n\n\t\t/**\n\t\t * Row-body middle click: emits `row-click` like a click, so the host\n\t\t * (or `rowClickRoute`) can open the row in a new tab. Ignored for other\n\t\t * buttons, nested controls, drags and select-on-click tables.\n\t\t *\n\t\t * @param {object} row The clicked row object\n\t\t * @param {MouseEvent} event The originating auxclick event.\n\t\t */\n\t\tonRowAuxClick(row, event) {\n\t\t\tif (!isRowMiddleClick(event) || this.wasDrag(event)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.selectable && !this.rowClickToView) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitRowClick(row, event)\n\t\t},\n\n\t\t/**\n\t\t * Emit `row-click` and follow `rowClickRoute` when set.\n\t\t *\n\t\t * @param {object} row The clicked row object\n\t\t * @param {MouseEvent} [event] The originating click or auxclick event.\n\t\t */\n\t\temitRowClick(row, event) {\n\t\t\t/**\n\t\t\t * @event row-click Emitted on a row-body click for navigation, and on a middle click (auxclick). Fires when `selectable` is false, OR when `rowClickToView` is set (selection then happens via the checkbox column). Payload: `(row, event)` — the clicked row object and the native click/auxclick event, so a host can open the row in a new tab on a ctrl/cmd/shift or middle click (see `openRowTarget`).\n\t\t\t * @type {object} The clicked row object.\n\t\t\t */\n\t\t\tthis.$emit('row-click', row, event)\n\t\t\t// A ctrl/cmd/shift or middle click opens the route in a new tab,\n\t\t\t// unless a row-click listener already did.\n\t\t\tif (this.rowClickRoute && this.$router && !isNewTabHandled(event)) {\n\t\t\t\tconst route = this.rowClickRoute(row)\n\t\t\t\tif (route) {\n\t\t\t\t\tmarkNewTabHandled(event, openRowTarget(event, typeof route === 'string' ? { path: route } : route, this.$router))\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Row right-click: forward the row + originating event so a host can\n\t\t * open a context menu (the browser default is prevented).\n\t\t *\n\t\t * @param {object} row The right-clicked row object.\n\t\t * @param {MouseEvent} event The originating contextmenu event.\n\t\t */\n\t\tonRowContextMenu(row, event) {\n\t\t\t/**\n\t\t\t * @event row-context-menu Emitted on a row right-click (contextmenu) for hosts that render a context menu.\n\t\t\t * @type {{ row: object, event: MouseEvent }}\n\t\t\t */\n\t\t\tthis.$emit('row-context-menu', { row, event })\n\t\t},\n\n\t\t/**\n\t\t * Index of `key` within `effectiveSortKeys`, or -1 when not active.\n\t\t * Used by the template for the arrow, the numbered badge, and aria-sort.\n\t\t *\n\t\t * @param {string} key Column key.\n\t\t * @return {number}\n\t\t */\n\t\tsortKeyIndex(key) {\n\t\t\treturn this.effectiveSortKeys.findIndex((k) => k && k.key === key)\n\t\t},\n\n\t\t/**\n\t\t * `aria-sort` value for a column header: `'ascending'`/`'descending'`\n\t\t * for the PRIMARY (index 0) active sort key only — secondary/tertiary\n\t\t * keys carry the visible numbered badge instead, per WCAG guidance\n\t\t * that `aria-sort` describes single-column sort state. `null` omits\n\t\t * the attribute entirely (unsorted / not sortable).\n\t\t *\n\t\t * @param {object} col Column definition.\n\t\t * @return {string|null}\n\t\t */\n\t\tariaSortFor(col) {\n\t\t\tif (!col.sortable) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst primary = this.effectiveSortKeys[0]\n\t\t\tif (!primary || primary.key !== col.key) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn primary.order === 'asc' ? 'ascending' : 'descending'\n\t\t},\n\n\t\t/**\n\t\t * Header click: plain click = single-sort (existing behavior,\n\t\t * unchanged); shift+click appends/cycles the column as a secondary or\n\t\t * tertiary sort key. See `src/utils/multiColumnSort.js`.\n\t\t *\n\t\t * @param {string} key Column key.\n\t\t * @param {MouseEvent} [event] The originating click event.\n\t\t */\n\t\tonHeaderClick(key, event) {\n\t\t\tthis.applySort(key, !!(event && event.shiftKey))\n\t\t},\n\n\t\t/**\n\t\t * Header keydown: `Enter` = plain click, `Shift+Enter` = shift+click.\n\t\t *\n\t\t * @param {string} key Column key.\n\t\t * @param {KeyboardEvent} event The originating keydown event.\n\t\t */\n\t\tonHeaderKeydown(key, event) {\n\t\t\tif (event.key !== 'Enter') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tevent.preventDefault()\n\t\t\tthis.applySort(key, !!event.shiftKey)\n\t\t},\n\n\t\t/**\n\t\t * Compute and emit the next sort state for a header interaction.\n\t\t *\n\t\t * @param {string} key Column key.\n\t\t * @param {boolean} append `true` for a shift+click/shift+Enter (append/cycle a secondary key).\n\t\t */\n\t\tapplySort(key, append) {\n\t\t\tconst keys = nextSortState(this.effectiveSortKeys, key, { append })\n\t\t\tconst primary = keys[0] || null\n\t\t\t/**\n\t\t\t * @event sort Emitted when a sortable column header is clicked (plain click) or shift-clicked (multi-sort).\n\t\t\t * @type {{ key: string|null, order: 'asc'|'desc'|null, keys: Array<{key: string, order: 'asc'|'desc'}> }}\n\t\t\t * `key`/`order` mirror the PRIMARY (first) active sort key exactly as the pre-multi-sort single-key\n\t\t\t * contract did (`null`/`null` when cleared) — existing listeners destructuring `{ key, order }` are\n\t\t\t * unaffected. `keys` is new: the full ordered list (0 to 3 entries) for multi-sort-aware hosts.\n\t\t\t */\n\t\t\tthis.$emit('sort', {\n\t\t\t\tkey: primary ? primary.key : null,\n\t\t\t\torder: primary ? primary.order : null,\n\t\t\t\tkeys,\n\t\t\t})\n\t\t},\n\n\t\ttoggleSelect(row) {\n\t\t\tconst id = row[this.rowKey]\n\t\t\tconst newIds = this.isSelected(row)\n\t\t\t\t? this.selectedIds.filter((i) => i !== id)\n\t\t\t\t: [...this.selectedIds, id]\n\t\t\t/** @event select Emitted when row selection changes. Payload: array of selected IDs. */\n\t\t\tthis.$emit('select', newIds)\n\t\t},\n\n\t\ttoggleSelectAll() {\n\t\t\tif (this.allSelected) {\n\t\t\t\t// Remove only current page IDs, preserving cross-page selections\n\t\t\t\tconst currentPageIds = new Set(this.rows.map((row) => row[this.rowKey]))\n\t\t\t\tthis.$emit('select', this.selectedIds.filter((id) => !currentPageIds.has(id)))\n\t\t\t} else {\n\t\t\t\t// Add current page IDs to existing selections\n\t\t\t\tconst merged = new Set([...this.selectedIds, ...this.rows.map((row) => row[this.rowKey])])\n\t\t\t\tthis.$emit('select', [...merged])\n\t\t\t}\n\t\t\t/** @event select-all Emitted when select-all checkbox is toggled. */\n\t\t\tthis.$emit('select-all', !this.allSelected)\n\t\t},\n\t},\n}\n</script>\n"],"names":["CnCellRenderer","CnIcon","CnLockIndicator","t","axios"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnDataTable.vue2.js","sources":["../../../../src/components/CnDataTable/CnDataTable.vue"],"sourcesContent":["<template>\n\t<div\n\t\tclass=\"cn-table-container\"\n\t\tdata-testid=\"cn-object-list\"\n\t\t:class=\"{\n\t\t\t'cn-table-container--scrollable': scrollable,\n\t\t\t'cn-table-container--borderless': borderless,\n\t\t\t'cn-table-container--fill': fillHeight,\n\t\t}\">\n\t\t<!-- Optional card header (folded from the retired CnTableWidget): a title\n\t\t + total-count badge. Only rendered when `title` is set; bare table\n\t\t usage is unchanged. -->\n\t\t<div v-if=\"title\" class=\"cn-data-table__header\">\n\t\t\t<h3 class=\"cn-data-table__title\">\n\t\t\t\t{{ title }}\n\t\t\t</h3>\n\t\t\t<span v-if=\"totalRowCount > 0\" class=\"cn-data-table__count\">\n\t\t\t\t{{ totalRowCount }}\n\t\t\t</span>\n\t\t</div>\n\n\t\t<!-- Loading State -->\n\t\t<div v-if=\"isLoading\" class=\"cn-table-loading\" data-testid=\"cn-object-list-loading\">\n\t\t\t<!-- Decorative: the adjacent <p> already carries the accessible\n\t\t\t name (loadingText), so the spinner is hidden from the\n\t\t\t accessibility tree rather than exposed as an unlabelled\n\t\t\t role=\"img\" (WCAG 1.1.1 / axe \"role-img-alt\"). -->\n\t\t\t<NcLoadingIcon :size=\"32\" aria-hidden=\"true\" />\n\t\t\t<p>{{ loadingText }}</p>\n\t\t</div>\n\n\t\t<!-- Table. The horizontal scroll lives on this wrapper, NOT on\n\t\t `.cn-table-container`: `overflow-x: auto` on the container coerces\n\t\t its `overflow-y` from `visible` to `auto` (CSS forbids mixing\n\t\t `visible` with a non-visible value), which silently made the\n\t\t container the nearest scrollport. The sticky footer then anchored\n\t\t to a container that never scrolls, so \"View all\" scrolled away with\n\t\t the rows instead of pinning to the bottom of the enclosing widget. -->\n\t\t<!-- The horizontal scrollport must be reachable by keyboard: a region\n\t\t that scrolls but cannot take focus gives a keyboard-only user no\n\t\t way to reach the columns past the fold (axe\n\t\t `scrollable-region-focusable`, serious; WCAG 2.1.1).\n\n\t\t Gated on ACTUAL overflow rather than applied unconditionally, for\n\t\t two reasons. A table that fits needs no scrolling, so a permanent\n\t\t tab stop would put every table in the fleet on the keyboard path\n\t\t for nothing. And the axe rule itself only applies to elements that\n\t\t really are scrollable, so the conditional attribute is present in\n\t\t exactly the cases the rule evaluates.\n\n\t\t `role=\"group\"`, NOT `role=\"region\"`: this element is nested inside\n\t\t `.cn-widget-wrapper__content[role=\"region\"]` on the dashboard-widget\n\t\t path, and a second landmark there would surface as a duplicate.\n\t\t `group` is nameable but is not a landmark. A name is required\n\t\t rather than optional — `aria-label` is PROHIBITED on a role-less\n\t\t generic element, so a bare `tabindex` div would trade this\n\t\t violation for `aria-prohibited-attr` plus an unlabelled mystery\n\t\t stop in the tab order. -->\n\t\t<div\n\t\t\tv-else\n\t\t\tref=\"scrollEl\"\n\t\t\tclass=\"cn-data-table__scroll\"\n\t\t\t:tabindex=\"isScrollable ? 0 : undefined\"\n\t\t\t:role=\"isScrollable ? 'group' : undefined\"\n\t\t\t:aria-label=\"isScrollable ? scrollRegionLabel : undefined\">\n\t\t\t<table\n\t\t\t\tclass=\"cn-data-table\"\n\t\t\t\t:class=\"{ 'cn-data-table--fixed': fixedLayout }\"\n\t\t\t\tdata-testid=\"cn-object-list-table\">\n\t\t\t\t<thead v-if=\"!hideHeader\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<!-- Checkbox column -->\n\t\t\t\t\t\t<th v-if=\"selectable\" class=\"cn-table-col--checkbox\">\n\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t:modelValue=\"allSelected\"\n\t\t\t\t\t\t\t\t:indeterminate=\"someSelected && !allSelected\"\n\t\t\t\t\t\t\t\t:aria-label=\"selectAllLabel\"\n\t\t\t\t\t\t\t\t@update:modelValue=\"toggleSelectAll\" />\n\t\t\t\t\t\t</th>\n\n\t\t\t\t\t\t<!-- Leading icon column (header is intentionally blank) -->\n\t\t\t\t\t\t<th v-if=\"rowIcon\" class=\"cn-table-col--icon\" />\n\n\t\t\t\t\t\t<!-- Data columns -->\n\t\t\t\t\t\t<th\n\t\t\t\t\t\t\tv-for=\"col in effectiveColumns\"\n\t\t\t\t\t\t\t:key=\"col.key\"\n\t\t\t\t\t\t\t:class=\"[\n\t\t\t\t\t\t\t\tcol.sortable ? 'cn-table-header--sortable' : '',\n\t\t\t\t\t\t\t\tcol.class || '',\n\t\t\t\t\t\t\t]\"\n\t\t\t\t\t\t\t:style=\"col.width ? { width: col.width } : {}\"\n\t\t\t\t\t\t\t:tabindex=\"col.sortable ? 0 : null\"\n\t\t\t\t\t\t\t:aria-sort=\"ariaSortFor(col)\"\n\t\t\t\t\t\t\t:title=\"translateLabel(col.description) || null\"\n\t\t\t\t\t\t\t@click=\"col.sortable ? onHeaderClick(col.key, $event) : null\"\n\t\t\t\t\t\t\t@keydown.enter=\"col.sortable ? onHeaderKeydown(col.key, $event) : null\">\n\t\t\t\t\t\t\t<span :class=\"col.description ? 'cn-table-header--described' : ''\">\n\t\t\t\t\t\t\t\t{{ translateLabel(col.label) }}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tv-if=\"col.sortable && sortKeyIndex(col.key) !== -1\"\n\t\t\t\t\t\t\t\tclass=\"cn-table-sort-indicator\">\n\t\t\t\t\t\t\t\t{{ effectiveSortKeys[sortKeyIndex(col.key)].order === 'asc' ? '▲' : '▼' }}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tv-if=\"col.sortable && effectiveSortKeys.length > 1 && sortKeyIndex(col.key) !== -1\"\n\t\t\t\t\t\t\t\tclass=\"cn-table-sort-badge\">\n\t\t\t\t\t\t\t\t{{ sortKeyIndex(col.key) + 1 }}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</th>\n\n\t\t\t\t\t\t<!-- Actions column -->\n\t\t\t\t\t\t<th v-if=\"$slots['row-actions']\" class=\"cn-table-col--actions\">\n\t\t\t\t\t\t\t<!-- @slot Header cell content above the row-actions column (blank by default). -->\n\t\t\t\t\t\t\t<slot name=\"actions-header\" />\n\t\t\t\t\t\t</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<!-- Empty state -->\n\t\t\t\t\t<tr v-if=\"effectiveRows.length === 0\" class=\"cn-table-empty\" data-testid=\"cn-object-list-empty\">\n\t\t\t\t\t\t<td :colspan=\"totalColumns\">\n\t\t\t\t\t\t\t<!-- @slot Empty-state content shown when there are no rows (defaults to `emptyText`). -->\n\t\t\t\t\t\t\t<slot name=\"empty\">\n\t\t\t\t\t\t\t\t{{ translateLabel(emptyText) }}\n\t\t\t\t\t\t\t</slot>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<!-- Data rows -->\n\t\t\t\t\t<tr\n\t\t\t\t\t\tv-for=\"row in effectiveRows\"\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:key=\"row[rowKey]\"\n\t\t\t\t\t\tclass=\"cn-table-row\"\n\t\t\t\t\t\tdata-testid=\"cn-object-row\"\n\t\t\t\t\t\t:data-testid-row-id=\"row[rowKey]\"\n\t\t\t\t\t\t:class=\"[\n\t\t\t\t\t\t\tisSelected(row) ? 'cn-table-row--selected' : '',\n\t\t\t\t\t\t\trowLinks[String(row[rowKey])] ? 'cn-table-row--linked' : '',\n\t\t\t\t\t\t\trowClass ? rowClass(row) : '',\n\t\t\t\t\t\t]\"\n\t\t\t\t\t\t@mousedown=\"onRowMouseDown\"\n\t\t\t\t\t\t@click=\"onRowClick(row, $event)\"\n\t\t\t\t\t\t@auxclick=\"onRowAuxClick(row, $event)\"\n\t\t\t\t\t\t@contextmenu=\"onRowContextMenu(row, $event)\">\n\t\t\t\t\t\t<!-- Checkbox -->\n\t\t\t\t\t\t<td v-if=\"selectable\"\n\t\t\t\t\t\t\tclass=\"cn-table-col--checkbox\"\n\t\t\t\t\t\t\t@click.stop\n\t\t\t\t\t\t\t@auxclick.stop>\n\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t:modelValue=\"isSelected(row)\"\n\t\t\t\t\t\t\t\t:aria-label=\"selectRowLabel\"\n\t\t\t\t\t\t\t\t@update:modelValue=\"toggleSelect(row)\" />\n\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t<!-- Leading icon -->\n\t\t\t\t\t\t<td v-if=\"rowIcon\" class=\"cn-table-col--icon\">\n\t\t\t\t\t\t\t<CnIcon :name=\"getRowIcon(row)\" :size=\"20\" />\n\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t<!-- Data cells -->\n\t\t\t\t\t\t<td\n\t\t\t\t\t\t\tv-for=\"(col, colIndex) in effectiveColumns\"\n\t\t\t\t\t\t\t:key=\"col.key\"\n\t\t\t\t\t\t\t:class=\"[col.class || '', col.cellClass || '', cellClass ? cellClass(row, col) : '']\"\n\t\t\t\t\t\t\t:style=\"col.width ? { maxWidth: col.width } : {}\"\n\t\t\t\t\t\t\t@mouseenter=\"titleWhenClipped\">\n\t\t\t\t\t\t\t<!-- A row with a `rowClickRoute` is a real link: this anchor\n\t\t\t\t\t\t\t is stretched over the whole row by CSS, so hovering shows\n\t\t\t\t\t\t\t the URL, a middle or ctrl click opens a new tab natively,\n\t\t\t\t\t\t\t and the row is reachable with Tab. The row's own click\n\t\t\t\t\t\t\t handlers treat it as a nested control and leave it be. -->\n\t\t\t\t\t\t\t<a v-if=\"colIndex === 0 && rowLinks[String(row[rowKey])]\"\n\t\t\t\t\t\t\t\tclass=\"cn-table-row__link\"\n\t\t\t\t\t\t\t\t:href=\"rowLinks[String(row[rowKey])].href\"\n\t\t\t\t\t\t\t\t:aria-label=\"rowLinkLabel(row, col)\"\n\t\t\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-row-link\"\n\t\t\t\t\t\t\t\t@click=\"onRowLinkClick(row, $event)\" />\n\t\t\t\t\t\t\t<!-- The padlock rides the FIRST data cell, beside whatever\n\t\t\t\t\t\t\t names the row. Deliberately OUTSIDE the #column-<key>\n\t\t\t\t\t\t\t slot: a consumer overriding that column's rendering is\n\t\t\t\t\t\t\t customising their own data, not opting out of being told\n\t\t\t\t\t\t\t the record is locked. It renders nothing when unlocked,\n\t\t\t\t\t\t\t so an unlocked table is byte-for-byte what it was. -->\n\t\t\t\t\t\t\t<CnLockIndicator\n\t\t\t\t\t\t\t\tv-if=\"colIndex === 0\"\n\t\t\t\t\t\t\t\t:object=\"row\"\n\t\t\t\t\t\t\t\t:size=\"16\" />\n\t\t\t\t\t\t\t<!-- Declared state indicators ride the first data cell\n\t\t\t\t\t\t\t beside the padlock. Each one renders as an icon WITH a\n\t\t\t\t\t\t\t text alternative and a tooltip, never as colour alone,\n\t\t\t\t\t\t\t and an indicator the page did not declare cannot appear\n\t\t\t\t\t\t\t however the record is shaped. Past the cap the rest move\n\t\t\t\t\t\t\t into the row menu, because a row of nine icons is not a\n\t\t\t\t\t\t\t row anyone can triage at a glance. -->\n\t\t\t\t\t\t\t<span v-if=\"colIndex === 0 && indicatorsFor(row).shown.length > 0\"\n\t\t\t\t\t\t\t\tclass=\"cn-table-row-indicators\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-row-indicators\">\n\t\t\t\t\t\t\t\t<span v-for=\"indicator in indicatorsFor(row).shown\"\n\t\t\t\t\t\t\t\t\t:key=\"indicator.id || indicator.field\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-table-row-indicator\"\n\t\t\t\t\t\t\t\t\t:title=\"indicator.tooltip || indicator.text\"\n\t\t\t\t\t\t\t\t\t:data-testid=\"`cn-row-indicator-${indicator.id || indicator.field}`\">\n\t\t\t\t\t\t\t\t\t<CnIcon :name=\"indicator.icon || 'InformationOutline'\" :size=\"16\" />\n\t\t\t\t\t\t\t\t\t<span class=\"hidden-visually\">{{ indicator.text }}</span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<!-- @slot Per-column cell override (`#column-<key>`), scoped with { row, value }. Wins over CnCellRenderer. -->\n\t\t\t\t\t\t\t<slot :name=\"'column-' + col.key\" :row=\"row\" :value=\"cellValue(row, col)\">\n\t\t\t\t\t\t\t\t<!-- Every column renders through CnCellRenderer: it resolves\n\t\t\t\t\t\t\t col.formatter / col.widget against the injected registries\n\t\t\t\t\t\t\t (cnFormatters / cnCellWidgets), uses the schema property when\n\t\t\t\t\t\t\t one is available (else {}) for type-aware rendering, and\n\t\t\t\t\t\t\t falls back to formatValue(). Columns with `aggregate` get a\n\t\t\t\t\t\t\t count of related objects (see cellValue/loadAggregates). The\n\t\t\t\t\t\t\t #column-{key} slot still wins. -->\n\t\t\t\t\t\t\t\t<CnCellRenderer\n\t\t\t\t\t\t\t\t\t:value=\"cellValue(row, col)\"\n\t\t\t\t\t\t\t\t\t:property=\"columnProperty(col)\"\n\t\t\t\t\t\t\t\t\t:formatter=\"col.formatter || null\"\n\t\t\t\t\t\t\t\t\t:formatterOptions=\"col.formatterOptions || null\"\n\t\t\t\t\t\t\t\t\t:widget=\"col.widget || null\"\n\t\t\t\t\t\t\t\t\t:widgetProps=\"col.widgetProps || undefined\"\n\t\t\t\t\t\t\t\t\t:format=\"columnFormat(col)\"\n\t\t\t\t\t\t\t\t\t:row=\"row\"\n\t\t\t\t\t\t\t\t\t:rowKey=\"rowKey\" />\n\t\t\t\t\t\t\t</slot>\n\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t<!-- Row actions -->\n\t\t\t\t\t\t<td v-if=\"$slots['row-actions']\"\n\t\t\t\t\t\t\tclass=\"cn-table-col--actions\"\n\t\t\t\t\t\t\t:class=\"[cellClass ? cellClass(row, { key: 'actions' }) : '']\"\n\t\t\t\t\t\t\t@click.stop\n\t\t\t\t\t\t\t@auxclick.stop>\n\t\t\t\t\t\t\t<!-- @slot Per-row actions menu (e.g. a CnRowActions), scoped with { row }. Supplying it adds the trailing actions column. -->\n\t\t\t\t\t\t\t<slot name=\"row-actions\" :row=\"row\" />\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\n\t\t<!-- Optional footer. A `#footer` scoped slot lets a host render its own\n\t\t footer link (e.g. a \"+ New\" create action or an always-shown\n\t\t \"View all\") with its own click handler — useful when the widget runs\n\t\t outside a vue-router context (the built-in link uses $router). When\n\t\t no slot is given, the built-in \"View all\" control (folded from the\n\t\t retired CnTableWidget) is shown for a `limit`-ed subset.\n\n\t\t The control is a real link (with an href) when the router resolves\n\t\t `viewAllRoute` to a URL, and a real button otherwise. An `<a>`\n\t\t without an href has no link role and is not keyboard focusable\n\t\t (WCAG 2.1.1, 4.1.2), so it is never rendered. -->\n\t\t<div\n\t\t\tv-if=\"$slots.footer || (viewAllRoute && totalRowCount > effectiveRows.length)\"\n\t\t\tclass=\"cn-data-table__footer\">\n\t\t\t<!-- @slot Custom footer content, scoped with { total, shown } (defaults to the built-in \"View all\" link). -->\n\t\t\t<slot name=\"footer\" :total=\"totalRowCount\" :shown=\"effectiveRows.length\">\n\t\t\t\t<a\n\t\t\t\t\tv-if=\"viewAllHref\"\n\t\t\t\t\tclass=\"cn-data-table__view-all\"\n\t\t\t\t\t:href=\"viewAllHref\"\n\t\t\t\t\t@click=\"onViewAll\">\n\t\t\t\t\t{{ viewAllLabel }}\n\t\t\t\t</a>\n\t\t\t\t<button\n\t\t\t\t\tv-else\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-data-table__view-all\"\n\t\t\t\t\t@click=\"onViewAll\">\n\t\t\t\t\t{{ viewAllLabel }}\n\t\t\t\t</button>\n\t\t\t</slot>\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcCheckboxRadioSwitch, NcLoadingIcon } from '@nextcloud/vue'\nimport { useClickDragGuard } from '../../composables/useClickDragGuard.js'\nimport { followLinkClick, openRowTarget, resolveHref } from '../../utils/linkNavigation.js'\nimport { nextSortState } from '../../utils/multiColumnSort.js'\nimport { isNewTabClick, isNewTabHandled, isRowMiddleClick, markNewTabHandled, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'\nimport { DEFAULT_ROW_INDICATOR_CAP, resolveRowIndicators } from '../../utils/rowIndicators.js'\nimport { columnsFromSchema } from '../../utils/schema.js'\nimport { CnCellRenderer } from '../CnCellRenderer/index.js'\nimport { CnIcon } from '../CnIcon/index.js'\nimport { CnLockIndicator } from '../CnLockIndicator/index.js'\n\n// CnDataTable has no scoped styles of its own — its entire look lives in the\n// shared table stylesheet. Import it here so the table is styled even when the\n// consuming app does not pull in the library's global css/index.css.\nimport '../../css/table.css'\n\n/**\n * CnDataTable — Generic sortable data table for list views.\n *\n * Replaces the copy-pasted `<table class=\"viewTable\">` HTML pattern found in\n * every list view across OpenRegister, Pipelinq, and Dossiq. Supports sorting,\n * row selection, custom cell rendering via scoped slots, loading states,\n * and empty states.\n *\n * Sorting: a plain click on a sortable header is single-sort (cycle asc →\n * desc → cleared), unchanged from before. Shift+click (or Shift+Enter on a\n * focused header) appends the column as a secondary/tertiary sort key —\n * capped at 3 — with numbered priority badges (1, 2, 3) once more than one\n * key is active. Pass `sortKeys: [{key, order}, ...]` for multi-sort (falls\n * back to the legacy `sortKey`/`sortOrder` props when empty). The `sort`\n * event payload is extended, not replaced: `{key, order}` still mirrors the\n * primary key exactly as before; a new `keys` field carries the full\n * ordered list. See `src/utils/multiColumnSort.js` for the state machine.\n *\n * When a `schema` prop is provided, columns are auto-generated from schema\n * properties and cells render through CnCellRenderer for type-aware formatting\n * (dates, booleans, UUIDs, enums, etc.). Scoped slots still override individual\n * columns when needed.\n *\n * Manual columns (backwards compatible)\n * ```vue\n * <CnDataTable\n * :columns=\"[\n * { key: 'name', label: 'Name', sortable: true },\n * { key: 'email', label: 'Email' },\n * ]\"\n * :rows=\"clients\"\n * @row-click=\"openClient\" />\n * ```\n *\n * Schema-driven (auto columns)\n * ```vue\n * <CnDataTable :schema=\"schema\" :rows=\"objects\" />\n * ```\n *\n * Schema with overrides and custom cell\n * ```vue\n * <CnDataTable\n * :schema=\"schema\"\n * :exclude-columns=\"['description']\"\n * :column-overrides=\"{ status: { width: '200px' } }\"\n * :rows=\"objects\">\n * <template #column-status=\"{ row, value }\">\n * <QuickStatusDropdown :case-obj=\"row\" />\n * </template>\n * </CnDataTable>\n * ```\n */\nexport default {\n\tname: 'CnDataTable',\n\n\tcomponents: {\n\t\tNcLoadingIcon,\n\t\tNcCheckboxRadioSwitch,\n\t\tCnCellRenderer,\n\t\tCnIcon,\n\t\tCnLockIndicator,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Consumer translation function, provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id, e.g.\n\t\t * `t.bind(null, 'docudesk')`). Column headers come from schema\n\t\t * property titles, which are authored in English as the canonical\n\t\t * source (API predictability); the visible label is resolved through\n\t\t * this function so it follows the user's language, with the English\n\t\t * source key living in each app's l10n files. Defaults to identity\n\t\t * when the table is used standalone (no CnAppRoot ancestor).\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * Column definitions (manual mode).\n\t\t * Not required when `schema` is provided.\n\t\t * Each entry may be a full column object OR a bare string key; bare strings\n\t\t * are normalised to `{ key, label }` by `effectiveColumns` so manifest-driven\n\t\t * pages that pass `config.columns` as a string array work without extra mapping.\n\t\t *\n\t\t * `description` renders as the header cell's tooltip and marks the label with a\n\t\t * dotted underline, so a column whose meaning is not obvious from its name (a\n\t\t * maturity level, a computed score, a domain term) can explain itself where the\n\t\t * reader is looking. `columnsFromSchema` fills it from the JSON Schema property\n\t\t * description automatically, so schema-driven tables get it for free.\n\t\t *\n\t\t * @type {Array<{key: string, label: string, description: string, sortable: boolean, width: string, class: string, cellClass: string}|string>}\n\t\t */\n\t\tcolumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Optional leading icon shown at the start of every row. Either a static\n\t\t * MDI icon name (PascalCase, e.g. `'FileDocumentOutline'`) applied to all\n\t\t * rows, or a function `(row) => iconName` to vary it per row. The icon is\n\t\t * resolved through the shared CnIcon registry. Unset = no icon column.\n\t\t *\n\t\t * @type {string | ((row: object) => string) | null}\n\t\t */\n\t\trowIcon: {\n\t\t\ttype: [String, Function],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * State indicators a page declares for its rows. Each entry is\n\t\t * `{ id, field, equals?, in?, icon, text, tooltip? }`: `field` is a\n\t\t * dotted path on the row, the condition is `equals`, `in`, or plain\n\t\t * truthiness when neither is given, `icon` is a CnIcon name, and `text`\n\t\t * is the text alternative. An entry without `text` does not render,\n\t\t * because an icon with no text is colour and shape alone.\n\t\t *\n\t\t * The page declares which indicators exist. A record cannot add one the\n\t\t * page has not declared, however it is shaped. A page declaring none\n\t\t * renders its rows exactly as before.\n\t\t *\n\t\t * @type {Array<{id?: string, field: string, equals?: (string|number|boolean|null), in?: Array, icon?: string, text: string, tooltip?: string}>}\n\t\t */\n\t\trowIndicators: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * How many declared indicators render on the row itself. The rest are\n\t\t * available from `indicatorsFor(row).overflow` for the row menu.\n\t\t *\n\t\t * @type {number}\n\t\t */\n\t\trowIndicatorCap: {\n\t\t\ttype: Number,\n\t\t\tdefault: DEFAULT_ROW_INDICATOR_CAP,\n\t\t},\n\n\t\t/**\n\t\t * Schema object with `properties` field (schema-driven mode).\n\t\t * When provided, columns are auto-generated from schema properties.\n\t\t */\n\t\tschema: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Per-column overrides when using schema mode: { key: { width, label, sortable, ... } } */\n\t\tcolumnOverrides: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Column keys to exclude when using schema mode */\n\t\texcludeColumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Column keys to include when using schema mode (whitelist) */\n\t\tincludeColumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Row data array. Each row should have a unique identifier (see rowKey). */\n\t\trows: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Whether data is loading (shows loading spinner) */\n\t\tloading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Current sort column key */\n\t\tsortKey: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Current sort order: 'asc', 'desc', or null (no sort) */\n\t\tsortOrder: {\n\t\t\ttype: String,\n\t\t\tdefault: 'asc',\n\t\t\tvalidator: (v) => v === null || ['asc', 'desc'].includes(v),\n\t\t},\n\n\t\t/**\n\t\t * Ordered multi-column sort state: `[{ key, order }, ...]` (priority\n\t\t * order, 0 to 3 entries). Optional — when empty (the default), the\n\t\t * table falls back to the legacy `sortKey`/`sortOrder` props, so\n\t\t * single-sort hosts are completely unaffected. Shift+click a\n\t\t * sortable header to append/cycle a secondary or tertiary key (see\n\t\t * `src/utils/multiColumnSort.js`).\n\t\t *\n\t\t * @type {Array<{key: string, order: 'asc'|'desc'}>}\n\t\t */\n\t\tsortKeys: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Whether rows can be selected with checkboxes */\n\t\tselectable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Array of currently selected row IDs */\n\t\tselectedIds: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Property name used as unique row identifier */\n\t\trowKey: {\n\t\t\ttype: String,\n\t\t\tdefault: 'id',\n\t\t},\n\n\t\t/** Text shown when there are no rows */\n\t\temptyText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'No items found'),\n\t\t},\n\n\t\t/** Function returning CSS class(es) for a row: (row) => string|object */\n\t\trowClass: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Function returning CSS class(es) for a data cell: (row, col) => string|object */\n\t\tcellClass: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Whether to constrain table height and make it scrollable */\n\t\tscrollable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Text shown while loading */\n\t\tloadingText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Loading…'),\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for the select-all checkbox in the header row.\n\t\t * Used as the checkbox's `aria-label` so screen readers announce a\n\t\t * named control (WCAG 4.1.2). Defaults to the lib's translation of\n\t\t * \"Select all rows\".\n\t\t */\n\t\tselectAllLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Select all rows'),\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for a per-row select checkbox. Used as the\n\t\t * checkbox's `aria-label` so screen readers announce a named control\n\t\t * (WCAG 4.1.2). Defaults to the lib's translation of \"Select row\".\n\t\t */\n\t\tselectRowLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Select row'),\n\t\t},\n\n\t\t/**\n\t\t * Optional card title rendered in a header above the table. When set, the\n\t\t * table reads as a self-contained card (the container's own border/radius\n\t\t * is the card chrome). Folded in from the retired CnTableWidget.\n\t\t */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Drop the container's card chrome (border, radius, shadow) so the table\n\t\t * sits flush inside a parent that already provides a card (e.g. a\n\t\t * CnWidgetWrapper dashboard slot). Folded in from CnTableWidget.\n\t\t */\n\t\tborderless: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Fill the height of the parent (a flex-column card / widget content\n\t\t * area) so the optional `#footer` is pushed to the bottom instead of\n\t\t * floating directly under a short list. When the list is long enough to\n\t\t * overflow, the footer stays pinned via its sticky rule. No-op outside a\n\t\t * height-constrained parent. Opt-in so ordinary in-flow tables are\n\t\t * unaffected.\n\t\t */\n\t\tfillHeight: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Hide the column-header row (`<thead>`). Useful for compact dashboard\n\t\t * list widgets that want a plain bordered-row list without column labels.\n\t\t */\n\t\thideHeader: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Switch the table to `table-layout: fixed`, making each column's `width`\n\t\t * authoritative instead of a hint the browser may override. Opt in when a\n\t\t * column's content would otherwise dictate the layout — a long unbreakable\n\t\t * value (a PHP FQCN, a UUID) widens its column under the default auto\n\t\t * layout and can render past the cell box into its neighbour, while any\n\t\t * column left unsized soaks up all remaining width. Cells also break long\n\t\t * words rather than overflowing. Columns with no `width` share whatever\n\t\t * space is left, so size every column when you want exact control.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tfixedLayout: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Max number of rows to display. When the total exceeds it, only the first\n\t\t * `limit` render and the \"View all\" footer appears (with `viewAllRoute`).\n\t\t * 0 = show all. Folded in from CnTableWidget.\n\t\t */\n\t\tlimit: {\n\t\t\ttype: Number,\n\t\t\tdefault: 0,\n\t\t},\n\n\t\t/**\n\t\t * vue-router route object for the \"View all\" footer link. The footer only\n\t\t * shows when set AND the rows are a `limit`-ed subset. Folded in from CnTableWidget.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tviewAllRoute: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Pre-translated \"View all\" footer label. */\n\t\tviewAllLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'View all'),\n\t\t},\n\n\t\t/**\n\t\t * Self-fetch mode (folded from CnTableWidget): the OpenRegister register\n\t\t * id/slug. When `register` + `schemaId` are set and no `rows` are passed,\n\t\t * the table fetches `/apps/openregister/api/objects/{register}/{schemaId}`.\n\t\t *\n\t\t * @type {string|number|null}\n\t\t */\n\t\tregister: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Self-fetch mode (folded from CnTableWidget): the OpenRegister schema\n\t\t * id used together with `register`. (Distinct from the `schema` prop,\n\t\t * which is a JSON Schema object for column generation.)\n\t\t *\n\t\t * @type {string|number|null}\n\t\t */\n\t\tschemaId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Extra query parameters sent with the self-fetch request (register +\n\t\t * schemaId mode) — e.g. a resolved filter map, `_order[field]` ordering,\n\t\t * or `_limit`. Changing it re-triggers the self-fetch, so a host widget\n\t\t * (CnWidgetObjectTable's declarative `source`) can drive filtering and\n\t\t * ordering without re-implementing the fetch. Ignored when external\n\t\t * `rows` are supplied.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tfetchParams: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Convenience navigation (folded from CnTableWidget): a function that\n\t\t * receives a row and returns the vue-router route it opens. When set,\n\t\t * each row renders as a real link to that route, stretched over the\n\t\t * row: a click navigates there (the `row-click` event still fires), and\n\t\t * a ctrl/cmd/shift or middle click opens it in a new tab. A table whose\n\t\t * row click selects (`selectable` without `rowClickToView`) gets no link.\n\t\t *\n\t\t * @type {((row: object) => object)|null}\n\t\t */\n\t\trowClickRoute: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * When true, a row-body click emits `row-click` (for navigation) even\n\t\t * while `selectable` — selection then happens only via the checkbox\n\t\t * column. Lets \"click row = open, tick box = select\" coexist. Default\n\t\t * false keeps the legacy behaviour (selectable rows select on body click).\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\trowClickToView: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: ['row-click', 'row-aux-click', 'row-context-menu', 'select', 'select-all', 'sort', 'view-all'],\n\n\tsetup() {\n\t\t// Tell a deliberate row click apart from a text-selection drag.\n\t\treturn useClickDragGuard()\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * Resolved aggregate-column values, keyed by `String(row[rowKey])`\n\t\t\t * then by column key. Populated by `loadAggregates()` for columns\n\t\t\t * that declare `aggregate` (see CnIndexPage's manifest config).\n\t\t\t *\n\t\t\t * @type {{[rowId: string]: {[colKey: string]: number}}}\n\t\t\t */\n\t\t\taggregateValues: {},\n\t\t\t/**\n\t\t\t * Whether the table currently overflows its scrollport horizontally.\n\t\t\t * Drives the keyboard tab stop on `.cn-data-table__scroll`; see the\n\t\t\t * comment on that element.\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t */\n\t\t\tisScrollable: false,\n\t\t\t/** True while a batch of aggregate-count requests is in flight. */\n\t\t\taggregateLoading: false,\n\t\t\t/** Monotonic id used to discard a stale aggregate batch when `rows` changes mid-flight. */\n\t\t\taggregateRequestId: 0,\n\t\t\t/** Rows fetched in self-fetch mode (register + schemaId). */\n\t\t\tfetchedRows: [],\n\t\t\t/** True while a self-fetch request is in flight. */\n\t\t\tselfFetchLoading: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Accessible name for the horizontal scrollport when it becomes a tab\n\t\t * stop. Prefers the table's own `title` so the announcement identifies\n\t\t * WHICH table the user has landed in — several can share a dashboard.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tscrollRegionLabel() {\n\t\t\treturn this.title\n\t\t\t\t? t('nextcloud-vue', '{title} — scrollable table', { title: this.title })\n\t\t\t\t: t('nextcloud-vue', 'Scrollable table')\n\t\t},\n\n\t\t/**\n\t\t * The row source: external `rows` when provided, else the self-fetched\n\t\t * rows (register + schemaId mode). External rows always win.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\tsourceRows() {\n\t\t\tif (this.rows && this.rows.length > 0) {\n\t\t\t\treturn this.rows\n\t\t\t}\n\t\t\tif (this.register !== null && this.register !== undefined && this.schemaId !== null && this.schemaId !== undefined) {\n\t\t\t\treturn this.fetchedRows\n\t\t\t}\n\t\t\treturn this.rows\n\t\t},\n\n\t\t/**\n\t\t * The rows actually rendered — `sourceRows` capped to `limit` (0 = all).\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\teffectiveRows() {\n\t\t\treturn this.limit > 0 ? this.sourceRows.slice(0, this.limit) : this.sourceRows\n\t\t},\n\n\t\t/**\n\t\t * Total row count before the `limit` cap (drives the count badge + the\n\t\t * \"View all\" footer condition).\n\t\t *\n\t\t * @return {number}\n\t\t */\n\t\ttotalRowCount() {\n\t\t\treturn this.sourceRows.length\n\t\t},\n\n\t\t/**\n\t\t * The URL the router resolves `viewAllRoute` to, or `null` when there is\n\t\t * no route or no router (a widget mounted outside a vue-router context).\n\t\t * Decides whether the \"View all\" footer renders as a link or a button.\n\t\t *\n\t\t * @return {string|null}\n\t\t */\n\t\tviewAllHref() {\n\t\t\tif (!this.viewAllRoute || !this.$router || typeof this.$router.resolve !== 'function') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst resolved = this.$router.resolve(this.viewAllRoute)\n\t\t\t\treturn (resolved && resolved.href) || null\n\t\t\t} catch {\n\t\t\t\treturn null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Whether to show the loading state — the external `loading` prop OR a\n\t\t * self-fetch in flight.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisLoading() {\n\t\t\treturn this.loading || this.selfFetchLoading\n\t\t},\n\n\t\t/**\n\t\t * Effective columns: schema-generated or manually provided.\n\t\t * Schema columns take precedence when schema is provided and no manual columns given.\n\t\t */\n\t\teffectiveColumns() {\n\t\t\tconst cols = (this.schema && this.columns.length === 0)\n\t\t\t\t? columnsFromSchema(this.schema, {\n\t\t\t\t\t\texclude: this.excludeColumns,\n\t\t\t\t\t\tinclude: this.includeColumns,\n\t\t\t\t\t\toverrides: this.columnOverrides,\n\t\t\t\t\t})\n\t\t\t\t: this.columns\n\t\t\tif (!(cols || []).some((c) => typeof c === 'string')) {\n\t\t\t\treturn cols || []\n\t\t\t}\n\t\t\tconst schemaCols = this.schema\n\t\t\t\t? columnsFromSchema(this.schema, { overrides: this.columnOverrides })\n\t\t\t\t: []\n\t\t\tconst byKey = new Map(schemaCols.map((c) => [c.key, c]))\n\t\t\treturn (cols || []).map((c) => {\n\t\t\t\tif (typeof c !== 'string') {\n\t\t\t\t\treturn c\n\t\t\t\t}\n\t\t\t\treturn byKey.get(c) || { key: c, label: c, sortable: true }\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The active ordered sort-key list: the `sortKeys` prop when non-empty,\n\t\t * else a single-entry list derived from the legacy `sortKey`/`sortOrder`\n\t\t * props (empty when neither is active). Every header/badge/aria-sort\n\t\t * computation reads this so single-sort hosts (no `sortKeys` passed)\n\t\t * render exactly as before.\n\t\t *\n\t\t * @return {Array<{key: string, order: 'asc'|'desc'}>}\n\t\t */\n\t\t/**\n\t\t * The link each row opens, keyed by row key: the `rowClickRoute`\n\t\t * location and its href. Empty when rows have no route, or when a row\n\t\t * click selects instead of navigating.\n\t\t *\n\t\t * @return {{[key: string]: {target: object, href: string}}}\n\t\t */\n\t\trowLinks() {\n\t\t\tconst links = {}\n\t\t\tif (!this.rowClickRoute || !this.$router || (this.selectable && !this.rowClickToView)) {\n\t\t\t\treturn links\n\t\t\t}\n\t\t\tfor (const row of this.effectiveRows) {\n\t\t\t\tconst route = this.rowClickRoute(row)\n\t\t\t\tif (!route) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst target = typeof route === 'string' ? { path: route } : route\n\t\t\t\tconst href = resolveHref(target, this.$router)\n\t\t\t\tif (href) {\n\t\t\t\t\tlinks[String(row[this.rowKey])] = { target, href }\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn links\n\t\t},\n\n\t\teffectiveSortKeys() {\n\t\t\tif (this.sortKeys && this.sortKeys.length > 0) {\n\t\t\t\treturn this.sortKeys\n\t\t\t}\n\t\t\tif (this.sortKey) {\n\t\t\t\treturn [{ key: this.sortKey, order: this.sortOrder || 'asc' }]\n\t\t\t}\n\t\t\treturn []\n\t\t},\n\n\t\ttotalColumns() {\n\t\t\tlet count = this.effectiveColumns.length\n\t\t\tif (this.selectable) {\n\t\t\t\tcount++\n\t\t\t}\n\t\t\tif (this.rowIcon) {\n\t\t\t\tcount++\n\t\t\t}\n\t\t\tif (this.$slots['row-actions']) {\n\t\t\t\tcount++\n\t\t\t}\n\t\t\treturn count\n\t\t},\n\n\t\t/**\n\t\t * Stable signature of the self-fetch inputs so the watcher refetches\n\t\t * only on a real change (register / schemaId / fetchParams).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tselfFetchKey() {\n\t\t\treturn JSON.stringify({\n\t\t\t\tregister: this.register,\n\t\t\t\tschemaId: this.schemaId,\n\t\t\t\tfetchParams: this.fetchParams || null,\n\t\t\t})\n\t\t},\n\n\t\tallSelected() {\n\t\t\treturn this.effectiveRows.length > 0\n\t\t\t\t&& this.effectiveRows.every((row) => this.selectedIds.includes(row[this.rowKey]))\n\t\t},\n\n\t\tsomeSelected() {\n\t\t\treturn this.effectiveRows.some((row) => this.selectedIds.includes(row[this.rowKey]))\n\t\t},\n\t},\n\n\twatch: {\n\t\trows: {\n\t\t\thandler() {\n\t\t\t\tthis.loadAggregates()\n\t\t\t},\n\t\t},\n\n\t\teffectiveColumns: {\n\t\t\thandler() {\n\t\t\t\tthis.loadAggregates()\n\t\t\t},\n\n\t\t\tdeep: false,\n\t\t},\n\n\t\t/**\n\t\t * Re-run the self-fetch when its inputs (register, schemaId, or the\n\t\t * host-driven `fetchParams`) change — a token-resolved filter (e.g.\n\t\t * `@workspace.*`) can change after mount. External rows still win.\n\t\t */\n\t\tselfFetchKey() {\n\t\t\tif ((!this.rows || this.rows.length === 0) && this.register !== null && this.register !== undefined && this.schemaId !== null && this.schemaId !== undefined) {\n\t\t\t\tthis.fetchData()\n\t\t\t}\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.loadAggregates()\n\t\t// Self-fetch mode: pull rows from OpenRegister when register + schemaId\n\t\t// are given and no external rows were passed (folded from CnTableWidget).\n\t\tif ((!this.rows || this.rows.length === 0) && this.register !== null && this.register !== undefined && this.schemaId !== null && this.schemaId !== undefined) {\n\t\t\tthis.fetchData()\n\t\t}\n\t\tthis.observeScrollOverflow()\n\t},\n\n\tupdated() {\n\t\t// Columns and rows can change after mount (self-fetch resolving, a\n\t\t// column toggled), and either can flip the table between fitting and\n\t\t// overflowing. ResizeObserver alone would miss a change that alters\n\t\t// content width without resizing the box.\n\t\tthis.measureScrollOverflow()\n\t},\n\n\tbeforeUnmount() {\n\t\tthis.disconnectScrollOverflow()\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * The declared indicators that apply to one row, split into the ones\n\t\t * that fit on the row and the ones that go to the row menu.\n\t\t *\n\t\t * @param {object} row The row.\n\t\t * @return {{shown: Array<object>, overflow: Array<object>}}\n\t\t * @spec openspec/changes/working-list-row-actions/specs/index-page/spec.md\n\t\t */\n\t\tindicatorsFor(row) {\n\t\t\treturn resolveRowIndicators(this.rowIndicators, row, this.rowIndicatorCap)\n\t\t},\n\n\t\t/**\n\t\t * Give a cell its full text on hover, and only when it is cut short.\n\t\t *\n\t\t * Cells are one line with an ellipsis, so a long value is readable only\n\t\t * as far as the column goes. A `title` on every cell would answer that,\n\t\t * and would also put a tooltip on the cells that need none — repeating\n\t\t * back what is already on screen.\n\t\t *\n\t\t * Read on ENTER rather than on render: `scrollWidth > clientWidth` forces\n\t\t * layout, and doing it per cell per paint would cost a reflow for a\n\t\t * tooltip almost none of them want. On enter it is one read of one cell,\n\t\t * and it is re-read every time, so a column resized since the last hover\n\t\t * answers for its new width rather than its old one.\n\t\t *\n\t\t * @param {MouseEvent} event The enter event.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\ttitleWhenClipped(event) {\n\t\t\tconst el = event.currentTarget\n\t\t\tif (!el) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// 1px of tolerance, as the scrollport check uses: sub-pixel rounding\n\t\t\t// otherwise reports a cell that visually fits as clipped.\n\t\t\tif (el.scrollWidth - el.clientWidth > 1) {\n\t\t\t\tel.setAttribute('title', (el.textContent || '').trim())\n\t\t\t} else {\n\t\t\t\tel.removeAttribute('title')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Start watching the scrollport for horizontal overflow.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tobserveScrollOverflow() {\n\t\t\tthis.measureScrollOverflow()\n\t\t\tif (typeof ResizeObserver === 'undefined') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis._scrollObserver = new ResizeObserver(() => this.measureScrollOverflow())\n\t\t\tconst el = this.$refs.scrollEl\n\t\t\tif (el) {\n\t\t\t\tthis._scrollObserver.observe(el)\n\t\t\t\t// The table itself, not just the port: a column widening pushes\n\t\t\t\t// the content past the fold without the port changing size.\n\t\t\t\tconst table = el.querySelector('table')\n\t\t\t\tif (table) {\n\t\t\t\t\tthis._scrollObserver.observe(table)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Recompute whether the scrollport overflows horizontally.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tmeasureScrollOverflow() {\n\t\t\tconst el = this.$refs.scrollEl\n\t\t\t// 1px of tolerance: sub-pixel layout rounding otherwise reports a\n\t\t\t// table that visually fits as scrollable, which would put a tab\n\t\t\t// stop on it for no reachable content.\n\t\t\tconst next = !!el && (el.scrollWidth - el.clientWidth) > 1\n\t\t\tif (next !== this.isScrollable) {\n\t\t\t\tthis.isScrollable = next\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Tear down the overflow observer.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tdisconnectScrollOverflow() {\n\t\t\tif (this._scrollObserver) {\n\t\t\t\tthis._scrollObserver.disconnect()\n\t\t\t\tthis._scrollObserver = null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Resolve a column header label through the consumer's translation\n\t\t * function. Column labels originate from schema property titles\n\t\t * (English canonical source); this makes the rendered header follow\n\t\t * the user's language when the host app provides `cnTranslate`, and\n\t\t * returns the label unchanged when it does not.\n\t\t *\n\t\t * @param {string} label The English source label (schema property title).\n\t\t * @return {string} The translated label, or the input unchanged.\n\t\t */\n\t\ttranslateLabel(label) {\n\t\t\tif (!label) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst fn = typeof this.cnTranslate === 'function' ? this.cnTranslate : (k) => k\n\t\t\treturn fn(label)\n\t\t},\n\n\t\t/**\n\t\t * Self-fetch rows from OpenRegister (register + schemaId mode). Best-effort:\n\t\t * any failure leaves the fetched rows empty. Folded from CnTableWidget.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync fetchData() {\n\t\t\tthis.selfFetchLoading = true\n\t\t\ttry {\n\t\t\t\tconst url = generateUrl('/apps/openregister/api/objects/{register}/{schemaId}', {\n\t\t\t\t\tregister: String(this.register),\n\t\t\t\t\tschemaId: String(this.schemaId),\n\t\t\t\t})\n\t\t\t\tconst { data } = await axios.get(url, {\n\t\t\t\t\theaders: { 'OCS-APIREQUEST': 'true' },\n\t\t\t\t\t...(this.fetchParams ? { params: this.fetchParams } : {}),\n\t\t\t\t})\n\t\t\t\tthis.fetchedRows = (data && data.results) || (Array.isArray(data) ? data : [])\n\t\t\t} catch {\n\t\t\t\tthis.fetchedRows = []\n\t\t\t} finally {\n\t\t\t\tthis.selfFetchLoading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Activate the \"View all\" footer control: emit `view-all`, then push\n\t\t * `viewAllRoute` through the router when there is one. A plain left\n\t\t * click on the link is handled in-app; a modified click (ctrl/cmd/\n\t\t * shift/middle) is left to the browser so \"open in new tab\" keeps\n\t\t * working on the real href.\n\t\t *\n\t\t * @param {MouseEvent} [event] The click event, when triggered by one.\n\t\t * @return {void}\n\t\t */\n\t\tonViewAll(event) {\n\t\t\tconst modified = Boolean(event && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.button))\n\t\t\tif (event && !modified) {\n\t\t\t\tevent.preventDefault()\n\t\t\t}\n\t\t\t/** @event view-all Emitted when the built-in \"View all\" footer control is activated. Payload: the `viewAllRoute` object. */\n\t\t\tthis.$emit('view-all', this.viewAllRoute)\n\t\t\tif (modified) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.viewAllRoute && this.$router) {\n\t\t\t\tthis.$router.push(this.viewAllRoute).catch(() => {})\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Resolve the leading-row icon name for a row. Returns the static\n\t\t * `rowIcon` string, or the result of the `rowIcon(row)` function.\n\t\t *\n\t\t * @param {object} row The row object.\n\t\t * @return {string} The MDI icon name (PascalCase).\n\t\t */\n\t\tgetRowIcon(row) {\n\t\t\treturn typeof this.rowIcon === 'function' ? this.rowIcon(row) : this.rowIcon\n\t\t},\n\n\t\t/**\n\t\t * Get a cell value from a row using dot-notation key.\n\t\t *\n\t\t * OpenRegister system/metadata fields (created, updated, owner, uri,\n\t\t * size, register, schema, ...) live under the object's `@self` block.\n\t\t * For a flat key we fall back to `@self` when the top level has no\n\t\t * value, so sidebar-enabled metadata columns resolve. Top-level fields\n\t\t * always win, keeping existing behaviour unchanged.\n\t\t *\n\t\t * @param {object} row The row data\n\t\t * @param {string} key The column key (supports dot notation: 'address.city')\n\t\t * @return {unknown} The cell value\n\t\t */\n\t\tgetCellValue(row, key) {\n\t\t\tif (typeof key !== 'string') {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tif (key.includes('.')) {\n\t\t\t\treturn key.split('.').reduce((obj, k) => obj?.[k], row)\n\t\t\t}\n\t\t\tif (row?.[key] === undefined && row?.['@self'] && typeof row['@self'] === 'object') {\n\t\t\t\treturn row['@self'][key]\n\t\t\t}\n\t\t\treturn row?.[key]\n\t\t},\n\n\t\t/**\n\t\t * Get the schema property definition for a column key, or `{}` when\n\t\t * there is no schema (manual mode) or no matching property. The result\n\t\t * is handed to `CnCellRenderer` for type-aware rendering; an empty\n\t\t * object makes it fall back to `formatValue()` (plain truncated text).\n\t\t *\n\t\t * @param {string} key Column key\n\t\t * @return {object} Property definition (possibly empty).\n\t\t */\n\t\tgetSchemaProperty(key) {\n\t\t\treturn this.schema?.properties?.[key] || {}\n\t\t},\n\n\t\t/**\n\t\t * Effective property definition handed to CnCellRenderer for a column:\n\t\t * the schema property augmented with the column's own `type`/`format`/\n\t\t * `enum`/`enumLabels` hints. Lets synthesized columns that have no\n\t\t * schema property (e.g. metadata fields with `format: 'date-time'` /\n\t\t * `'uri'`, or a dotted path into a reference this table was never\n\t\t * handed a `:schema` for at all) still get type-aware rendering.\n\t\t * `enumLabels` rides with `enum` rather than getting its own `if`\n\t\t * branch: a column can't usefully declare labels without also\n\t\t * declaring the codes they label.\n\t\t *\n\t\t * @param {object} col Column definition.\n\t\t * @return {object} Property definition for CnCellRenderer.\n\t\t */\n\t\tcolumnProperty(col) {\n\t\t\tconst base = this.getSchemaProperty(col.key)\n\t\t\tif (col && (col.format || col.type || col.enum)) {\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\t...(col.type ? { type: col.type } : {}),\n\t\t\t\t\t...(col.format ? { format: col.format } : {}),\n\t\t\t\t\t...(col.enum ? { enum: col.enum, enumLabels: col.enumLabels || base.enumLabels } : {}),\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn base\n\t\t},\n\n\t\t/**\n\t\t * Declarative cell-format spec handed to CnCellRenderer's `format` prop\n\t\t * (an object: `{ style, currency, decimals, ... }`). `col.format` is\n\t\t * overloaded — for schema-derived columns it is the schema format STRING\n\t\t * (`'date'`, `'uri'`, ...), which is NOT a declarative spec and drives\n\t\t * type-aware rendering via `columnProperty()` instead. Only forward an\n\t\t * object here, so a string schema-format no longer trips CnCellRenderer's\n\t\t * `Object`-typed `format` prop (Vue prop-type warning).\n\t\t *\n\t\t * @param {object} col Column definition.\n\t\t * @return {object|null} The declarative format spec, or null.\n\t\t */\n\t\tcolumnFormat(col) {\n\t\t\treturn (col && typeof col.format === 'object') ? col.format : null\n\t\t},\n\n\t\t/**\n\t\t * Value to render in a cell. For a column that declares `aggregate`\n\t\t * (a count of related objects), returns the cached count once\n\t\t * `loadAggregates()` has resolved it (or `'…'` while pending, `'—'`\n\t\t * if it failed / there's nothing to count). Otherwise the row's\n\t\t * property value via `getCellValue`.\n\t\t *\n\t\t * @param {object} row The row data.\n\t\t * @param {object} col The column definition.\n\t\t * @return {unknown} The value handed to the slot / CnCellRenderer.\n\t\t */\n\t\tcellValue(row, col) {\n\t\t\tif (col && col.aggregate) {\n\t\t\t\tconst cached = this.aggregateValues[String(row[this.rowKey])]\n\t\t\t\tconst v = cached ? cached[col.key] : undefined\n\t\t\t\tif (v === undefined) {\n\t\t\t\t\treturn this.aggregateLoading ? '…' : '—'\n\t\t\t\t}\n\t\t\t\treturn v\n\t\t\t}\n\t\t\treturn this.getCellValue(row, col.key)\n\t\t},\n\n\t\t/**\n\t\t * Interpolate a column's `aggregate.where` map for one row: any string\n\t\t * value of the form `\"@self.<path>\"` is replaced with\n\t\t * `getCellValue(row, path)`; everything else is passed through.\n\t\t *\n\t\t * @param {object} where The `aggregate.where` map (may be undefined).\n\t\t * @param {object} row The parent row.\n\t\t * @return {object} The resolved filter map.\n\t\t */\n\t\tresolveAggregateWhere(where, row) {\n\t\t\tconst out = {}\n\t\t\tfor (const [k, v] of Object.entries(where || {})) {\n\t\t\t\tif (typeof v === 'string' && v.startsWith('@self.')) {\n\t\t\t\t\tout[k] = this.getCellValue(row, v.slice('@self.'.length))\n\t\t\t\t} else {\n\t\t\t\t\tout[k] = v\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out\n\t\t},\n\n\t\t/**\n\t\t * For every column that declares `aggregate` (currently `op: \"count\"`),\n\t\t * issue one `_limit=0` count request per visible row against the related\n\t\t * OpenRegister collection and cache the totals in `aggregateValues`.\n\t\t * Batched with `Promise.all`; a per-request failure degrades that one\n\t\t * cell to `'—'` (logged), never the page. A monotonic request id\n\t\t * discards a stale batch when `rows` / columns change mid-flight.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync loadAggregates() {\n\t\t\tconst aggCols = this.effectiveColumns.filter((c) => c && c.aggregate && c.aggregate.op === 'count')\n\t\t\tif (aggCols.length === 0) {\n\t\t\t\tif (Object.keys(this.aggregateValues).length > 0) {\n\t\t\t\t\tthis.aggregateValues = {}\n\t\t\t\t}\n\t\t\t\tthis.aggregateLoading = false\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst id = ++this.aggregateRequestId\n\t\t\tthis.aggregateLoading = true\n\t\t\tconst next = {}\n\t\t\tconst jobs = []\n\t\t\tfor (const row of this.rows) {\n\t\t\t\tconst rowKey = String(row[this.rowKey])\n\t\t\t\tnext[rowKey] = {}\n\t\t\t\tfor (const col of aggCols) {\n\t\t\t\t\tconst agg = col.aggregate\n\t\t\t\t\tif (!agg.register || !agg.schema) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst where = this.resolveAggregateWhere(agg.where, row)\n\t\t\t\t\tjobs.push(axios.get(generateUrl(`/apps/openregister/api/objects/${agg.register}/${agg.schema}`), {\n\t\t\t\t\t\tparams: { ...where, _limit: 0 },\n\t\t\t\t\t})\n\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\tconst d = res && res.data\n\t\t\t\t\t\t\tnext[rowKey][col.key] = (d && (d.total ?? (Array.isArray(d.results) ? d.results.length : undefined))) ?? 0\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((e) => {\n\t\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\t\tconsole.warn(`[CnDataTable] aggregate \"${col.key}\" count failed for row ${rowKey}`, e)\n\t\t\t\t\t\t\tnext[rowKey][col.key] = undefined\n\t\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait Promise.all(jobs)\n\t\t\tif (id !== this.aggregateRequestId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.aggregateValues = next\n\t\t\tthis.aggregateLoading = false\n\t\t},\n\n\t\tisSelected(row) {\n\t\t\treturn this.selectedIds.includes(row[this.rowKey])\n\t\t},\n\n\t\t/**\n\t\t * Row-body click: toggles selection when `selectable` (ignoring drags),\n\t\t * otherwise emits `row-click` for navigation.\n\t\t *\n\t\t * @param {object} row The clicked row object\n\t\t * @param {MouseEvent} [event] The originating click event.\n\t\t */\n\t\tonRowClick(row, event) {\n\t\t\tif (this.wasDrag(event)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.selectable && !this.rowClickToView) {\n\t\t\t\tthis.toggleSelect(row)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitRowClick(row, event)\n\t\t},\n\n\t\t/**\n\t\t * Row mousedown: record the press for the drag guard, and on a row a\n\t\t * middle click opens, keep the browser from starting autoscroll.\n\t\t *\n\t\t * @param {MouseEvent} event The mousedown event.\n\t\t */\n\t\tonRowMouseDown(event) {\n\t\t\tthis.onPointerDown(event)\n\t\t\tif (!this.selectable || this.rowClickToView) {\n\t\t\t\tpreventMiddleClickAutoscroll(event)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Row-body middle click: emits `row-aux-click`, not `row-click`, so an\n\t\t * existing `row-click` listener that navigates never moves the current\n\t\t * tab away; `rowClickRoute` still opens the row in a new tab. Ignored\n\t\t * for other buttons, nested controls, drags and select-on-click tables.\n\t\t *\n\t\t * @param {object} row The clicked row object\n\t\t * @param {MouseEvent} event The originating auxclick event.\n\t\t */\n\t\tonRowAuxClick(row, event) {\n\t\t\tif (!isRowMiddleClick(event) || this.wasDrag(event)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.selectable && !this.rowClickToView) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event row-aux-click Emitted on a row-body middle click, under the same conditions as `row-click`, so a host can open the row in a new tab (see `openRowTarget`). Payload: `(row, event)` — the clicked row object and the native auxclick event.\n\t\t\t * @type {object} The clicked row object.\n\t\t\t */\n\t\t\tthis.$emit('row-aux-click', row, event)\n\t\t\tthis.followRowClickRoute(row, event)\n\t\t},\n\n\t\t/**\n\t\t * Emit `row-click` and follow `rowClickRoute` when set.\n\t\t *\n\t\t * @param {object} row The clicked row object\n\t\t * @param {MouseEvent} [event] The originating click event.\n\t\t */\n\t\temitRowClick(row, event) {\n\t\t\t/**\n\t\t\t * @event row-click Emitted on a row-body click for navigation. Fires when `selectable` is false, OR when `rowClickToView` is set (selection then happens via the checkbox column). Payload: `(row, event)` — the clicked row object and the native click event, so a host can open the row in a new tab on a ctrl/cmd/shift click (see `openRowTarget`). A middle click emits `row-aux-click` instead.\n\t\t\t * @type {object} The clicked row object.\n\t\t\t */\n\t\t\tthis.$emit('row-click', row, event)\n\t\t\tthis.followRowClickRoute(row, event)\n\t\t},\n\n\t\t/**\n\t\t * Follow `rowClickRoute` for a row click: in place, or in a new tab on\n\t\t * a ctrl/cmd/shift or middle click.\n\t\t *\n\t\t * @param {object} row The clicked row object\n\t\t * @param {MouseEvent} [event] The originating click or auxclick event.\n\t\t */\n\t\tfollowRowClickRoute(row, event) {\n\t\t\t// A new-tab click opens the route in a new tab, unless a listener\n\t\t\t// already did.\n\t\t\tif (this.rowClickRoute && this.$router && !isNewTabHandled(event)) {\n\t\t\t\tconst route = this.rowClickRoute(row)\n\t\t\t\tif (route) {\n\t\t\t\t\tmarkNewTabHandled(event, openRowTarget(event, typeof route === 'string' ? { path: route } : route, this.$router))\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A plain or alt click on a row link routes in place; a new-tab click\n\t\t * is left to the browser, which opens the href itself.\n\t\t *\n\t\t * @param {object} row The row the link belongs to.\n\t\t * @param {MouseEvent} event The click event.\n\t\t */\n\t\tonRowLinkClick(row, event) {\n\t\t\tconst link = this.rowLinks[String(row[this.rowKey])]\n\t\t\tif (!link) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Alt-click on a link downloads it; a row opens like a plain click.\n\t\t\tif (event.altKey && !isNewTabClick(event) && !event.defaultPrevented) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.$router.push(link.target).catch(() => {})\n\t\t\t\treturn\n\t\t\t}\n\t\t\tfollowLinkClick(event, link.target, this.$router)\n\t\t},\n\n\t\t/**\n\t\t * The row link's accessible name: the row's first cell when it holds\n\t\t * plain text, else a generic name.\n\t\t *\n\t\t * @param {object} row The row.\n\t\t * @param {object} col The first data column.\n\t\t * @return {string}\n\t\t */\n\t\trowLinkLabel(row, col) {\n\t\t\tconst value = this.cellValue(row, col)\n\t\t\tif (['string', 'number'].includes(typeof value) && String(value).trim() !== '') {\n\t\t\t\treturn String(value)\n\t\t\t}\n\t\t\treturn t('nextcloud-vue', 'Open row')\n\t\t},\n\n\t\t/**\n\t\t * Row right-click: forward the row + originating event so a host can\n\t\t * open a context menu. The browser menu is prevented, except on a row\n\t\t * link when no host listens, so its link actions stay available.\n\t\t *\n\t\t * @param {object} row The right-clicked row object.\n\t\t * @param {MouseEvent} event The originating contextmenu event.\n\t\t */\n\t\tonRowContextMenu(row, event) {\n\t\t\tconst fromRowLink = event.target?.closest?.('.cn-table-row__link')\n\t\t\t// `$.vnode.props`, not `$attrs`: a declared emit is stripped from `$attrs`.\n\t\t\tif (!fromRowLink || this.$.vnode.props?.onRowContextMenu) {\n\t\t\t\tevent.preventDefault()\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event row-context-menu Emitted on a row right-click (contextmenu) for hosts that render a context menu.\n\t\t\t * @type {{ row: object, event: MouseEvent }}\n\t\t\t */\n\t\t\tthis.$emit('row-context-menu', { row, event })\n\t\t},\n\n\t\t/**\n\t\t * Index of `key` within `effectiveSortKeys`, or -1 when not active.\n\t\t * Used by the template for the arrow, the numbered badge, and aria-sort.\n\t\t *\n\t\t * @param {string} key Column key.\n\t\t * @return {number}\n\t\t */\n\t\tsortKeyIndex(key) {\n\t\t\treturn this.effectiveSortKeys.findIndex((k) => k && k.key === key)\n\t\t},\n\n\t\t/**\n\t\t * `aria-sort` value for a column header: `'ascending'`/`'descending'`\n\t\t * for the PRIMARY (index 0) active sort key only — secondary/tertiary\n\t\t * keys carry the visible numbered badge instead, per WCAG guidance\n\t\t * that `aria-sort` describes single-column sort state. `null` omits\n\t\t * the attribute entirely (unsorted / not sortable).\n\t\t *\n\t\t * @param {object} col Column definition.\n\t\t * @return {string|null}\n\t\t */\n\t\tariaSortFor(col) {\n\t\t\tif (!col.sortable) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst primary = this.effectiveSortKeys[0]\n\t\t\tif (!primary || primary.key !== col.key) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn primary.order === 'asc' ? 'ascending' : 'descending'\n\t\t},\n\n\t\t/**\n\t\t * Header click: plain click = single-sort (existing behavior,\n\t\t * unchanged); shift+click appends/cycles the column as a secondary or\n\t\t * tertiary sort key. See `src/utils/multiColumnSort.js`.\n\t\t *\n\t\t * @param {string} key Column key.\n\t\t * @param {MouseEvent} [event] The originating click event.\n\t\t */\n\t\tonHeaderClick(key, event) {\n\t\t\tthis.applySort(key, !!(event && event.shiftKey))\n\t\t},\n\n\t\t/**\n\t\t * Header keydown: `Enter` = plain click, `Shift+Enter` = shift+click.\n\t\t *\n\t\t * @param {string} key Column key.\n\t\t * @param {KeyboardEvent} event The originating keydown event.\n\t\t */\n\t\tonHeaderKeydown(key, event) {\n\t\t\tif (event.key !== 'Enter') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tevent.preventDefault()\n\t\t\tthis.applySort(key, !!event.shiftKey)\n\t\t},\n\n\t\t/**\n\t\t * Compute and emit the next sort state for a header interaction.\n\t\t *\n\t\t * @param {string} key Column key.\n\t\t * @param {boolean} append `true` for a shift+click/shift+Enter (append/cycle a secondary key).\n\t\t */\n\t\tapplySort(key, append) {\n\t\t\tconst keys = nextSortState(this.effectiveSortKeys, key, { append })\n\t\t\tconst primary = keys[0] || null\n\t\t\t/**\n\t\t\t * @event sort Emitted when a sortable column header is clicked (plain click) or shift-clicked (multi-sort).\n\t\t\t * @type {{ key: string|null, order: 'asc'|'desc'|null, keys: Array<{key: string, order: 'asc'|'desc'}> }}\n\t\t\t * `key`/`order` mirror the PRIMARY (first) active sort key exactly as the pre-multi-sort single-key\n\t\t\t * contract did (`null`/`null` when cleared) — existing listeners destructuring `{ key, order }` are\n\t\t\t * unaffected. `keys` is new: the full ordered list (0 to 3 entries) for multi-sort-aware hosts.\n\t\t\t */\n\t\t\tthis.$emit('sort', {\n\t\t\t\tkey: primary ? primary.key : null,\n\t\t\t\torder: primary ? primary.order : null,\n\t\t\t\tkeys,\n\t\t\t})\n\t\t},\n\n\t\ttoggleSelect(row) {\n\t\t\tconst id = row[this.rowKey]\n\t\t\tconst newIds = this.isSelected(row)\n\t\t\t\t? this.selectedIds.filter((i) => i !== id)\n\t\t\t\t: [...this.selectedIds, id]\n\t\t\t/** @event select Emitted when row selection changes. Payload: array of selected IDs. */\n\t\t\tthis.$emit('select', newIds)\n\t\t},\n\n\t\ttoggleSelectAll() {\n\t\t\tif (this.allSelected) {\n\t\t\t\t// Remove only current page IDs, preserving cross-page selections\n\t\t\t\tconst currentPageIds = new Set(this.rows.map((row) => row[this.rowKey]))\n\t\t\t\tthis.$emit('select', this.selectedIds.filter((id) => !currentPageIds.has(id)))\n\t\t\t} else {\n\t\t\t\t// Add current page IDs to existing selections\n\t\t\t\tconst merged = new Set([...this.selectedIds, ...this.rows.map((row) => row[this.rowKey])])\n\t\t\t\tthis.$emit('select', [...merged])\n\t\t\t}\n\t\t\t/** @event select-all Emitted when select-all checkbox is toggled. */\n\t\t\tthis.$emit('select-all', !this.allSelected)\n\t\t},\n\t},\n}\n</script>\n"],"names":["CnCellRenderer","CnIcon","CnLockIndicator","t","axios"],"mappings":"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"}
|
|
@@ -48,18 +48,19 @@ const _hoisted_16 = {
|
|
|
48
48
|
key: 1,
|
|
49
49
|
class: "cn-table-col--icon"
|
|
50
50
|
};
|
|
51
|
-
const _hoisted_17 =
|
|
52
|
-
|
|
51
|
+
const _hoisted_17 = ["href", "aria-label", "onClick"];
|
|
52
|
+
const _hoisted_18 = {
|
|
53
|
+
key: 2,
|
|
53
54
|
class: "cn-table-row-indicators",
|
|
54
55
|
"data-testid": "cn-row-indicators"
|
|
55
56
|
};
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const
|
|
57
|
+
const _hoisted_19 = ["title", "data-testid"];
|
|
58
|
+
const _hoisted_20 = { class: "hidden-visually" };
|
|
59
|
+
const _hoisted_21 = {
|
|
59
60
|
key: 3,
|
|
60
61
|
class: "cn-data-table__footer"
|
|
61
62
|
};
|
|
62
|
-
const
|
|
63
|
+
const _hoisted_22 = ["href"];
|
|
63
64
|
|
|
64
65
|
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
65
66
|
const _component_NcLoadingIcon = resolveComponent("NcLoadingIcon");
|
|
@@ -167,14 +168,15 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
167
168
|
key: row[$props.rowKey],
|
|
168
169
|
class: normalizeClass(["cn-table-row", [
|
|
169
170
|
$options.isSelected(row) ? 'cn-table-row--selected' : '',
|
|
171
|
+
$options.rowLinks[String(row[$props.rowKey])] ? 'cn-table-row--linked' : '',
|
|
170
172
|
$props.rowClass ? $props.rowClass(row) : '',
|
|
171
173
|
]]),
|
|
172
174
|
"data-testid": "cn-object-row",
|
|
173
175
|
"data-testid-row-id": row[$props.rowKey],
|
|
174
|
-
onMousedown: _cache[5] || (_cache[5] = (...args) => (
|
|
176
|
+
onMousedown: _cache[5] || (_cache[5] = (...args) => ($options.onRowMouseDown && $options.onRowMouseDown(...args))),
|
|
175
177
|
onClick: $event => ($options.onRowClick(row, $event)),
|
|
176
178
|
onAuxclick: $event => ($options.onRowAuxClick(row, $event)),
|
|
177
|
-
onContextmenu:
|
|
179
|
+
onContextmenu: $event => ($options.onRowContextMenu(row, $event))
|
|
178
180
|
}, [
|
|
179
181
|
($props.selectable)
|
|
180
182
|
? (openBlock(), createElementBlock("td", {
|
|
@@ -205,15 +207,26 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
205
207
|
style: normalizeStyle(col.width ? { maxWidth: col.width } : {}),
|
|
206
208
|
onMouseenter: _cache[2] || (_cache[2] = (...args) => ($options.titleWhenClipped && $options.titleWhenClipped(...args)))
|
|
207
209
|
}, [
|
|
210
|
+
(colIndex === 0 && $options.rowLinks[String(row[$props.rowKey])])
|
|
211
|
+
? (openBlock(), createElementBlock("a", {
|
|
212
|
+
key: 0,
|
|
213
|
+
class: "cn-table-row__link",
|
|
214
|
+
href: $options.rowLinks[String(row[$props.rowKey])].href,
|
|
215
|
+
"aria-label": $options.rowLinkLabel(row, col),
|
|
216
|
+
draggable: "false",
|
|
217
|
+
"data-testid": "cn-row-link",
|
|
218
|
+
onClick: $event => ($options.onRowLinkClick(row, $event))
|
|
219
|
+
}, null, 8 /* PROPS */, _hoisted_17))
|
|
220
|
+
: createCommentVNode("v-if", true),
|
|
208
221
|
(colIndex === 0)
|
|
209
222
|
? (openBlock(), createBlock(_component_CnLockIndicator, {
|
|
210
|
-
key:
|
|
223
|
+
key: 1,
|
|
211
224
|
object: row,
|
|
212
225
|
size: 16
|
|
213
226
|
}, null, 8 /* PROPS */, ["object"]))
|
|
214
227
|
: createCommentVNode("v-if", true),
|
|
215
228
|
(colIndex === 0 && $options.indicatorsFor(row).shown.length > 0)
|
|
216
|
-
? (openBlock(), createElementBlock("span",
|
|
229
|
+
? (openBlock(), createElementBlock("span", _hoisted_18, [
|
|
217
230
|
(openBlock(true), createElementBlock(Fragment, null, renderList($options.indicatorsFor(row).shown, (indicator) => {
|
|
218
231
|
return (openBlock(), createElementBlock("span", {
|
|
219
232
|
key: indicator.id || indicator.field,
|
|
@@ -225,8 +238,8 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
225
238
|
name: indicator.icon || 'InformationOutline',
|
|
226
239
|
size: 16
|
|
227
240
|
}, null, 8 /* PROPS */, ["name"]),
|
|
228
|
-
createElementVNode("span",
|
|
229
|
-
], 8 /* PROPS */,
|
|
241
|
+
createElementVNode("span", _hoisted_20, toDisplayString(indicator.text), 1 /* TEXT */)
|
|
242
|
+
], 8 /* PROPS */, _hoisted_19))
|
|
230
243
|
}), 128 /* KEYED_FRAGMENT */))
|
|
231
244
|
]))
|
|
232
245
|
: createCommentVNode("v-if", true),
|
|
@@ -264,7 +277,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
264
277
|
], 2 /* CLASS */)
|
|
265
278
|
], 8 /* PROPS */, _hoisted_5)),
|
|
266
279
|
(_ctx.$slots.footer || ($props.viewAllRoute && $options.totalRowCount > $options.effectiveRows.length))
|
|
267
|
-
? (openBlock(), createElementBlock("div",
|
|
280
|
+
? (openBlock(), createElementBlock("div", _hoisted_21, [
|
|
268
281
|
renderSlot(_ctx.$slots, "footer", {
|
|
269
282
|
total: $options.totalRowCount,
|
|
270
283
|
shown: $options.effectiveRows.length
|
|
@@ -275,7 +288,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
275
288
|
class: "cn-data-table__view-all",
|
|
276
289
|
href: $options.viewAllHref,
|
|
277
290
|
onClick: _cache[6] || (_cache[6] = (...args) => ($options.onViewAll && $options.onViewAll(...args)))
|
|
278
|
-
}, toDisplayString($props.viewAllLabel), 9 /* TEXT, PROPS */,
|
|
291
|
+
}, toDisplayString($props.viewAllLabel), 9 /* TEXT, PROPS */, _hoisted_22))
|
|
279
292
|
: (openBlock(), createElementBlock("button", {
|
|
280
293
|
key: 1,
|
|
281
294
|
type: "button",
|