@conduction/nextcloud-vue 2.79.0 → 2.81.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/CnActionButtons/CnActionButtons.vue2.js.map +1 -1
- package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js +3 -1
- package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +32 -3
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +13 -11
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +80 -4
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +95 -91
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +179 -13
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js +52 -16
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +96 -4
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +158 -110
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue.js +10 -0
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue.js.map +1 -0
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue2.js +252 -0
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue3.js +140 -0
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnChipsFieldWidget/index.js +26 -0
- package/dist/esm/components/CnChipsFieldWidget/index.js.map +1 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue.js +10 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue.js.map +1 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue2.js +354 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue3.js +172 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnChoicePickerWidget/index.js +27 -0
- package/dist/esm/components/CnChoicePickerWidget/index.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js +2 -2
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +65 -5
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +2 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +19 -11
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +4 -2
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +134 -4
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +21 -4
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +24 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +43 -4
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js +1 -1
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFacetSidebar/CnFacetSidebar.vue2.js +7 -7
- package/dist/esm/components/CnFacetSidebar/CnFacetSidebar.vue2.js.map +1 -1
- package/dist/esm/components/CnFacetSidebar/CnFacetSidebar.vue3.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +11 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +867 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +238 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnFactsWidget/index.js +30 -0
- package/dist/esm/components/CnFactsWidget/index.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js +10 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js +626 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js +396 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/index.js +29 -0
- package/dist/esm/components/CnFieldListWidget/index.js.map +1 -0
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +302 -4
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +417 -244
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowser.js +101 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowser.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowserColumns.js +141 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowserColumns.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +65 -17
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +4 -4
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnFormPage/CnFormPage.vue2.js +78 -3
- package/dist/esm/components/CnFormPage/CnFormPage.vue2.js.map +1 -1
- package/dist/esm/components/CnFormPage/CnFormPage.vue3.js +74 -49
- package/dist/esm/components/CnFormPage/CnFormPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +333 -73
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +79 -17
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js +10 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js.map +1 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js +99 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js.map +1 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js +48 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js.map +1 -0
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js +7 -7
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js +1 -1
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +65 -2
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +6 -2
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +63 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +8 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js +14 -0
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue3.js +5 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js +29 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue.js +10 -0
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue2.js +174 -0
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue3.js +75 -0
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnRadioCardsWidget/index.js +28 -0
- package/dist/esm/components/CnRadioCardsWidget/index.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +10 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +411 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +178 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/index.js +31 -0
- package/dist/esm/components/CnRecordListWidget/index.js.map +1 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue.js +10 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue2.js +222 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue3.js +64 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSavedViewsWidget/index.js +30 -0
- package/dist/esm/components/CnSavedViewsWidget/index.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js +10 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js +351 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js +71 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/index.js +35 -0
- package/dist/esm/components/CnSectionsWidget/index.js.map +1 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js.map +1 -1
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js.map +1 -1
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue.js +10 -0
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue2.js +347 -0
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue3.js +184 -0
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSettingsFormWidget/index.js +27 -0
- package/dist/esm/components/CnSettingsFormWidget/index.js.map +1 -0
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +81 -2
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +87 -6
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +1 -0
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue2.js +84 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue3.js +85 -41
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue.js +10 -0
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue2.js +159 -0
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue3.js +60 -0
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSwitchRowsWidget/index.js +26 -0
- package/dist/esm/components/CnSwitchRowsWidget/index.js.map +1 -0
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +168 -7
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +86 -23
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js +80 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js +75 -32
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue.js +10 -0
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue.js.map +1 -0
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue2.js +269 -0
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue3.js +106 -0
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnToggleTableWidget/index.js +27 -0
- package/dist/esm/components/CnToggleTableWidget/index.js.map +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +11 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +7 -2
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/dashboardRegistration.js +5 -0
- package/dist/esm/components/CnWidgetObjectTable/dashboardRegistration.js.map +1 -1
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js +301 -6
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js +153 -55
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js.map +1 -1
- package/dist/esm/composables/useFormDraft.js +140 -9
- package/dist/esm/composables/useFormDraft.js.map +1 -1
- package/dist/esm/composables/useListView.js +4 -4
- package/dist/esm/composables/useListView.js.map +1 -1
- package/dist/esm/index.js +21 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js +28 -20
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js +9 -0
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection.js +21 -0
- package/dist/esm/integrations/builtin/field-inspection.js.map +1 -1
- package/dist/esm/integrations/offline/checklistSubmission.js +141 -0
- package/dist/esm/integrations/offline/checklistSubmission.js.map +1 -0
- package/dist/esm/integrations/offline/fieldCollectionHelpers.js +70 -5
- package/dist/esm/integrations/offline/fieldCollectionHelpers.js.map +1 -1
- package/dist/esm/integrations/offline/index.js +2 -1
- package/dist/esm/integrations/offline/index.js.map +1 -1
- package/dist/esm/integrations/offline/offlineDb.js +6 -1
- package/dist/esm/integrations/offline/offlineDb.js.map +1 -1
- package/dist/esm/integrations/offline/syncReplayService.js +8 -2
- package/dist/esm/integrations/offline/syncReplayService.js.map +1 -1
- package/dist/esm/l10n/en.json.js +20 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +70 -2
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +2192 -222
- package/dist/esm/utils/contentHeaderLink.js +51 -0
- package/dist/esm/utils/contentHeaderLink.js.map +1 -0
- package/dist/esm/utils/detailActionModel.js +60 -3
- package/dist/esm/utils/detailActionModel.js.map +1 -1
- package/dist/esm/utils/facets.js +75 -3
- package/dist/esm/utils/facets.js.map +1 -1
- package/dist/esm/utils/fetchFilterCounts.js +40 -5
- package/dist/esm/utils/fetchFilterCounts.js.map +1 -1
- package/dist/esm/utils/fillTemplate.js +120 -0
- package/dist/esm/utils/fillTemplate.js.map +1 -0
- package/dist/esm/utils/initials.js +32 -0
- package/dist/esm/utils/initials.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +11 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/objectWrite.js +59 -0
- package/dist/esm/utils/objectWrite.js.map +1 -0
- package/dist/esm/utils/pageControls.js +81 -0
- package/dist/esm/utils/pageControls.js.map +1 -0
- package/dist/esm/utils/personalLenses.js +40 -3
- package/dist/esm/utils/personalLenses.js.map +1 -1
- package/dist/esm/utils/queryPresets.js +96 -0
- package/dist/esm/utils/queryPresets.js.map +1 -0
- package/dist/esm/utils/resolveFilterTokens.js +12 -1
- package/dist/esm/utils/resolveFilterTokens.js.map +1 -1
- package/dist/esm/utils/resolveManifestTokens.js +2 -0
- package/dist/esm/utils/resolveManifestTokens.js.map +1 -1
- package/dist/esm/utils/schema.js +21 -0
- package/dist/esm/utils/schema.js.map +1 -1
- package/dist/esm/utils/sentinelTokens.js +22 -4
- package/dist/esm/utils/sentinelTokens.js.map +1 -1
- package/dist/esm/utils/userGroupsPeek.js +91 -0
- package/dist/esm/utils/userGroupsPeek.js.map +1 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/esm/utils/visibleWhen.js +57 -5
- package/dist/esm/utils/visibleWhen.js.map +1 -1
- package/dist/esm/utils/widgetDispatch.js +7 -1
- package/dist/esm/utils/widgetDispatch.js.map +1 -1
- package/dist/esm/utils/widgetVisibility.js +4 -57
- package/dist/esm/utils/widgetVisibility.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +19708 -9301
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +2192 -222
- package/l10n/en.json +20 -1
- package/l10n/nl.json +70 -2
- package/package.json +2 -1
- package/scripts/check-docs-mdx.mjs +108 -0
- package/src/components/CnActionButtons/CnActionButtons.vue +2 -0
- package/src/components/CnActionsBar/CnActionsBar.md +4 -0
- package/src/components/CnActionsBar/CnActionsBar.vue +48 -11
- package/src/components/CnAppRoot/CnAppRoot.md +4 -2
- package/src/components/CnAppRoot/CnAppRoot.vue +151 -59
- package/src/components/CnBannerWidget/CnBannerWidget.vue +244 -23
- package/src/components/CnCellRenderer/CnCellRenderer.md +2 -0
- package/src/components/CnCellRenderer/CnCellRenderer.vue +235 -5
- package/src/components/CnChipsFieldWidget/CnChipsFieldWidget.vue +433 -0
- package/src/components/CnChipsFieldWidget/index.js +25 -0
- package/src/components/CnChoicePickerWidget/CnChoicePickerWidget.vue +556 -0
- package/src/components/CnChoicePickerWidget/index.js +26 -0
- package/src/components/CnConversationThread/CnConversationWidget.vue +1 -1
- package/src/components/CnDashboardGrid/CnDashboardGrid.vue +2 -2
- package/src/components/CnDashboardPage/CnDashboardPage.vue +78 -5
- package/src/components/CnDataTable/CnDataTable.vue +22 -12
- package/src/components/CnDetailPage/CnDetailPage.md +1 -1
- package/src/components/CnDetailPage/CnDetailPage.vue +152 -6
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +66 -0
- package/src/components/CnDocumentReviewList/CnDocumentReviewWidget.vue +1 -1
- package/src/components/CnFacetSidebar/CnFacetSidebar.vue +7 -7
- package/src/components/CnFactsWidget/CnFactsWidget.vue +1190 -0
- package/src/components/CnFactsWidget/index.js +29 -0
- package/src/components/CnFieldListWidget/CnFieldListWidget.vue +1008 -0
- package/src/components/CnFieldListWidget/index.js +28 -0
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +588 -117
- package/src/components/CnFilesBrowser/filesBrowser.js +100 -0
- package/src/components/CnFilesBrowser/filesBrowserColumns.js +140 -0
- package/src/components/CnFormDialog/CnFormDialog.md +9 -3
- package/src/components/CnFormDialog/CnFormDialog.vue +69 -21
- package/src/components/CnFormPage/CnFormPage.vue +99 -3
- package/src/components/CnIndexPage/CnIndexPage.vue +309 -9
- package/src/components/CnIndexPage/CnIndexPageWidgets.vue +169 -0
- package/src/components/CnIndexSidebar/CnIndexSidebar.vue +7 -7
- package/src/components/CnNextStepCard/CnNextStepWidget.vue +1 -1
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +69 -2
- package/src/components/CnObjectSidebar/CnFilesTab.vue +70 -1
- package/src/components/CnObjectSidebar/CnNotesTab.vue +16 -0
- package/src/components/CnPageRenderer/CnPageRenderer.vue +29 -1
- package/src/components/CnRadioCardsWidget/CnRadioCardsWidget.vue +313 -0
- package/src/components/CnRadioCardsWidget/index.js +27 -0
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +652 -0
- package/src/components/CnRecordListWidget/index.js +30 -0
- package/src/components/CnSavedViewsWidget/CnSavedViewsWidget.vue +296 -0
- package/src/components/CnSavedViewsWidget/index.js +29 -0
- package/src/components/CnSectionsWidget/CnSectionsWidget.vue +489 -0
- package/src/components/CnSectionsWidget/index.js +34 -0
- package/src/components/CnSegmentedControl/CnSegmentedControl.vue +13 -0
- package/src/components/CnSettingsFormWidget/CnSettingsFormWidget.vue +555 -0
- package/src/components/CnSettingsFormWidget/index.js +26 -0
- package/src/components/CnStagesWidget/CnStagesWidget.vue +81 -2
- package/src/components/CnStatWidget/CnStatWidget.vue +88 -7
- package/src/components/CnStatsBlockWidget/CnStatsBlockWidget.vue +180 -3
- package/src/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue +226 -0
- package/src/components/CnSwitchRowsWidget/index.js +25 -0
- package/src/components/CnTabsWidget/CnTabsWidget.vue +263 -8
- package/src/components/CnTasksWidget/CnTasksWidget.vue +175 -15
- package/src/components/CnToggleTableWidget/CnToggleTableWidget.vue +386 -0
- package/src/components/CnToggleTableWidget/index.js +26 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +11 -0
- package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +7 -2
- package/src/components/CnWidgetObjectTable/dashboardRegistration.js +5 -0
- package/src/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue +493 -11
- package/src/components/index.js +19 -0
- package/src/composables/__tests__/useFormDraft.spec.js +69 -0
- package/src/composables/useFormDraft.js +139 -8
- package/src/composables/useListView.js +4 -4
- package/src/css/form-field.css +14 -0
- package/src/css/index-page.css +71 -0
- package/src/css/kpi-card.css +32 -0
- package/src/css/look-board-detail.css +113 -2
- package/src/css/look-board-index.css +90 -8
- package/src/css/look-board.css +109 -2
- package/src/css/table.css +19 -0
- package/src/index.js +19 -0
- package/src/integrations/builtin/field-inspection/CnFieldInspectionCard.vue +35 -20
- package/src/integrations/builtin/field-inspection.js +21 -0
- package/src/integrations/offline/checklistSubmission.js +137 -0
- package/src/integrations/offline/fieldCollectionHelpers.js +69 -4
- package/src/integrations/offline/index.js +3 -0
- package/src/integrations/offline/offlineDb.js +6 -1
- package/src/integrations/offline/syncReplayService.js +8 -2
- package/src/schemas/app-manifest-v2.schema.json +196 -13
- package/src/utils/contentHeaderLink.js +48 -0
- package/src/utils/detailActionModel.js +59 -2
- package/src/utils/facets.js +74 -2
- package/src/utils/fetchFilterCounts.js +39 -4
- package/src/utils/fillTemplate.js +116 -0
- package/src/utils/initials.js +29 -0
- package/src/utils/libraryWidgetKeys.js +11 -0
- package/src/utils/objectWrite.js +55 -0
- package/src/utils/pageControls.js +78 -0
- package/src/utils/personalLenses.js +39 -2
- package/src/utils/queryPresets.js +93 -0
- package/src/utils/resolveFilterTokens.js +14 -1
- package/src/utils/resolveManifestTokens.js +2 -0
- package/src/utils/schema.js +21 -0
- package/src/utils/sentinelTokens.js +22 -4
- package/src/utils/userGroupsPeek.js +87 -0
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/visibleWhen.js +56 -4
- package/src/utils/widgetDispatch.js +7 -1
- package/src/utils/widgetVisibility.js +7 -56
|
@@ -452,6 +452,7 @@
|
|
|
452
452
|
:layout="section.layout"
|
|
453
453
|
:editable="section.editable"
|
|
454
454
|
:columns="columns"
|
|
455
|
+
:columnOpts="gridColumnOpts"
|
|
455
456
|
:cellHeight="cellHeight"
|
|
456
457
|
:margin="gridMargin"
|
|
457
458
|
:float="gridFloat"
|
|
@@ -933,7 +934,8 @@ import { normalizeLook } from '../../composables/useLook.js'
|
|
|
933
934
|
import { pageViews } from '../../mixins/pageViews.js'
|
|
934
935
|
import { mergeUserLayout, resolveUserLayoutApi } from '../../store/plugins/dashboardLayouts.js'
|
|
935
936
|
import { isAppInstalled } from '../../utils/appInstalled.js'
|
|
936
|
-
import {
|
|
937
|
+
import { contentHeaderLink } from '../../utils/contentHeaderLink.js'
|
|
938
|
+
import { compareVisibleWhen, evaluateWorkspaceCondition, isWorkspaceCondition, readVisibleWhenValue } from '../../utils/visibleWhen.js'
|
|
937
939
|
import { canonicalWidgetType } from '../../utils/widgetTypeAliases.js'
|
|
938
940
|
import { CnActionButtons } from '../CnActionButtons/index.js'
|
|
939
941
|
import { CnActionsMenu } from '../CnActionsMenu/index.js'
|
|
@@ -2082,6 +2084,22 @@ export default {
|
|
|
2082
2084
|
return this.compactDisplayLayout(visible)
|
|
2083
2085
|
},
|
|
2084
2086
|
|
|
2087
|
+
/**
|
|
2088
|
+
* The responsive columns of the grid. Under the board look a phone gets
|
|
2089
|
+
* one column: below 640px the widgets stack in reading order (top to
|
|
2090
|
+
* bottom, then left to right) instead of squeezing six columns into
|
|
2091
|
+
* 150px. Without the board look the grid keeps its fixed columns.
|
|
2092
|
+
*
|
|
2093
|
+
* @return {object|null} GridStack `columnOpts`, or null.
|
|
2094
|
+
* @spec openspec/changes/screens-dashboard-phone/specs/dashboard-phone/spec.md#requirement-a-board-dashboard-stacks-on-a-phone
|
|
2095
|
+
*/
|
|
2096
|
+
gridColumnOpts() {
|
|
2097
|
+
if (!this.isBoardLook) {
|
|
2098
|
+
return null
|
|
2099
|
+
}
|
|
2100
|
+
return { columnMax: this.columns, breakpoints: [{ w: 640, c: 1 }], layout: 'list', breakpointForWindow: true }
|
|
2101
|
+
},
|
|
2102
|
+
|
|
2085
2103
|
/**
|
|
2086
2104
|
* The layout this page renders: the user's arrangement when they have
|
|
2087
2105
|
* one, the manifest otherwise.
|
|
@@ -2256,6 +2274,10 @@ export default {
|
|
|
2256
2274
|
const items = []
|
|
2257
2275
|
for (const id of ids) {
|
|
2258
2276
|
if (this.getWidgetDef(id) || this.hasWidgetSlot(id)) {
|
|
2277
|
+
// A tile a page control hides surrenders its cell.
|
|
2278
|
+
if (!this.gridEditable && this.isHiddenByWorkspace(id)) {
|
|
2279
|
+
continue
|
|
2280
|
+
}
|
|
2259
2281
|
items.push({ widgetId: id })
|
|
2260
2282
|
} else if (process.env.NODE_ENV !== 'production') {
|
|
2261
2283
|
// eslint-disable-next-line no-console
|
|
@@ -3401,7 +3423,8 @@ export default {
|
|
|
3401
3423
|
const layout = content.layout || props.layout || ''
|
|
3402
3424
|
const title = layout === 'attention' ? (content.title || props.title || '') : ''
|
|
3403
3425
|
return {
|
|
3404
|
-
|
|
3426
|
+
// A banner with only a bold `lead` has words to show too.
|
|
3427
|
+
text: content.text || props.text || content.lead || props.lead || title || '',
|
|
3405
3428
|
visibleWhen: (def && def.visibleWhen) || content.visibleWhen || props.visibleWhen || null,
|
|
3406
3429
|
layout,
|
|
3407
3430
|
}
|
|
@@ -3435,6 +3458,11 @@ export default {
|
|
|
3435
3458
|
if (!visibleWhen) {
|
|
3436
3459
|
return false
|
|
3437
3460
|
}
|
|
3461
|
+
// A workspace condition (a page control's choice) is answered at
|
|
3462
|
+
// once from the reactive bag; nothing is fetched for it.
|
|
3463
|
+
if (isWorkspaceCondition(visibleWhen)) {
|
|
3464
|
+
return !evaluateWorkspaceCondition(visibleWhen, this.workspaceContext)
|
|
3465
|
+
}
|
|
3438
3466
|
const outcome = this.widgetConditionOutcome[item.widgetId]
|
|
3439
3467
|
if (outcome && outcome.failed === true && layout === 'attention' && this.isBannerDef(def)) {
|
|
3440
3468
|
return false
|
|
@@ -3442,6 +3470,23 @@ export default {
|
|
|
3442
3470
|
return !outcome || outcome.met !== true
|
|
3443
3471
|
},
|
|
3444
3472
|
|
|
3473
|
+
/**
|
|
3474
|
+
* Whether a page control (a workspace condition on `visibleWhen`)
|
|
3475
|
+
* hides this widget right now. Other conditions are not looked at.
|
|
3476
|
+
*
|
|
3477
|
+
* @param {string} widgetId The widget id.
|
|
3478
|
+
* @return {boolean} True when the widget must not draw.
|
|
3479
|
+
* @spec openspec/changes/screens-page-lenses/specs/page-lenses/spec.md#requirement-a-widget-can-be-shown-by-a-workspace-value
|
|
3480
|
+
*/
|
|
3481
|
+
isHiddenByWorkspace(widgetId) {
|
|
3482
|
+
const def = this.getWidgetDef(widgetId)
|
|
3483
|
+
if (!def || !def.type) {
|
|
3484
|
+
return false
|
|
3485
|
+
}
|
|
3486
|
+
const { visibleWhen } = this.widgetDisplayConfig(def)
|
|
3487
|
+
return isWorkspaceCondition(visibleWhen) && !evaluateWorkspaceCondition(visibleWhen, this.workspaceContext)
|
|
3488
|
+
},
|
|
3489
|
+
|
|
3445
3490
|
/**
|
|
3446
3491
|
* Evaluate every conditional widget's `visibleWhen` into
|
|
3447
3492
|
* `widgetConditionOutcome` — the verdict AND the raw field value,
|
|
@@ -3464,7 +3509,8 @@ export default {
|
|
|
3464
3509
|
async evaluateWidgetConditions() {
|
|
3465
3510
|
const defs = [...(this.widgets || []), ...this.normalizedViews.flatMap((view) => view.widgets)]
|
|
3466
3511
|
const conditional = defs.filter((def) => def && def.id && def.type
|
|
3467
|
-
&& this.widgetDisplayConfig(def).visibleWhen
|
|
3512
|
+
&& this.widgetDisplayConfig(def).visibleWhen
|
|
3513
|
+
&& !isWorkspaceCondition(this.widgetDisplayConfig(def).visibleWhen))
|
|
3468
3514
|
// Skip when the CONDITIONAL SET is unchanged: the deep `widgets`
|
|
3469
3515
|
// watch fires on any def edit, but only an added/removed/edited
|
|
3470
3516
|
// predicate warrants refetching every conditional endpoint.
|
|
@@ -3484,8 +3530,13 @@ export default {
|
|
|
3484
3530
|
const cond = this.widgetDisplayConfig(def).visibleWhen
|
|
3485
3531
|
let outcome
|
|
3486
3532
|
try {
|
|
3487
|
-
|
|
3533
|
+
// `sink` keeps the first row of a source query, for a banner that names it.
|
|
3534
|
+
const sink = {}
|
|
3535
|
+
const value = await readVisibleWhenValue(cond, undefined, sink)
|
|
3488
3536
|
outcome = { met: compareVisibleWhen(value, cond.op || 'eq', cond.value), value }
|
|
3537
|
+
if (sink.row) {
|
|
3538
|
+
outcome.row = sink.row
|
|
3539
|
+
}
|
|
3489
3540
|
} catch (error) {
|
|
3490
3541
|
// Fail-safe: not met. But the failure is kept, and said
|
|
3491
3542
|
// out loud: a failed count and "nothing to report" look
|
|
@@ -3985,6 +4036,11 @@ export default {
|
|
|
3985
4036
|
const def = this.getWidgetDef(item.widgetId)
|
|
3986
4037
|
const value = item.showTitle !== undefined ? item.showTitle : def?.showTitle
|
|
3987
4038
|
if (value === undefined || value === null) {
|
|
4039
|
+
// A banner that names no title draws no title row: it used to show
|
|
4040
|
+
// its widget id ("attention-first") as the card title.
|
|
4041
|
+
if (this.isBannerDef(def) && !item.customTitle && !def?.customTitle && !def?.title) {
|
|
4042
|
+
return false
|
|
4043
|
+
}
|
|
3988
4044
|
return !this.isCardWidget(item)
|
|
3989
4045
|
}
|
|
3990
4046
|
return value !== false
|
|
@@ -4093,7 +4149,12 @@ export default {
|
|
|
4093
4149
|
return item.headerLink
|
|
4094
4150
|
}
|
|
4095
4151
|
const def = this.getWidgetDef(item.widgetId)
|
|
4096
|
-
|
|
4152
|
+
if (def?.headerLink && typeof def.headerLink === 'object') {
|
|
4153
|
+
return def.headerLink
|
|
4154
|
+
}
|
|
4155
|
+
// Last, what the widget's own content asks for (`headerLink`, or the
|
|
4156
|
+
// `viewAllRoute` / `viewAllLabel` of the tasks widget).
|
|
4157
|
+
return contentHeaderLink(item?.content) || contentHeaderLink(def?.content)
|
|
4097
4158
|
},
|
|
4098
4159
|
|
|
4099
4160
|
/**
|
|
@@ -4842,6 +4903,18 @@ export default {
|
|
|
4842
4903
|
.cn-dashboard-page__content-item {
|
|
4843
4904
|
width: 100%;
|
|
4844
4905
|
}
|
|
4906
|
+
/* On a phone (screens-dashboard-phone) the touch targets of a board dashboard
|
|
4907
|
+
are 44px: the widget Actions menu and the KPI tiles. */
|
|
4908
|
+
@media (max-width: 640px) {
|
|
4909
|
+
.cn-dashboard-page--board :deep(.cn-widget-wrapper__actions .action-item__menutoggle),
|
|
4910
|
+
.cn-dashboard-page--board :deep(.cn-widget-wrapper__actions .button-vue) {
|
|
4911
|
+
min-height: 44px;
|
|
4912
|
+
}
|
|
4913
|
+
|
|
4914
|
+
.cn-dashboard-page--board .cn-dashboard-page__kpi-cell {
|
|
4915
|
+
min-height: 44px;
|
|
4916
|
+
}
|
|
4917
|
+
}
|
|
4845
4918
|
</style>
|
|
4846
4919
|
|
|
4847
4920
|
<!-- Unscoped, anchored on the stable `data-testid` NcActions renders on both
|
|
@@ -130,6 +130,7 @@
|
|
|
130
130
|
col.class || '',
|
|
131
131
|
pinClass(leadingCount + colIndex),
|
|
132
132
|
isGrowColumn(col) ? 'cn-table-col--grow' : '',
|
|
133
|
+
colIndex === 0 ? 'cn-table-head--title' : '',
|
|
133
134
|
]"
|
|
134
135
|
:style="{ ...(col.width ? { width: col.width } : {}), ...pinStyle(leadingCount + colIndex) }"
|
|
135
136
|
:aria-sort="ariaSortFor(col)"
|
|
@@ -320,6 +321,7 @@
|
|
|
320
321
|
:formatterOptions="col.formatterOptions || null"
|
|
321
322
|
:widget="col.widget || null"
|
|
322
323
|
:widgetProps="col.widgetProps || undefined"
|
|
324
|
+
:secondary="col.widget === 'avatar' ? secondaryValue(row, col) : ''"
|
|
323
325
|
:format="columnFormat(col)"
|
|
324
326
|
:row="row"
|
|
325
327
|
:rowKey="rowKey" />
|
|
@@ -329,7 +331,7 @@
|
|
|
329
331
|
of the row. Lets one column read "title" over "number ·
|
|
330
332
|
requester" without a custom cell. -->
|
|
331
333
|
<span
|
|
332
|
-
v-if="secondaryValue(row, col)"
|
|
334
|
+
v-if="col.widget !== 'avatar' && secondaryValue(row, col)"
|
|
333
335
|
class="cn-table-cell__secondary"
|
|
334
336
|
data-testid="cn-cell-secondary">{{ secondaryValue(row, col) }}</span>
|
|
335
337
|
<!-- A row that entered a file-content search through an attached
|
|
@@ -1764,17 +1766,6 @@ export default {
|
|
|
1764
1766
|
return (col && typeof col.format === 'object') ? col.format : null
|
|
1765
1767
|
},
|
|
1766
1768
|
|
|
1767
|
-
/**
|
|
1768
|
-
* Value to render in a cell. For a column that declares `aggregate`
|
|
1769
|
-
* (a count of related objects), returns the cached count once
|
|
1770
|
-
* `loadAggregates()` has resolved it (or `'…'` while pending, `'—'`
|
|
1771
|
-
* if it failed / there's nothing to count). Otherwise the row's
|
|
1772
|
-
* property value via `getCellValue`.
|
|
1773
|
-
*
|
|
1774
|
-
* @param {object} row The row data.
|
|
1775
|
-
* @param {object} col The column definition.
|
|
1776
|
-
* @return {unknown} The value handed to the slot / CnCellRenderer.
|
|
1777
|
-
*/
|
|
1778
1769
|
/**
|
|
1779
1770
|
* The secondary line of a cell, from `col.secondary`: a function is
|
|
1780
1771
|
* called with the row; a string with `{field}` placeholders is a
|
|
@@ -1805,6 +1796,21 @@ export default {
|
|
|
1805
1796
|
return asText(this.getCellValue(row, spec))
|
|
1806
1797
|
},
|
|
1807
1798
|
|
|
1799
|
+
/**
|
|
1800
|
+
* Value to render in a cell. For a column that declares `aggregate`
|
|
1801
|
+
* (a count of related objects), returns the cached count once
|
|
1802
|
+
* `loadAggregates()` has resolved it (or `'…'` while pending, `'—'`
|
|
1803
|
+
* if it failed / there's nothing to count). A count of zero reads as
|
|
1804
|
+
* `aggregate.zeroLabel` when the column sets one ("None", which the
|
|
1805
|
+
* app's `cnTranslate` turns into "Geen" as the boards draw it); without
|
|
1806
|
+
* it the cell shows `0` as before. Otherwise the row's property value
|
|
1807
|
+
* via `getCellValue`.
|
|
1808
|
+
*
|
|
1809
|
+
* @spec openspec/changes/aggregate-zero-label/specs/aggregate-zero-label/spec.md#requirement-a-count-column-can-name-zero
|
|
1810
|
+
* @param {object} row The row data.
|
|
1811
|
+
* @param {object} col The column definition.
|
|
1812
|
+
* @return {unknown} The value handed to the slot / CnCellRenderer.
|
|
1813
|
+
*/
|
|
1808
1814
|
cellValue(row, col) {
|
|
1809
1815
|
if (col && col.aggregate) {
|
|
1810
1816
|
const cached = this.aggregateValues[String(row[this.rowKey])]
|
|
@@ -1812,6 +1818,10 @@ export default {
|
|
|
1812
1818
|
if (v === undefined) {
|
|
1813
1819
|
return this.aggregateLoading ? '…' : '—'
|
|
1814
1820
|
}
|
|
1821
|
+
const zeroLabel = col.aggregate.zeroLabel
|
|
1822
|
+
if ((v === 0 || v === '0') && typeof zeroLabel === 'string' && zeroLabel !== '') {
|
|
1823
|
+
return typeof this.cnTranslate === 'function' ? this.cnTranslate(zeroLabel) : zeroLabel
|
|
1824
|
+
}
|
|
1815
1825
|
return v
|
|
1816
1826
|
}
|
|
1817
1827
|
return this.getCellValue(row, col.key)
|
|
@@ -422,7 +422,7 @@ Four levels of action and the case surfaces around them. All opt in. See [the re
|
|
|
422
422
|
| `quickActions` | Array | `[]` | At most three always visible header buttons. |
|
|
423
423
|
| `actionsMenu` | Object \| null | `null` | `{ showRefresh?, showHelpLinks?, label? }` for the overflow menu. |
|
|
424
424
|
| `nextStep` | Object \| null | `null` | The "what now" card per stage, rendered by `CnNextStepCard`. |
|
|
425
|
-
| `typePill` | Object \| null | `null` | `{ field, colorMap?, labels?, variant? }`, a pill above the title. |
|
|
425
|
+
| `typePill` | Object \| null | `null` | `{ field, colorMap?, labels?, variant? }`, a pill above the title. Instead of `field`: `text` (a constant) or `countFrom` + `countLabel` (a count of a related list). |
|
|
426
426
|
| `statusPill` | Object \| null | `null` | A second pill, same shape. |
|
|
427
427
|
| `headerFields` | Array | `[]` | Fields shown as chips under the title (manifest `config.headerFields`). Each entry is a property key, or `{ key, format, labelField, colorField, warnWhenPast }`; `format` is `text` (default), `mono`, `badge`, `user` or `date`. A `$ref` value shows `labelField` of the referenced object and falls back to the raw id in mono; a badge maps `colorField` (`success`, `warning`, `error`, `info`, `neutral`) to a variant; `warnWhenPast` gives a past date the error variant. An empty value shows no chip, a page without the key shows no row. Each chip reads "Title: value" to a screen reader, and the row prints as plain text. |
|
|
428
428
|
| `sideColumn` | Array | `[]` | Widget definitions or widget ids, rendered as a column of cards beside the body. |
|
|
@@ -379,7 +379,7 @@
|
|
|
379
379
|
:showDocumentation="showDocumentation && menuShowsHelpLinks"
|
|
380
380
|
:actionsMenuLabel="boardMenuLabel"
|
|
381
381
|
:variant="isBoard ? 'secondary' : undefined"
|
|
382
|
-
:hasPrimaryItems="headerMenuGroups.length > 0 || showMarkUnread"
|
|
382
|
+
:hasPrimaryItems="headerMenuGroups.length > 0 || showMarkUnread || showOpenSidebar"
|
|
383
383
|
:documentationUrl="documentationUrl"
|
|
384
384
|
:docsAnchor="resolvedPageId"
|
|
385
385
|
:documentationLabel="documentationLabel || undefined"
|
|
@@ -390,7 +390,7 @@
|
|
|
390
390
|
testidBase="cn-detail-page"
|
|
391
391
|
@refresh="onHeaderRefresh"
|
|
392
392
|
@requestFeature="onHeaderRequestFeature">
|
|
393
|
-
<template v-if="headerMenuGroups.length || showMarkUnread" #primary-items>
|
|
393
|
+
<template v-if="headerMenuGroups.length || showMarkUnread || showOpenSidebar" #primary-items>
|
|
394
394
|
<!-- One block per group. A page that groups nothing has
|
|
395
395
|
a single captionless group, and renders exactly the
|
|
396
396
|
flat list it always did. -->
|
|
@@ -449,6 +449,20 @@
|
|
|
449
449
|
</template>
|
|
450
450
|
{{ markUnreadLabel }}
|
|
451
451
|
</NcActionButton>
|
|
452
|
+
<!-- Board look: the sidebar's own open toggle is hidden (it sat
|
|
453
|
+
over the header's last button, where the board draws none), so
|
|
454
|
+
the menu opens it. -->
|
|
455
|
+
<NcActionButton
|
|
456
|
+
v-if="showOpenSidebar"
|
|
457
|
+
key="open-sidebar"
|
|
458
|
+
data-testid="cn-detail-page-open-sidebar"
|
|
459
|
+
:closeAfterClick="true"
|
|
460
|
+
@click="openSidebar">
|
|
461
|
+
<template #icon>
|
|
462
|
+
<DockRight :size="20" />
|
|
463
|
+
</template>
|
|
464
|
+
{{ openSidebarLabel }}
|
|
465
|
+
</NcActionButton>
|
|
452
466
|
<!-- Divides the page's own actions from the help links
|
|
453
467
|
below. With the help links switched off there is
|
|
454
468
|
nothing below to divide from. -->
|
|
@@ -745,7 +759,7 @@
|
|
|
745
759
|
:layout="section.layout"
|
|
746
760
|
:editable="section.editable"
|
|
747
761
|
:columns="12"
|
|
748
|
-
:columnOpts="
|
|
762
|
+
:columnOpts="bodyColumnOpts"
|
|
749
763
|
class="cn-detail-page__grid"
|
|
750
764
|
@layoutChange="section.view ? onViewLayoutChange($event) : onBodyLayoutChange($event)">
|
|
751
765
|
<template #widget="{ item }">
|
|
@@ -1191,6 +1205,7 @@ import Check from 'vue-material-design-icons/Check.vue'
|
|
|
1191
1205
|
import ChevronLeft from 'vue-material-design-icons/ChevronLeft.vue'
|
|
1192
1206
|
import ChevronRight from 'vue-material-design-icons/ChevronRight.vue'
|
|
1193
1207
|
import Cog from 'vue-material-design-icons/Cog.vue'
|
|
1208
|
+
import DockRight from 'vue-material-design-icons/DockRight.vue'
|
|
1194
1209
|
import EyeOffOutline from 'vue-material-design-icons/EyeOffOutline.vue'
|
|
1195
1210
|
import FileQuestionOutline from 'vue-material-design-icons/FileQuestionOutline.vue'
|
|
1196
1211
|
import InformationOutline from 'vue-material-design-icons/InformationOutline.vue'
|
|
@@ -1231,12 +1246,15 @@ import {
|
|
|
1231
1246
|
groupMenuEntries,
|
|
1232
1247
|
MAX_QUICK_ACTIONS,
|
|
1233
1248
|
normalisePinnedAction,
|
|
1249
|
+
pillCountSource,
|
|
1250
|
+
resolveCountPill,
|
|
1234
1251
|
resolveNextStep,
|
|
1235
1252
|
resolvePill,
|
|
1236
1253
|
stageEntry,
|
|
1237
1254
|
stageOf,
|
|
1238
1255
|
} from '../../utils/detailActionModel.js'
|
|
1239
1256
|
import { reportBindingProblems } from '../../utils/diagnostics.js'
|
|
1257
|
+
import { fetchListTotal } from '../../utils/fetchFilterCounts.js'
|
|
1240
1258
|
import { cnGridCellStyle, hasGridRow } from '../../utils/grid.js'
|
|
1241
1259
|
import { isActivityWidget, resolveHeaderMeta } from '../../utils/headerMeta.js'
|
|
1242
1260
|
import { patchStoredSelf } from '../../utils/patchStoredSelf.js'
|
|
@@ -1292,6 +1310,35 @@ const DEFAULT_DETAIL_COLUMN_OPTS = Object.freeze({
|
|
|
1292
1310
|
breakpointForWindow: false,
|
|
1293
1311
|
})
|
|
1294
1312
|
|
|
1313
|
+
/**
|
|
1314
|
+
* Where the default table stacks when a side column sits beside the body grid.
|
|
1315
|
+
*
|
|
1316
|
+
* The side column takes about 320px, so the grid it leaves is far narrower than
|
|
1317
|
+
* the page: 790px at a 1100px window. Stacking that at 1000px made a row of
|
|
1318
|
+
* small tiles (a KPI row of 5 or 6 stat tiles) impossible beside a side column.
|
|
1319
|
+
* 1000px exists to keep a `gridWidth: 3` side PANEL inside the grid readable; a
|
|
1320
|
+
* page with a real side column has no such panel, and 12 columns at 600px is
|
|
1321
|
+
* still 50px a column, enough for a tile. Below 600px it stacks as before.
|
|
1322
|
+
*/
|
|
1323
|
+
const SIDE_COLUMN_STACK_WIDTH = 600
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* Whether `opts` is the untouched default table, so a page that passed its own
|
|
1327
|
+
* `columnOpts` keeps exactly what it asked for.
|
|
1328
|
+
*
|
|
1329
|
+
* @param {object|null} opts The `columnOpts` value.
|
|
1330
|
+
* @return {boolean}
|
|
1331
|
+
*/
|
|
1332
|
+
function isDefaultColumnOpts(opts) {
|
|
1333
|
+
const breakpoints = opts && opts.breakpoints
|
|
1334
|
+
return !!opts
|
|
1335
|
+
&& opts.columnMax === DEFAULT_DETAIL_COLUMN_OPTS.columnMax
|
|
1336
|
+
&& Array.isArray(breakpoints)
|
|
1337
|
+
&& breakpoints.length === 1
|
|
1338
|
+
&& breakpoints[0].w === DEFAULT_DETAIL_COLUMN_OPTS.breakpoints[0].w
|
|
1339
|
+
&& breakpoints[0].c === 1
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1295
1342
|
/**
|
|
1296
1343
|
* Event-bus channel a page-level refresh is announced on. The page's own
|
|
1297
1344
|
* Actions menu emits it, the manifest `refresh` / `api-call` actions bump it,
|
|
@@ -1408,6 +1455,7 @@ export default {
|
|
|
1408
1455
|
CnSummaryAggregates,
|
|
1409
1456
|
CnDetailHeaderChips,
|
|
1410
1457
|
CnFollowToggle,
|
|
1458
|
+
DockRight,
|
|
1411
1459
|
EyeOffOutline,
|
|
1412
1460
|
CnRelatedCollections,
|
|
1413
1461
|
CnBodySections,
|
|
@@ -2393,9 +2441,13 @@ export default {
|
|
|
2393
2441
|
* A pill above the title saying what kind of record this is
|
|
2394
2442
|
* (manifest `config.typePill`): `{ field, colorMap?, labels?, variant? }`.
|
|
2395
2443
|
* Rendered through `CnStatusBadge`; `colorMap` is keyed on the field's
|
|
2396
|
-
* raw value, `labels` maps a raw value to the text to show.
|
|
2444
|
+
* raw value, `labels` maps a raw value to the text to show. Instead of
|
|
2445
|
+
* `field`: `text`, a constant ("Inwoner"), or `countFrom`
|
|
2446
|
+
* (`{ register, schema, filter? }`) with `countLabel` (`{ one, other }`
|
|
2447
|
+
* with `{count}`), a count of a related list ("1 lopende zaak") that
|
|
2448
|
+
* shows nothing at 0.
|
|
2397
2449
|
*
|
|
2398
|
-
* @type {{field
|
|
2450
|
+
* @type {{field?: string, text?: string, countFrom?: object, countLabel?: object, colorMap?: object, labels?: object, variant?: string}|null}
|
|
2399
2451
|
*/
|
|
2400
2452
|
typePill: {
|
|
2401
2453
|
type: Object,
|
|
@@ -2747,6 +2799,10 @@ export default {
|
|
|
2747
2799
|
|
|
2748
2800
|
data() {
|
|
2749
2801
|
return {
|
|
2802
|
+
/** The counts of the header's count pills (`countFrom`), by pill key (`type`, `status`). */
|
|
2803
|
+
pillCounts: {},
|
|
2804
|
+
/** Sequence of the last pill count round, so a late answer does not overwrite a newer one. */
|
|
2805
|
+
pillCountSeq: 0,
|
|
2750
2806
|
/** `register/schema/id` the read-state call was last made for, so it is sent once per load. */
|
|
2751
2807
|
readStateSentFor: '',
|
|
2752
2808
|
/** Whether the user is arranging the chosen view (`userLayout`). */
|
|
@@ -3259,12 +3315,25 @@ export default {
|
|
|
3259
3315
|
headerPills() {
|
|
3260
3316
|
return [['type', this.typePill], ['status', this.statusPill]]
|
|
3261
3317
|
.map(([key, config]) => {
|
|
3262
|
-
const pill =
|
|
3318
|
+
const pill = pillCountSource(config)
|
|
3319
|
+
? resolveCountPill(config, this.pillCounts[key], (text) => this.effectiveTranslate(text))
|
|
3320
|
+
: resolvePill(config, this.resolvedObject)
|
|
3263
3321
|
return pill ? { ...pill, key, label: this.effectiveTranslate(pill.label) } : null
|
|
3264
3322
|
})
|
|
3265
3323
|
.filter(Boolean)
|
|
3266
3324
|
},
|
|
3267
3325
|
|
|
3326
|
+
/**
|
|
3327
|
+
* What the count pills depend on: the record id and the lists they
|
|
3328
|
+
* count. A change counts again.
|
|
3329
|
+
*
|
|
3330
|
+
* @return {string} The key.
|
|
3331
|
+
* @spec openspec/changes/screens-relation-pages/specs/relation-pages/spec.md#requirement-a-header-pill-can-be-a-constant-or-a-count
|
|
3332
|
+
*/
|
|
3333
|
+
pillCountKey() {
|
|
3334
|
+
return JSON.stringify([this.objectId, pillCountSource(this.typePill), pillCountSource(this.statusPill)])
|
|
3335
|
+
},
|
|
3336
|
+
|
|
3268
3337
|
/**
|
|
3269
3338
|
* The widget the header holds (`headerWidget`): the definition in
|
|
3270
3339
|
* `widgets` with that id, or null without the key or a match.
|
|
@@ -3311,6 +3380,20 @@ export default {
|
|
|
3311
3380
|
.map(({ widget }) => widget)
|
|
3312
3381
|
},
|
|
3313
3382
|
|
|
3383
|
+
/**
|
|
3384
|
+
* The `columnOpts` the body grid gets: the default table stacks at 1000px
|
|
3385
|
+
* of grid width, or at 600px when a side column narrows the grid. An
|
|
3386
|
+
* explicit `columnOpts` prop is passed through untouched.
|
|
3387
|
+
*
|
|
3388
|
+
* @return {object|null} The column options.
|
|
3389
|
+
*/
|
|
3390
|
+
bodyColumnOpts() {
|
|
3391
|
+
if (!this.showsSideColumn || !isDefaultColumnOpts(this.columnOpts)) {
|
|
3392
|
+
return this.columnOpts
|
|
3393
|
+
}
|
|
3394
|
+
return { ...this.columnOpts, breakpoints: [{ w: SIDE_COLUMN_STACK_WIDTH, c: 1 }] }
|
|
3395
|
+
},
|
|
3396
|
+
|
|
3314
3397
|
/**
|
|
3315
3398
|
* Whether the side column renders.
|
|
3316
3399
|
*
|
|
@@ -3842,6 +3925,22 @@ export default {
|
|
|
3842
3925
|
&& this.register !== '' && this.schema !== '' && this.objectId !== ''
|
|
3843
3926
|
},
|
|
3844
3927
|
|
|
3928
|
+
/**
|
|
3929
|
+
* Whether the header menu offers "Open sidebar": the board look, where the
|
|
3930
|
+
* sidebar's own toggle is hidden, on a page whose sidebar is active and
|
|
3931
|
+
* closed.
|
|
3932
|
+
*
|
|
3933
|
+
* @return {boolean}
|
|
3934
|
+
*/
|
|
3935
|
+
showOpenSidebar() {
|
|
3936
|
+
return this.isBoard && this.hasExternalSidebar && this.sidebarActive && this.objectSidebarState.open !== true
|
|
3937
|
+
},
|
|
3938
|
+
|
|
3939
|
+
/** @return {string} Label of the Open sidebar entry. */
|
|
3940
|
+
openSidebarLabel() {
|
|
3941
|
+
return t('nextcloud-vue', 'Open sidebar')
|
|
3942
|
+
},
|
|
3943
|
+
|
|
3845
3944
|
/** @return {string} Label of the Mark as unread entry. */
|
|
3846
3945
|
markUnreadLabel() {
|
|
3847
3946
|
return t('nextcloud-vue', 'Mark as unread')
|
|
@@ -4337,6 +4436,14 @@ export default {
|
|
|
4337
4436
|
},
|
|
4338
4437
|
|
|
4339
4438
|
watch: {
|
|
4439
|
+
// The header's count pills count again for another record or other lists.
|
|
4440
|
+
pillCountKey: {
|
|
4441
|
+
immediate: true,
|
|
4442
|
+
handler() {
|
|
4443
|
+
this.refreshPillCounts()
|
|
4444
|
+
},
|
|
4445
|
+
},
|
|
4446
|
+
|
|
4340
4447
|
// Opening a record marks it read, once, after its data has rendered.
|
|
4341
4448
|
readStateDue: {
|
|
4342
4449
|
immediate: true,
|
|
@@ -4544,6 +4651,17 @@ export default {
|
|
|
4544
4651
|
},
|
|
4545
4652
|
|
|
4546
4653
|
methods: {
|
|
4654
|
+
/**
|
|
4655
|
+
* Open the object sidebar through the shared channel.
|
|
4656
|
+
*
|
|
4657
|
+
* @return {void}
|
|
4658
|
+
*/
|
|
4659
|
+
openSidebar() {
|
|
4660
|
+
if (this.objectSidebarState) {
|
|
4661
|
+
this.objectSidebarState.open = true
|
|
4662
|
+
}
|
|
4663
|
+
},
|
|
4664
|
+
|
|
4547
4665
|
/**
|
|
4548
4666
|
* Start or finish arranging the chosen view. Finishing stores the
|
|
4549
4667
|
* arrangement of every view the user moved, once.
|
|
@@ -4754,6 +4872,33 @@ export default {
|
|
|
4754
4872
|
}
|
|
4755
4873
|
},
|
|
4756
4874
|
|
|
4875
|
+
/**
|
|
4876
|
+
* Count the lists behind the header's count pills (`countFrom`): one
|
|
4877
|
+
* list request each (`_limit=1`, the `total`). A failed count, or a
|
|
4878
|
+
* record without an id yet, shows no pill.
|
|
4879
|
+
*
|
|
4880
|
+
* @return {Promise<void>}
|
|
4881
|
+
* @spec openspec/changes/screens-relation-pages/specs/relation-pages/spec.md#requirement-a-header-pill-can-be-a-constant-or-a-count
|
|
4882
|
+
*/
|
|
4883
|
+
async refreshPillCounts() {
|
|
4884
|
+
const pills = [['type', this.typePill], ['status', this.statusPill]]
|
|
4885
|
+
.map(([key, config]) => [key, pillCountSource(config)])
|
|
4886
|
+
.filter(([, source]) => source)
|
|
4887
|
+
const seq = ++this.pillCountSeq
|
|
4888
|
+
if (pills.length === 0 || this.objectId === null || this.objectId === undefined || this.objectId === '') {
|
|
4889
|
+
this.pillCounts = {}
|
|
4890
|
+
return
|
|
4891
|
+
}
|
|
4892
|
+
const ctx = { objectId: this.objectId, object: this.resolvedObject || undefined }
|
|
4893
|
+
const counts = {}
|
|
4894
|
+
await Promise.all(pills.map(async ([key, source]) => {
|
|
4895
|
+
counts[key] = await fetchListTotal(source.register, source.schema, source.filter, ctx).catch(() => null)
|
|
4896
|
+
}))
|
|
4897
|
+
if (seq === this.pillCountSeq) {
|
|
4898
|
+
this.pillCounts = counts
|
|
4899
|
+
}
|
|
4900
|
+
},
|
|
4901
|
+
|
|
4757
4902
|
/**
|
|
4758
4903
|
* A `cn:page:refresh` reached the page — re-read the object so every
|
|
4759
4904
|
* object-bound widget re-renders from what the backend now holds.
|
|
@@ -4768,6 +4913,7 @@ export default {
|
|
|
4768
4913
|
* @return {void}
|
|
4769
4914
|
*/
|
|
4770
4915
|
onPageRefreshBus(payload) {
|
|
4916
|
+
this.refreshPillCounts()
|
|
4771
4917
|
if (!this.hasSchemaDrivenFetch) {
|
|
4772
4918
|
return
|
|
4773
4919
|
}
|
|
@@ -169,10 +169,28 @@
|
|
|
169
169
|
:showActions="actionsShown || catalogAddEnabled"
|
|
170
170
|
:showRefresh="false"
|
|
171
171
|
:showRequestFeature="false"
|
|
172
|
+
:headerLink="rendererHeader.link"
|
|
172
173
|
class="cn-detail-page__catalog-card">
|
|
173
174
|
<template v-if="widget.icon" #title-icon>
|
|
174
175
|
<CnIcon :name="widget.icon" :size="20" />
|
|
175
176
|
</template>
|
|
177
|
+
<!-- A renderer that reports its own header (`header` event:
|
|
178
|
+
`{ link, note }`, e.g. record-list's "3 in totaal"). -->
|
|
179
|
+
<template v-if="rendererHeader.note || rendererHeader.action" #actions>
|
|
180
|
+
<span
|
|
181
|
+
v-if="rendererHeader.note"
|
|
182
|
+
class="cn-detail-page__catalog-note"
|
|
183
|
+
data-testid="cn-detail-widget-header-note">{{ rendererHeader.note }}</span>
|
|
184
|
+
<button
|
|
185
|
+
v-if="rendererHeader.action"
|
|
186
|
+
type="button"
|
|
187
|
+
class="cn-detail-page__catalog-action"
|
|
188
|
+
data-testid="cn-detail-widget-header-action"
|
|
189
|
+
@click="rendererHeader.action.run()">
|
|
190
|
+
<CnIcon v-if="rendererHeader.action.icon" :name="rendererHeader.action.icon" :size="16" />
|
|
191
|
+
{{ rendererHeader.action.label }}
|
|
192
|
+
</button>
|
|
193
|
+
</template>
|
|
176
194
|
<template v-if="catalogAddEnabled" #action-items>
|
|
177
195
|
<NcActionButton @click="invokeCatalogAdd">
|
|
178
196
|
<template #icon>
|
|
@@ -185,6 +203,7 @@
|
|
|
185
203
|
:is="renderer"
|
|
186
204
|
ref="renderer"
|
|
187
205
|
v-bind="rendererProps"
|
|
206
|
+
@header="onRendererHeader"
|
|
188
207
|
@selectObject="onSelectObject" />
|
|
189
208
|
</CnWidgetWrapper>
|
|
190
209
|
|
|
@@ -534,6 +553,17 @@ export default {
|
|
|
534
553
|
}
|
|
535
554
|
},
|
|
536
555
|
|
|
556
|
+
data() {
|
|
557
|
+
return {
|
|
558
|
+
/**
|
|
559
|
+
* The card header a content-only renderer reports through its
|
|
560
|
+
* `header` event (screens-relation-pages): a link and a note,
|
|
561
|
+
* with the list's total already filled in.
|
|
562
|
+
*/
|
|
563
|
+
rendererHeader: { link: null, note: '', action: null },
|
|
564
|
+
}
|
|
565
|
+
},
|
|
566
|
+
|
|
537
567
|
computed: {
|
|
538
568
|
/**
|
|
539
569
|
* Whether the caller owns the title and card.
|
|
@@ -992,6 +1022,19 @@ export default {
|
|
|
992
1022
|
},
|
|
993
1023
|
|
|
994
1024
|
methods: {
|
|
1025
|
+
/**
|
|
1026
|
+
* Take the header a content-only renderer reports.
|
|
1027
|
+
*
|
|
1028
|
+
* @param {{link?: object|null, note?: string, action?: {label: string, icon?: string, run: () => unknown}|null}} header The header parts.
|
|
1029
|
+
* @spec openspec/changes/screens-relation-pages/specs/relation-pages/spec.md#requirement-a-record-list-shows-the-objects-that-point-at-this-record
|
|
1030
|
+
*/
|
|
1031
|
+
onRendererHeader(header) {
|
|
1032
|
+
const link = header && header.link && typeof header.link === 'object' ? header.link : null
|
|
1033
|
+
const note = header && typeof header.note === 'string' ? header.note : ''
|
|
1034
|
+
const action = header && header.action && typeof header.action.run === 'function' && header.action.label ? header.action : null
|
|
1035
|
+
this.rendererHeader = { link, note, action }
|
|
1036
|
+
},
|
|
1037
|
+
|
|
995
1038
|
/**
|
|
996
1039
|
* A manifest label through the host's translate; '' stays ''.
|
|
997
1040
|
*
|
|
@@ -1110,6 +1153,29 @@ export default {
|
|
|
1110
1153
|
</script>
|
|
1111
1154
|
|
|
1112
1155
|
<style scoped>
|
|
1156
|
+
.cn-detail-page__catalog-action {
|
|
1157
|
+
align-items: center;
|
|
1158
|
+
background: var(--color-primary-element-light);
|
|
1159
|
+
border: 0;
|
|
1160
|
+
border-radius: 16px;
|
|
1161
|
+
color: var(--color-primary-element-light-text, var(--color-primary-element));
|
|
1162
|
+
cursor: pointer;
|
|
1163
|
+
display: inline-flex;
|
|
1164
|
+
font: inherit;
|
|
1165
|
+
font-size: 13px;
|
|
1166
|
+
font-weight: 700;
|
|
1167
|
+
gap: 6px;
|
|
1168
|
+
min-height: 32px;
|
|
1169
|
+
padding: 0 14px;
|
|
1170
|
+
white-space: nowrap;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
.cn-detail-page__catalog-note {
|
|
1174
|
+
color: var(--color-text-maxcontrast);
|
|
1175
|
+
font-size: 14px;
|
|
1176
|
+
white-space: nowrap;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1113
1179
|
.cn-detail-widget-host,
|
|
1114
1180
|
.cn-detail-widget-host > * {
|
|
1115
1181
|
height: 100%;
|
|
@@ -31,7 +31,7 @@ import { readPath } from '../../utils/readPath.js'
|
|
|
31
31
|
* Renders CnDocumentReviewList from a list on the bound record:
|
|
32
32
|
* `content: { field, title?, statusField?, statuses?, rowAction?: { label, route } }`.
|
|
33
33
|
* A row action with a `route` opens that route with the row's key as `id`.
|
|
34
|
-
* Resolved by its registry key,
|
|
34
|
+
* Resolved by its registry key, and exported for an app that renders it itself.
|
|
35
35
|
*/
|
|
36
36
|
export default {
|
|
37
37
|
name: 'CnDocumentReviewWidget',
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
<script>
|
|
63
63
|
import { translate as t } from '@nextcloud/l10n'
|
|
64
64
|
import { NcButton, NcCheckboxRadioSwitch, NcLoadingIcon, NcSelect, NcTextField } from '@nextcloud/vue'
|
|
65
|
-
import {
|
|
65
|
+
import { facetOptions } from '../../utils/facets.js'
|
|
66
66
|
import { filtersFromSchema } from '../../utils/schema.js'
|
|
67
67
|
|
|
68
68
|
/**
|
|
@@ -175,12 +175,12 @@ export default {
|
|
|
175
175
|
|
|
176
176
|
getFilterOptions(filter) {
|
|
177
177
|
// Use facet data if available (live values with counts)
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
178
|
+
const live = facetOptions(
|
|
179
|
+
this.facetData[filter.key],
|
|
180
|
+
(count) => t('nextcloud-vue', 'No value ({count})', { count }),
|
|
181
|
+
)
|
|
182
|
+
if (live !== null) {
|
|
183
|
+
return live
|
|
184
184
|
}
|
|
185
185
|
// Fall back to static enum options from schema
|
|
186
186
|
return filter.options || []
|