@conduction/nextcloud-vue 2.58.0 → 2.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +12 -2
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +1 -2
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js +14 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +0 -3
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +1 -2
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +39 -0
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +46 -4
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +224 -9
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js +79 -25
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue2.js +42 -3
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue2.js.map +1 -1
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue3.js +39 -6
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue3.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +58 -5
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +13 -5
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue.js +10 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue.js.map +1 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js +39 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js.map +1 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js +16 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js.map +1 -0
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js +9 -1
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js.map +1 -1
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +117 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +147 -89
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js +6 -1
- package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js.map +1 -1
- package/dist/esm/components/CnContextMenu/CnContextMenu.vue3.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js +10 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js +259 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js +131 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js +10 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js +116 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js +24 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +116 -15
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +27 -14
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js +13 -6
- package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js.map +1 -1
- package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js +2 -0
- package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +532 -29
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +300 -142
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue.js +10 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue2.js +237 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue2.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue3.js +120 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue3.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue.js +10 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js +77 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js +27 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js +1 -2
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +3 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +17 -17
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js +4 -21
- package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js +0 -13
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js +8 -8
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue2.js.map +1 -1
- package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js +3 -2
- package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +169 -12
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +15 -7
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue2.js +37 -3
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue2.js.map +1 -1
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue3.js +44 -16
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +199 -16
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +20 -10
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/manifestActionDispatch.js +31 -11
- package/dist/esm/components/CnIndexPage/manifestActionDispatch.js.map +1 -1
- package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue2.js.map +1 -1
- package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js +1 -2
- package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js.map +1 -1
- package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js +0 -1
- package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js +2 -17
- package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js +35 -11
- package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js.map +1 -1
- package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js +3 -2
- package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js.map +1 -1
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue.js +10 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js +150 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js +106 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue.js +9 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js +47 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue3.js +17 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js +23 -5
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js +1 -1
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +49 -0
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue2.js +6 -0
- package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue2.js +46 -0
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue3.js +15 -3
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectList/CnObjectList.vue2.js +19 -3
- package/dist/esm/components/CnObjectList/CnObjectList.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectList/CnObjectList.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +45 -15
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -2
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js +24 -6
- package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js +1 -1
- package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +0 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js +4 -2
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +37 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js +29 -13
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js +100 -3
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnRowActions/CnRowActions.vue2.js +7 -2
- package/dist/esm/components/CnRowActions/CnRowActions.vue2.js.map +1 -1
- package/dist/esm/components/CnRowActions/CnRowActions.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js +50 -3
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js.map +1 -1
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue.js +10 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue.js.map +1 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js +186 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js.map +1 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js +46 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js.map +1 -0
- package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js +5 -3
- package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue.js +11 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js +298 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js +77 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js +10 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue2.js +169 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue2.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue3.js +48 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue3.js.map +1 -0
- package/dist/esm/components/CnTabs/CnTab.vue2.js +35 -0
- package/dist/esm/components/CnTabs/CnTab.vue2.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTab.vue3.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue2.js +120 -7
- package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue3.js +57 -5
- package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +59 -4
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +6 -2
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js +3 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js +1 -0
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js +10 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js +484 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js +115 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js +10 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue2.js +189 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue2.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue3.js +74 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue3.js.map +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +82 -8
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js +6 -0
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js +68 -53
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js +17 -0
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js +21 -19
- package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/email/CnEmailCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/email/CnEmailTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/flow/CnFlowCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/forms/CnFormsCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/maps/CnMapsCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/polls/CnPollsCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/shares/CnSharesTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js +3 -6
- package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js +3 -1
- package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/talk/CnTalkCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js +3 -1
- package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js +2 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js +2 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js +1 -2
- package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js +4 -1
- package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js +6 -3
- package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js +2 -4
- package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js.map +1 -1
- package/dist/esm/l10n/en.json.js +55 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +55 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +998 -7
- package/dist/esm/utils/actionLink.js +5 -0
- package/dist/esm/utils/actionLink.js.map +1 -1
- package/dist/esm/utils/actionsDispatcher.js +16 -1
- package/dist/esm/utils/actionsDispatcher.js.map +1 -1
- package/dist/esm/utils/dateVariant.js +124 -0
- package/dist/esm/utils/dateVariant.js.map +1 -0
- package/dist/esm/utils/detailActionModel.js +260 -0
- package/dist/esm/utils/detailActionModel.js.map +1 -0
- package/dist/esm/utils/dueRule.js +84 -0
- package/dist/esm/utils/dueRule.js.map +1 -0
- package/dist/esm/utils/fetchAggregate.js +37 -1
- package/dist/esm/utils/fetchAggregate.js.map +1 -1
- package/dist/esm/utils/fetchFilterCounts.js +186 -0
- package/dist/esm/utils/fetchFilterCounts.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +5 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/linkNavigation.js +6 -3
- package/dist/esm/utils/linkNavigation.js.map +1 -1
- package/dist/esm/utils/readPath.js +30 -0
- package/dist/esm/utils/readPath.js.map +1 -0
- package/dist/esm/utils/rowAuxClick.js +30 -5
- package/dist/esm/utils/rowAuxClick.js.map +1 -1
- package/dist/esm/utils/safeHref.js +18 -3
- package/dist/esm/utils/safeHref.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +15855 -9353
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +998 -7
- package/l10n/en.json +55 -1
- package/l10n/nl.json +55 -1
- package/package.json +1 -1
- package/scripts/.jsdoc-baselines.json +3 -0
- package/src/components/CnActionsBar/CnActionsBar.vue +14 -5
- package/src/components/CnActionsMenu/CnActionsMenu.vue +14 -4
- package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +1 -2
- package/src/components/CnAppNav/CnAppNav.md +26 -0
- package/src/components/CnAppNav/CnAppNav.vue +104 -1
- package/src/components/CnBannerWidget/CnBannerWidget.vue +365 -10
- package/src/components/CnBannerWidgetForm/CnBannerWidgetForm.vue +65 -3
- package/src/components/CnBoardView/CnBoardView.vue +90 -5
- package/src/components/CnBrandStripe/CnBrandStripe.md +22 -0
- package/src/components/CnBrandStripe/CnBrandStripe.vue +100 -0
- package/src/components/CnBrandStripe/index.js +4 -0
- package/src/components/CnCardGrid/CnCardGrid.vue +9 -1
- package/src/components/CnCellRenderer/CnCellRenderer.vue +207 -1
- package/src/components/CnContextMenu/CnContextMenu.vue +6 -1
- package/src/components/CnConversationThread/CnConversationThread.md +51 -0
- package/src/components/CnConversationThread/CnConversationThread.vue +457 -0
- package/src/components/CnConversationThread/CnConversationWidget.vue +144 -0
- package/src/components/CnConversationThread/index.js +4 -0
- package/src/components/CnDataTable/CnDataTable.md +1 -1
- package/src/components/CnDataTable/CnDataTable.vue +131 -17
- package/src/components/CnDateAxisView/CnDateAxisView.vue +15 -6
- package/src/components/CnDetailPage/CnDetailPage.md +17 -1
- package/src/components/CnDetailPage/CnDetailPage.vue +712 -49
- package/src/components/CnDocumentReviewList/CnDocumentReviewList.md +55 -0
- package/src/components/CnDocumentReviewList/CnDocumentReviewList.vue +384 -0
- package/src/components/CnDocumentReviewList/CnDocumentReviewWidget.vue +108 -0
- package/src/components/CnDocumentReviewList/index.js +4 -0
- package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +1 -2
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +5 -3
- package/src/components/CnFilesWidget/CnFilesWidget.vue +4 -21
- package/src/components/CnFlowRunsWidget/CnFlowRunsWidget.vue +8 -21
- package/src/components/CnFlowsPage/CnFlowsPage.vue +2 -1
- package/src/components/CnHeaderWidget/CnHeaderWidget.vue +189 -14
- package/src/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue +53 -3
- package/src/components/CnIndexPage/CnIndexPage.vue +210 -17
- package/src/components/CnIndexPage/manifestActionDispatch.js +31 -11
- package/src/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue +1 -2
- package/src/components/CnInteractionFormWidget/CnInteractionFormWidget.vue +0 -1
- package/src/components/CnLinkButtonWidget/CnLinkButtonWidget.vue +2 -17
- package/src/components/CnLogsPage/CnLogsPage.vue +37 -12
- package/src/components/CnNextStepCard/CnNextStepCard.md +40 -0
- package/src/components/CnNextStepCard/CnNextStepCard.vue +319 -0
- package/src/components/CnNextStepCard/CnNextStepWidget.vue +59 -0
- package/src/components/CnNextStepCard/index.js +4 -0
- package/src/components/CnObjectCard/CnObjectCard.vue +24 -6
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +49 -0
- package/src/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue +6 -0
- package/src/components/CnObjectKanban/CnObjectKanban.vue +86 -2
- package/src/components/CnObjectList/CnObjectList.vue +19 -3
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +47 -15
- package/src/components/CnObjectRow/CnObjectRow.vue +25 -7
- package/src/components/CnObjectSidebar/CnFilesTab.vue +0 -1
- package/src/components/CnPageRenderer/CnPageRenderer.vue +2 -0
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.md +3 -0
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +60 -1
- package/src/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue +100 -3
- package/src/components/CnRowActions/CnRowActions.vue +7 -2
- package/src/components/CnSavedViewsControl/CnSavedViewsControl.vue +50 -3
- package/src/components/CnSegmentedControl/CnSegmentedControl.md +46 -0
- package/src/components/CnSegmentedControl/CnSegmentedControl.vue +291 -0
- package/src/components/CnSegmentedControl/index.js +4 -0
- package/src/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue +5 -3
- package/src/components/CnStackedBarWidget/CnStackedBarWidget.md +15 -0
- package/src/components/CnStackedBarWidget/CnStackedBarWidget.vue +414 -0
- package/src/components/CnStackedBarWidget/index.js +14 -0
- package/src/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue +224 -0
- package/src/components/CnStackedBarWidgetForm/index.js +4 -0
- package/src/components/CnTabs/CnTab.vue +35 -0
- package/src/components/CnTabs/CnTabs.vue +251 -13
- package/src/components/CnTabsWidget/CnTabsWidget.vue +63 -4
- package/src/components/CnTasksWidget/CnTasksWidget.vue +4 -1
- package/src/components/CnWeekStripWidget/CnWeekStripWidget.md +31 -0
- package/src/components/CnWeekStripWidget/CnWeekStripWidget.vue +668 -0
- package/src/components/CnWeekStripWidget/index.js +14 -0
- package/src/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue +265 -0
- package/src/components/CnWeekStripWidgetForm/index.js +4 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +74 -0
- package/src/components/index.js +11 -0
- package/src/css/detail-page.css +47 -0
- package/src/css/table.css +26 -0
- package/src/index.js +9 -0
- package/src/integrations/builtin/analytics/CnAnalyticsCard.vue +3 -2
- package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +5 -6
- package/src/integrations/builtin/bookmarks/CnBookmarksCard.vue +12 -1
- package/src/integrations/builtin/bookmarks/CnBookmarksTab.vue +23 -6
- package/src/integrations/builtin/bookmarks/__tests__/CnBookmarksTab.spec.js +7 -2
- package/src/integrations/builtin/collectives/CnCollectivesCard.vue +3 -2
- package/src/integrations/builtin/collectives/CnCollectivesTab.vue +5 -6
- package/src/integrations/builtin/cospend/CnCospendCard.vue +2 -2
- package/src/integrations/builtin/cospend/CnCospendTab.vue +3 -4
- package/src/integrations/builtin/deck/CnDeckCard.vue +2 -2
- package/src/integrations/builtin/deck/CnDeckTab.vue +3 -4
- package/src/integrations/builtin/email/CnEmailCard.vue +6 -2
- package/src/integrations/builtin/email/CnEmailTab.vue +7 -4
- package/src/integrations/builtin/flow/CnFlowCard.vue +2 -2
- package/src/integrations/builtin/flow/CnFlowTab.vue +3 -4
- package/src/integrations/builtin/forms/CnFormsCard.vue +3 -2
- package/src/integrations/builtin/forms/CnFormsTab.vue +5 -6
- package/src/integrations/builtin/maps/CnMapsCard.vue +3 -2
- package/src/integrations/builtin/maps/CnMapsTab.vue +5 -6
- package/src/integrations/builtin/maps/__tests__/CnMapsTab.spec.js +9 -0
- package/src/integrations/builtin/openproject/CnOpenprojectCard.vue +3 -2
- package/src/integrations/builtin/openproject/CnOpenprojectTab.vue +5 -6
- package/src/integrations/builtin/photos/CnPhotosCard.vue +2 -2
- package/src/integrations/builtin/photos/CnPhotosTab.vue +3 -4
- package/src/integrations/builtin/polls/CnPollsCard.vue +2 -2
- package/src/integrations/builtin/polls/CnPollsTab.vue +3 -4
- package/src/integrations/builtin/shares/CnSharesTab.vue +3 -6
- package/src/integrations/builtin/talk/CnTalkCard.vue +3 -2
- package/src/integrations/builtin/talk/CnTalkTab.vue +5 -6
- package/src/integrations/builtin/time-tracker/CnTimeTrackerCard.vue +2 -2
- package/src/integrations/builtin/time-tracker/CnTimeTrackerTab.vue +3 -4
- package/src/integrations/builtin/xwiki/CnXwikiCard.vue +4 -2
- package/src/integrations/builtin/xwiki/CnXwikiTab.vue +7 -7
- package/src/integrations/builtin/xwiki/__tests__/CnXwikiTab.spec.js +9 -0
- package/src/schemas/app-manifest-v2.schema.json +389 -1
- package/src/schemas/app-manifest.schema.json +2 -1
- package/src/utils/actionLink.js +5 -0
- package/src/utils/actionsDispatcher.js +15 -0
- package/src/utils/dateVariant.js +120 -0
- package/src/utils/detailActionModel.js +256 -0
- package/src/utils/dueRule.js +94 -0
- package/src/utils/fetchAggregate.js +36 -0
- package/src/utils/fetchFilterCounts.js +182 -0
- package/src/utils/index.js +1 -0
- package/src/utils/libraryWidgetKeys.js +5 -0
- package/src/utils/linkNavigation.js +6 -3
- package/src/utils/readPath.js +27 -0
- package/src/utils/rowAuxClick.js +29 -4
- package/src/utils/safeHref.js +18 -3
- package/src/utils/validateManifestV2.compiled.js +2 -2
package/src/utils/actionLink.js
CHANGED
|
@@ -62,6 +62,11 @@ export function resolveItemActionLink(action, item, router) {
|
|
|
62
62
|
* on an in-app link that opens in place goes through the router; a URL, a
|
|
63
63
|
* new-tab target or a modified click is left to the browser.
|
|
64
64
|
*
|
|
65
|
+
* Hand-rolled rather than `NcActionRouter` / `NcButton :to`: the menus and
|
|
66
|
+
* bars using it must still emit their own events on click, and without an
|
|
67
|
+
* installed router `NcButton :to` falls back to a button that goes nowhere,
|
|
68
|
+
* while an `<a href>` still navigates.
|
|
69
|
+
*
|
|
65
70
|
* @param {MouseEvent} event The click event.
|
|
66
71
|
* @param {{to: (string|object|null), target: (string|undefined)}} link The resolved link.
|
|
67
72
|
* @param {object} [router] The app's router.
|
|
@@ -341,6 +341,21 @@ export function interpolateActionTarget(target, ctx) {
|
|
|
341
341
|
return interpolateActionString(target || '', ctx || {})
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
+
// The tokens interpolateActionString resolves; a bare `@` or `{` is not one.
|
|
345
|
+
const ACTION_TARGET_TOKEN = /@(?:objectId|object\.|page\.|workspace\.|config\.|range\.)|\{objectId\}/
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Whether an action target carries a token that interpolation would resolve,
|
|
349
|
+
* so it can only be known once the page context is. A `mailto:` address or a
|
|
350
|
+
* URL with an `@handle` in it has none.
|
|
351
|
+
*
|
|
352
|
+
* @param {string} target The action's raw `target`.
|
|
353
|
+
* @return {boolean}
|
|
354
|
+
*/
|
|
355
|
+
export function hasActionTargetTokens(target) {
|
|
356
|
+
return typeof target === 'string' && ACTION_TARGET_TOKEN.test(target)
|
|
357
|
+
}
|
|
358
|
+
|
|
344
359
|
/**
|
|
345
360
|
* The link an action renders as when its only job is to navigate to a target
|
|
346
361
|
* known at render time: `navigate` (token-interpolated like the dispatcher)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
|
|
3
|
+
* SPDX-License-Identifier: EUPL-1.2
|
|
4
|
+
*
|
|
5
|
+
* dateVariant: turn "how far away is this date" into a colour variant.
|
|
6
|
+
*
|
|
7
|
+
* A deadline reads differently depending on how close it is. The rules are the
|
|
8
|
+
* `variantWhen` shape the stat tile already uses (`[{ op, value, variant }]`,
|
|
9
|
+
* first match wins), compared against the number of CALENDAR days from today
|
|
10
|
+
* until the date: `0` is today, a negative number is overdue.
|
|
11
|
+
*
|
|
12
|
+
* ```js
|
|
13
|
+
* resolveDateVariant('2026-10-01', [
|
|
14
|
+
* { op: 'lt', value: 0, variant: 'error' }, // overdue
|
|
15
|
+
* { op: 'lte', value: 5, variant: 'warning' }, // within five days
|
|
16
|
+
* ])
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Shared by the `date` cell widget (CnCellRenderer) and the week strip, and
|
|
20
|
+
* meant for board cards too, so a deadline is coloured by one rule everywhere.
|
|
21
|
+
*
|
|
22
|
+
* @module utils/dateVariant
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { compareVisibleWhen } from './visibleWhen.js'
|
|
26
|
+
|
|
27
|
+
/** Variants a date rule may name. `danger` is accepted as an alias of `error`. */
|
|
28
|
+
export const DATE_VARIANTS = Object.freeze(['default', 'success', 'warning', 'error'])
|
|
29
|
+
|
|
30
|
+
const MS_PER_DAY = 86400000
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse a value into a Date. A date-only string (`2026-10-05`) is read as a
|
|
34
|
+
* LOCAL day, so it does not slide to the day before in a timezone west of UTC.
|
|
35
|
+
*
|
|
36
|
+
* @param {unknown} value A Date, a timestamp, or an ISO string.
|
|
37
|
+
* @return {Date|null} The date, or null when the value is not one.
|
|
38
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells
|
|
39
|
+
*/
|
|
40
|
+
export function parseDateValue(value) {
|
|
41
|
+
if (value === null || value === undefined || value === '') {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
if (value instanceof Date) {
|
|
45
|
+
return Number.isNaN(value.getTime()) ? null : value
|
|
46
|
+
}
|
|
47
|
+
if (typeof value === 'string') {
|
|
48
|
+
const dateOnly = value.match(/^(\d{4})-(\d{2})-(\d{2})$/)
|
|
49
|
+
if (dateOnly) {
|
|
50
|
+
return new Date(Number(dateOnly[1]), Number(dateOnly[2]) - 1, Number(dateOnly[3]))
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (typeof value !== 'string' && typeof value !== 'number') {
|
|
54
|
+
return null
|
|
55
|
+
}
|
|
56
|
+
const parsed = new Date(value)
|
|
57
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The local calendar day of a date as `YYYY-MM-DD`.
|
|
62
|
+
*
|
|
63
|
+
* @param {Date} date The date.
|
|
64
|
+
* @return {string} The day key.
|
|
65
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
66
|
+
*/
|
|
67
|
+
export function dayKey(date) {
|
|
68
|
+
const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
69
|
+
const day = String(date.getDate()).padStart(2, '0')
|
|
70
|
+
return `${date.getFullYear()}-${month}-${day}`
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Whole calendar days from `now` until `value`: 0 today, negative when past.
|
|
75
|
+
*
|
|
76
|
+
* @param {unknown} value The date.
|
|
77
|
+
* @param {Date} [now] The reference moment (defaults to the current time).
|
|
78
|
+
* @return {number|null} The day count, or null when `value` is not a date.
|
|
79
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells
|
|
80
|
+
*/
|
|
81
|
+
export function daysUntil(value, now = new Date()) {
|
|
82
|
+
const date = parseDateValue(value)
|
|
83
|
+
if (date === null) {
|
|
84
|
+
return null
|
|
85
|
+
}
|
|
86
|
+
// UTC midnights of the two LOCAL days, so a daylight-saving hour never
|
|
87
|
+
// turns one day into zero or two.
|
|
88
|
+
const target = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())
|
|
89
|
+
const today = Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())
|
|
90
|
+
return Math.round((target - today) / MS_PER_DAY)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The variant of the first rule the date matches, or '' when none does.
|
|
95
|
+
*
|
|
96
|
+
* @param {unknown} value The date.
|
|
97
|
+
* @param {Array<{op: string, value: number, variant: string}>} rules The `variantWhen` rules.
|
|
98
|
+
* @param {Date} [now] The reference moment (defaults to the current time).
|
|
99
|
+
* @return {string} `success | warning | error | default`, or '' for no match.
|
|
100
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-avatar-and-date-cells
|
|
101
|
+
*/
|
|
102
|
+
export function resolveDateVariant(value, rules, now = new Date()) {
|
|
103
|
+
if (!Array.isArray(rules) || rules.length === 0) {
|
|
104
|
+
return ''
|
|
105
|
+
}
|
|
106
|
+
const days = daysUntil(value, now)
|
|
107
|
+
if (days === null) {
|
|
108
|
+
return ''
|
|
109
|
+
}
|
|
110
|
+
for (const rule of rules) {
|
|
111
|
+
if (!rule || typeof rule !== 'object') {
|
|
112
|
+
continue
|
|
113
|
+
}
|
|
114
|
+
if (compareVisibleWhen(days, rule.op || 'eq', rule.value) === true) {
|
|
115
|
+
const variant = rule.variant === 'danger' ? 'error' : rule.variant
|
|
116
|
+
return DATE_VARIANTS.includes(variant) ? variant : ''
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return ''
|
|
120
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
|
|
3
|
+
* SPDX-License-Identifier: EUPL-1.2
|
|
4
|
+
*
|
|
5
|
+
* detailActionModel: the rules behind a detail page's four action levels and
|
|
6
|
+
* the case surfaces that read the record's stage.
|
|
7
|
+
*
|
|
8
|
+
* 1. the next step: one primary button, chosen by the record's stage,
|
|
9
|
+
* 2. quick actions: at most three always visible buttons,
|
|
10
|
+
* 3. the overflow menu: the rest, in named groups,
|
|
11
|
+
* 4. admin actions: the last group, for admins only.
|
|
12
|
+
*
|
|
13
|
+
* Pure functions, no Vue and no fetch, so CnDetailPage, the widgets and the
|
|
14
|
+
* tests all read one implementation.
|
|
15
|
+
*
|
|
16
|
+
* @module utils/detailActionModel
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { readPath } from './readPath.js'
|
|
20
|
+
import { evaluateVisibleWhenLocal } from './visibleWhen.js'
|
|
21
|
+
|
|
22
|
+
/** The most quick actions a page shows. Later entries are dropped. */
|
|
23
|
+
export const MAX_QUICK_ACTIONS = 3
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The record's stage, as the string a stage map is keyed on.
|
|
27
|
+
*
|
|
28
|
+
* @param {object|null} object The record.
|
|
29
|
+
* @param {string} [stageField] Dot-path to the stage. Defaults to `status`.
|
|
30
|
+
* @return {string} The stage, or '' when the record has none.
|
|
31
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-primary-action-follows-the-stage
|
|
32
|
+
*/
|
|
33
|
+
export function stageOf(object, stageField = 'status') {
|
|
34
|
+
if (!object || typeof object !== 'object') {
|
|
35
|
+
return ''
|
|
36
|
+
}
|
|
37
|
+
const value = readPath(object, stageField || 'status')
|
|
38
|
+
if (value === null || value === undefined || typeof value === 'object') {
|
|
39
|
+
return ''
|
|
40
|
+
}
|
|
41
|
+
return String(value)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Look a stage up in a stage-keyed map. An exact key wins; otherwise the
|
|
46
|
+
* match ignores case, because a status is stored as `in_behandeling` in one
|
|
47
|
+
* register and `In_Behandeling` in the next.
|
|
48
|
+
*
|
|
49
|
+
* @param {object|null} map The stage-keyed map.
|
|
50
|
+
* @param {string} stage The stage.
|
|
51
|
+
* @return {unknown} The entry, or undefined.
|
|
52
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-primary-action-follows-the-stage
|
|
53
|
+
*/
|
|
54
|
+
export function stageEntry(map, stage) {
|
|
55
|
+
if (!map || typeof map !== 'object' || Array.isArray(map) || stage === '') {
|
|
56
|
+
return undefined
|
|
57
|
+
}
|
|
58
|
+
if (Object.hasOwn(map, stage)) {
|
|
59
|
+
return map[stage]
|
|
60
|
+
}
|
|
61
|
+
const wanted = stage.toLowerCase()
|
|
62
|
+
const key = Object.keys(map).find((candidate) => candidate.toLowerCase() === wanted)
|
|
63
|
+
return key === undefined ? undefined : map[key]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Turn a pinned action entry into a descriptor the page can dispatch.
|
|
68
|
+
*
|
|
69
|
+
* An entry is the id of a declared header action, or an action object of its
|
|
70
|
+
* own. An object without an id gets `fallbackId`, since every dispatched
|
|
71
|
+
* action is addressed by id.
|
|
72
|
+
*
|
|
73
|
+
* @param {string|object|null} entry The entry.
|
|
74
|
+
* @param {string} fallbackId Id for an inline action that names none.
|
|
75
|
+
* @return {{id: string, inline: object|null}|null} The id, plus the inline definition when the entry carried one.
|
|
76
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-quick-actions
|
|
77
|
+
*/
|
|
78
|
+
export function normalisePinnedAction(entry, fallbackId) {
|
|
79
|
+
if (typeof entry === 'string') {
|
|
80
|
+
return entry === '' ? null : { id: entry, inline: null }
|
|
81
|
+
}
|
|
82
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
83
|
+
return null
|
|
84
|
+
}
|
|
85
|
+
if (typeof entry.label !== 'string' || entry.label === '') {
|
|
86
|
+
return null
|
|
87
|
+
}
|
|
88
|
+
const id = typeof entry.id === 'string' && entry.id !== '' ? entry.id : fallbackId
|
|
89
|
+
return { id, inline: { ...entry, id } }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Split menu entries into the groups the overflow menu draws.
|
|
94
|
+
*
|
|
95
|
+
* Ungrouped entries come first, under no caption. Named groups follow in the
|
|
96
|
+
* order they first appear. Admin only entries are dropped for everyone else
|
|
97
|
+
* and form the last group for admins, whatever `group` they also name.
|
|
98
|
+
*
|
|
99
|
+
* `adminOnly` hides a control. It is never an authorization decision: the
|
|
100
|
+
* endpoint behind the action decides who may call it.
|
|
101
|
+
*
|
|
102
|
+
* @param {Array<object>} entries Menu-ready entries, each with an `id`.
|
|
103
|
+
* @param {object} actionsById The declared actions by id, carrying `group` / `adminOnly`.
|
|
104
|
+
* @param {{isAdmin?: boolean, adminLabel?: string}} [options] Who is looking, and what the admin group is called.
|
|
105
|
+
* @return {Array<{key: string, label: string, entries: Array<object>}>} The non-empty groups, in render order.
|
|
106
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-grouped-and-admin-only-menu-actions
|
|
107
|
+
*/
|
|
108
|
+
export function groupMenuEntries(entries, actionsById = {}, options = {}) {
|
|
109
|
+
const isAdmin = options.isAdmin === true
|
|
110
|
+
const plain = { key: '', label: '', entries: [] }
|
|
111
|
+
const named = []
|
|
112
|
+
const admin = { key: 'cn-admin', label: options.adminLabel || '', entries: [] }
|
|
113
|
+
for (const entry of Array.isArray(entries) ? entries : []) {
|
|
114
|
+
const declared = (entry && actionsById[entry.id]) || {}
|
|
115
|
+
if (declared.adminOnly === true) {
|
|
116
|
+
if (isAdmin) {
|
|
117
|
+
admin.entries.push(entry)
|
|
118
|
+
}
|
|
119
|
+
continue
|
|
120
|
+
}
|
|
121
|
+
const label = typeof declared.group === 'string' ? declared.group.trim() : ''
|
|
122
|
+
if (label === '') {
|
|
123
|
+
plain.entries.push(entry)
|
|
124
|
+
continue
|
|
125
|
+
}
|
|
126
|
+
let group = named.find((candidate) => candidate.label === label)
|
|
127
|
+
if (!group) {
|
|
128
|
+
group = { key: `cn-group-${named.length}`, label, entries: [] }
|
|
129
|
+
named.push(group)
|
|
130
|
+
}
|
|
131
|
+
group.entries.push(entry)
|
|
132
|
+
}
|
|
133
|
+
return [plain, ...named, admin].filter((group) => group.entries.length > 0)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Whether one checklist item is done for this record.
|
|
138
|
+
*
|
|
139
|
+
* `done` (a literal) wins, then `doneWhen` (a local visibleWhen condition),
|
|
140
|
+
* then `doneField` (truthy, and for a list: not empty).
|
|
141
|
+
*
|
|
142
|
+
* @param {object} item The checklist item.
|
|
143
|
+
* @param {object|null} object The record.
|
|
144
|
+
* @return {boolean} True when the item is done.
|
|
145
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card
|
|
146
|
+
*/
|
|
147
|
+
export function isChecklistItemDone(item, object) {
|
|
148
|
+
if (!item || typeof item !== 'object') {
|
|
149
|
+
return false
|
|
150
|
+
}
|
|
151
|
+
if (typeof item.done === 'boolean') {
|
|
152
|
+
return item.done
|
|
153
|
+
}
|
|
154
|
+
const data = object && typeof object === 'object' ? object : {}
|
|
155
|
+
if (item.doneWhen && typeof item.doneWhen === 'object') {
|
|
156
|
+
return evaluateVisibleWhenLocal(item.doneWhen, data)
|
|
157
|
+
}
|
|
158
|
+
if (typeof item.doneField === 'string' && item.doneField !== '') {
|
|
159
|
+
const value = readPath(data, item.doneField)
|
|
160
|
+
return Array.isArray(value) ? value.length > 0 : Boolean(value)
|
|
161
|
+
}
|
|
162
|
+
return false
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Resolve the "what now" card for the record's stage.
|
|
167
|
+
*
|
|
168
|
+
* @param {{stages?: object, title?: string}|null} config The `nextStep` config.
|
|
169
|
+
* @param {object|null} object The record.
|
|
170
|
+
* @param {string} [stageField] Dot-path to the stage.
|
|
171
|
+
* @return {{stage: string, title: string, items: Array<{label: string, done: boolean, hint: string}>, after: string}|null} The card, or null when this stage declares no checklist.
|
|
172
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card
|
|
173
|
+
*/
|
|
174
|
+
export function resolveNextStep(config, object, stageField = 'status') {
|
|
175
|
+
if (!config || typeof config !== 'object') {
|
|
176
|
+
return null
|
|
177
|
+
}
|
|
178
|
+
const stage = stageOf(object, config.field || stageField)
|
|
179
|
+
const declared = stageEntry(config.stages, stage)
|
|
180
|
+
if (!declared || typeof declared !== 'object' || !Array.isArray(declared.checklist)) {
|
|
181
|
+
return null
|
|
182
|
+
}
|
|
183
|
+
const items = declared.checklist
|
|
184
|
+
.filter((item) => item && typeof item === 'object' && typeof item.label === 'string' && item.label !== '')
|
|
185
|
+
.map((item) => ({
|
|
186
|
+
label: item.label,
|
|
187
|
+
done: isChecklistItemDone(item, object),
|
|
188
|
+
hint: typeof item.hint === 'string' ? item.hint : '',
|
|
189
|
+
}))
|
|
190
|
+
if (items.length === 0) {
|
|
191
|
+
return null
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
stage,
|
|
195
|
+
title: typeof declared.title === 'string' ? declared.title : (typeof config.title === 'string' ? config.title : ''),
|
|
196
|
+
items,
|
|
197
|
+
after: typeof declared.after === 'string' ? declared.after : '',
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Resolve a header pill from the record.
|
|
203
|
+
*
|
|
204
|
+
* @param {{field?: string, colorMap?: object, labels?: object, variant?: string}|null} config The pill config.
|
|
205
|
+
* @param {object|null} object The record.
|
|
206
|
+
* @return {{label: string, colorKey: string, colorMap: object|null, variant: string}|null} What CnStatusBadge needs, or null when the field is empty.
|
|
207
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-header-pills
|
|
208
|
+
*/
|
|
209
|
+
export function resolvePill(config, object) {
|
|
210
|
+
if (!config || typeof config !== 'object' || typeof config.field !== 'string' || config.field === '') {
|
|
211
|
+
return null
|
|
212
|
+
}
|
|
213
|
+
const raw = stageOf(object, config.field)
|
|
214
|
+
if (raw === '') {
|
|
215
|
+
return null
|
|
216
|
+
}
|
|
217
|
+
const mapped = stageEntry(config.labels, raw)
|
|
218
|
+
return {
|
|
219
|
+
label: typeof mapped === 'string' && mapped !== '' ? mapped : raw,
|
|
220
|
+
colorKey: raw,
|
|
221
|
+
colorMap: config.colorMap && typeof config.colorMap === 'object' ? config.colorMap : null,
|
|
222
|
+
variant: typeof config.variant === 'string' && config.variant !== '' ? config.variant : 'default',
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Resolve a tab's count.
|
|
228
|
+
*
|
|
229
|
+
* `count` (a number) wins. Otherwise `countField` is read off the record: a
|
|
230
|
+
* list counts its items, a number is taken as is.
|
|
231
|
+
*
|
|
232
|
+
* @param {{count?: number, countField?: string}|null} tab The tab declaration.
|
|
233
|
+
* @param {object|null} object The record.
|
|
234
|
+
* @return {number|null} The count, or null when the tab declares none.
|
|
235
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-tab-counts-and-overflow
|
|
236
|
+
*/
|
|
237
|
+
export function resolveTabCount(tab, object) {
|
|
238
|
+
if (!tab || typeof tab !== 'object') {
|
|
239
|
+
return null
|
|
240
|
+
}
|
|
241
|
+
if (typeof tab.count === 'number' && Number.isFinite(tab.count)) {
|
|
242
|
+
return tab.count
|
|
243
|
+
}
|
|
244
|
+
if (typeof tab.countField !== 'string' || tab.countField === '') {
|
|
245
|
+
return null
|
|
246
|
+
}
|
|
247
|
+
const value = readPath(object && typeof object === 'object' ? object : {}, tab.countField)
|
|
248
|
+
if (Array.isArray(value)) {
|
|
249
|
+
return value.length
|
|
250
|
+
}
|
|
251
|
+
if (value === null || value === undefined || value === '') {
|
|
252
|
+
return 0
|
|
253
|
+
}
|
|
254
|
+
const number = Number(value)
|
|
255
|
+
return Number.isFinite(number) ? number : null
|
|
256
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
|
|
3
|
+
* SPDX-License-Identifier: EUPL-1.2
|
|
4
|
+
*
|
|
5
|
+
* dueRule: decides whether a dated card is overdue, due soon or fine.
|
|
6
|
+
*
|
|
7
|
+
* A board's rule is `{ field, soonDays?, variantWhen? }`. `field` is a
|
|
8
|
+
* dot-path to the date on the row. `soonDays` (default 3) is how many days
|
|
9
|
+
* ahead still counts as "soon"; a date before today is overdue.
|
|
10
|
+
*
|
|
11
|
+
* The deciding is done by `utils/dateVariant.js`, the same rules a table's
|
|
12
|
+
* date cell uses, so a list and its board agree on what late means.
|
|
13
|
+
* `{ soonDays: 3 }` is shorthand for
|
|
14
|
+
* `variantWhen: [{ op: 'lt', value: 0, variant: 'error' }, { op: 'lte', value: 3, variant: 'warning' }]`,
|
|
15
|
+
* and a rule that carries its own `variantWhen` is used as written:
|
|
16
|
+
* `error` reads as overdue, `warning` as due soon.
|
|
17
|
+
*
|
|
18
|
+
* @module utils/dueRule
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { daysUntil, parseDateValue, resolveDateVariant } from './dateVariant.js'
|
|
22
|
+
import { readPath } from './readPath.js'
|
|
23
|
+
|
|
24
|
+
export { daysUntil }
|
|
25
|
+
|
|
26
|
+
/** How many days ahead counts as "soon" when the rule does not say. */
|
|
27
|
+
export const DEFAULT_SOON_DAYS = 3
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Local midnight of a date value. A bare `YYYY-MM-DD` is a LOCAL day.
|
|
31
|
+
*
|
|
32
|
+
* @param {unknown} value A Date, a timestamp or a date string.
|
|
33
|
+
* @return {Date|null} Local midnight of that day, or null when unreadable.
|
|
34
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-late-marking-on-board-cards
|
|
35
|
+
*/
|
|
36
|
+
export function toLocalDay(value) {
|
|
37
|
+
const date = parseDateValue(value)
|
|
38
|
+
return date === null ? null : new Date(date.getFullYear(), date.getMonth(), date.getDate())
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The `variantWhen` rules a due rule stands for.
|
|
43
|
+
*
|
|
44
|
+
* @param {{soonDays?: number, variantWhen?: Array<object>}|null} [rule] The due rule.
|
|
45
|
+
* @return {Array<{op: string, value: number, variant: string}>} The rules `resolveDateVariant` takes.
|
|
46
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-late-marking-on-board-cards
|
|
47
|
+
*/
|
|
48
|
+
export function dueRuleToVariantWhen(rule = {}) {
|
|
49
|
+
if (Array.isArray(rule?.variantWhen) && rule.variantWhen.length > 0) {
|
|
50
|
+
return rule.variantWhen
|
|
51
|
+
}
|
|
52
|
+
const given = rule?.soonDays
|
|
53
|
+
const soonDays = given !== null && given !== undefined && Number.isFinite(Number(given)) ? Number(given) : DEFAULT_SOON_DAYS
|
|
54
|
+
return [
|
|
55
|
+
{ op: 'lt', value: 0, variant: 'error' },
|
|
56
|
+
{ op: 'lte', value: soonDays, variant: 'warning' },
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The due state of one date under a rule.
|
|
62
|
+
*
|
|
63
|
+
* @param {unknown} value The date.
|
|
64
|
+
* @param {{soonDays?: number, variantWhen?: Array<object>}|null} [rule] The rule.
|
|
65
|
+
* @param {Date} [now] The moment to measure from.
|
|
66
|
+
* @return {'overdue'|'soon'|'ok'|null} The state, or null when there is no readable date.
|
|
67
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-late-marking-on-board-cards
|
|
68
|
+
*/
|
|
69
|
+
export function dueStateOf(value, rule = {}, now = new Date()) {
|
|
70
|
+
if (daysUntil(value, now) === null) {
|
|
71
|
+
return null
|
|
72
|
+
}
|
|
73
|
+
const variant = resolveDateVariant(value, dueRuleToVariantWhen(rule), now)
|
|
74
|
+
if (variant === 'error') {
|
|
75
|
+
return 'overdue'
|
|
76
|
+
}
|
|
77
|
+
return variant === 'warning' ? 'soon' : 'ok'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The due state of a row under a `{ field, soonDays }` rule.
|
|
82
|
+
*
|
|
83
|
+
* @param {object} row The row or card.
|
|
84
|
+
* @param {{field?: string, soonDays?: number, variantWhen?: Array<object>}|null} rule The rule. Null or field-less means no marking.
|
|
85
|
+
* @param {Date} [now] The moment to measure from.
|
|
86
|
+
* @return {'overdue'|'soon'|'ok'|null} The state, or null when the rule does not apply.
|
|
87
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-late-marking-on-board-cards
|
|
88
|
+
*/
|
|
89
|
+
export function dueStateForRow(row, rule, now = new Date()) {
|
|
90
|
+
if (!rule || typeof rule.field !== 'string' || rule.field === '' || !row) {
|
|
91
|
+
return null
|
|
92
|
+
}
|
|
93
|
+
return dueStateOf(readPath(row, rule.field), rule, now)
|
|
94
|
+
}
|
|
@@ -77,3 +77,39 @@ export async function fetchAggregateValue(source, ctx) {
|
|
|
77
77
|
const res = await axios.get(url, { params })
|
|
78
78
|
return (res && res.data && res.data.value !== undefined) ? res.data.value : null
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Fetch the object count per distinct value of one field, in ONE request,
|
|
83
|
+
* from OpenRegister's `/grouped` aggregation endpoint.
|
|
84
|
+
*
|
|
85
|
+
* @param {object} source The grouped descriptor.
|
|
86
|
+
* @param {string} source.register The register slug.
|
|
87
|
+
* @param {string} source.schema The schema slug.
|
|
88
|
+
* @param {string} source.groupBy The field to group on.
|
|
89
|
+
* @param {object} [source.filter] The filter map.
|
|
90
|
+
* @param {{objectId?: (string|number), object?: object, workspace?: object}} [ctx] Optional
|
|
91
|
+
* token-resolution context for the filter.
|
|
92
|
+
* @return {Promise<Array<{key: string, count: number}>>} One entry per group; [] when the source is incomplete.
|
|
93
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-stacked-bar-widget
|
|
94
|
+
*/
|
|
95
|
+
export async function fetchGroupedCounts(source, ctx) {
|
|
96
|
+
const s = source || {}
|
|
97
|
+
if (!s.register || !s.schema || !s.groupBy) {
|
|
98
|
+
return []
|
|
99
|
+
}
|
|
100
|
+
const [{ default: axios }, { generateUrl }] = await Promise.all([
|
|
101
|
+
import('@nextcloud/axios'),
|
|
102
|
+
import('@nextcloud/router'),
|
|
103
|
+
])
|
|
104
|
+
const url = generateUrl(
|
|
105
|
+
'/apps/openregister/api/objects/aggregations/{register}/{schema}/grouped',
|
|
106
|
+
{ register: s.register, schema: s.schema },
|
|
107
|
+
)
|
|
108
|
+
const params = { groupBy: s.groupBy, metric: 'count' }
|
|
109
|
+
flattenAggFilter(params, s.filter || {}, ctx)
|
|
110
|
+
const res = await axios.get(url, { params })
|
|
111
|
+
const groups = (res && res.data && Array.isArray(res.data.groups)) ? res.data.groups : []
|
|
112
|
+
return groups
|
|
113
|
+
.filter((g) => g && g.key !== null && g.key !== undefined && g.key !== '')
|
|
114
|
+
.map((g) => ({ key: String(g.key), count: Number(g.value) || 0 }))
|
|
115
|
+
}
|