@conduction/nextcloud-vue 2.85.0 → 2.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue.js +1 -1
- package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue2.js +3 -2
- package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue2.js.map +1 -1
- package/dist/esm/components/CnAdvancedFormDialog/CnMetadataTab.vue3.js.map +1 -1
- package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue.js +1 -1
- package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue2.js +5 -4
- package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue2.js.map +1 -1
- package/dist/esm/components/CnAdvancedFormDialog/CnPropertyValueCell.vue3.js.map +1 -1
- package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue.js +1 -1
- package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue2.js +2 -1
- package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue2.js.map +1 -1
- package/dist/esm/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue3.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue.js +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +2 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue.js +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +156 -14
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +105 -74
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
- package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue.js +1 -1
- package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue2.js +2 -1
- package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue2.js.map +1 -1
- package/dist/esm/components/CnCalendarEventPicker/CnCalendarEventPicker.vue3.js.map +1 -1
- package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue.js +1 -1
- package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue2.js +2 -1
- package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +6 -5
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue.js +1 -1
- package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue2.js +2 -1
- package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue2.js.map +1 -1
- package/dist/esm/components/CnCollectivePagePicker/CnCollectivePagePicker.vue3.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js +2 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -1
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue.js +1 -1
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js +2 -1
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +2 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue.js +1 -1
- package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue2.js +3 -1
- package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue2.js.map +1 -1
- package/dist/esm/components/CnDataMatrix/CnDataMatrix.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailHeaderChips.vue2.js +2 -1
- package/dist/esm/components/CnDetailPage/CnDetailHeaderChips.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailHeaderChips.vue3.js.map +1 -1
- package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue.js +1 -1
- package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue2.js +2 -1
- package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue2.js.map +1 -1
- package/dist/esm/components/CnEmailPicker/CnEmailPicker.vue3.js.map +1 -1
- package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue.js +1 -1
- package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue2.js +3 -1
- package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue2.js.map +1 -1
- package/dist/esm/components/CnFederationStatus/CnFederationStatus.vue3.js.map +1 -1
- package/dist/esm/components/CnFileManager/CnFileManager.vue.js +1 -1
- package/dist/esm/components/CnFileManager/CnFileManager.vue2.js +3 -1
- package/dist/esm/components/CnFileManager/CnFileManager.vue2.js.map +1 -1
- package/dist/esm/components/CnFileManager/CnFileManager.vue3.js.map +1 -1
- package/dist/esm/components/CnFilePreview/CnFilePreview.vue.js +1 -1
- package/dist/esm/components/CnFilePreview/CnFilePreview.vue2.js +2 -1
- package/dist/esm/components/CnFilePreview/CnFilePreview.vue2.js.map +1 -1
- package/dist/esm/components/CnFilePreview/CnFilePreview.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +49 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +3 -3
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue.js +1 -1
- package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue2.js +2 -1
- package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue2.js.map +1 -1
- package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +30 -5
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue.js +1 -1
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue2.js +2 -1
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue2.js.map +1 -1
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue.js +1 -1
- package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue2.js +3 -2
- package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectCalendar/CnObjectCalendar.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue.js +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +28 -0
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js +82 -75
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue.js +1 -1
- package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue2.js +5 -4
- package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue2.js +2 -1
- package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnAuditTrailTab.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue2.js +2 -1
- package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFlowTasksPanel.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js +2 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue2.js +2 -1
- package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnTasksTab.vue3.js.map +1 -1
- package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue.js +1 -1
- package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue2.js +2 -1
- package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue2.js.map +1 -1
- package/dist/esm/components/CnPropertySourceField/CnPropertySourceField.vue3.js.map +1 -1
- package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue.js +1 -1
- package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue2.js +2 -1
- package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue2.js.map +1 -1
- package/dist/esm/components/CnRoadmapItem/CnRoadmapItem.vue3.js.map +1 -1
- package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue2.js +2 -0
- package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue3.js +2 -2
- package/dist/esm/components/CnSchemaFormDialog/CnSchemaFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue.js +1 -1
- package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue2.js +2 -1
- package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue2.js.map +1 -1
- package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue3.js.map +1 -1
- package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue.js +1 -1
- package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue2.js +2 -1
- package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue2.js.map +1 -1
- package/dist/esm/components/CnSummaryAggregates/CnSummaryAggregates.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +36 -0
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +55 -40
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTasksCard/CnTasksCard.vue.js +1 -1
- package/dist/esm/components/CnTasksCard/CnTasksCard.vue2.js +2 -1
- package/dist/esm/components/CnTasksCard/CnTasksCard.vue2.js.map +1 -1
- package/dist/esm/components/CnTasksCard/CnTasksCard.vue3.js.map +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +2 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue.js +1 -1
- package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue2.js +2 -1
- package/dist/esm/components/CnTranslatedBadge/CnTranslatedBadge.vue2.js.map +1 -1
- package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue.js +1 -1
- package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue2.js +2 -1
- package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue2.js.map +1 -1
- package/dist/esm/components/CnVersionHistory/CnVersionHistory.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue.js +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +3 -26
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
- package/dist/esm/dialogs/CnNoteHistoryDialog.vue.js +1 -1
- package/dist/esm/dialogs/CnNoteHistoryDialog.vue2.js +2 -1
- package/dist/esm/dialogs/CnNoteHistoryDialog.vue2.js.map +1 -1
- package/dist/esm/dialogs/CnNoteHistoryDialog.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/activity/CnActivityCard.vue.js +1 -1
- package/dist/esm/integrations/builtin/activity/CnActivityCard.vue2.js +3 -2
- package/dist/esm/integrations/builtin/activity/CnActivityCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/activity/CnActivityCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/activity/CnActivityTab.vue.js +1 -1
- package/dist/esm/integrations/builtin/activity/CnActivityTab.vue2.js +4 -3
- package/dist/esm/integrations/builtin/activity/CnActivityTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/activity/CnActivityTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue.js +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -2
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue.js +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue.js +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue2.js +6 -5
- package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue.js +1 -1
- package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/contactmoment/CnContactmomentCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue.js +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.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue.js +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.map +1 -1
- package/dist/esm/integrations/builtin/email/CnEmailCard.vue.js +1 -1
- package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js +2 -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/field-inspection/CnFieldInspectionCard.vue.js +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue.js +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue.js +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.map +1 -1
- package/dist/esm/l10n/en.json.js +35 -2
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +38 -2
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +1068 -962
- package/dist/esm/store/useObjectStore.js +7 -2
- package/dist/esm/store/useObjectStore.js.map +1 -1
- package/dist/esm/utils/boardColumns.js +50 -1
- package/dist/esm/utils/boardColumns.js.map +1 -1
- package/dist/esm/utils/boardReferenceColumns.js +115 -4
- package/dist/esm/utils/boardReferenceColumns.js.map +1 -1
- package/dist/esm/utils/contentHeaderLink.js +48 -1
- package/dist/esm/utils/contentHeaderLink.js.map +1 -1
- package/dist/esm/utils/schema.js +5 -4
- package/dist/esm/utils/schema.js.map +1 -1
- package/dist/esm/utils/userLocale.js +30 -0
- package/dist/esm/utils/userLocale.js.map +1 -0
- 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 +1088 -476
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +1068 -962
- package/l10n/en.json +35 -2
- package/l10n/nl.json +38 -2
- package/package.json +1 -1
- package/src/components/CnAdvancedFormDialog/CnMetadataTab.vue +3 -2
- package/src/components/CnAdvancedFormDialog/CnPropertyValueCell.vue +5 -4
- package/src/components/CnAnalyticsReportPicker/CnAnalyticsReportPicker.vue +2 -1
- package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +2 -1
- package/src/components/CnBoardView/CnBoardView.vue +189 -24
- package/src/components/CnCalendarEventPicker/CnCalendarEventPicker.vue +2 -1
- package/src/components/CnCalendarWidget/CnCalendarWidget.vue +2 -1
- package/src/components/CnChartWidget/CnChartWidget.vue +6 -5
- package/src/components/CnCollectivePagePicker/CnCollectivePagePicker.vue +2 -1
- package/src/components/CnConversationThread/CnConversationThread.vue +2 -1
- package/src/components/CnCountdownWidget/CnCountdownWidget.vue +2 -1
- package/src/components/CnDashboardPage/CnDashboardPage.vue +2 -1
- package/src/components/CnDataMatrix/CnDataMatrix.vue +2 -1
- package/src/components/CnDetailPage/CnDetailHeaderChips.vue +2 -1
- package/src/components/CnEmailPicker/CnEmailPicker.vue +2 -1
- package/src/components/CnFederationStatus/CnFederationStatus.vue +3 -1
- package/src/components/CnFileManager/CnFileManager.vue +2 -1
- package/src/components/CnFilePreview/CnFilePreview.vue +2 -1
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +54 -6
- package/src/components/CnFollowToggle/CnFollowToggle.vue +2 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +30 -4
- package/src/components/CnNotesCard/CnNotesCard.vue +2 -1
- package/src/components/CnObjectCalendar/CnObjectCalendar.vue +3 -2
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +36 -0
- package/src/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue +5 -4
- package/src/components/CnObjectSidebar/CnAuditTrailTab.vue +2 -1
- package/src/components/CnObjectSidebar/CnFlowTasksPanel.vue +2 -1
- package/src/components/CnObjectSidebar/CnNotesTab.vue +2 -1
- package/src/components/CnObjectSidebar/CnTasksTab.vue +2 -1
- package/src/components/CnPropertySourceField/CnPropertySourceField.vue +2 -1
- package/src/components/CnRoadmapItem/CnRoadmapItem.vue +2 -1
- package/src/components/CnSchemaFormDialog/CnSchemaFormDialog.vue +4 -2
- package/src/components/CnStatsBlock/CnStatsBlock.vue +2 -1
- package/src/components/CnSummaryAggregates/CnSummaryAggregates.vue +2 -1
- package/src/components/CnTabsWidget/CnTabsWidget.vue +71 -0
- package/src/components/CnTasksCard/CnTasksCard.vue +2 -1
- package/src/components/CnTimelineWidget/CnTimelineWidget.vue +2 -1
- package/src/components/CnTranslatedBadge/CnTranslatedBadge.vue +2 -1
- package/src/components/CnVersionHistory/CnVersionHistory.vue +2 -1
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +3 -26
- package/src/css/board.css +40 -0
- package/src/dialogs/CnNoteHistoryDialog.vue +2 -1
- package/src/integrations/builtin/activity/CnActivityCard.vue +3 -2
- package/src/integrations/builtin/activity/CnActivityTab.vue +4 -3
- package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +3 -2
- package/src/integrations/builtin/calendar/CnCalendarCard.vue +2 -1
- package/src/integrations/builtin/calendar/CnCalendarTab.vue +6 -5
- package/src/integrations/builtin/contactmoment/CnContactmomentCard.vue +2 -1
- package/src/integrations/builtin/cospend/CnCospendTab.vue +2 -1
- package/src/integrations/builtin/deck/CnDeckTab.vue +2 -1
- package/src/integrations/builtin/email/CnEmailCard.vue +2 -1
- package/src/integrations/builtin/field-inspection/CnFieldInspectionCard.vue +2 -1
- package/src/integrations/builtin/field-inspection/CnFieldInspectionTab.vue +2 -1
- package/src/integrations/builtin/photos/CnPhotosTab.vue +2 -1
- package/src/schemas/app-manifest-v2.schema.json +4 -1
- package/src/store/useObjectStore.js +7 -2
- package/src/utils/boardColumns.js +49 -0
- package/src/utils/boardReferenceColumns.js +114 -3
- package/src/utils/contentHeaderLink.js +47 -0
- package/src/utils/schema.js +5 -4
- package/src/utils/userLocale.js +26 -0
- package/src/utils/validateManifestV2.compiled.js +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnBoardView.vue2.js","sources":["../../../../src/components/CnBoardView/CnBoardView.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div\n\t\tclass=\"cn-board-view\"\n\t\t:class=\"{ 'cn-board-view--board': isBoardLook, 'cn-board-view--wrap': wrapColumns, 'cn-board-view--selecting': selectedKeys.length > 0 }\"\n\t\tdata-testid=\"cn-board-view\">\n\t\t<p v-if=\"!usable\" class=\"cn-board-view__unusable\" data-testid=\"cn-board-unusable\">\n\t\t\t{{ unusableText }}\n\t\t</p>\n\n\t\t<div\n\t\t\tv-for=\"lane in lanes\"\n\t\t\tv-else\n\t\t\t:key=\"`lane-${lane.key}`\"\n\t\t\tclass=\"cn-board-view__lane\"\n\t\t\tdata-testid=\"cn-board-lane\"\n\t\t\t:data-lane=\"lane.key\">\n\t\t\t<button\n\t\t\t\tv-if=\"lane.key !== ''\"\n\t\t\t\tclass=\"cn-board-view__lane-header\"\n\t\t\t\tdata-testid=\"cn-board-lane-header\"\n\t\t\t\t:aria-expanded=\"String(!isCollapsed(lane.key))\"\n\t\t\t\t@click=\"toggleLane(lane.key)\">\n\t\t\t\t{{ lane.label }} ({{ lane.count }})\n\t\t\t</button>\n\n\t\t\t<div\n\t\t\t\tv-show=\"!isCollapsed(lane.key)\"\n\t\t\t\tclass=\"cn-board-view__columns\"\n\t\t\t\trole=\"list\"\n\t\t\t\t:aria-label=\"lane.key === '' ? boardLabel : lane.label\">\n\t\t\t\t<section\n\t\t\t\t\tv-for=\"column in lane.columns\"\n\t\t\t\t\t:key=\"`col-${lane.key}-${column.key}`\"\n\t\t\t\t\tclass=\"cn-board-view__column\"\n\t\t\t\t\t:class=\"{ 'cn-board-view__column--unreachable': isUnreachable(column) }\"\n\t\t\t\t\trole=\"listitem\"\n\t\t\t\t\tdata-testid=\"cn-board-column\"\n\t\t\t\t\t:data-column=\"column.key\"\n\t\t\t\t\t:data-unreachable=\"isUnreachable(column) ? 'true' : null\"\n\t\t\t\t\t@dragover.prevent\n\t\t\t\t\t@drop=\"onDrop(column, $event)\">\n\t\t\t\t\t<!-- Board look: a dot, the label and a white count badge, with an\n\t\t\t\t\t optional sum line under it (screens-kanban-parity). -->\n\t\t\t\t\t<div v-if=\"isBoardLook\" class=\"cn-board-view__column-head\">\n\t\t\t\t\t\t<h2 class=\"cn-board-view__column-header cn-board-view__column-header--board\">\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"cn-board-view__dot\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-board-dot\"\n\t\t\t\t\t\t\t\t:style=\"{ background: dotColor(column) }\"\n\t\t\t\t\t\t\t\taria-hidden=\"true\" />\n\t\t\t\t\t\t\t<span class=\"cn-board-view__column-title\">{{ column.label }}</span>\n\t\t\t\t\t\t\t<span class=\"cn-board-view__badge\" data-testid=\"cn-board-count\">\n\t\t\t\t\t\t\t\t{{ column.count }}<span v-if=\"paged\" class=\"hidden-visually\"> {{ t('nextcloud-vue', 'on this page') }}</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tv-if=\"columnSum(column) !== ''\"\n\t\t\t\t\t\t\tclass=\"cn-board-view__sum\"\n\t\t\t\t\t\t\tdata-testid=\"cn-board-sum\">\n\t\t\t\t\t\t\t{{ columnSum(column) }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3 v-else class=\"cn-board-view__column-header\">\n\t\t\t\t\t\t{{ column.label }}\n\t\t\t\t\t\t<span class=\"cn-board-view__count\" data-testid=\"cn-board-count\">\n\t\t\t\t\t\t\t{{ countLabel(column) }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</h3>\n\n\t\t\t\t\t<!--\n\t\t\t\t\t\tA list of its own, so a reader is told how many cards\n\t\t\t\t\t\tthis column holds. The column is a listitem of the\n\t\t\t\t\t\tboard's list of columns; the cards are a list inside\n\t\t\t\t\t\tit, not more items of that same list.\n\t\t\t\t\t-->\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-if=\"column.cards.length > 0\"\n\t\t\t\t\t\tclass=\"cn-board-view__cards\"\n\t\t\t\t\t\trole=\"list\"\n\t\t\t\t\t\t:aria-label=\"column.label\">\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\tThe card is a CONTAINER, and every action on it is\n\t\t\t\t\t\t\tits own control. It carries the drag and nothing\n\t\t\t\t\t\t\telse: no tabindex, no click, no key handler, and\n\t\t\t\t\t\t\tnever role=\"button\".\n\n\t\t\t\t\t\t\t🔴 role=\"button\" HERE WOULD BREAK THE MOVE. An\n\t\t\t\t\t\t\telement with that role has presentational children,\n\t\t\t\t\t\t\tso the <select> below would be an interactive\n\t\t\t\t\t\t\tcontrol inside a button. That is invalid, and it\n\t\t\t\t\t\t\ttakes away the only way a keyboard user can move a\n\t\t\t\t\t\t\tcard. It would also collapse every field on the\n\t\t\t\t\t\t\tcard into one button label. See\n\t\t\t\t\t\t\topenspec/changes/board-card-role-and-keyboard.\n\n\t\t\t\t\t\t\tMeasured rather than argued: putting role=\"button\"\n\t\t\t\t\t\t\there makes axe report nested-interactive (serious,\n\t\t\t\t\t\t\t\"Interactive controls must not be nested\") and\n\t\t\t\t\t\t\taria-required-children (critical), and four tests\n\t\t\t\t\t\t\tin tests/a11y/CnBoardView.a11y.spec.js go red.\n\t\t\t\t\t\t\tGate 32 suggests exactly this change. The gate is a\n\t\t\t\t\t\t\tmechanical floor, not the standard.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<article\n\t\t\t\t\t\t\tv-for=\"card in visibleCards(lane, column)\"\n\t\t\t\t\t\t\t:key=\"`card-${cardKey(card)}`\"\n\t\t\t\t\t\t\tclass=\"cn-board-view__card\"\n\t\t\t\t\t\t\t:class=\"[\n\t\t\t\t\t\t\t\tcardDueState(card) ? `cn-board-view__card--${cardDueState(card)}` : null,\n\t\t\t\t\t\t\t\t{ 'cn-board-view__card--board': isBoardLook },\n\t\t\t\t\t\t\t]\"\n\t\t\t\t\t\t\trole=\"listitem\"\n\t\t\t\t\t\t\tdata-testid=\"cn-board-card\"\n\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t:draggable=\"canMove\"\n\t\t\t\t\t\t\t@dragstart=\"onDragStart(card, column, $event)\"\n\t\t\t\t\t\t\t@dragend=\"onDragEnd\"\n\t\t\t\t\t\t\t@keydown=\"onCardKeydown(card, column, lane, $event)\">\n\t\t\t\t\t\t\t<!-- Board look: title link, sub line, pill, footer, and a\n\t\t\t\t\t\t\t menu button instead of the Move to select. -->\n\t\t\t\t\t\t\t<template v-if=\"isBoardLook\">\n\t\t\t\t\t\t\t\t<div class=\"cn-board-view__card-head\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\tv-if=\"selectable\"\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__select\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-select\"\n\t\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t\t:checked=\"isSelected(card)\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"selectLabel(card)\"\n\t\t\t\t\t\t\t\t\t\t@change=\"toggleSelected(card)\">\n\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\thref=\"#\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-title\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-open\"\n\t\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"cardLabel(card, column)\"\n\t\t\t\t\t\t\t\t\t\t@click.prevent=\"openCard(card, $event)\"\n\t\t\t\t\t\t\t\t\t\t@mousedown=\"preventMiddleClickAutoscroll\"\n\t\t\t\t\t\t\t\t\t\t@auxclick=\"onCardAuxClick(card, $event)\">\n\t\t\t\t\t\t\t\t\t\t{{ roleText(card, roles.title) || cardKey(card) }}\n\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t<span class=\"cn-board-view__menu-wrap\">\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu-button\"\n\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-menu\"\n\t\t\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t\t\taria-haspopup=\"menu\"\n\t\t\t\t\t\t\t\t\t\t\t:aria-expanded=\"String(isMenuOpen(card))\"\n\t\t\t\t\t\t\t\t\t\t\t:aria-label=\"menuButtonLabel(card)\"\n\t\t\t\t\t\t\t\t\t\t\t@click=\"toggleMenu(card)\">\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"cn-board-view__menu-dots\" aria-hidden=\"true\">⋯</span>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tv-if=\"isMenuOpen(card)\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu\"\n\t\t\t\t\t\t\t\t\t\t\trole=\"menu\"\n\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-menu-list\"\n\t\t\t\t\t\t\t\t\t\t\t:aria-label=\"menuButtonLabel(card)\"\n\t\t\t\t\t\t\t\t\t\t\t@keydown=\"onMenuKeydown(card, $event)\">\n\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\tv-if=\"canMove\"\n\t\t\t\t\t\t\t\t\t\t\t\trole=\"group\"\n\t\t\t\t\t\t\t\t\t\t\t\t:aria-label=\"moveLabel\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"cn-board-view__menu-heading\" aria-hidden=\"true\">{{ moveLabel }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\tv-for=\"target in moveTargets(lane, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t:key=\"`m-${cardKey(card)}-${target.key}`\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\trole=\"menuitem\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu-item\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-menu-move\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t:data-target=\"target.key\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t:aria-disabled=\"isMoveAllowed(card, target) ? null : 'true'\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t:class=\"{ 'cn-board-view__menu-item--blocked': !isMoveAllowed(card, target) }\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t@click=\"isMoveAllowed(card, target) && onMenuMove(card, column, target)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{{ target.label }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tv-if=\"!isMoveAllowed(card, target)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu-note\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-menu-blocked\">{{ notAllowedLabel }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\trole=\"menuitem\"\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu-item\"\n\t\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-menu-new-tab\"\n\t\t\t\t\t\t\t\t\t\t\t\t@click=\"onMenuOpenNewTab(card)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ openInNewTabLabel }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-if=\"roleText(card, roles.sub) !== ''\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-sub\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-sub\">\n\t\t\t\t\t\t\t\t\t{{ roleText(card, roles.sub) }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-if=\"roleText(card, roles.pill) !== ''\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-pills\">\n\t\t\t\t\t\t\t\t\t<CnStatusBadge\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__pill\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-pill\"\n\t\t\t\t\t\t\t\t\t\t:label=\"roleText(card, roles.pill)\"\n\t\t\t\t\t\t\t\t\t\t:variant=\"pillVariant(card)\" />\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-if=\"dueText(card) !== '' || ownerName(card) !== ''\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-footer\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-footer\">\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__due-text\"\n\t\t\t\t\t\t\t\t\t\t:class=\"cardDueState(card) ? `cn-board-view__due-text--${cardDueState(card)}` : null\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-due\">\n\t\t\t\t\t\t\t\t\t\t{{ dueText(card) }}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tv-if=\"ownerName(card) !== ''\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__avatar\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-owner\"\n\t\t\t\t\t\t\t\t\t\t:title=\"ownerName(card)\"\n\t\t\t\t\t\t\t\t\t\trole=\"img\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"ownerName(card)\">\n\t\t\t\t\t\t\t\t\t\t<span aria-hidden=\"true\">{{ ownerInitials(card) }}</span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template v-else>\n\t\t\t\t\t\t\t\t<label v-if=\"selectable\" class=\"cn-board-view__select-label\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__select\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-select\"\n\t\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t\t:checked=\"isSelected(card)\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"selectLabel(card)\"\n\t\t\t\t\t\t\t\t\t\t@change=\"toggleSelected(card)\">\n\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-if=\"dueLabel(card)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__due\"\n\t\t\t\t\t\t\t\t\t:class=\"`cn-board-view__due--${dueState(card)}`\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-due\">\n\t\t\t\t\t\t\t\t\t{{ dueLabel(card) }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-for=\"field in cardFields\"\n\t\t\t\t\t\t\t\t\t:key=\"`f-${cardKey(card)}-${field}`\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-field\">\n\t\t\t\t\t\t\t\t\t{{ card[field] }}\n\t\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tOpening the card. A native button, so Enter and\n\t\t\t\t\t\t\t\tSpace both work: the old markup handled Enter\n\t\t\t\t\t\t\t\tonly, and Space is what most people try on\n\t\t\t\t\t\t\t\tsomething that looks like a button.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-open\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-open\"\n\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"cardLabel(card, column)\"\n\t\t\t\t\t\t\t\t\t@click=\"openCard(card, $event)\"\n\t\t\t\t\t\t\t\t\t@mousedown=\"preventMiddleClickAutoscroll\"\n\t\t\t\t\t\t\t\t\t@auxclick=\"onCardAuxClick(card, $event)\">\n\t\t\t\t\t\t\t\t\t{{ openLabel }}\n\t\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tThe keyboard's way to do what a drag does. A board\n\t\t\t\t\t\t\t\twhose only move is a drag is a board a keyboard\n\t\t\t\t\t\t\t\tuser cannot use at all, and \"drag the card\" is not\n\t\t\t\t\t\t\t\tan instruction you can follow with a keyboard.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t\t<label v-if=\"canMove\" class=\"cn-board-view__move\">\n\t\t\t\t\t\t\t\t\t<span class=\"cn-board-view__move-label\">{{ moveLabel }}</span>\n\t\t\t\t\t\t\t\t\t<select\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-move\"\n\t\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t\t:value=\"column.key\"\n\t\t\t\t\t\t\t\t\t\t@change=\"onMoveTo(card, column, $event)\">\n\t\t\t\t\t\t\t\t\t\t<option\n\t\t\t\t\t\t\t\t\t\t\tv-for=\"target in lane.columns\"\n\t\t\t\t\t\t\t\t\t\t\t:key=\"`t-${cardKey(card)}-${target.key}`\"\n\t\t\t\t\t\t\t\t\t\t\t:value=\"target.key\">\n\t\t\t\t\t\t\t\t\t\t\t{{ target.label }}\n\t\t\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</article>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\tclass=\"cn-board-view__empty\"\n\t\t\t\t\t\tdata-testid=\"cn-board-column-empty\">\n\t\t\t\t\t\t{{ emptyColumnText }}\n\t\t\t\t\t</p>\n\n\t\t\t\t\t<!-- A column cut by `columnLimit`: the rest behind one dashed\n\t\t\t\t\t button. The badge keeps showing the column's total. -->\n\t\t\t\t\t<button\n\t\t\t\t\t\tv-if=\"hiddenCount(lane, column) > 0\"\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-board-view__show-more\"\n\t\t\t\t\t\tdata-testid=\"cn-board-show-more\"\n\t\t\t\t\t\t@click=\"showMore(lane, column)\">\n\t\t\t\t\t\t{{ showMoreLabel(hiddenCount(lane, column)) }}\n\t\t\t\t\t</button>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<p\n\t\t\tv-if=\"refusal\"\n\t\t\tclass=\"cn-board-view__refusal\"\n\t\t\tdata-testid=\"cn-board-refusal\"\n\t\t\trole=\"alert\">\n\t\t\t{{ refusal }}\n\t\t</p>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport CnStatusBadge from '../CnStatusBadge/CnStatusBadge.vue'\nimport { normalizeLook } from '../../composables/useLook.js'\nimport { isBadgeVariant } from '../../utils/badgeVariants.js'\nimport { buildBoardColumns, resolveStageColor } from '../../utils/boardColumns.js'\nimport { buildSwimlanes } from '../../utils/boardSwimlanes.js'\nimport { DROP_OUTCOMES, runBoardDrop } from '../../utils/boardTransition.js'\nimport { daysUntil, dueStateForRow } from '../../utils/dueRule.js'\nimport { formatMetricValue } from '../../utils/formatMetric.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { isRowMiddleClick, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'\n\nimport '../../css/board.css'\n\n/**\n * CnBoardView — the index page's rows as a board, one column per stage.\n *\n * THE COLUMNS ARE THE SCHEMA'S, NOT THE DATA'S. `buildBoardColumns` decides\n * them and is tested on its own; this renders what it returns. A board that\n * built its columns from the values present would lose the stage nothing is\n * in, which is the one you drag a card into.\n *\n * 🔴 A MOVE GOES THROUGH THE HOST'S TRANSITION AND NEVER WRITES THE STATUS\n * FIELD. Writing it here would skip every guard, side effect and audit entry\n * the transition carries, and the board would become a way to move a case past\n * a rule the case page enforces. `runBoardDrop` owns that contract; this\n * component owns the gestures that reach it.\n *\n * 🔴 THERE ARE TWO GESTURES, ALWAYS. A board whose only move is a drag is a\n * board a keyboard user cannot use, and \"drag the card\" is not an instruction\n * anybody can follow with a keyboard. Move to on the card runs the identical\n * call.\n *\n * @event {object} card-click — A card was opened. Payload: the row.\n * @event {object} moved — A card moved. Payload: `{ card, toKey }`.\n * @event {object} refused — A move was refused. Payload: `{ card, message }`.\n * @event {object} stale — The card had already moved. Payload: `{ card }`.\n */\nexport default {\n\tname: 'CnBoardView',\n\n\tcomponents: { CnStatusBadge },\n\n\tinject: {\n\t\t/**\n\t\t * The look the app is drawn in, provided by CnAppRoot. The board look\n\t\t * draws the screens' board anatomy (screens-kanban-parity).\n\t\t */\n\t\tcnLook: { default: 'nextcloud' },\n\t\t/**\n\t\t * The app's cell-formatter registry, provided by CnAppRoot. A card\n\t\t * role named in `cardRoles.formatters` shows its value through it, as\n\t\t * the table's cells do (screens-board-reference-columns).\n\t\t */\n\t\tcnFormatters: { default: () => ({}) },\n\t},\n\n\tprops: {\n\t\t/** The rows the list holds. */\n\t\trows: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** The status field's schema: its enum or its lifecycle states. */\n\t\tstatusFieldSchema: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The property a row's status lives on. */\n\t\tstatusField: {\n\t\t\ttype: String,\n\t\t\tdefault: 'status',\n\t\t},\n\n\t\t/** The fields a card shows. */\n\t\tcardFields: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** A second field to group the board into rows by. */\n\t\tswimlaneField: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The row key, so a card is identifiable. */\n\t\trowKey: {\n\t\t\ttype: String,\n\t\t\tdefault: 'id',\n\t\t},\n\n\t\t/**\n\t\t * The host's transition. Absent, the board is read-only: no drag, no\n\t\t * Move to, because a gesture that cannot do anything is worse than no\n\t\t * gesture at all.\n\t\t */\n\t\trunTransition: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Re-read one card, to check it has not moved under the dragger. */\n\t\treread: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Whether the counts are of one page. A count of a page shown as\n\t\t * though it were the total is a number somebody quotes in a meeting.\n\t\t */\n\t\tpaged: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Marks late cards: `{ field, soonDays? }`. `field` is the dot-path to\n\t\t * a card's due date. A date before today gets an error edge and the\n\t\t * label \"Overdue\"; a date within `soonDays` (default 3) gets \"Due\n\t\t * soon\" in the warning colour. `null` (the default) marks nothing.\n\t\t *\n\t\t * The same rule shape the table's date cell uses, so a list and its\n\t\t * board agree on what late means.\n\t\t *\n\t\t * @type {{field: string, soonDays?: number}|null}\n\t\t */\n\t\tdueRule: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The board look's card roles (manifest `config.board.card`):\n\t\t * `{ title, sub, pill, due, owner, pillColors? }`. `sub` is a field or\n\t\t * a list of fields joined by a middle dot; `pillColors` maps a pill\n\t\t * value to a badge variant. Missing, the first of `cardFields` is the\n\t\t * title and the rest form the sub line. The Nextcloud look ignores it.\n\t\t *\n\t\t * @type {{title?: string, sub?: string|Array<string>, pill?: string, due?: string, owner?: string, pillColors?: object}|null}\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-card-anatomy\n\t\t */\n\t\tcardRoles: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The field on a column's state that holds its dot colour (manifest\n\t\t * `config.board.colorField`). Empty, the lifecycle state's declared\n\t\t * `color` is used, else the secondary text colour.\n\t\t *\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-column-header\n\t\t */\n\t\tcolorField: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * A numeric field whose sum each column shows under its heading\n\t\t * (manifest `config.board.sumField`). Empty shows no sum line.\n\t\t *\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-column-header\n\t\t */\n\t\tsumField: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * How the sum is formatted, the metric format shape:\n\t\t * `{ style: 'currency', currency: 'EUR', decimals: 2 }`.\n\t\t *\n\t\t * @type {{style?: string, currency?: string, decimals?: number}|null}\n\t\t */\n\t\tsumFormat: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * How many cards a column draws before a \"Show N more\" button\n\t\t * (manifest `config.board.columnLimit`). 0 (the default) draws every\n\t\t * card.\n\t\t *\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-a-long-column-is-cut-with-a-show-more-button\n\t\t */\n\t\tcolumnLimit: {\n\t\t\ttype: Number,\n\t\t\tdefault: 0,\n\t\t},\n\n\t\t/**\n\t\t * The column a row belongs in, for a status whose raw value is not\n\t\t * the column key: a reference whose rows are merged by name\n\t\t * (screens-board-reference-columns). Absent, the row's `statusField`\n\t\t * value is the key.\n\t\t *\n\t\t * @type {((row: object) => string)|null}\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-columns-can-be-the-rows-a-field-references\n\t\t */\n\t\tcolumnKeyOf: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Wrap the columns onto more rows, as many to a row as fit at 240px,\n\t\t * instead of one row that scrolls sideways (manifest\n\t\t * `config.board.wrap`). For a board with more stages than fit.\n\t\t *\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-a-wide-board-can-wrap-its-columns\n\t\t */\n\t\twrapColumns: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Offer a checkbox on every card, so cards can be selected for the\n\t\t * list's bulk actions (the same selection the table holds).\n\t\t *\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-cards-can-be-selected-for-bulk-actions\n\t\t */\n\t\tselectable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * The selected cards, by row key.\n\t\t *\n\t\t * @type {Array<string|number>}\n\t\t */\n\t\tselectedIds: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The columns one card may move to, asked when its menu opens or its\n\t\t * drag starts: `(card) => Promise<Array<string>|null>`, column keys,\n\t\t * `null` for every column. A column the card cannot reach is greyed\n\t\t * during the drag and marked \"not allowed\" in the menu, and a drop on\n\t\t * it is refused without asking the host. Absent, every column is\n\t\t * offered and the host's move decides.\n\t\t *\n\t\t * @type {((card: object) => Promise<Array<string>|null>)|null}\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-the-board-shows-where-a-card-can-go\n\t\t */\n\t\tallowedMoves: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\temits: ['card-click', 'card-aux-click', 'moved', 'refused', 'stale', 'load-more', 'select'],\n\n\tdata() {\n\t\treturn {\n\t\t\t/** Lanes the reader has collapsed, for as long as they are here. */\n\t\t\tcollapsed: [],\n\t\t\t/** The guard's own words, when it refused the last move. */\n\t\t\trefusal: '',\n\t\t\t/** The card being dragged, and where from. */\n\t\t\tdragging: null,\n\t\t\t/** The day late marking measures from. */\n\t\t\ttoday: new Date(),\n\t\t\t/** Columns the reader has expanded past `columnLimit` (lane::column). */\n\t\t\texpanded: [],\n\t\t\t/** The card whose menu is open (board look), by card key. */\n\t\t\topenMenuKey: null,\n\t\t\t/** Column keys each card may move to (`allowedMoves`), by card key; absent = not asked yet. */\n\t\t\tallowedByCard: {},\n\t\t\t/** The column keys the dragged card may reach, or null for all. */\n\t\t\tdragAllowed: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {boolean} Whether the status field can back a board at all. */\n\t\tusable() {\n\t\t\treturn this.board.usable\n\t\t},\n\n\t\t/** @return {object} The columns, from the schema. */\n\t\tboard() {\n\t\t\treturn buildBoardColumns({\n\t\t\t\tfield: this.statusFieldSchema,\n\t\t\t\trows: this.rows,\n\t\t\t\tstatusField: this.statusField,\n\t\t\t\toffBoardLabel: t('nextcloud-vue', 'Elsewhere'),\n\t\t\t\tcolorField: this.colorField,\n\t\t\t\tkeyOf: this.columnKeyOf,\n\t\t\t})\n\t\t},\n\n\t\t/** @return {boolean} Whether the app takes the board look. */\n\t\tisBoardLook() {\n\t\t\treturn normalizeLook(this.cnLook) === 'board'\n\t\t},\n\n\t\t/**\n\t\t * The card's roles: `cardRoles`, else the first of `cardFields` as the\n\t\t * title and the rest as the sub line.\n\t\t *\n\t\t * @return {{title: string, sub: Array<string>, pill: string, due: string, owner: string, pillColors: object}} The roles.\n\t\t */\n\t\troles() {\n\t\t\tconst given = this.cardRoles && typeof this.cardRoles === 'object' ? this.cardRoles : null\n\t\t\tconst fields = Array.isArray(this.cardFields) ? this.cardFields : []\n\t\t\tconst sub = given && given.sub !== undefined\n\t\t\t\t? (Array.isArray(given.sub) ? given.sub : [given.sub])\n\t\t\t\t: (given ? [] : fields.slice(1))\n\t\t\treturn {\n\t\t\t\ttitle: (given && given.title) || fields[0] || '',\n\t\t\t\tsub: sub.filter(Boolean),\n\t\t\t\tpill: (given && given.pill) || '',\n\t\t\t\tdue: (given && given.due) || '',\n\t\t\t\towner: (given && given.owner) || '',\n\t\t\t\tpillColors: (given && given.pillColors) || {},\n\t\t\t\tformatters: (given && given.formatters && typeof given.formatters === 'object') ? given.formatters : {},\n\t\t\t}\n\t\t},\n\n\t\t/** @return {string} The note on a menu target the card cannot reach. */\n\t\tnotAllowedLabel() {\n\t\t\treturn t('nextcloud-vue', 'not allowed')\n\t\t},\n\n\t\t/** @return {Array<string>} The selected row keys as strings. */\n\t\tselectedKeys() {\n\t\t\treturn (Array.isArray(this.selectedIds) ? this.selectedIds : []).map(String)\n\t\t},\n\n\t\t/** @return {string} The Open in new tab menu item. */\n\t\topenInNewTabLabel() {\n\t\t\treturn t('nextcloud-vue', 'Open in new tab')\n\t\t},\n\n\t\t/** @return {Array<object>} The board as rows of columns. */\n\t\tlanes() {\n\t\t\treturn buildSwimlanes({\n\t\t\t\tcolumns: this.board.columns,\n\t\t\t\tswimlaneField: this.swimlaneField,\n\t\t\t\tunassignedLabel: t('nextcloud-vue', 'Unassigned'),\n\t\t\t})\n\t\t},\n\n\t\t/** @return {boolean} Whether a move is possible at all. */\n\t\tcanMove() {\n\t\t\treturn typeof this.runTransition === 'function'\n\t\t},\n\n\t\t/** @return {string} What to say when the field cannot back a board. */\n\t\tunusableText() {\n\t\t\treturn t('nextcloud-vue', 'This list has no status field with stages, so it cannot be shown as a board.')\n\t\t},\n\n\t\t/** @return {string} The board's accessible name. */\n\t\tboardLabel() {\n\t\t\treturn t('nextcloud-vue', 'Board')\n\t\t},\n\n\t\t/** @return {string} The Move to control's label. */\n\t\tmoveLabel() {\n\t\t\treturn t('nextcloud-vue', 'Move to')\n\t\t},\n\n\t\t/**\n\t\t * The visible text on a card's opening control.\n\t\t *\n\t\t * Short, because it repeats on every card. Which card it opens is\n\t\t * said by the control's `aria-label`, so a reader hearing a list of\n\t\t * buttons hears the card's own name rather than \"Open\" nine times.\n\t\t *\n\t\t * @return {string} The label.\n\t\t */\n\t\topenLabel() {\n\t\t\treturn t('nextcloud-vue', 'Open')\n\t\t},\n\n\t\t/** @return {string} What an empty column says. */\n\t\temptyColumnText() {\n\t\t\treturn t('nextcloud-vue', 'Nothing here')\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\tpreventMiddleClickAutoscroll,\n\n\t\t/**\n\t\t * Whether a card is selected.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {boolean} True when selected.\n\t\t */\n\t\tisSelected(card) {\n\t\t\treturn this.selectedKeys.includes(this.cardKey(card))\n\t\t},\n\n\t\t/**\n\t\t * The checkbox's accessible name.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {string} \"Select <name>\".\n\t\t */\n\t\tselectLabel(card) {\n\t\t\tconst name = this.roleText(card, this.roles.title) || this.cardKey(card)\n\t\t\treturn t('nextcloud-vue', 'Select {name}', { name })\n\t\t},\n\n\t\t/**\n\t\t * Select a card, or unselect it.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-cards-can-be-selected-for-bulk-actions\n\t\t */\n\t\ttoggleSelected(card) {\n\t\t\tconst key = this.cardKey(card)\n\t\t\tconst next = this.isSelected(card)\n\t\t\t\t? this.selectedIds.filter((id) => String(id) !== key)\n\t\t\t\t: [...this.selectedIds, card?.[this.rowKey]]\n\t\t\t/**\n\t\t\t * @event select Emitted when a card's checkbox changes. Payload: the selected row keys.\n\t\t\t */\n\t\t\tthis.$emit('select', next)\n\t\t},\n\n\t\t/**\n\t\t * Ask the host where one card may go (`allowedMoves`), once per card.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {Promise<Array<string>|null>} The column keys, or null for all.\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-the-board-shows-where-a-card-can-go\n\t\t */\n\t\tasync loadAllowed(card) {\n\t\t\tif (typeof this.allowedMoves !== 'function') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst key = this.cardKey(card)\n\t\t\tif (Object.hasOwn(this.allowedByCard, key)) {\n\t\t\t\treturn this.allowedByCard[key]\n\t\t\t}\n\t\t\tlet allowed\n\t\t\ttry {\n\t\t\t\tconst answer = await this.allowedMoves(card)\n\t\t\t\tallowed = Array.isArray(answer) ? answer.map(String) : null\n\t\t\t} catch {\n\t\t\t\t// Unknown is not \"nowhere\": the host's move stays the authority.\n\t\t\t\tallowed = null\n\t\t\t}\n\t\t\tthis.allowedByCard = { ...this.allowedByCard, [key]: allowed }\n\t\t\treturn allowed\n\t\t},\n\n\t\t/**\n\t\t * Whether a card may move to a column, as far as the board knows.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {object} target The column.\n\t\t * @return {boolean} False only when the host said it cannot.\n\t\t */\n\t\tisMoveAllowed(card, target) {\n\t\t\tconst allowed = this.allowedByCard[this.cardKey(card)]\n\t\t\treturn !Array.isArray(allowed) || allowed.includes(String(target.key))\n\t\t},\n\n\t\t/**\n\t\t * Whether a column is out of reach for the card being dragged.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {boolean} True while a drag is on and the card cannot go there.\n\t\t */\n\t\tisUnreachable(column) {\n\t\t\treturn this.dragging !== null\n\t\t\t\t&& Array.isArray(this.dragAllowed)\n\t\t\t\t&& column.key !== this.dragging.fromKey\n\t\t\t\t&& !this.dragAllowed.includes(String(column.key))\n\t\t},\n\n\t\t/**\n\t\t * A card's due state under `dueRule`.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {'overdue'|'soon'|'ok'|null} The state, or null when no rule applies.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-late-marking-on-board-cards\n\t\t */\n\t\tdueState(card) {\n\t\t\treturn dueStateForRow(card, this.dueRule, this.today)\n\t\t},\n\n\t\t/**\n\t\t * The due state of a card: in the board look from the card's `due`\n\t\t * role (under `dueRule` when given), else from `dueRule` as before.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {'overdue'|'soon'|'ok'|null} The state.\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-card-anatomy\n\t\t */\n\t\tcardDueState(card) {\n\t\t\tif (this.isBoardLook && this.roles.due !== '') {\n\t\t\t\tconst rule = { ...(this.dueRule || {}), field: this.roles.due }\n\t\t\t\treturn dueStateForRow(card, rule, this.today)\n\t\t\t}\n\t\t\treturn this.dueState(card)\n\t\t},\n\n\t\t/**\n\t\t * The text of one role on a card: a field's value, or a list of\n\t\t * fields joined by a middle dot. An empty value drops out together\n\t\t * with its separator.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @param {string|Array<string>} role The field or fields.\n\t\t * @return {string} The text, '' when every value is empty.\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-card-anatomy\n\t\t */\n\t\troleText(card, role) {\n\t\t\tconst fields = Array.isArray(role) ? role : [role]\n\t\t\treturn fields\n\t\t\t\t.filter((field) => typeof field === 'string' && field !== '')\n\t\t\t\t.map((field) => this.fieldText(card, field))\n\t\t\t\t.filter((value) => value !== '')\n\t\t\t\t.join(' \\u00b7 ')\n\t\t},\n\n\t\t/**\n\t\t * One card field as text: through the formatter `cardRoles.formatters`\n\t\t * names for it, else the value itself.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @param {string} field The dot-path.\n\t\t * @return {string} The text.\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-a-card-field-can-show-through-a-formatter\n\t\t */\n\t\tfieldText(card, field) {\n\t\t\tconst raw = readPath(card, field)\n\t\t\tconst id = this.roles.formatters[field]\n\t\t\tconst fn = id && this.cnFormatters ? this.cnFormatters[id] : null\n\t\t\tif (typeof fn === 'function') {\n\t\t\t\ttry {\n\t\t\t\t\tconst out = fn(raw, card, null)\n\t\t\t\t\treturn out === null || out === undefined ? '' : String(out).trim()\n\t\t\t\t} catch {\n\t\t\t\t\treturn this.textOf(raw)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this.textOf(raw)\n\t\t},\n\n\t\t/**\n\t\t * A value as text: a string or number as is, an object by its label.\n\t\t *\n\t\t * @param {unknown} value The raw value.\n\t\t * @return {string} The text.\n\t\t */\n\t\ttextOf(value) {\n\t\t\tif (value === null || value === undefined) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tif (typeof value === 'object') {\n\t\t\t\tconst named = value.displayName ?? value.name ?? value.label ?? value.title ?? ''\n\t\t\t\treturn String(named).trim()\n\t\t\t}\n\t\t\treturn String(value).trim()\n\t\t},\n\n\t\t/**\n\t\t * The pill's badge variant, from `cardRoles.pillColors`.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {string} A CnStatusBadge variant.\n\t\t */\n\t\tpillVariant(card) {\n\t\t\tconst raw = this.fieldText(card, this.roles.pill)\n\t\t\tconst variant = this.roles.pillColors[raw] ?? this.roles.pillColors[raw.toLowerCase()]\n\t\t\treturn isBadgeVariant(variant) ? variant : 'default'\n\t\t},\n\n\t\t/**\n\t\t * The footer's due text: \"Due today\", \"Due 2 Nov\", or \"Overdue 2 Nov\"\n\t\t * for a date in the past. Words, so the late tone is not colour alone.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {string} The text, '' without a readable date.\n\t\t */\n\t\tdueText(card) {\n\t\t\tif (this.roles.due === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst value = readPath(card, this.roles.due)\n\t\t\tconst days = daysUntil(value, this.today)\n\t\t\tif (days === null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tif (days === 0) {\n\t\t\t\treturn t('nextcloud-vue', 'Due today')\n\t\t\t}\n\t\t\tconst date = new Date(value)\n\t\t\tconst shown = Number.isNaN(date.getTime())\n\t\t\t\t? String(value)\n\t\t\t\t: date.toLocaleDateString(undefined, { day: 'numeric', month: 'short' })\n\t\t\treturn days < 0\n\t\t\t\t? t('nextcloud-vue', 'Overdue {date}', { date: shown })\n\t\t\t\t: t('nextcloud-vue', 'Due {date}', { date: shown })\n\t\t},\n\n\t\t/**\n\t\t * The owner's name.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {string} The name, '' when there is none.\n\t\t */\n\t\townerName(card) {\n\t\t\treturn this.roles.owner === '' ? '' : this.fieldText(card, this.roles.owner)\n\t\t},\n\n\t\t/**\n\t\t * The owner's initials: the first letters of the first two words.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {string} Up to two capital letters.\n\t\t */\n\t\townerInitials(card) {\n\t\t\treturn this.ownerName(card)\n\t\t\t\t.split(/\\s+/)\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.slice(0, 2)\n\t\t\t\t.map((word) => word.charAt(0).toUpperCase())\n\t\t\t\t.join('')\n\t\t},\n\n\t\t/**\n\t\t * The colour of a column's dot.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {string} A CSS colour or variable.\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-column-header\n\t\t */\n\t\tdotColor(column) {\n\t\t\treturn resolveStageColor(column.color)\n\t\t},\n\n\t\t/**\n\t\t * The sum of `sumField` over a column's cards, formatted.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {string} The sum, '' when no `sumField` is set.\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-column-header\n\t\t */\n\t\tcolumnSum(column) {\n\t\t\tif (!this.sumField) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst total = column.cards.reduce((sum, card) => {\n\t\t\t\tconst n = Number(readPath(card, this.sumField))\n\t\t\t\treturn Number.isFinite(n) ? sum + n : sum\n\t\t\t}, 0)\n\t\t\treturn formatMetricValue(total, this.sumFormat || { style: 'decimal', decimals: 0 }, {})\n\t\t},\n\n\t\t/**\n\t\t * The cards a column draws: all of them, or the first `columnLimit`\n\t\t * until the reader shows the rest.\n\t\t *\n\t\t * @param {object} lane The lane.\n\t\t * @param {object} column The column.\n\t\t * @return {Array<object>} The cards.\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-a-long-column-is-cut-with-a-show-more-button\n\t\t */\n\t\tvisibleCards(lane, column) {\n\t\t\tconst limit = Number(this.columnLimit)\n\t\t\tif (!(limit > 0) || this.expanded.includes(this.expandKey(lane, column))) {\n\t\t\t\treturn column.cards\n\t\t\t}\n\t\t\treturn column.cards.slice(0, limit)\n\t\t},\n\n\t\t/**\n\t\t * How many cards of a column are cut.\n\t\t *\n\t\t * @param {object} lane The lane.\n\t\t * @param {object} column The column.\n\t\t * @return {number} The hidden count.\n\t\t */\n\t\thiddenCount(lane, column) {\n\t\t\treturn column.cards.length - this.visibleCards(lane, column).length\n\t\t},\n\n\t\t/**\n\t\t * @param {object} lane The lane.\n\t\t * @param {object} column The column.\n\t\t * @return {string} The key `expanded` holds.\n\t\t */\n\t\texpandKey(lane, column) {\n\t\t\treturn `${lane.key}::${column.key}`\n\t\t},\n\n\t\t/**\n\t\t * The show-more button's text.\n\t\t *\n\t\t * @param {number} count The hidden count.\n\t\t * @return {string} \"Show N more\".\n\t\t */\n\t\tshowMoreLabel(count) {\n\t\t\treturn t('nextcloud-vue', 'Show {count} more', { count })\n\t\t},\n\n\t\t/**\n\t\t * Show the rest of one column. With `paged` the host is also asked\n\t\t * for the column's next page (`load-more`), and the column is\n\t\t * expanded so the rows that arrive show.\n\t\t *\n\t\t * @param {object} lane The lane.\n\t\t * @param {object} column The column.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-a-long-column-is-cut-with-a-show-more-button\n\t\t */\n\t\tshowMore(lane, column) {\n\t\t\tif (this.paged) {\n\t\t\t\t/**\n\t\t\t\t * @event load-more Emitted when the reader presses \"Show N more\" on a paged board. Payload: `{ columnKey }`; the host loads that column's next page.\n\t\t\t\t */\n\t\t\t\tthis.$emit('load-more', { columnKey: column.key })\n\t\t\t}\n\t\t\tthis.expanded = [...this.expanded, this.expandKey(lane, column)]\n\t\t},\n\n\t\t/**\n\t\t * The columns a card can move to: every other column of its lane.\n\t\t *\n\t\t * @param {object} lane The lane.\n\t\t * @param {object} column The card's own column.\n\t\t * @return {Array<object>} The targets.\n\t\t */\n\t\tmoveTargets(lane, column) {\n\t\t\treturn lane.columns.filter((target) => target.key !== column.key)\n\t\t},\n\n\t\t/**\n\t\t * @param {object} card The card.\n\t\t * @return {boolean} Whether its menu is open.\n\t\t */\n\t\tisMenuOpen(card) {\n\t\t\treturn this.openMenuKey === this.cardKey(card)\n\t\t},\n\n\t\t/**\n\t\t * @param {object} card The card.\n\t\t * @return {string} The menu button's accessible name.\n\t\t */\n\t\tmenuButtonLabel(card) {\n\t\t\tconst name = this.roleText(card, this.roles.title) || this.cardKey(card)\n\t\t\treturn t('nextcloud-vue', 'Actions for {name}', { name })\n\t\t},\n\n\t\t/**\n\t\t * Open or close a card's menu, and put focus on its first item.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {void}\n\t\t */\n\t\ttoggleMenu(card) {\n\t\t\tconst key = this.cardKey(card)\n\t\t\tthis.openMenuKey = this.openMenuKey === key ? null : key\n\t\t\tif (this.openMenuKey !== null) {\n\t\t\t\tthis.loadAllowed(card)\n\t\t\t\tthis.focusMenuItem(card, 0)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Close the open menu, optionally returning focus to its button.\n\t\t *\n\t\t * @param {object} [card] The card whose button gets focus back.\n\t\t * @return {void}\n\t\t */\n\t\tcloseMenu(card) {\n\t\t\tthis.openMenuKey = null\n\t\t\tif (card && this.$el && typeof this.$el.querySelector === 'function') {\n\t\t\t\tthis.$nextTick(() => {\n\t\t\t\t\tconst button = this.$el.querySelector(`[data-testid=\"cn-board-card-menu\"][data-card-id=\"${this.cardKey(card)}\"]`)\n\t\t\t\t\tbutton?.focus?.()\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Focus the menu item at an index (opened menus only).\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {number} index The item's position.\n\t\t * @return {void}\n\t\t */\n\t\tfocusMenuItem(card, index) {\n\t\t\tthis.$nextTick(() => {\n\t\t\t\tconst items = this.menuItems(card)\n\t\t\t\tconst item = items[((index % items.length) + items.length) % items.length]\n\t\t\t\titem?.focus?.()\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * @param {object} card The card.\n\t\t * @return {Array<HTMLElement>} The open menu's items.\n\t\t */\n\t\tmenuItems(card) {\n\t\t\tconst article = this.$el?.querySelector?.(`[data-testid=\"cn-board-card\"][data-card-id=\"${this.cardKey(card)}\"]`)\n\t\t\treturn article ? Array.from(article.querySelectorAll('[role=\"menuitem\"]')) : []\n\t\t},\n\n\t\t/**\n\t\t * Keys inside the open menu: arrows move, Escape closes.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {KeyboardEvent} event The key press.\n\t\t * @return {void}\n\t\t */\n\t\tonMenuKeydown(card, event) {\n\t\t\tconst items = this.menuItems(card)\n\t\t\tconst at = items.indexOf(document.activeElement)\n\t\t\tif (event.key === 'Escape') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tthis.closeMenu(card)\n\t\t\t} else if (event.key === 'ArrowDown') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.focusMenuItem(card, at + 1)\n\t\t\t} else if (event.key === 'ArrowUp') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.focusMenuItem(card, at - 1)\n\t\t\t} else if (event.key === 'Tab') {\n\t\t\t\tthis.closeMenu()\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * M on a card, or a control inside it, opens its menu. Only in the\n\t\t * board look and only when the card can move.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {object} column Its column.\n\t\t * @param {object} lane Its lane.\n\t\t * @param {KeyboardEvent} event The key press.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-card-shows-no-form-controls-at-rest\n\t\t */\n\t\tonCardKeydown(card, column, lane, event) {\n\t\t\tif (!this.isBoardLook || !this.canMove) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif ((event.key === 'm' || event.key === 'M') && !event.ctrlKey && !event.metaKey && !event.altKey) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tif (!this.isMenuOpen(card)) {\n\t\t\t\t\tthis.openMenuKey = this.cardKey(card)\n\t\t\t\t\tthis.loadAllowed(card)\n\t\t\t\t\tthis.focusMenuItem(card, 0)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Choose a column from the card's menu: the identical call a drop runs.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {object} column Its column.\n\t\t * @param {object} target The column chosen.\n\t\t * @return {Promise<void>} Nothing.\n\t\t */\n\t\tasync onMenuMove(card, column, target) {\n\t\t\tthis.closeMenu(card)\n\t\t\tawait this.move(card, column.key, target.key)\n\t\t},\n\n\t\t/**\n\t\t * Open the card in a new tab: the same event a ctrl-click emits.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {void}\n\t\t */\n\t\tonMenuOpenNewTab(card) {\n\t\t\tthis.closeMenu(card)\n\t\t\tthis.openCard(card, new MouseEvent('click', { ctrlKey: true, bubbles: true }))\n\t\t},\n\n\t\t/**\n\t\t * The words a late card carries. Colour alone would not reach a reader\n\t\t * who cannot see it, or cannot tell red from amber.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {string} \"Overdue\", \"Due soon\", or '' for a card that is fine.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-late-marking-on-board-cards\n\t\t */\n\t\tdueLabel(card) {\n\t\t\tconst state = this.dueState(card)\n\t\t\tif (state === 'overdue') {\n\t\t\t\treturn t('nextcloud-vue', 'Overdue')\n\t\t\t}\n\t\t\treturn state === 'soon' ? t('nextcloud-vue', 'Due soon') : ''\n\t\t},\n\n\t\t/**\n\t\t * Open one card. The pointer and the keyboard both come through here,\n\t\t * so a reader on Enter reaches the same record as a reader on click.\n\t\t *\n\t\t * @param {object} card The card the reader picked.\n\t\t * @param {MouseEvent|KeyboardEvent} [event] The originating event.\n\t\t * @return {void} Nothing.\n\t\t */\n\t\topenCard(card, event) {\n\t\t\t/**\n\t\t\t * @event card-click Emitted when a reader opens a card, by click or Enter. Payload: `(card, event)` — the card row and the native event, so the host can open it in a new tab on a ctrl/cmd/shift click. A middle click emits `card-aux-click` instead.\n\t\t\t */\n\t\t\tthis.$emit('card-click', card, event)\n\t\t},\n\n\t\t/**\n\t\t * Middle click on a card's open button: emits `card-aux-click`, not\n\t\t * `card-click`, so an existing listener that navigates never moves the\n\t\t * current tab away.\n\t\t *\n\t\t * @param {object} card The card the reader picked.\n\t\t * @param {MouseEvent} event The auxclick event.\n\t\t * @return {void} Nothing.\n\t\t */\n\t\tonCardAuxClick(card, event) {\n\t\t\tif (isRowMiddleClick(event)) {\n\t\t\t\t/**\n\t\t\t\t * @event card-aux-click Emitted when a reader middle-clicks a card, for opening it in a new tab (see `openRowTarget`). Payload: `(card, event)` — the card row and the native auxclick event.\n\t\t\t\t */\n\t\t\t\tthis.$emit('card-aux-click', card, event)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A card's identity.\n\t\t *\n\t\t * @param {object} card The row.\n\t\t * @return {string} Its key.\n\t\t */\n\t\tcardKey(card) {\n\t\t\treturn String(card?.[this.rowKey] ?? '')\n\t\t},\n\n\t\t/**\n\t\t * A column's count, said as a page count when that is what it is.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {string} The count.\n\t\t */\n\t\tcountLabel(column) {\n\t\t\treturn this.paged\n\t\t\t\t? t('nextcloud-vue', '{count} on this page', { count: column.count })\n\t\t\t\t: String(column.count)\n\t\t},\n\n\t\t/**\n\t\t * What a card is called to somebody who cannot see which column it is in.\n\t\t *\n\t\t * @param {object} card The row.\n\t\t * @param {object} column Its column.\n\t\t * @return {string} The accessible name.\n\t\t */\n\t\tcardLabel(card, column) {\n\t\t\tconst name = this.cardFields.map((field) => card?.[field]).filter(Boolean).join(', ')\n\t\t\treturn t('nextcloud-vue', '{name}, in {column}', { name: name || this.cardKey(card), column: column.label })\n\t\t},\n\n\t\t/**\n\t\t * Whether a lane is collapsed.\n\t\t *\n\t\t * @param {string} key The lane.\n\t\t * @return {boolean} True when collapsed.\n\t\t */\n\t\tisCollapsed(key) {\n\t\t\treturn this.collapsed.includes(key)\n\t\t},\n\n\t\t/**\n\t\t * Collapse a lane, or open it again.\n\t\t *\n\t\t * Held in the component for as long as the reader is on the view, and\n\t\t * deliberately not persisted: a collapsed lane somebody forgot they\n\t\t * collapsed is work that has gone missing for them.\n\t\t *\n\t\t * @param {string} key The lane.\n\t\t */\n\t\ttoggleLane(key) {\n\t\t\tthis.collapsed = this.isCollapsed(key)\n\t\t\t\t? this.collapsed.filter((entry) => entry !== key)\n\t\t\t\t: [...this.collapsed, key]\n\t\t},\n\n\t\t/**\n\t\t * Remember which card is being dragged and where from.\n\t\t *\n\t\t * @param {object} card The row.\n\t\t * @param {object} column Its column.\n\t\t * @param {DragEvent} event The event.\n\t\t */\n\t\tonDragStart(card, column, event) {\n\t\t\tthis.dragging = { card, fromKey: column.key }\n\t\t\tthis.dragAllowed = null\n\t\t\t// Firefox drops a drag that carries no data.\n\t\t\tevent?.dataTransfer?.setData?.('text/plain', this.cardKey(card))\n\t\t\tif (typeof this.allowedMoves === 'function') {\n\t\t\t\tthis.loadAllowed(card).then((allowed) => {\n\t\t\t\t\tif (this.dragging && this.dragging.card === card) {\n\t\t\t\t\t\tthis.dragAllowed = allowed\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The drag ended (dropped anywhere, or cancelled): no column stays\n\t\t * greyed. A drop on a column has already run by now.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonDragEnd() {\n\t\t\tthis.dragging = null\n\t\t\tthis.dragAllowed = null\n\t\t},\n\n\t\t/**\n\t\t * A drop on a column.\n\t\t *\n\t\t * @param {object} column The column dropped on.\n\t\t * @return {Promise<void>} Nothing.\n\t\t */\n\t\tasync onDrop(column) {\n\t\t\tif (!this.dragging) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst { card, fromKey } = this.dragging\n\t\t\tthis.dragging = null\n\t\t\tthis.dragAllowed = null\n\t\t\tif (column.key !== fromKey && !this.isMoveAllowed(card, column)) {\n\t\t\t\tconst name = this.roleText(card, this.roles.title) || this.cardKey(card)\n\t\t\t\tthis.refusal = t('nextcloud-vue', '{name} cannot move to {column}.', { name, column: column.label })\n\t\t\t\tthis.$emit('refused', { card, message: this.refusal })\n\t\t\t\treturn\n\t\t\t}\n\t\t\tawait this.move(card, fromKey, column.key)\n\t\t},\n\n\t\t/**\n\t\t * Move to, from the card's own menu.\n\t\t *\n\t\t * @param {object} card The row.\n\t\t * @param {object} column Its column.\n\t\t * @param {Event} event The change event.\n\t\t * @return {Promise<void>} Nothing.\n\t\t */\n\t\tasync onMoveTo(card, column, event) {\n\t\t\tawait this.move(card, column.key, event?.target?.value ?? '')\n\t\t},\n\n\t\t/**\n\t\t * The one move, whichever gesture asked for it.\n\t\t *\n\t\t * @param {object} card The row.\n\t\t * @param {string} fromKey Where it was.\n\t\t * @param {string} toKey Where it is going.\n\t\t * @return {Promise<void>} Nothing.\n\t\t */\n\t\tasync move(card, fromKey, toKey) {\n\t\t\tthis.refusal = ''\n\n\t\t\tconst result = await runBoardDrop({\n\t\t\t\tcard,\n\t\t\t\tfromKey,\n\t\t\t\ttoKey,\n\t\t\t\tstatusField: this.statusField,\n\t\t\t\trunTransition: this.runTransition,\n\t\t\t\treread: this.reread,\n\t\t\t})\n\n\t\t\tif (result.outcome === DROP_OUTCOMES.MOVED) {\n\t\t\t\t/**\n\t\t\t\t * @event moved Emitted when the host's transition accepted the move and the card now sits in the new lane. Payload: `{ card, toKey }`.\n\t\t\t\t */\n\t\t\t\tthis.$emit('moved', { card: result.card, toKey })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (result.outcome === DROP_OUTCOMES.REFUSED) {\n\t\t\t\t// The guard's own sentence when it gave one. Our own only when\n\t\t\t\t// it did not, so the two are never confused.\n\t\t\t\tthis.refusal = result.message || t('nextcloud-vue', 'That move was refused.')\n\t\t\t\t/**\n\t\t\t\t * @event refused Emitted when the guard turned the move down. Payload: `{ card, message }`, the message being the guard's own sentence when it gave one.\n\t\t\t\t */\n\t\t\t\tthis.$emit('refused', { card: result.card, message: this.refusal })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (result.outcome === DROP_OUTCOMES.STALE) {\n\t\t\t\tthis.refusal = t('nextcloud-vue', 'Somebody else moved this card. It is shown where it is now.')\n\t\t\t\t/**\n\t\t\t\t * @event stale Emitted when somebody else moved the card first, so the board shows it where it is now. Payload: `{ card }`.\n\t\t\t\t */\n\t\t\t\tthis.$emit('stale', { card: result.card })\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.cn-board-view__columns {\n\tdisplay: flex;\n\tgap: 12px;\n\toverflow-x: auto;\n\talign-items: flex-start;\n}\n\n.cn-board-view__column {\n\tflex: 0 0 260px;\n\tbackground-color: var(--color-background-hover);\n\tborder-radius: var(--border-radius-large);\n\tpadding: 8px;\n}\n\n.cn-board-view__column-header {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\tgap: 8px;\n\tfont-size: 1rem;\n\tmargin: 0 0 8px;\n}\n\n.cn-board-view__count,\n.cn-board-view__empty,\n.cn-board-view__unusable {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-board-view__card {\n\tdisplay: block;\n\tbackground-color: var(--color-main-background);\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius);\n\tpadding: 8px;\n\tmargin-bottom: 8px;\n}\n\n.cn-board-view__card-field {\n\tdisplay: block;\n}\n\n/* A late card: an edge in the error colour, drawn as an inset shadow so the\n card keeps its size and its rounded corners. The label below carries the\n meaning; the edge only helps a sighted reader find it. */\n.cn-board-view__card--overdue {\n\tborder-color: var(--color-error);\n\tbox-shadow: inset 3px 0 0 var(--color-error);\n}\n\n.cn-board-view__due {\n\tdisplay: block;\n\tfont-size: 0.85em;\n\tfont-weight: 700;\n}\n\n.cn-board-view__due--overdue {\n\tcolor: var(--color-error-text, var(--color-error));\n}\n\n.cn-board-view__due--soon {\n\tcolor: var(--color-warning-text, var(--color-main-text));\n\tfont-weight: 600;\n}\n\n/*\n * The card's opening control. The cursor and the focus ring live here now,\n * on the thing that actually does something, rather than on the box.\n */\n.cn-board-view__card-open {\n\tbackground: none;\n\tborder: none;\n\tpadding: 0;\n\tcursor: pointer;\n\tcolor: var(--color-primary-element);\n\tfont-size: 0.8rem;\n}\n\n.cn-board-view__card-open:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-board-view__lane-header {\n\tbackground: none;\n\tborder: none;\n\tfont-weight: bold;\n\tpadding: 8px 0;\n\tcursor: pointer;\n\tcolor: var(--color-main-text);\n}\n\n.cn-board-view__move-label {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.8rem;\n}\n\n.cn-board-view__refusal {\n\tcolor: var(--color-error);\n}\n</style>\n"],"names":["CnStatusBadge","t"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnBoardView.vue2.js","sources":["../../../../src/components/CnBoardView/CnBoardView.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div\n\t\tclass=\"cn-board-view\"\n\t\t:class=\"{ 'cn-board-view--board': isBoardLook, 'cn-board-view--wrap': wrapColumns, 'cn-board-view--selecting': selectedKeys.length > 0 }\"\n\t\tdata-testid=\"cn-board-view\">\n\t\t<p v-if=\"!usable\" class=\"cn-board-view__unusable\" data-testid=\"cn-board-unusable\">\n\t\t\t{{ unusableText }}\n\t\t</p>\n\n\t\t<div\n\t\t\tv-for=\"lane in lanes\"\n\t\t\tv-else\n\t\t\t:key=\"`lane-${lane.key}`\"\n\t\t\tclass=\"cn-board-view__lane\"\n\t\t\tdata-testid=\"cn-board-lane\"\n\t\t\t:data-lane=\"lane.key\">\n\t\t\t<button\n\t\t\t\tv-if=\"lane.key !== ''\"\n\t\t\t\tclass=\"cn-board-view__lane-header\"\n\t\t\t\tdata-testid=\"cn-board-lane-header\"\n\t\t\t\t:aria-expanded=\"String(!isCollapsed(lane.key))\"\n\t\t\t\t@click=\"toggleLane(lane.key)\">\n\t\t\t\t{{ lane.label }} ({{ lane.count }})\n\t\t\t</button>\n\n\t\t\t<div\n\t\t\t\tv-show=\"!isCollapsed(lane.key)\"\n\t\t\t\tclass=\"cn-board-view__columns\"\n\t\t\t\trole=\"list\"\n\t\t\t\t:aria-label=\"lane.key === '' ? boardLabel : lane.label\">\n\t\t\t\t<section\n\t\t\t\t\tv-for=\"column in lane.columns\"\n\t\t\t\t\t:key=\"`col-${lane.key}-${column.key}`\"\n\t\t\t\t\tclass=\"cn-board-view__column\"\n\t\t\t\t\t:class=\"{ 'cn-board-view__column--unreachable': isUnreachable(column), 'cn-board-view__column--full': isFull(column), 'cn-board-view__column--reason': dragReason(column) !== '' }\"\n\t\t\t\t\trole=\"listitem\"\n\t\t\t\t\tdata-testid=\"cn-board-column\"\n\t\t\t\t\t:data-column=\"column.key\"\n\t\t\t\t\t:data-unreachable=\"isUnreachable(column) ? 'true' : null\"\n\t\t\t\t\t:data-full=\"isFull(column) ? 'true' : null\"\n\t\t\t\t\t@dragover.prevent\n\t\t\t\t\t@drop=\"onDrop(column, $event)\">\n\t\t\t\t\t<!-- Board look: a dot, the label and a white count badge, with an\n\t\t\t\t\t optional sum line under it (screens-kanban-parity). -->\n\t\t\t\t\t<div v-if=\"isBoardLook\" class=\"cn-board-view__column-head\">\n\t\t\t\t\t\t<h2 class=\"cn-board-view__column-header cn-board-view__column-header--board\">\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"cn-board-view__dot\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-board-dot\"\n\t\t\t\t\t\t\t\t:style=\"{ background: dotColor(column) }\"\n\t\t\t\t\t\t\t\taria-hidden=\"true\" />\n\t\t\t\t\t\t\t<span class=\"cn-board-view__column-title\">{{ column.label }}</span>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"cn-board-view__badge\"\n\t\t\t\t\t\t\t\t:class=\"{ 'cn-board-view__badge--full': isFull(column) }\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-board-count\">\n\t\t\t\t\t\t\t\t{{ capacityOf(column) === null ? column.count : capacityText(column) }}<span v-if=\"paged\" class=\"hidden-visually\"> {{ t('nextcloud-vue', 'on this page') }}</span><span v-if=\"isFull(column)\" class=\"hidden-visually\">{{ ' ' + t('nextcloud-vue', 'full') }}</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tv-if=\"columnSum(column) !== ''\"\n\t\t\t\t\t\t\tclass=\"cn-board-view__sum\"\n\t\t\t\t\t\t\tdata-testid=\"cn-board-sum\">\n\t\t\t\t\t\t\t{{ columnSum(column) }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3 v-else class=\"cn-board-view__column-header\">\n\t\t\t\t\t\t{{ column.label }}\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclass=\"cn-board-view__count\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-board-view__count--full': isFull(column) }\"\n\t\t\t\t\t\t\tdata-testid=\"cn-board-count\">\n\t\t\t\t\t\t\t{{ countLabel(column) }}<span v-if=\"isFull(column)\" class=\"hidden-visually\">{{ ' ' + t('nextcloud-vue', 'full') }}</span>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</h3>\n\n\t\t\t\t\t<p\n\t\t\t\t\t\tv-if=\"dragReason(column) !== ''\"\n\t\t\t\t\t\tclass=\"cn-board-view__column-reason\"\n\t\t\t\t\t\tdata-testid=\"cn-board-column-reason\">\n\t\t\t\t\t\t{{ dragReason(column) }}\n\t\t\t\t\t</p>\n\n\t\t\t\t\t<!--\n\t\t\t\t\t\tA list of its own, so a reader is told how many cards\n\t\t\t\t\t\tthis column holds. The column is a listitem of the\n\t\t\t\t\t\tboard's list of columns; the cards are a list inside\n\t\t\t\t\t\tit, not more items of that same list.\n\t\t\t\t\t-->\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-if=\"column.cards.length > 0\"\n\t\t\t\t\t\tclass=\"cn-board-view__cards\"\n\t\t\t\t\t\trole=\"list\"\n\t\t\t\t\t\t:aria-label=\"column.label\">\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\tThe card is a CONTAINER, and every action on it is\n\t\t\t\t\t\t\tits own control. It carries the drag and nothing\n\t\t\t\t\t\t\telse: no tabindex, no click, no key handler, and\n\t\t\t\t\t\t\tnever role=\"button\".\n\n\t\t\t\t\t\t\t🔴 role=\"button\" HERE WOULD BREAK THE MOVE. An\n\t\t\t\t\t\t\telement with that role has presentational children,\n\t\t\t\t\t\t\tso the <select> below would be an interactive\n\t\t\t\t\t\t\tcontrol inside a button. That is invalid, and it\n\t\t\t\t\t\t\ttakes away the only way a keyboard user can move a\n\t\t\t\t\t\t\tcard. It would also collapse every field on the\n\t\t\t\t\t\t\tcard into one button label. See\n\t\t\t\t\t\t\topenspec/changes/board-card-role-and-keyboard.\n\n\t\t\t\t\t\t\tMeasured rather than argued: putting role=\"button\"\n\t\t\t\t\t\t\there makes axe report nested-interactive (serious,\n\t\t\t\t\t\t\t\"Interactive controls must not be nested\") and\n\t\t\t\t\t\t\taria-required-children (critical), and four tests\n\t\t\t\t\t\t\tin tests/a11y/CnBoardView.a11y.spec.js go red.\n\t\t\t\t\t\t\tGate 32 suggests exactly this change. The gate is a\n\t\t\t\t\t\t\tmechanical floor, not the standard.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<article\n\t\t\t\t\t\t\tv-for=\"card in visibleCards(lane, column)\"\n\t\t\t\t\t\t\t:key=\"`card-${cardKey(card)}`\"\n\t\t\t\t\t\t\tclass=\"cn-board-view__card\"\n\t\t\t\t\t\t\t:class=\"[\n\t\t\t\t\t\t\t\tcardDueState(card) ? `cn-board-view__card--${cardDueState(card)}` : null,\n\t\t\t\t\t\t\t\t{ 'cn-board-view__card--board': isBoardLook },\n\t\t\t\t\t\t\t]\"\n\t\t\t\t\t\t\trole=\"listitem\"\n\t\t\t\t\t\t\tdata-testid=\"cn-board-card\"\n\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t:draggable=\"canMove\"\n\t\t\t\t\t\t\t@dragstart=\"onDragStart(card, column, $event)\"\n\t\t\t\t\t\t\t@dragend=\"onDragEnd\"\n\t\t\t\t\t\t\t@keydown=\"onCardKeydown(card, column, lane, $event)\">\n\t\t\t\t\t\t\t<!-- Board look: title link, sub line, pill, footer, and a\n\t\t\t\t\t\t\t menu button instead of the Move to select. -->\n\t\t\t\t\t\t\t<template v-if=\"isBoardLook\">\n\t\t\t\t\t\t\t\t<div class=\"cn-board-view__card-head\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\tv-if=\"selectable\"\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__select\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-select\"\n\t\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t\t:checked=\"isSelected(card)\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"selectLabel(card)\"\n\t\t\t\t\t\t\t\t\t\t@change=\"toggleSelected(card)\">\n\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\thref=\"#\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-title\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-open\"\n\t\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"cardLabel(card, column)\"\n\t\t\t\t\t\t\t\t\t\t@click.prevent=\"openCard(card, $event)\"\n\t\t\t\t\t\t\t\t\t\t@mousedown=\"preventMiddleClickAutoscroll\"\n\t\t\t\t\t\t\t\t\t\t@auxclick=\"onCardAuxClick(card, $event)\">\n\t\t\t\t\t\t\t\t\t\t{{ roleText(card, roles.title) || cardKey(card) }}\n\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t<span class=\"cn-board-view__menu-wrap\">\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu-button\"\n\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-menu\"\n\t\t\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t\t\taria-haspopup=\"menu\"\n\t\t\t\t\t\t\t\t\t\t\t:aria-expanded=\"String(isMenuOpen(card))\"\n\t\t\t\t\t\t\t\t\t\t\t:aria-label=\"menuButtonLabel(card)\"\n\t\t\t\t\t\t\t\t\t\t\t@click=\"toggleMenu(card)\">\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"cn-board-view__menu-dots\" aria-hidden=\"true\">⋯</span>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tv-if=\"isMenuOpen(card)\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu\"\n\t\t\t\t\t\t\t\t\t\t\trole=\"menu\"\n\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-menu-list\"\n\t\t\t\t\t\t\t\t\t\t\t:aria-label=\"menuButtonLabel(card)\"\n\t\t\t\t\t\t\t\t\t\t\t@keydown=\"onMenuKeydown(card, $event)\">\n\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\tv-if=\"canMove\"\n\t\t\t\t\t\t\t\t\t\t\t\trole=\"group\"\n\t\t\t\t\t\t\t\t\t\t\t\t:aria-label=\"moveLabel\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"cn-board-view__menu-heading\" aria-hidden=\"true\">{{ moveLabel }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\tv-for=\"target in moveTargets(lane, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t:key=\"`m-${cardKey(card)}-${target.key}`\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\trole=\"menuitem\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu-item\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-menu-move\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t:data-target=\"target.key\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t:aria-disabled=\"canMoveTo(card, target) ? null : 'true'\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t:class=\"{ 'cn-board-view__menu-item--blocked': !canMoveTo(card, target), 'cn-board-view__menu-item--reason': blockReason(card, target) !== '' }\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t@click=\"canMoveTo(card, target) && onMenuMove(card, column, target)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{{ target.label }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tv-if=\"!canMoveTo(card, target) && blockedNote(card, target) !== ''\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu-note\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-menu-blocked\">{{ blockedNote(card, target) }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tv-if=\"blockReason(card, target) !== ''\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu-reason\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-menu-reason\">{{ blockReason(card, target) }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\trole=\"menuitem\"\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__menu-item\"\n\t\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-menu-new-tab\"\n\t\t\t\t\t\t\t\t\t\t\t\t@click=\"onMenuOpenNewTab(card)\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ openInNewTabLabel }}\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-if=\"roleText(card, roles.sub) !== ''\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-sub\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-sub\">\n\t\t\t\t\t\t\t\t\t{{ roleText(card, roles.sub) }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-if=\"roleText(card, roles.pill) !== ''\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-pills\">\n\t\t\t\t\t\t\t\t\t<CnStatusBadge\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__pill\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-pill\"\n\t\t\t\t\t\t\t\t\t\t:label=\"roleText(card, roles.pill)\"\n\t\t\t\t\t\t\t\t\t\t:variant=\"pillVariant(card)\" />\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-if=\"dueText(card) !== '' || ownerName(card) !== ''\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-footer\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-footer\">\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__due-text\"\n\t\t\t\t\t\t\t\t\t\t:class=\"cardDueState(card) ? `cn-board-view__due-text--${cardDueState(card)}` : null\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-due\">\n\t\t\t\t\t\t\t\t\t\t{{ dueText(card) }}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tv-if=\"ownerName(card) !== ''\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__avatar\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-owner\"\n\t\t\t\t\t\t\t\t\t\t:title=\"ownerName(card)\"\n\t\t\t\t\t\t\t\t\t\trole=\"img\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"ownerName(card)\">\n\t\t\t\t\t\t\t\t\t\t<span aria-hidden=\"true\">{{ ownerInitials(card) }}</span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template v-else>\n\t\t\t\t\t\t\t\t<label v-if=\"selectable\" class=\"cn-board-view__select-label\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__select\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-select\"\n\t\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t\t:checked=\"isSelected(card)\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"selectLabel(card)\"\n\t\t\t\t\t\t\t\t\t\t@change=\"toggleSelected(card)\">\n\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-if=\"dueLabel(card)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__due\"\n\t\t\t\t\t\t\t\t\t:class=\"`cn-board-view__due--${dueState(card)}`\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-due\">\n\t\t\t\t\t\t\t\t\t{{ dueLabel(card) }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-for=\"field in cardFields\"\n\t\t\t\t\t\t\t\t\t:key=\"`f-${cardKey(card)}-${field}`\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-field\">\n\t\t\t\t\t\t\t\t\t{{ card[field] }}\n\t\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tOpening the card. A native button, so Enter and\n\t\t\t\t\t\t\t\tSpace both work: the old markup handled Enter\n\t\t\t\t\t\t\t\tonly, and Space is what most people try on\n\t\t\t\t\t\t\t\tsomething that looks like a button.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-board-view__card-open\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-card-open\"\n\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"cardLabel(card, column)\"\n\t\t\t\t\t\t\t\t\t@click=\"openCard(card, $event)\"\n\t\t\t\t\t\t\t\t\t@mousedown=\"preventMiddleClickAutoscroll\"\n\t\t\t\t\t\t\t\t\t@auxclick=\"onCardAuxClick(card, $event)\">\n\t\t\t\t\t\t\t\t\t{{ openLabel }}\n\t\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tThe keyboard's way to do what a drag does. A board\n\t\t\t\t\t\t\t\twhose only move is a drag is a board a keyboard\n\t\t\t\t\t\t\t\tuser cannot use at all, and \"drag the card\" is not\n\t\t\t\t\t\t\t\tan instruction you can follow with a keyboard.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t\t<label v-if=\"canMove\" class=\"cn-board-view__move\">\n\t\t\t\t\t\t\t\t\t<span class=\"cn-board-view__move-label\">{{ moveLabel }}</span>\n\t\t\t\t\t\t\t\t\t<select\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-board-move\"\n\t\t\t\t\t\t\t\t\t\t:data-card-id=\"cardKey(card)\"\n\t\t\t\t\t\t\t\t\t\t:value=\"column.key\"\n\t\t\t\t\t\t\t\t\t\t@change=\"onMoveTo(card, column, $event)\">\n\t\t\t\t\t\t\t\t\t\t<option\n\t\t\t\t\t\t\t\t\t\t\tv-for=\"target in lane.columns\"\n\t\t\t\t\t\t\t\t\t\t\t:key=\"`t-${cardKey(card)}-${target.key}`\"\n\t\t\t\t\t\t\t\t\t\t\t:value=\"target.key\">\n\t\t\t\t\t\t\t\t\t\t\t{{ target.label }}\n\t\t\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</article>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\tclass=\"cn-board-view__empty\"\n\t\t\t\t\t\tdata-testid=\"cn-board-column-empty\">\n\t\t\t\t\t\t{{ emptyColumnText }}\n\t\t\t\t\t</p>\n\n\t\t\t\t\t<!-- A column cut by `columnLimit`: the rest behind one dashed\n\t\t\t\t\t button. The badge keeps showing the column's total. -->\n\t\t\t\t\t<button\n\t\t\t\t\t\tv-if=\"hiddenCount(lane, column) > 0\"\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-board-view__show-more\"\n\t\t\t\t\t\tdata-testid=\"cn-board-show-more\"\n\t\t\t\t\t\t@click=\"showMore(lane, column)\">\n\t\t\t\t\t\t{{ showMoreLabel(hiddenCount(lane, column)) }}\n\t\t\t\t\t</button>\n\t\t\t\t</section>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<p\n\t\t\tv-if=\"refusal\"\n\t\t\tclass=\"cn-board-view__refusal\"\n\t\t\tdata-testid=\"cn-board-refusal\"\n\t\t\trole=\"alert\">\n\t\t\t{{ refusal }}\n\t\t</p>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport CnStatusBadge from '../CnStatusBadge/CnStatusBadge.vue'\nimport { normalizeLook } from '../../composables/useLook.js'\nimport { isBadgeVariant } from '../../utils/badgeVariants.js'\nimport { buildBoardColumns, normalizeAllowed, resolveStageColor } from '../../utils/boardColumns.js'\nimport { buildSwimlanes } from '../../utils/boardSwimlanes.js'\nimport { DROP_OUTCOMES, runBoardDrop } from '../../utils/boardTransition.js'\nimport { daysUntil, dueStateForRow } from '../../utils/dueRule.js'\nimport { formatMetricValue } from '../../utils/formatMetric.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { isRowMiddleClick, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'\nimport { userLocale } from '../../utils/userLocale.js'\n\nimport '../../css/board.css'\n\n/**\n * CnBoardView — the index page's rows as a board, one column per stage.\n *\n * THE COLUMNS ARE THE SCHEMA'S, NOT THE DATA'S. `buildBoardColumns` decides\n * them and is tested on its own; this renders what it returns. A board that\n * built its columns from the values present would lose the stage nothing is\n * in, which is the one you drag a card into.\n *\n * 🔴 A MOVE GOES THROUGH THE HOST'S TRANSITION AND NEVER WRITES THE STATUS\n * FIELD. Writing it here would skip every guard, side effect and audit entry\n * the transition carries, and the board would become a way to move a case past\n * a rule the case page enforces. `runBoardDrop` owns that contract; this\n * component owns the gestures that reach it.\n *\n * 🔴 THERE ARE TWO GESTURES, ALWAYS. A board whose only move is a drag is a\n * board a keyboard user cannot use, and \"drag the card\" is not an instruction\n * anybody can follow with a keyboard. Move to on the card runs the identical\n * call.\n *\n * @event {object} card-click — A card was opened. Payload: the row.\n * @event {object} moved — A card moved. Payload: `{ card, toKey }`.\n * @event {object} refused — A move was refused. Payload: `{ card, message }`.\n * @event {object} stale — The card had already moved. Payload: `{ card }`.\n */\nexport default {\n\tname: 'CnBoardView',\n\n\tcomponents: { CnStatusBadge },\n\n\tinject: {\n\t\t/**\n\t\t * The look the app is drawn in, provided by CnAppRoot. The board look\n\t\t * draws the screens' board anatomy (screens-kanban-parity).\n\t\t */\n\t\tcnLook: { default: 'nextcloud' },\n\t\t/**\n\t\t * The app's cell-formatter registry, provided by CnAppRoot. A card\n\t\t * role named in `cardRoles.formatters` shows its value through it, as\n\t\t * the table's cells do (screens-board-reference-columns).\n\t\t */\n\t\tcnFormatters: { default: () => ({}) },\n\t},\n\n\tprops: {\n\t\t/** The rows the list holds. */\n\t\trows: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** The status field's schema: its enum or its lifecycle states. */\n\t\tstatusFieldSchema: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The property a row's status lives on. */\n\t\tstatusField: {\n\t\t\ttype: String,\n\t\t\tdefault: 'status',\n\t\t},\n\n\t\t/** The fields a card shows. */\n\t\tcardFields: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** A second field to group the board into rows by. */\n\t\tswimlaneField: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The row key, so a card is identifiable. */\n\t\trowKey: {\n\t\t\ttype: String,\n\t\t\tdefault: 'id',\n\t\t},\n\n\t\t/**\n\t\t * The host's transition. Absent, the board is read-only: no drag, no\n\t\t * Move to, because a gesture that cannot do anything is worse than no\n\t\t * gesture at all.\n\t\t */\n\t\trunTransition: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Re-read one card, to check it has not moved under the dragger. */\n\t\treread: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Whether the counts are of one page. A count of a page shown as\n\t\t * though it were the total is a number somebody quotes in a meeting.\n\t\t */\n\t\tpaged: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Marks late cards: `{ field, soonDays? }`. `field` is the dot-path to\n\t\t * a card's due date. A date before today gets an error edge and the\n\t\t * label \"Overdue\"; a date within `soonDays` (default 3) gets \"Due\n\t\t * soon\" in the warning colour. `null` (the default) marks nothing.\n\t\t *\n\t\t * The same rule shape the table's date cell uses, so a list and its\n\t\t * board agree on what late means.\n\t\t *\n\t\t * @type {{field: string, soonDays?: number}|null}\n\t\t */\n\t\tdueRule: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The board look's card roles (manifest `config.board.card`):\n\t\t * `{ title, sub, pill, due, owner, pillColors? }`. `sub` is a field or\n\t\t * a list of fields joined by a middle dot; `pillColors` maps a pill\n\t\t * value to a badge variant. Missing, the first of `cardFields` is the\n\t\t * title and the rest form the sub line. The Nextcloud look ignores it.\n\t\t *\n\t\t * @type {{title?: string, sub?: string|Array<string>, pill?: string, due?: string, owner?: string, pillColors?: object}|null}\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-card-anatomy\n\t\t */\n\t\tcardRoles: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The field on a column's state that holds its dot colour (manifest\n\t\t * `config.board.colorField`). Empty, the lifecycle state's declared\n\t\t * `color` is used, else the secondary text colour.\n\t\t *\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-column-header\n\t\t */\n\t\tcolorField: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * A numeric field whose sum each column shows under its heading\n\t\t * (manifest `config.board.sumField`). Empty shows no sum line.\n\t\t *\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-column-header\n\t\t */\n\t\tsumField: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * How the sum is formatted, the metric format shape:\n\t\t * `{ style: 'currency', currency: 'EUR', decimals: 2 }`.\n\t\t *\n\t\t * @type {{style?: string, currency?: string, decimals?: number}|null}\n\t\t */\n\t\tsumFormat: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * How many cards a column draws before a \"Show N more\" button\n\t\t * (manifest `config.board.columnLimit`). 0 (the default) draws every\n\t\t * card.\n\t\t *\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-a-long-column-is-cut-with-a-show-more-button\n\t\t */\n\t\tcolumnLimit: {\n\t\t\ttype: Number,\n\t\t\tdefault: 0,\n\t\t},\n\n\t\t/**\n\t\t * The column a row belongs in, for a status whose raw value is not\n\t\t * the column key: a reference whose rows are merged by name\n\t\t * (screens-board-reference-columns). Absent, the row's `statusField`\n\t\t * value is the key.\n\t\t *\n\t\t * @type {((row: object) => string)|null}\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-columns-can-be-the-rows-a-field-references\n\t\t */\n\t\tcolumnKeyOf: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Wrap the columns onto more rows, as many to a row as fit at 240px,\n\t\t * instead of one row that scrolls sideways (manifest\n\t\t * `config.board.wrap`). For a board with more stages than fit.\n\t\t *\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-a-wide-board-can-wrap-its-columns\n\t\t */\n\t\twrapColumns: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Offer a checkbox on every card, so cards can be selected for the\n\t\t * list's bulk actions (the same selection the table holds).\n\t\t *\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-cards-can-be-selected-for-bulk-actions\n\t\t */\n\t\tselectable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * The selected cards, by row key.\n\t\t *\n\t\t * @type {Array<string|number>}\n\t\t */\n\t\tselectedIds: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The columns one card may move to, asked when its menu opens or its\n\t\t * drag starts: `(card) => Promise<Array<string>|null>`, column keys,\n\t\t * `null` for every column. A column the card cannot reach is greyed\n\t\t * during the drag and marked \"not allowed\" in the menu, and a drop on\n\t\t * it is refused without asking the host. Absent, every column is\n\t\t * offered and the host's move decides.\n\t\t *\n\t\t * An entry may also be `{ key, allowed, reason }`. With `allowed:\n\t\t * false` the column is blocked: the menu shows the reason under its\n\t\t * name, the column shows it under its header during a drag, and a\n\t\t * drop there is refused with it.\n\t\t *\n\t\t * @type {((card: object) => Promise<Array<string|{key: string, allowed?: boolean, reason?: string}>|null>)|null}\n\t\t * @spec openspec/changes/board-move-block-reasons/specs/board-view/spec.md#requirement-a-move-target-can-be-blocked-with-a-reason\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-the-board-shows-where-a-card-can-go\n\t\t */\n\t\tallowedMoves: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\temits: ['card-click', 'card-aux-click', 'moved', 'refused', 'stale', 'load-more', 'select'],\n\n\tdata() {\n\t\treturn {\n\t\t\t/** Lanes the reader has collapsed, for as long as they are here. */\n\t\t\tcollapsed: [],\n\t\t\t/** The guard's own words, when it refused the last move. */\n\t\t\trefusal: '',\n\t\t\t/** The card being dragged, and where from. */\n\t\t\tdragging: null,\n\t\t\t/** The day late marking measures from. */\n\t\t\ttoday: new Date(),\n\t\t\t/** Columns the reader has expanded past `columnLimit` (lane::column). */\n\t\t\texpanded: [],\n\t\t\t/** The card whose menu is open (board look), by card key. */\n\t\t\topenMenuKey: null,\n\t\t\t/** Where each card may move (`allowedMoves`), as `{ keys, reasons }` by card key; null = everywhere, absent = not asked yet. */\n\t\t\tallowedByCard: {},\n\t\t\t/** Where the dragged card may move, as `{ keys, reasons }`, or null for everywhere. */\n\t\t\tdragAllowed: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {boolean} Whether the status field can back a board at all. */\n\t\tusable() {\n\t\t\treturn this.board.usable\n\t\t},\n\n\t\t/** @return {object} The columns, from the schema. */\n\t\tboard() {\n\t\t\treturn buildBoardColumns({\n\t\t\t\tfield: this.statusFieldSchema,\n\t\t\t\trows: this.rows,\n\t\t\t\tstatusField: this.statusField,\n\t\t\t\toffBoardLabel: t('nextcloud-vue', 'Elsewhere'),\n\t\t\t\tcolorField: this.colorField,\n\t\t\t\tkeyOf: this.columnKeyOf,\n\t\t\t})\n\t\t},\n\n\t\t/** @return {boolean} Whether the app takes the board look. */\n\t\tisBoardLook() {\n\t\t\treturn normalizeLook(this.cnLook) === 'board'\n\t\t},\n\n\t\t/**\n\t\t * The card's roles: `cardRoles`, else the first of `cardFields` as the\n\t\t * title and the rest as the sub line.\n\t\t *\n\t\t * @return {{title: string, sub: Array<string>, pill: string, due: string, owner: string, pillColors: object}} The roles.\n\t\t */\n\t\troles() {\n\t\t\tconst given = this.cardRoles && typeof this.cardRoles === 'object' ? this.cardRoles : null\n\t\t\tconst fields = Array.isArray(this.cardFields) ? this.cardFields : []\n\t\t\tconst sub = given && given.sub !== undefined\n\t\t\t\t? (Array.isArray(given.sub) ? given.sub : [given.sub])\n\t\t\t\t: (given ? [] : fields.slice(1))\n\t\t\treturn {\n\t\t\t\ttitle: (given && given.title) || fields[0] || '',\n\t\t\t\tsub: sub.filter(Boolean),\n\t\t\t\tpill: (given && given.pill) || '',\n\t\t\t\tdue: (given && given.due) || '',\n\t\t\t\towner: (given && given.owner) || '',\n\t\t\t\tpillColors: (given && given.pillColors) || {},\n\t\t\t\tformatters: (given && given.formatters && typeof given.formatters === 'object') ? given.formatters : {},\n\t\t\t}\n\t\t},\n\n\t\t/** @return {string} The note on a menu target the card cannot reach. */\n\t\tnotAllowedLabel() {\n\t\t\treturn t('nextcloud-vue', 'not allowed')\n\t\t},\n\n\t\t/** @return {string} The note on a menu target that is full. */\n\t\tfullLabel() {\n\t\t\treturn t('nextcloud-vue', 'full')\n\t\t},\n\n\t\t/**\n\t\t * Every column's total over all lanes, by key: what a limit is\n\t\t * measured against, since a swimlane holds only part of a column.\n\t\t *\n\t\t * @return {Map<string, number>} The totals.\n\t\t */\n\t\tcolumnTotals() {\n\t\t\treturn new Map(this.board.columns.map((column) => [String(column.key), column.count]))\n\t\t},\n\n\t\t/** @return {Array<string>} The selected row keys as strings. */\n\t\tselectedKeys() {\n\t\t\treturn (Array.isArray(this.selectedIds) ? this.selectedIds : []).map(String)\n\t\t},\n\n\t\t/** @return {string} The Open in new tab menu item. */\n\t\topenInNewTabLabel() {\n\t\t\treturn t('nextcloud-vue', 'Open in new tab')\n\t\t},\n\n\t\t/** @return {Array<object>} The board as rows of columns. */\n\t\tlanes() {\n\t\t\treturn buildSwimlanes({\n\t\t\t\tcolumns: this.board.columns,\n\t\t\t\tswimlaneField: this.swimlaneField,\n\t\t\t\tunassignedLabel: t('nextcloud-vue', 'Unassigned'),\n\t\t\t})\n\t\t},\n\n\t\t/** @return {boolean} Whether a move is possible at all. */\n\t\tcanMove() {\n\t\t\treturn typeof this.runTransition === 'function'\n\t\t},\n\n\t\t/** @return {string} What to say when the field cannot back a board. */\n\t\tunusableText() {\n\t\t\treturn t('nextcloud-vue', 'This list has no status field with stages, so it cannot be shown as a board.')\n\t\t},\n\n\t\t/** @return {string} The board's accessible name. */\n\t\tboardLabel() {\n\t\t\treturn t('nextcloud-vue', 'Board')\n\t\t},\n\n\t\t/** @return {string} The Move to control's label. */\n\t\tmoveLabel() {\n\t\t\treturn t('nextcloud-vue', 'Move to')\n\t\t},\n\n\t\t/**\n\t\t * The visible text on a card's opening control.\n\t\t *\n\t\t * Short, because it repeats on every card. Which card it opens is\n\t\t * said by the control's `aria-label`, so a reader hearing a list of\n\t\t * buttons hears the card's own name rather than \"Open\" nine times.\n\t\t *\n\t\t * @return {string} The label.\n\t\t */\n\t\topenLabel() {\n\t\t\treturn t('nextcloud-vue', 'Open')\n\t\t},\n\n\t\t/** @return {string} What an empty column says. */\n\t\temptyColumnText() {\n\t\t\treturn t('nextcloud-vue', 'Nothing here')\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\tpreventMiddleClickAutoscroll,\n\n\t\t/**\n\t\t * Whether a card is selected.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {boolean} True when selected.\n\t\t */\n\t\tisSelected(card) {\n\t\t\treturn this.selectedKeys.includes(this.cardKey(card))\n\t\t},\n\n\t\t/**\n\t\t * The checkbox's accessible name.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {string} \"Select <name>\".\n\t\t */\n\t\tselectLabel(card) {\n\t\t\tconst name = this.roleText(card, this.roles.title) || this.cardKey(card)\n\t\t\treturn t('nextcloud-vue', 'Select {name}', { name })\n\t\t},\n\n\t\t/**\n\t\t * Select a card, or unselect it.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-cards-can-be-selected-for-bulk-actions\n\t\t */\n\t\ttoggleSelected(card) {\n\t\t\tconst key = this.cardKey(card)\n\t\t\tconst next = this.isSelected(card)\n\t\t\t\t? this.selectedIds.filter((id) => String(id) !== key)\n\t\t\t\t: [...this.selectedIds, card?.[this.rowKey]]\n\t\t\t/**\n\t\t\t * @event select Emitted when a card's checkbox changes. Payload: the selected row keys.\n\t\t\t */\n\t\t\tthis.$emit('select', next)\n\t\t},\n\n\t\t/**\n\t\t * Ask the host where one card may go (`allowedMoves`), once per card.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {Promise<{keys: Array<string>, reasons: object}|null>} Where it may go, or null for everywhere.\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-the-board-shows-where-a-card-can-go\n\t\t */\n\t\tasync loadAllowed(card) {\n\t\t\tif (typeof this.allowedMoves !== 'function') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst key = this.cardKey(card)\n\t\t\tif (Object.hasOwn(this.allowedByCard, key)) {\n\t\t\t\treturn this.allowedByCard[key]\n\t\t\t}\n\t\t\tlet allowed\n\t\t\ttry {\n\t\t\t\tallowed = normalizeAllowed(await this.allowedMoves(card))\n\t\t\t} catch {\n\t\t\t\t// Unknown is not \"nowhere\": the host's move stays the authority.\n\t\t\t\tallowed = null\n\t\t\t}\n\t\t\tthis.allowedByCard = { ...this.allowedByCard, [key]: allowed }\n\t\t\treturn allowed\n\t\t},\n\n\t\t/**\n\t\t * Whether a card may move to a column, as far as the board knows.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {object} target The column.\n\t\t * @return {boolean} False only when the host said it cannot.\n\t\t */\n\t\tisMoveAllowed(card, target) {\n\t\t\tconst allowed = this.allowedByCard[this.cardKey(card)]\n\t\t\treturn !allowed || allowed.keys.includes(String(target.key))\n\t\t},\n\n\t\t/**\n\t\t * Why the host blocked a card's move to a column, when it said.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {object} target The column.\n\t\t * @return {string} The reason, '' when the move is allowed or no reason was given.\n\t\t * @spec openspec/changes/board-move-block-reasons/specs/board-view/spec.md#requirement-a-move-target-can-be-blocked-with-a-reason\n\t\t */\n\t\tblockReason(card, target) {\n\t\t\tconst allowed = this.allowedByCard[this.cardKey(card)]\n\t\t\tif (!allowed || this.isMoveAllowed(card, target)) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn allowed.reasons[String(target.key)] || ''\n\t\t},\n\n\t\t/**\n\t\t * The note beside a menu target the card cannot move to.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {object} target The column.\n\t\t * @return {string} \"full\" or \"not allowed\"; '' when a reason is shown instead.\n\t\t */\n\t\tblockedNote(card, target) {\n\t\t\tif (this.blockReason(card, target) !== '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn this.isMoveAllowed(card, target) && this.isFull(target) ? this.fullLabel : this.notAllowedLabel\n\t\t},\n\n\t\t/**\n\t\t * Why the dragged card cannot land on a column, shown under its header.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {string} The host's reason while a drag is on, else ''.\n\t\t * @spec openspec/changes/board-move-block-reasons/specs/board-view/spec.md#requirement-a-move-target-can-be-blocked-with-a-reason\n\t\t */\n\t\tdragReason(column) {\n\t\t\tif (this.dragging === null || !this.dragAllowed || column.key === this.dragging.fromKey) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst key = String(column.key)\n\t\t\treturn this.dragAllowed.keys.includes(key) ? '' : (this.dragAllowed.reasons[key] || '')\n\t\t},\n\n\t\t/**\n\t\t * A column's limit.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {number|null} The limit, or null when it has none.\n\t\t * @spec openspec/changes/board-column-capacity/specs/board-view/spec.md#requirement-a-column-can-carry-a-capacity\n\t\t */\n\t\tcapacityOf(column) {\n\t\t\tconst capacity = Number(column?.capacity)\n\t\t\treturn Number.isFinite(capacity) && capacity > 0 ? capacity : null\n\t\t},\n\n\t\t/**\n\t\t * Whether a column holds as many cards as its limit, or more.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {boolean} True when full; false without a limit.\n\t\t * @spec openspec/changes/board-column-capacity/specs/board-view/spec.md#requirement-a-column-can-carry-a-capacity\n\t\t */\n\t\tisFull(column) {\n\t\t\tconst capacity = this.capacityOf(column)\n\t\t\treturn capacity !== null && (this.columnTotals.get(String(column.key)) ?? column.count) >= capacity\n\t\t},\n\n\t\t/**\n\t\t * \"count / capacity\" for a column with a limit.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {string} The text.\n\t\t */\n\t\tcapacityText(column) {\n\t\t\treturn t('nextcloud-vue', '{count} / {capacity}', {\n\t\t\t\tcount: this.columnTotals.get(String(column.key)) ?? column.count,\n\t\t\t\tcapacity: this.capacityOf(column),\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Whether a card may move to a column: the host allows it and the\n\t\t * column is not full.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {object} target The column.\n\t\t * @return {boolean} True when the move may be asked for.\n\t\t * @spec openspec/changes/board-column-capacity/specs/board-view/spec.md#requirement-a-drop-into-a-full-column-is-refused\n\t\t */\n\t\tcanMoveTo(card, target) {\n\t\t\treturn this.isMoveAllowed(card, target) && !this.isFull(target)\n\t\t},\n\n\t\t/**\n\t\t * The sentence a drop into a full column is refused with.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {string} The sentence.\n\t\t */\n\t\tfullRefusal(column) {\n\t\t\treturn t('nextcloud-vue', '{column} is full: {count} of {capacity}.', {\n\t\t\t\tcolumn: column.label,\n\t\t\t\tcount: this.columnTotals.get(String(column.key)) ?? column.count,\n\t\t\t\tcapacity: this.capacityOf(column),\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Whether a column is out of reach for the card being dragged.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {boolean} True while a drag is on and the card cannot go there.\n\t\t */\n\t\tisUnreachable(column) {\n\t\t\tif (this.dragging === null || column.key === this.dragging.fromKey) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn this.isFull(column)\n\t\t\t\t|| (this.dragAllowed !== null && !this.dragAllowed.keys.includes(String(column.key)))\n\t\t},\n\n\t\t/**\n\t\t * A card's due state under `dueRule`.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {'overdue'|'soon'|'ok'|null} The state, or null when no rule applies.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-late-marking-on-board-cards\n\t\t */\n\t\tdueState(card) {\n\t\t\treturn dueStateForRow(card, this.dueRule, this.today)\n\t\t},\n\n\t\t/**\n\t\t * The due state of a card: in the board look from the card's `due`\n\t\t * role (under `dueRule` when given), else from `dueRule` as before.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {'overdue'|'soon'|'ok'|null} The state.\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-card-anatomy\n\t\t */\n\t\tcardDueState(card) {\n\t\t\tif (this.isBoardLook && this.roles.due !== '') {\n\t\t\t\tconst rule = { ...(this.dueRule || {}), field: this.roles.due }\n\t\t\t\treturn dueStateForRow(card, rule, this.today)\n\t\t\t}\n\t\t\treturn this.dueState(card)\n\t\t},\n\n\t\t/**\n\t\t * The text of one role on a card: a field's value, or a list of\n\t\t * fields joined by a middle dot. An empty value drops out together\n\t\t * with its separator.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @param {string|Array<string>} role The field or fields.\n\t\t * @return {string} The text, '' when every value is empty.\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-card-anatomy\n\t\t */\n\t\troleText(card, role) {\n\t\t\tconst fields = Array.isArray(role) ? role : [role]\n\t\t\treturn fields\n\t\t\t\t.filter((field) => typeof field === 'string' && field !== '')\n\t\t\t\t.map((field) => this.fieldText(card, field))\n\t\t\t\t.filter((value) => value !== '')\n\t\t\t\t.join(' \\u00b7 ')\n\t\t},\n\n\t\t/**\n\t\t * One card field as text: through the formatter `cardRoles.formatters`\n\t\t * names for it, else the value itself.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @param {string} field The dot-path.\n\t\t * @return {string} The text.\n\t\t * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-a-card-field-can-show-through-a-formatter\n\t\t */\n\t\tfieldText(card, field) {\n\t\t\tconst raw = readPath(card, field)\n\t\t\tconst id = this.roles.formatters[field]\n\t\t\tconst fn = id && this.cnFormatters ? this.cnFormatters[id] : null\n\t\t\tif (typeof fn === 'function') {\n\t\t\t\ttry {\n\t\t\t\t\tconst out = fn(raw, card, null)\n\t\t\t\t\treturn out === null || out === undefined ? '' : String(out).trim()\n\t\t\t\t} catch {\n\t\t\t\t\treturn this.textOf(raw)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this.textOf(raw)\n\t\t},\n\n\t\t/**\n\t\t * A value as text: a string or number as is, an object by its label.\n\t\t *\n\t\t * @param {unknown} value The raw value.\n\t\t * @return {string} The text.\n\t\t */\n\t\ttextOf(value) {\n\t\t\tif (value === null || value === undefined) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tif (typeof value === 'object') {\n\t\t\t\tconst named = value.displayName ?? value.name ?? value.label ?? value.title ?? ''\n\t\t\t\treturn String(named).trim()\n\t\t\t}\n\t\t\treturn String(value).trim()\n\t\t},\n\n\t\t/**\n\t\t * The pill's badge variant, from `cardRoles.pillColors`.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {string} A CnStatusBadge variant.\n\t\t */\n\t\tpillVariant(card) {\n\t\t\tconst raw = this.fieldText(card, this.roles.pill)\n\t\t\tconst variant = this.roles.pillColors[raw] ?? this.roles.pillColors[raw.toLowerCase()]\n\t\t\treturn isBadgeVariant(variant) ? variant : 'default'\n\t\t},\n\n\t\t/**\n\t\t * The footer's due text: \"Due today\", \"Due 2 Nov\", or \"Overdue 2 Nov\"\n\t\t * for a date in the past. Words, so the late tone is not colour alone.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {string} The text, '' without a readable date.\n\t\t */\n\t\tdueText(card) {\n\t\t\tif (this.roles.due === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst value = readPath(card, this.roles.due)\n\t\t\tconst days = daysUntil(value, this.today)\n\t\t\tif (days === null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tif (days === 0) {\n\t\t\t\treturn t('nextcloud-vue', 'Due today')\n\t\t\t}\n\t\t\tconst date = new Date(value)\n\t\t\tconst shown = Number.isNaN(date.getTime())\n\t\t\t\t? String(value)\n\t\t\t\t: date.toLocaleDateString(userLocale(), { day: 'numeric', month: 'short' })\n\t\t\treturn days < 0\n\t\t\t\t? t('nextcloud-vue', 'Overdue {date}', { date: shown })\n\t\t\t\t: t('nextcloud-vue', 'Due {date}', { date: shown })\n\t\t},\n\n\t\t/**\n\t\t * The owner's name.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {string} The name, '' when there is none.\n\t\t */\n\t\townerName(card) {\n\t\t\treturn this.roles.owner === '' ? '' : this.fieldText(card, this.roles.owner)\n\t\t},\n\n\t\t/**\n\t\t * The owner's initials: the first letters of the first two words.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {string} Up to two capital letters.\n\t\t */\n\t\townerInitials(card) {\n\t\t\treturn this.ownerName(card)\n\t\t\t\t.split(/\\s+/)\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.slice(0, 2)\n\t\t\t\t.map((word) => word.charAt(0).toUpperCase())\n\t\t\t\t.join('')\n\t\t},\n\n\t\t/**\n\t\t * The colour of a column's dot.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {string} A CSS colour or variable.\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-column-header\n\t\t */\n\t\tdotColor(column) {\n\t\t\treturn resolveStageColor(column.color)\n\t\t},\n\n\t\t/**\n\t\t * The sum of `sumField` over a column's cards, formatted.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {string} The sum, '' when no `sumField` is set.\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-board-column-header\n\t\t */\n\t\tcolumnSum(column) {\n\t\t\tif (!this.sumField) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst total = column.cards.reduce((sum, card) => {\n\t\t\t\tconst n = Number(readPath(card, this.sumField))\n\t\t\t\treturn Number.isFinite(n) ? sum + n : sum\n\t\t\t}, 0)\n\t\t\treturn formatMetricValue(total, this.sumFormat || { style: 'decimal', decimals: 0 }, {})\n\t\t},\n\n\t\t/**\n\t\t * The cards a column draws: all of them, or the first `columnLimit`\n\t\t * until the reader shows the rest.\n\t\t *\n\t\t * @param {object} lane The lane.\n\t\t * @param {object} column The column.\n\t\t * @return {Array<object>} The cards.\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-a-long-column-is-cut-with-a-show-more-button\n\t\t */\n\t\tvisibleCards(lane, column) {\n\t\t\tconst limit = Number(this.columnLimit)\n\t\t\tif (!(limit > 0) || this.expanded.includes(this.expandKey(lane, column))) {\n\t\t\t\treturn column.cards\n\t\t\t}\n\t\t\treturn column.cards.slice(0, limit)\n\t\t},\n\n\t\t/**\n\t\t * How many cards of a column are cut.\n\t\t *\n\t\t * @param {object} lane The lane.\n\t\t * @param {object} column The column.\n\t\t * @return {number} The hidden count.\n\t\t */\n\t\thiddenCount(lane, column) {\n\t\t\treturn column.cards.length - this.visibleCards(lane, column).length\n\t\t},\n\n\t\t/**\n\t\t * @param {object} lane The lane.\n\t\t * @param {object} column The column.\n\t\t * @return {string} The key `expanded` holds.\n\t\t */\n\t\texpandKey(lane, column) {\n\t\t\treturn `${lane.key}::${column.key}`\n\t\t},\n\n\t\t/**\n\t\t * The show-more button's text.\n\t\t *\n\t\t * @param {number} count The hidden count.\n\t\t * @return {string} \"Show N more\".\n\t\t */\n\t\tshowMoreLabel(count) {\n\t\t\treturn t('nextcloud-vue', 'Show {count} more', { count })\n\t\t},\n\n\t\t/**\n\t\t * Show the rest of one column. With `paged` the host is also asked\n\t\t * for the column's next page (`load-more`), and the column is\n\t\t * expanded so the rows that arrive show.\n\t\t *\n\t\t * @param {object} lane The lane.\n\t\t * @param {object} column The column.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-a-long-column-is-cut-with-a-show-more-button\n\t\t */\n\t\tshowMore(lane, column) {\n\t\t\tif (this.paged) {\n\t\t\t\t/**\n\t\t\t\t * @event load-more Emitted when the reader presses \"Show N more\" on a paged board. Payload: `{ columnKey }`; the host loads that column's next page.\n\t\t\t\t */\n\t\t\t\tthis.$emit('load-more', { columnKey: column.key })\n\t\t\t}\n\t\t\tthis.expanded = [...this.expanded, this.expandKey(lane, column)]\n\t\t},\n\n\t\t/**\n\t\t * The columns a card can move to: every other column of its lane.\n\t\t *\n\t\t * @param {object} lane The lane.\n\t\t * @param {object} column The card's own column.\n\t\t * @return {Array<object>} The targets.\n\t\t */\n\t\tmoveTargets(lane, column) {\n\t\t\treturn lane.columns.filter((target) => target.key !== column.key)\n\t\t},\n\n\t\t/**\n\t\t * @param {object} card The card.\n\t\t * @return {boolean} Whether its menu is open.\n\t\t */\n\t\tisMenuOpen(card) {\n\t\t\treturn this.openMenuKey === this.cardKey(card)\n\t\t},\n\n\t\t/**\n\t\t * @param {object} card The card.\n\t\t * @return {string} The menu button's accessible name.\n\t\t */\n\t\tmenuButtonLabel(card) {\n\t\t\tconst name = this.roleText(card, this.roles.title) || this.cardKey(card)\n\t\t\treturn t('nextcloud-vue', 'Actions for {name}', { name })\n\t\t},\n\n\t\t/**\n\t\t * Open or close a card's menu, and put focus on its first item.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {void}\n\t\t */\n\t\ttoggleMenu(card) {\n\t\t\tconst key = this.cardKey(card)\n\t\t\tthis.openMenuKey = this.openMenuKey === key ? null : key\n\t\t\tif (this.openMenuKey !== null) {\n\t\t\t\tthis.loadAllowed(card)\n\t\t\t\tthis.focusMenuItem(card, 0)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Close the open menu, optionally returning focus to its button.\n\t\t *\n\t\t * @param {object} [card] The card whose button gets focus back.\n\t\t * @return {void}\n\t\t */\n\t\tcloseMenu(card) {\n\t\t\tthis.openMenuKey = null\n\t\t\tif (card && this.$el && typeof this.$el.querySelector === 'function') {\n\t\t\t\tthis.$nextTick(() => {\n\t\t\t\t\tconst button = this.$el.querySelector(`[data-testid=\"cn-board-card-menu\"][data-card-id=\"${this.cardKey(card)}\"]`)\n\t\t\t\t\tbutton?.focus?.()\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Focus the menu item at an index (opened menus only).\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {number} index The item's position.\n\t\t * @return {void}\n\t\t */\n\t\tfocusMenuItem(card, index) {\n\t\t\tthis.$nextTick(() => {\n\t\t\t\tconst items = this.menuItems(card)\n\t\t\t\tconst item = items[((index % items.length) + items.length) % items.length]\n\t\t\t\titem?.focus?.()\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * @param {object} card The card.\n\t\t * @return {Array<HTMLElement>} The open menu's items.\n\t\t */\n\t\tmenuItems(card) {\n\t\t\tconst article = this.$el?.querySelector?.(`[data-testid=\"cn-board-card\"][data-card-id=\"${this.cardKey(card)}\"]`)\n\t\t\treturn article ? Array.from(article.querySelectorAll('[role=\"menuitem\"]')) : []\n\t\t},\n\n\t\t/**\n\t\t * Keys inside the open menu: arrows move, Escape closes.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {KeyboardEvent} event The key press.\n\t\t * @return {void}\n\t\t */\n\t\tonMenuKeydown(card, event) {\n\t\t\tconst items = this.menuItems(card)\n\t\t\tconst at = items.indexOf(document.activeElement)\n\t\t\tif (event.key === 'Escape') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tthis.closeMenu(card)\n\t\t\t} else if (event.key === 'ArrowDown') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.focusMenuItem(card, at + 1)\n\t\t\t} else if (event.key === 'ArrowUp') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.focusMenuItem(card, at - 1)\n\t\t\t} else if (event.key === 'Tab') {\n\t\t\t\tthis.closeMenu()\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * M on a card, or a control inside it, opens its menu. Only in the\n\t\t * board look and only when the card can move.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {object} column Its column.\n\t\t * @param {object} lane Its lane.\n\t\t * @param {KeyboardEvent} event The key press.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/screens-kanban-parity/specs/board-view/spec.md#requirement-the-card-shows-no-form-controls-at-rest\n\t\t */\n\t\tonCardKeydown(card, column, lane, event) {\n\t\t\tif (!this.isBoardLook || !this.canMove) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif ((event.key === 'm' || event.key === 'M') && !event.ctrlKey && !event.metaKey && !event.altKey) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tif (!this.isMenuOpen(card)) {\n\t\t\t\t\tthis.openMenuKey = this.cardKey(card)\n\t\t\t\t\tthis.loadAllowed(card)\n\t\t\t\t\tthis.focusMenuItem(card, 0)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Choose a column from the card's menu: the identical call a drop runs.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @param {object} column Its column.\n\t\t * @param {object} target The column chosen.\n\t\t * @return {Promise<void>} Nothing.\n\t\t */\n\t\tasync onMenuMove(card, column, target) {\n\t\t\tthis.closeMenu(card)\n\t\t\tawait this.move(card, column.key, target.key)\n\t\t},\n\n\t\t/**\n\t\t * Open the card in a new tab: the same event a ctrl-click emits.\n\t\t *\n\t\t * @param {object} card The card.\n\t\t * @return {void}\n\t\t */\n\t\tonMenuOpenNewTab(card) {\n\t\t\tthis.closeMenu(card)\n\t\t\tthis.openCard(card, new MouseEvent('click', { ctrlKey: true, bubbles: true }))\n\t\t},\n\n\t\t/**\n\t\t * The words a late card carries. Colour alone would not reach a reader\n\t\t * who cannot see it, or cannot tell red from amber.\n\t\t *\n\t\t * @param {object} card The card's row.\n\t\t * @return {string} \"Overdue\", \"Due soon\", or '' for a card that is fine.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-late-marking-on-board-cards\n\t\t */\n\t\tdueLabel(card) {\n\t\t\tconst state = this.dueState(card)\n\t\t\tif (state === 'overdue') {\n\t\t\t\treturn t('nextcloud-vue', 'Overdue')\n\t\t\t}\n\t\t\treturn state === 'soon' ? t('nextcloud-vue', 'Due soon') : ''\n\t\t},\n\n\t\t/**\n\t\t * Open one card. The pointer and the keyboard both come through here,\n\t\t * so a reader on Enter reaches the same record as a reader on click.\n\t\t *\n\t\t * @param {object} card The card the reader picked.\n\t\t * @param {MouseEvent|KeyboardEvent} [event] The originating event.\n\t\t * @return {void} Nothing.\n\t\t */\n\t\topenCard(card, event) {\n\t\t\t/**\n\t\t\t * @event card-click Emitted when a reader opens a card, by click or Enter. Payload: `(card, event)` — the card row and the native event, so the host can open it in a new tab on a ctrl/cmd/shift click. A middle click emits `card-aux-click` instead.\n\t\t\t */\n\t\t\tthis.$emit('card-click', card, event)\n\t\t},\n\n\t\t/**\n\t\t * Middle click on a card's open button: emits `card-aux-click`, not\n\t\t * `card-click`, so an existing listener that navigates never moves the\n\t\t * current tab away.\n\t\t *\n\t\t * @param {object} card The card the reader picked.\n\t\t * @param {MouseEvent} event The auxclick event.\n\t\t * @return {void} Nothing.\n\t\t */\n\t\tonCardAuxClick(card, event) {\n\t\t\tif (isRowMiddleClick(event)) {\n\t\t\t\t/**\n\t\t\t\t * @event card-aux-click Emitted when a reader middle-clicks a card, for opening it in a new tab (see `openRowTarget`). Payload: `(card, event)` — the card row and the native auxclick event.\n\t\t\t\t */\n\t\t\t\tthis.$emit('card-aux-click', card, event)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A card's identity.\n\t\t *\n\t\t * @param {object} card The row.\n\t\t * @return {string} Its key.\n\t\t */\n\t\tcardKey(card) {\n\t\t\treturn String(card?.[this.rowKey] ?? '')\n\t\t},\n\n\t\t/**\n\t\t * A column's count, said as a page count when that is what it is.\n\t\t *\n\t\t * @param {object} column The column.\n\t\t * @return {string} The count.\n\t\t */\n\t\tcountLabel(column) {\n\t\t\tif (this.capacityOf(column) !== null) {\n\t\t\t\treturn this.capacityText(column)\n\t\t\t}\n\t\t\treturn this.paged\n\t\t\t\t? t('nextcloud-vue', '{count} on this page', { count: column.count })\n\t\t\t\t: String(column.count)\n\t\t},\n\n\t\t/**\n\t\t * What a card is called to somebody who cannot see which column it is in.\n\t\t *\n\t\t * @param {object} card The row.\n\t\t * @param {object} column Its column.\n\t\t * @return {string} The accessible name.\n\t\t */\n\t\tcardLabel(card, column) {\n\t\t\tconst name = this.cardFields.map((field) => card?.[field]).filter(Boolean).join(', ')\n\t\t\treturn t('nextcloud-vue', '{name}, in {column}', { name: name || this.cardKey(card), column: column.label })\n\t\t},\n\n\t\t/**\n\t\t * Whether a lane is collapsed.\n\t\t *\n\t\t * @param {string} key The lane.\n\t\t * @return {boolean} True when collapsed.\n\t\t */\n\t\tisCollapsed(key) {\n\t\t\treturn this.collapsed.includes(key)\n\t\t},\n\n\t\t/**\n\t\t * Collapse a lane, or open it again.\n\t\t *\n\t\t * Held in the component for as long as the reader is on the view, and\n\t\t * deliberately not persisted: a collapsed lane somebody forgot they\n\t\t * collapsed is work that has gone missing for them.\n\t\t *\n\t\t * @param {string} key The lane.\n\t\t */\n\t\ttoggleLane(key) {\n\t\t\tthis.collapsed = this.isCollapsed(key)\n\t\t\t\t? this.collapsed.filter((entry) => entry !== key)\n\t\t\t\t: [...this.collapsed, key]\n\t\t},\n\n\t\t/**\n\t\t * Remember which card is being dragged and where from.\n\t\t *\n\t\t * @param {object} card The row.\n\t\t * @param {object} column Its column.\n\t\t * @param {DragEvent} event The event.\n\t\t */\n\t\tonDragStart(card, column, event) {\n\t\t\tthis.dragging = { card, fromKey: column.key }\n\t\t\tthis.dragAllowed = null\n\t\t\t// Firefox drops a drag that carries no data.\n\t\t\tevent?.dataTransfer?.setData?.('text/plain', this.cardKey(card))\n\t\t\tif (typeof this.allowedMoves === 'function') {\n\t\t\t\tthis.loadAllowed(card).then((allowed) => {\n\t\t\t\t\tif (this.dragging && this.dragging.card === card) {\n\t\t\t\t\t\tthis.dragAllowed = allowed\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The drag ended (dropped anywhere, or cancelled): no column stays\n\t\t * greyed. A drop on a column has already run by now.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonDragEnd() {\n\t\t\tthis.dragging = null\n\t\t\tthis.dragAllowed = null\n\t\t},\n\n\t\t/**\n\t\t * A drop on a column.\n\t\t *\n\t\t * @param {object} column The column dropped on.\n\t\t * @return {Promise<void>} Nothing.\n\t\t */\n\t\tasync onDrop(column) {\n\t\t\tif (!this.dragging) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst { card, fromKey } = this.dragging\n\t\t\tthis.dragging = null\n\t\t\tthis.dragAllowed = null\n\t\t\tif (column.key !== fromKey && !this.isMoveAllowed(card, column)) {\n\t\t\t\tconst name = this.roleText(card, this.roles.title) || this.cardKey(card)\n\t\t\t\tthis.refusal = this.blockReason(card, column)\n\t\t\t\t\t|| t('nextcloud-vue', '{name} cannot move to {column}.', { name, column: column.label })\n\t\t\t\tthis.$emit('refused', { card, message: this.refusal })\n\t\t\t\treturn\n\t\t\t}\n\t\t\tawait this.move(card, fromKey, column.key)\n\t\t},\n\n\t\t/**\n\t\t * Move to, from the card's own menu.\n\t\t *\n\t\t * @param {object} card The row.\n\t\t * @param {object} column Its column.\n\t\t * @param {Event} event The change event.\n\t\t * @return {Promise<void>} Nothing.\n\t\t */\n\t\tasync onMoveTo(card, column, event) {\n\t\t\tawait this.move(card, column.key, event?.target?.value ?? '')\n\t\t},\n\n\t\t/**\n\t\t * The one move, whichever gesture asked for it.\n\t\t *\n\t\t * @param {object} card The row.\n\t\t * @param {string} fromKey Where it was.\n\t\t * @param {string} toKey Where it is going.\n\t\t * @return {Promise<void>} Nothing.\n\t\t */\n\t\tasync move(card, fromKey, toKey) {\n\t\t\tthis.refusal = ''\n\n\t\t\tconst target = this.board.columns.find((column) => String(column.key) === String(toKey))\n\t\t\tif (target && String(toKey) !== String(fromKey) && this.isFull(target)) {\n\t\t\t\tthis.refusal = this.fullRefusal(target)\n\t\t\t\tthis.$emit('refused', { card, message: this.refusal })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst result = await runBoardDrop({\n\t\t\t\tcard,\n\t\t\t\tfromKey,\n\t\t\t\ttoKey,\n\t\t\t\tstatusField: this.statusField,\n\t\t\t\trunTransition: this.runTransition,\n\t\t\t\treread: this.reread,\n\t\t\t})\n\n\t\t\tif (result.outcome === DROP_OUTCOMES.MOVED) {\n\t\t\t\t/**\n\t\t\t\t * @event moved Emitted when the host's transition accepted the move and the card now sits in the new lane. Payload: `{ card, toKey }`.\n\t\t\t\t */\n\t\t\t\tthis.$emit('moved', { card: result.card, toKey })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (result.outcome === DROP_OUTCOMES.REFUSED) {\n\t\t\t\t// The guard's own sentence when it gave one. Our own only when\n\t\t\t\t// it did not, so the two are never confused.\n\t\t\t\tthis.refusal = result.message || t('nextcloud-vue', 'That move was refused.')\n\t\t\t\t/**\n\t\t\t\t * @event refused Emitted when the guard turned the move down. Payload: `{ card, message }`, the message being the guard's own sentence when it gave one.\n\t\t\t\t */\n\t\t\t\tthis.$emit('refused', { card: result.card, message: this.refusal })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (result.outcome === DROP_OUTCOMES.STALE) {\n\t\t\t\tthis.refusal = t('nextcloud-vue', 'Somebody else moved this card. It is shown where it is now.')\n\t\t\t\t/**\n\t\t\t\t * @event stale Emitted when somebody else moved the card first, so the board shows it where it is now. Payload: `{ card }`.\n\t\t\t\t */\n\t\t\t\tthis.$emit('stale', { card: result.card })\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.cn-board-view__columns {\n\tdisplay: flex;\n\tgap: 12px;\n\toverflow-x: auto;\n\talign-items: flex-start;\n}\n\n.cn-board-view__column {\n\tflex: 0 0 260px;\n\tbackground-color: var(--color-background-hover);\n\tborder-radius: var(--border-radius-large);\n\tpadding: 8px;\n}\n\n.cn-board-view__column-header {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\tgap: 8px;\n\tfont-size: 1rem;\n\tmargin: 0 0 8px;\n}\n\n.cn-board-view__count,\n.cn-board-view__empty,\n.cn-board-view__unusable {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-board-view__card {\n\tdisplay: block;\n\tbackground-color: var(--color-main-background);\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius);\n\tpadding: 8px;\n\tmargin-bottom: 8px;\n}\n\n.cn-board-view__card-field {\n\tdisplay: block;\n}\n\n/* A late card: an edge in the error colour, drawn as an inset shadow so the\n card keeps its size and its rounded corners. The label below carries the\n meaning; the edge only helps a sighted reader find it. */\n.cn-board-view__card--overdue {\n\tborder-color: var(--color-error);\n\tbox-shadow: inset 3px 0 0 var(--color-error);\n}\n\n.cn-board-view__due {\n\tdisplay: block;\n\tfont-size: 0.85em;\n\tfont-weight: 700;\n}\n\n.cn-board-view__due--overdue {\n\tcolor: var(--color-error-text, var(--color-error));\n}\n\n.cn-board-view__due--soon {\n\tcolor: var(--color-warning-text, var(--color-main-text));\n\tfont-weight: 600;\n}\n\n/*\n * The card's opening control. The cursor and the focus ring live here now,\n * on the thing that actually does something, rather than on the box.\n */\n.cn-board-view__card-open {\n\tbackground: none;\n\tborder: none;\n\tpadding: 0;\n\tcursor: pointer;\n\tcolor: var(--color-primary-element);\n\tfont-size: 0.8rem;\n}\n\n.cn-board-view__card-open:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-board-view__lane-header {\n\tbackground: none;\n\tborder: none;\n\tfont-weight: bold;\n\tpadding: 8px 0;\n\tcursor: pointer;\n\tcolor: var(--color-main-text);\n}\n\n.cn-board-view__move-label {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.8rem;\n}\n\n.cn-board-view__refusal {\n\tcolor: var(--color-error);\n}\n\n.cn-board-view__count--full {\n\tcolor: var(--color-error-text, var(--color-error));\n\tfont-weight: 600;\n}\n</style>\n"],"names":["CnStatusBadge","t"],"mappings":"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"}
|