@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
|
@@ -86,6 +86,7 @@ import { useEndpointSource } from '../../composables/useEndpointSource.js'
|
|
|
86
86
|
import { useObjectStore } from '../../store/useObjectStore.js'
|
|
87
87
|
import { dispatchAction, resolveObjectOpType } from '../../utils/actionsDispatcher.js'
|
|
88
88
|
import { resolveObjectTokenContext } from '../../utils/detailObjectContext.js'
|
|
89
|
+
import { pageFilter, pageSort } from '../../utils/pageControls.js'
|
|
89
90
|
import { dropOptionalUnresolved, hasUnresolvedTokens, resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
90
91
|
import { compareVisibleWhen, readVisibleWhenPath } from '../../utils/visibleWhen.js'
|
|
91
92
|
import { CnIcon } from '../CnIcon/index.js'
|
|
@@ -517,7 +518,8 @@ export default {
|
|
|
517
518
|
* @return {object}
|
|
518
519
|
*/
|
|
519
520
|
resolvedFilter() {
|
|
520
|
-
|
|
521
|
+
const filter = pageFilter(this.source && this.source.pageControls, this.workspaceCtx, this.source && this.source.filter)
|
|
522
|
+
return dropOptionalUnresolved(resolveFilterTokens(filter, this.tokenCtx))
|
|
521
523
|
},
|
|
522
524
|
|
|
523
525
|
/**
|
|
@@ -590,7 +592,10 @@ export default {
|
|
|
590
592
|
resolvedFetchParams() {
|
|
591
593
|
const src = this.source || {}
|
|
592
594
|
const params = {}
|
|
593
|
-
|
|
595
|
+
// A page sort control (`source.pageControls.sort`) replaces the order.
|
|
596
|
+
const chosen = pageSort(src.pageControls, this.workspaceCtx, null)
|
|
597
|
+
const order = chosen ? { [chosen.field]: chosen.dir } : (src.order || {})
|
|
598
|
+
for (const [field, dir] of Object.entries(order)) {
|
|
594
599
|
params[`_order[${field}]`] = dir === 'desc' ? 'desc' : 'asc'
|
|
595
600
|
}
|
|
596
601
|
if (typeof src.limit === 'number' && src.limit > 0) {
|
|
@@ -73,6 +73,11 @@ export function objectTableContentToProps(content) {
|
|
|
73
73
|
if (hasLimit) {
|
|
74
74
|
source.limit = limit
|
|
75
75
|
}
|
|
76
|
+
// The page controls the table listens to belong to its source.
|
|
77
|
+
if (rest.pageControls && typeof rest.pageControls === 'object') {
|
|
78
|
+
source.pageControls = rest.pageControls
|
|
79
|
+
delete rest.pageControls
|
|
80
|
+
}
|
|
76
81
|
return { ...rest, source }
|
|
77
82
|
}
|
|
78
83
|
|
|
@@ -4,28 +4,101 @@
|
|
|
4
4
|
-->
|
|
5
5
|
|
|
6
6
|
<template>
|
|
7
|
-
<div
|
|
8
|
-
|
|
7
|
+
<div
|
|
8
|
+
class="cn-workspace-filter-widget"
|
|
9
|
+
:class="{
|
|
10
|
+
'cn-workspace-filter-widget--start': isStart,
|
|
11
|
+
'cn-workspace-filter-widget--chips': style === 'chips',
|
|
12
|
+
'cn-workspace-filter-widget--bar': isBar,
|
|
13
|
+
'cn-workspace-filter-widget--inline': content.inline === true,
|
|
14
|
+
'cn-workspace-filter-widget--end': content.align === 'end',
|
|
15
|
+
}"
|
|
16
|
+
data-testid="cn-workspace-filter-widget">
|
|
17
|
+
<!-- The start card (`layout: "start"`): a title and one line of
|
|
18
|
+
guidance beside the control, as the "Contact starten" card. -->
|
|
19
|
+
<div v-if="isStart && (title || description)" class="cn-workspace-filter-widget__text">
|
|
20
|
+
<h3 v-if="title" class="cn-workspace-filter-widget__title">
|
|
21
|
+
{{ title }}
|
|
22
|
+
</h3>
|
|
23
|
+
<p v-if="description" class="cn-workspace-filter-widget__description">
|
|
24
|
+
{{ description }}
|
|
25
|
+
</p>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<!-- A bar (`layout: "bar"`): its `controls` side by side in one row,
|
|
29
|
+
each a workspace filter of its own (chips, a switch, a select). -->
|
|
30
|
+
<template v-if="isBar">
|
|
31
|
+
<CnWorkspaceFilterWidget
|
|
32
|
+
v-for="(control, index) in barControls"
|
|
33
|
+
:key="index"
|
|
34
|
+
:content="control"
|
|
35
|
+
@change="$emit('change', $event)" />
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<p v-if="!isBar && label && style !== 'chips' && style !== 'toggle'" class="cn-workspace-filter-widget__label">
|
|
9
39
|
{{ label }}
|
|
10
40
|
</p>
|
|
11
41
|
|
|
12
|
-
|
|
42
|
+
<!-- An object picker (`objectSource`): searches OpenRegister on the
|
|
43
|
+
server, so it reaches every object, not a fetched page. -->
|
|
44
|
+
<CnResourceSelect
|
|
45
|
+
v-if="!isBar && objectSource"
|
|
46
|
+
class="cn-workspace-filter-widget__control"
|
|
47
|
+
:register="objectSource.register"
|
|
48
|
+
:schema="objectSource.schema"
|
|
49
|
+
:labelField="objectSource.labelField || 'title'"
|
|
50
|
+
:modelValue="selected === undefined || selected === null ? '' : String(selected)"
|
|
51
|
+
:placeholder="tr(objectSource.placeholder || '')"
|
|
52
|
+
:ariaLabelCombobox="tr(objectSource.ariaLabel || '') || title || label || writeKey"
|
|
53
|
+
:preload="objectSource.preload !== false"
|
|
54
|
+
:clearable="Boolean(content.allLabel)"
|
|
55
|
+
:allowCreate="false"
|
|
56
|
+
data-testid="cn-workspace-filter-object"
|
|
57
|
+
@update:modelValue="applySelection($event || '')" />
|
|
58
|
+
|
|
59
|
+
<div v-else-if="loading" class="cn-workspace-filter-widget__status">
|
|
13
60
|
{{ loadingLabel }}
|
|
14
61
|
</div>
|
|
15
62
|
|
|
63
|
+
<!-- Chips style (screens-page-lenses): one compact segmented group,
|
|
64
|
+
a count after each label, arrow keys move the choice. -->
|
|
65
|
+
<CnSegmentedControl
|
|
66
|
+
v-else-if="style === 'chips'"
|
|
67
|
+
class="cn-workspace-filter-widget__chips"
|
|
68
|
+
size="compact"
|
|
69
|
+
:options="chipOptions"
|
|
70
|
+
:modelValue="selected === undefined || selected === null ? null : String(selected)"
|
|
71
|
+
:ariaLabel="label || writeKey"
|
|
72
|
+
data-testid="cn-workspace-filter-chips"
|
|
73
|
+
@update:modelValue="applySelection" />
|
|
74
|
+
|
|
75
|
+
<!-- Toggle style (screens-page-controls): a switch that writes
|
|
76
|
+
`onValue` / `offValue` (true / false) to the key. -->
|
|
77
|
+
<NcCheckboxRadioSwitch
|
|
78
|
+
v-else-if="style === 'toggle'"
|
|
79
|
+
class="cn-workspace-filter-widget__toggle"
|
|
80
|
+
type="switch"
|
|
81
|
+
:modelValue="toggleOn"
|
|
82
|
+
data-testid="cn-workspace-filter-toggle"
|
|
83
|
+
@update:modelValue="onToggle">
|
|
84
|
+
{{ tr(label) }}
|
|
85
|
+
</NcCheckboxRadioSwitch>
|
|
86
|
+
|
|
16
87
|
<!-- Select style -->
|
|
17
88
|
<NcSelect
|
|
18
89
|
v-else-if="style === 'select'"
|
|
19
90
|
:modelValue="selectedOption"
|
|
20
91
|
:options="displayOptions"
|
|
21
92
|
:clearable="false"
|
|
22
|
-
:inputLabel="label || writeKey"
|
|
93
|
+
:inputLabel="content.inline ? '' : (label || writeKey)"
|
|
94
|
+
:labelOutside="content.inline === true"
|
|
95
|
+
:ariaLabelCombobox="label || writeKey"
|
|
23
96
|
label="label"
|
|
24
97
|
data-testid="cn-workspace-filter-select"
|
|
25
98
|
@update:modelValue="onSelect" />
|
|
26
99
|
|
|
27
100
|
<!-- Radio-list style (default) -->
|
|
28
|
-
<ul v-else
|
|
101
|
+
<ul v-else-if="!isBar"
|
|
29
102
|
class="cn-workspace-filter-widget__list"
|
|
30
103
|
role="radiogroup"
|
|
31
104
|
:aria-label="label || writeKey">
|
|
@@ -47,13 +120,27 @@
|
|
|
47
120
|
</NcCheckboxRadioSwitch>
|
|
48
121
|
</li>
|
|
49
122
|
</ul>
|
|
123
|
+
|
|
124
|
+
<component
|
|
125
|
+
:is="startLink.to ? 'router-link' : 'a'"
|
|
126
|
+
v-if="startLink"
|
|
127
|
+
:to="startLink.to || undefined"
|
|
128
|
+
:href="startLink.href || undefined"
|
|
129
|
+
class="cn-workspace-filter-widget__link"
|
|
130
|
+
data-testid="cn-workspace-filter-link">
|
|
131
|
+
{{ startLink.label }}
|
|
132
|
+
</component>
|
|
50
133
|
</div>
|
|
51
134
|
</template>
|
|
52
135
|
|
|
53
136
|
<script>
|
|
137
|
+
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
|
|
54
138
|
import { translate as t } from '@nextcloud/l10n'
|
|
55
139
|
import { NcCheckboxRadioSwitch, NcSelect } from '@nextcloud/vue'
|
|
140
|
+
import CnResourceSelect from '../CnResourceSelect/CnResourceSelect.vue'
|
|
141
|
+
import CnSegmentedControl from '../CnSegmentedControl/CnSegmentedControl.vue'
|
|
56
142
|
import { fetchEndpointSource } from '../../composables/useEndpointSource.js'
|
|
143
|
+
import { fetchListTotal } from '../../utils/fetchFilterCounts.js'
|
|
57
144
|
import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
58
145
|
|
|
59
146
|
/**
|
|
@@ -84,7 +171,7 @@ import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
|
84
171
|
* content: {
|
|
85
172
|
* label: 'Queue',
|
|
86
173
|
* writes: '@workspace.queue',
|
|
87
|
-
* style: 'radio', // 'radio' (default) | 'select'
|
|
174
|
+
* style: 'radio', // 'radio' (default) | 'select' | 'chips'
|
|
88
175
|
* allLabel: 'All',
|
|
89
176
|
* showCounts: true,
|
|
90
177
|
* source: { register: 'pipelinq', schema: 'werkitem', groupBy: 'queue' },
|
|
@@ -94,7 +181,7 @@ import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
|
94
181
|
export default {
|
|
95
182
|
name: 'CnWorkspaceFilterWidget',
|
|
96
183
|
|
|
97
|
-
components: { NcSelect, NcCheckboxRadioSwitch },
|
|
184
|
+
components: { CnResourceSelect, CnSegmentedControl, NcSelect, NcCheckboxRadioSwitch },
|
|
98
185
|
|
|
99
186
|
inject: {
|
|
100
187
|
/**
|
|
@@ -104,13 +191,35 @@ export default {
|
|
|
104
191
|
* Null on pages without one (the widget then just emits `@change`).
|
|
105
192
|
*/
|
|
106
193
|
cnWorkspaceContext: { default: null },
|
|
194
|
+
/** Host translate function, for the start card's texts. */
|
|
195
|
+
cnTranslate: { default: () => (key) => key },
|
|
107
196
|
},
|
|
108
197
|
|
|
109
198
|
props: {
|
|
110
199
|
/**
|
|
111
200
|
* Persisted configuration blob.
|
|
112
201
|
*
|
|
113
|
-
*
|
|
202
|
+
* Start card keys (abstract-start-card): `layout: "start"` draws
|
|
203
|
+
* `title` and `description` beside the control, and `link`
|
|
204
|
+
* (`{ label, route? | href? }`) after it. `objectSource`
|
|
205
|
+
* (`{ register, schema, labelField?, placeholder?, ariaLabel?, preload? }`)
|
|
206
|
+
* makes the control an OpenRegister object picker that searches on the
|
|
207
|
+
* server and writes the picked object's id; without a selection and
|
|
208
|
+
* without `allLabel` it selects the first object.
|
|
209
|
+
*
|
|
210
|
+
* Chips (screens-page-lenses): `style: "chips"` draws the options as one
|
|
211
|
+
* compact segmented group with a count after each label. An option's
|
|
212
|
+
* `countFrom` (`{ register, schema, filter? }`, or a list of them that
|
|
213
|
+
* are added up) counts that list; a static `count` is used otherwise.
|
|
214
|
+
* `urlKey` keeps the choice in the address (`?<urlKey>=<value>`), and
|
|
215
|
+
* the address wins over `default` on load.
|
|
216
|
+
*
|
|
217
|
+
* Page controls (screens-page-controls): `style: "toggle"` is a switch
|
|
218
|
+
* that writes `onValue` / `offValue` (true / false); `layout: "bar"`
|
|
219
|
+
* with `controls` draws several controls side by side in one row, and
|
|
220
|
+
* `align: "end"` pushes a control to the right edge.
|
|
221
|
+
*
|
|
222
|
+
* @type {{label?: string, controls?: Array<object>, onValue?: unknown, offValue?: unknown, align?: string, urlKey?: string, writes?: string, style?: string, allLabel?: string, showCounts?: boolean, options?: Array, source?: object, endpointSource?: object, objectSource?: object, default?: (string|number), layout?: string, title?: string, description?: string, link?: object}}
|
|
114
223
|
*/
|
|
115
224
|
content: {
|
|
116
225
|
type: Object,
|
|
@@ -128,6 +237,8 @@ export default {
|
|
|
128
237
|
loading: false,
|
|
129
238
|
/** The currently-selected value (mirrors the workspace key). */
|
|
130
239
|
selected: undefined,
|
|
240
|
+
/** Counted totals of the options that ask (`countFrom`), by option position. */
|
|
241
|
+
optionCounts: {},
|
|
131
242
|
}
|
|
132
243
|
},
|
|
133
244
|
|
|
@@ -137,9 +248,117 @@ export default {
|
|
|
137
248
|
return this.content.label || ''
|
|
138
249
|
},
|
|
139
250
|
|
|
140
|
-
/**
|
|
251
|
+
/** Whether the widget draws the start card. */
|
|
252
|
+
isStart() {
|
|
253
|
+
return this.content.layout === 'start'
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
/** The start card's title, translated. */
|
|
257
|
+
title() {
|
|
258
|
+
return this.tr(this.content.title || '')
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
/** The start card's guidance line, translated. */
|
|
262
|
+
description() {
|
|
263
|
+
return this.tr(this.content.description || '')
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* The link after the control, or null.
|
|
268
|
+
*
|
|
269
|
+
* @return {{label: string, to?: object, href?: string}|null}
|
|
270
|
+
*/
|
|
271
|
+
startLink() {
|
|
272
|
+
const link = this.content.link
|
|
273
|
+
if (!link || typeof link !== 'object' || !link.label) {
|
|
274
|
+
return null
|
|
275
|
+
}
|
|
276
|
+
if (link.route && typeof link.route === 'object' && link.route.name) {
|
|
277
|
+
return { label: this.tr(link.label), to: link.route }
|
|
278
|
+
}
|
|
279
|
+
if (typeof link.href === 'string' && link.href !== '') {
|
|
280
|
+
return { label: this.tr(link.label), href: link.href }
|
|
281
|
+
}
|
|
282
|
+
return null
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* The object picker declaration, or null.
|
|
287
|
+
*
|
|
288
|
+
* @return {{register: string, schema: string, labelField?: string}|null}
|
|
289
|
+
*/
|
|
290
|
+
objectSource() {
|
|
291
|
+
const src = this.content.objectSource
|
|
292
|
+
return src && typeof src === 'object' && src.register && src.schema ? src : null
|
|
293
|
+
},
|
|
294
|
+
|
|
295
|
+
/** Choice style: 'chips', 'select' or 'radio' (default). */
|
|
141
296
|
style() {
|
|
142
|
-
return this.content.style
|
|
297
|
+
return ['select', 'chips', 'toggle'].includes(this.content.style) ? this.content.style : 'radio'
|
|
298
|
+
},
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* The chips: each option with its label translated and its count,
|
|
302
|
+
* the static one or the counted one.
|
|
303
|
+
*
|
|
304
|
+
* @return {Array<{value: string, label: string, count?: number}>}
|
|
305
|
+
* @spec openspec/changes/screens-page-lenses/specs/page-lenses/spec.md#requirement-a-workspace-filter-can-draw-chips-with-counts
|
|
306
|
+
*/
|
|
307
|
+
chipOptions() {
|
|
308
|
+
return this.displayOptions.map((option, index) => {
|
|
309
|
+
const counted = this.optionCounts[index]
|
|
310
|
+
const count = counted !== undefined && counted !== null ? counted : option.count
|
|
311
|
+
const chip = { value: String(option.value), label: this.tr(option.label) }
|
|
312
|
+
if (this.showCounts && Number.isFinite(count)) {
|
|
313
|
+
chip.count = count
|
|
314
|
+
}
|
|
315
|
+
return chip
|
|
316
|
+
})
|
|
317
|
+
},
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Whether the widget is a bar of controls (`layout: "bar"`).
|
|
321
|
+
*
|
|
322
|
+
* @return {boolean}
|
|
323
|
+
* @spec openspec/changes/screens-page-controls/specs/page-controls/spec.md#requirement-a-bar-holds-the-pages-controls-in-one-row
|
|
324
|
+
*/
|
|
325
|
+
isBar() {
|
|
326
|
+
return this.content.layout === 'bar' && Array.isArray(this.content.controls)
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* The bar's controls, each an inline workspace filter of its own.
|
|
331
|
+
*
|
|
332
|
+
* @return {Array<object>}
|
|
333
|
+
*/
|
|
334
|
+
barControls() {
|
|
335
|
+
return this.content.controls
|
|
336
|
+
.filter((control) => control && typeof control === 'object')
|
|
337
|
+
.map((control) => ({ ...control, inline: true }))
|
|
338
|
+
},
|
|
339
|
+
|
|
340
|
+
/** @return {unknown} The value a switch writes when on. */
|
|
341
|
+
onValue() {
|
|
342
|
+
return this.content.onValue !== undefined ? this.content.onValue : true
|
|
343
|
+
},
|
|
344
|
+
|
|
345
|
+
/** @return {unknown} The value a switch writes when off. */
|
|
346
|
+
offValue() {
|
|
347
|
+
return this.content.offValue !== undefined ? this.content.offValue : false
|
|
348
|
+
},
|
|
349
|
+
|
|
350
|
+
/** @return {boolean} Whether the switch is on. */
|
|
351
|
+
toggleOn() {
|
|
352
|
+
return this.selected !== undefined && String(this.selected) === String(this.onValue)
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* The address key that carries the choice (`urlKey`), or ''.
|
|
357
|
+
*
|
|
358
|
+
* @return {string}
|
|
359
|
+
*/
|
|
360
|
+
urlKey() {
|
|
361
|
+
return typeof this.content.urlKey === 'string' ? this.content.urlKey : ''
|
|
143
362
|
},
|
|
144
363
|
|
|
145
364
|
/** Whether to render per-option counts. */
|
|
@@ -220,17 +439,115 @@ export default {
|
|
|
220
439
|
// Seed the selection: existing workspace value → content.default → the
|
|
221
440
|
// "All" clear option (empty) when present, else the first option once
|
|
222
441
|
// loaded (handled in loadOptions).
|
|
442
|
+
const fromAddress = this.readAddress()
|
|
223
443
|
const existing = this.readWorkspace()
|
|
224
|
-
if (
|
|
444
|
+
if (fromAddress !== undefined) {
|
|
445
|
+
this.selected = fromAddress
|
|
446
|
+
this.writeWorkspace(fromAddress)
|
|
447
|
+
} else if (existing !== undefined) {
|
|
225
448
|
this.selected = existing
|
|
226
449
|
} else if (this.content.default !== undefined) {
|
|
227
450
|
this.selected = this.content.default
|
|
228
451
|
this.writeWorkspace(this.content.default)
|
|
452
|
+
} else if (this.style === 'toggle') {
|
|
453
|
+
// A switch starts off, and says so, so a condition on its key holds.
|
|
454
|
+
this.selected = this.offValue
|
|
455
|
+
this.writeWorkspace(this.offValue)
|
|
229
456
|
}
|
|
230
457
|
this.loadOptions()
|
|
231
458
|
},
|
|
232
459
|
|
|
460
|
+
mounted() {
|
|
461
|
+
this.onPageRefresh = () => this.loadCounts()
|
|
462
|
+
subscribe('cn:page:refresh', this.onPageRefresh)
|
|
463
|
+
this.loadCounts()
|
|
464
|
+
},
|
|
465
|
+
|
|
466
|
+
beforeUnmount() {
|
|
467
|
+
unsubscribe('cn:page:refresh', this.onPageRefresh)
|
|
468
|
+
},
|
|
469
|
+
|
|
233
470
|
methods: {
|
|
471
|
+
/**
|
|
472
|
+
* The choice named in the address (`?<urlKey>=…`), when it is one of
|
|
473
|
+
* the options; undefined otherwise.
|
|
474
|
+
*
|
|
475
|
+
* @return {string|undefined}
|
|
476
|
+
* @spec openspec/changes/screens-page-lenses/specs/page-lenses/spec.md#requirement-the-choice-is-in-the-address
|
|
477
|
+
*/
|
|
478
|
+
readAddress() {
|
|
479
|
+
if (!this.urlKey || !this.$route || !this.$route.query) {
|
|
480
|
+
return undefined
|
|
481
|
+
}
|
|
482
|
+
const raw = this.$route.query[this.urlKey]
|
|
483
|
+
if (this.style === 'toggle') {
|
|
484
|
+
if (raw === undefined) {
|
|
485
|
+
return undefined
|
|
486
|
+
}
|
|
487
|
+
return [this.onValue, this.offValue].find((value) => String(value) === String(raw))
|
|
488
|
+
}
|
|
489
|
+
const known = this.displayOptions.some((option) => String(option.value) === String(raw))
|
|
490
|
+
return known ? String(raw) : undefined
|
|
491
|
+
},
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Write the choice to the address, replacing the history entry and
|
|
495
|
+
* keeping the other query keys.
|
|
496
|
+
*
|
|
497
|
+
* @param {unknown} value The chosen value.
|
|
498
|
+
* @return {void}
|
|
499
|
+
* @spec openspec/changes/screens-page-lenses/specs/page-lenses/spec.md#requirement-the-choice-is-in-the-address
|
|
500
|
+
*/
|
|
501
|
+
writeAddress(value) {
|
|
502
|
+
if (!this.urlKey || !this.$router || !this.$route) {
|
|
503
|
+
return
|
|
504
|
+
}
|
|
505
|
+
const query = this.$route.query || {}
|
|
506
|
+
if (String(query[this.urlKey]) === String(value)) {
|
|
507
|
+
return
|
|
508
|
+
}
|
|
509
|
+
const result = this.$router.replace({ query: { ...query, [this.urlKey]: String(value) } })
|
|
510
|
+
if (result && typeof result.catch === 'function') {
|
|
511
|
+
result.catch(() => {})
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Count the lists behind the options that ask (`countFrom`: a list
|
|
517
|
+
* `{ register, schema, filter? }`, or several that are added up). One
|
|
518
|
+
* list request each; an option whose count failed shows none.
|
|
519
|
+
*
|
|
520
|
+
* @return {Promise<void>}
|
|
521
|
+
* @spec openspec/changes/screens-page-lenses/specs/page-lenses/spec.md#requirement-a-workspace-filter-can-draw-chips-with-counts
|
|
522
|
+
*/
|
|
523
|
+
async loadCounts() {
|
|
524
|
+
const options = this.displayOptions
|
|
525
|
+
const seq = (this.countSeq = (this.countSeq || 0) + 1)
|
|
526
|
+
const ctx = { workspace: this.readWorkspaceBag() }
|
|
527
|
+
await Promise.all(options.map(async (option, index) => {
|
|
528
|
+
const raw = (Array.isArray(this.content.options) ? this.content.options : [])
|
|
529
|
+
.find((candidate) => candidate && typeof candidate === 'object' && String(candidate.value ?? candidate.id) === String(option.value))
|
|
530
|
+
const from = raw ? raw.countFrom : null
|
|
531
|
+
const lists = (Array.isArray(from) ? from : [from]).filter((list) => list && typeof list === 'object' && list.register && list.schema)
|
|
532
|
+
if (lists.length === 0) {
|
|
533
|
+
return
|
|
534
|
+
}
|
|
535
|
+
let total
|
|
536
|
+
try {
|
|
537
|
+
const parts = await Promise.all(lists.map((list) => fetchListTotal(list.register, list.schema, list.filter || {}, ctx)))
|
|
538
|
+
if (parts.some((part) => part === null)) {
|
|
539
|
+
throw new Error('no total')
|
|
540
|
+
}
|
|
541
|
+
total = parts.reduce((sum, part) => sum + part, 0)
|
|
542
|
+
} catch {
|
|
543
|
+
total = null
|
|
544
|
+
}
|
|
545
|
+
if (seq === this.countSeq) {
|
|
546
|
+
this.optionCounts = { ...this.optionCounts, [index]: total }
|
|
547
|
+
}
|
|
548
|
+
}))
|
|
549
|
+
},
|
|
550
|
+
|
|
234
551
|
/**
|
|
235
552
|
* Normalise a raw option into `{ value, label, count? }`. Accepts
|
|
236
553
|
* `{ value, label, count }`, `{ id, name }`, `{ key, count }` (OR
|
|
@@ -263,6 +580,10 @@ export default {
|
|
|
263
580
|
* @return {Promise<void>}
|
|
264
581
|
*/
|
|
265
582
|
async loadOptions() {
|
|
583
|
+
if (this.objectSource) {
|
|
584
|
+
await this.seedFirstObject()
|
|
585
|
+
return
|
|
586
|
+
}
|
|
266
587
|
if (this.content.endpointSource && this.content.endpointSource.url) {
|
|
267
588
|
await this.loadFromEndpoint()
|
|
268
589
|
} else if (this.content.source && this.content.source.schema) {
|
|
@@ -281,6 +602,51 @@ export default {
|
|
|
281
602
|
}
|
|
282
603
|
},
|
|
283
604
|
|
|
605
|
+
/**
|
|
606
|
+
* Translate a manifest string through the host app.
|
|
607
|
+
*
|
|
608
|
+
* @param {string} text The text.
|
|
609
|
+
* @return {string}
|
|
610
|
+
*/
|
|
611
|
+
tr(text) {
|
|
612
|
+
if (typeof text !== 'string' || text === '') {
|
|
613
|
+
return ''
|
|
614
|
+
}
|
|
615
|
+
return typeof this.cnTranslate === 'function' ? this.cnTranslate(text) : text
|
|
616
|
+
},
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* The object picker's default: with nothing selected, no `default` and
|
|
620
|
+
* no `allLabel`, select the first object the source lists, so the page
|
|
621
|
+
* always has one in focus. Fail-safe: a failed read selects nothing.
|
|
622
|
+
*
|
|
623
|
+
* @return {Promise<void>}
|
|
624
|
+
*/
|
|
625
|
+
async seedFirstObject() {
|
|
626
|
+
if ((this.selected !== undefined && this.selected !== '') || this.content.allLabel || this.content.default !== undefined) {
|
|
627
|
+
return
|
|
628
|
+
}
|
|
629
|
+
const src = this.objectSource
|
|
630
|
+
try {
|
|
631
|
+
const [{ default: axios }, { generateUrl }] = await Promise.all([
|
|
632
|
+
import('@nextcloud/axios'),
|
|
633
|
+
import('@nextcloud/router'),
|
|
634
|
+
])
|
|
635
|
+
const url = generateUrl('/apps/openregister/api/objects/{register}/{schema}', { register: src.register, schema: src.schema })
|
|
636
|
+
const res = await axios.get(url, { params: { _limit: 1 } })
|
|
637
|
+
const data = res && res.data
|
|
638
|
+
const rows = Array.isArray(data) ? data : ((data && data.results) || [])
|
|
639
|
+
const first = rows[0]
|
|
640
|
+
const id = first && (first.id || (first['@self'] && first['@self'].id))
|
|
641
|
+
if (id && (this.selected === undefined || this.selected === '') && this.readWorkspace() === undefined) {
|
|
642
|
+
this.selected = String(id)
|
|
643
|
+
this.writeWorkspace(String(id))
|
|
644
|
+
}
|
|
645
|
+
} catch {
|
|
646
|
+
// Nothing selected: the siblings wait for a pick.
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
|
|
284
650
|
/**
|
|
285
651
|
* Fetch options from an `endpointSource` (array of options at
|
|
286
652
|
* responsePath). Fail-safe: a failed fetch leaves an empty list.
|
|
@@ -358,6 +724,17 @@ export default {
|
|
|
358
724
|
this.applySelection(option.value)
|
|
359
725
|
},
|
|
360
726
|
|
|
727
|
+
/**
|
|
728
|
+
* Switch handler: write `onValue` or `offValue`.
|
|
729
|
+
*
|
|
730
|
+
* @param {boolean} on Whether the switch is on.
|
|
731
|
+
* @return {void}
|
|
732
|
+
* @spec openspec/changes/screens-page-controls/specs/page-controls/spec.md#requirement-a-toggle-and-a-select-are-page-controls
|
|
733
|
+
*/
|
|
734
|
+
onToggle(on) {
|
|
735
|
+
this.applySelection(on ? this.onValue : this.offValue)
|
|
736
|
+
},
|
|
737
|
+
|
|
361
738
|
/**
|
|
362
739
|
* NcSelect input handler.
|
|
363
740
|
*
|
|
@@ -378,6 +755,7 @@ export default {
|
|
|
378
755
|
applySelection(value) {
|
|
379
756
|
this.selected = value
|
|
380
757
|
this.writeWorkspace(value)
|
|
758
|
+
this.writeAddress(value)
|
|
381
759
|
/**
|
|
382
760
|
* @event change Emitted when the selection changes. Payload: `{ key, value }`.
|
|
383
761
|
*/
|
|
@@ -465,6 +843,85 @@ export default {
|
|
|
465
843
|
gap: 2px;
|
|
466
844
|
}
|
|
467
845
|
|
|
846
|
+
/* The chips: the compact segmented group, left, in the card the grid draws. */
|
|
847
|
+
.cn-workspace-filter-widget--chips {
|
|
848
|
+
flex-direction: row;
|
|
849
|
+
flex-wrap: wrap;
|
|
850
|
+
align-items: center;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/* A bar: its controls in one row, an `align: "end"` control pushed right. */
|
|
854
|
+
.cn-workspace-filter-widget--bar {
|
|
855
|
+
flex-direction: row;
|
|
856
|
+
flex-wrap: wrap;
|
|
857
|
+
align-items: center;
|
|
858
|
+
gap: 12px 16px;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/* An inline control sits in a bar: label left of the control, width to its content. */
|
|
862
|
+
.cn-workspace-filter-widget--inline {
|
|
863
|
+
flex-direction: row;
|
|
864
|
+
align-items: center;
|
|
865
|
+
gap: 8px;
|
|
866
|
+
width: auto;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
.cn-workspace-filter-widget--inline .cn-workspace-filter-widget__label {
|
|
870
|
+
font-weight: 400;
|
|
871
|
+
color: var(--color-text-maxcontrast);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
.cn-workspace-filter-widget--end {
|
|
875
|
+
margin-inline-start: auto;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
.cn-workspace-filter-widget--end ~ .cn-workspace-filter-widget--end {
|
|
879
|
+
margin-inline-start: 0;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.cn-workspace-filter-widget__toggle {
|
|
883
|
+
font-weight: 600;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/* The start card: text left, control (and link) right, as PqDashboard's "Contact starten". */
|
|
887
|
+
.cn-workspace-filter-widget--start {
|
|
888
|
+
flex-direction: row;
|
|
889
|
+
flex-wrap: wrap;
|
|
890
|
+
align-items: center;
|
|
891
|
+
gap: 16px 24px;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
.cn-workspace-filter-widget__text {
|
|
895
|
+
flex: 1 1 320px;
|
|
896
|
+
min-width: 0;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
.cn-workspace-filter-widget__title {
|
|
900
|
+
margin: 0 0 4px;
|
|
901
|
+
font-size: 17px;
|
|
902
|
+
font-weight: 700;
|
|
903
|
+
color: var(--color-main-text);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.cn-workspace-filter-widget__description {
|
|
907
|
+
margin: 0;
|
|
908
|
+
max-width: 420px;
|
|
909
|
+
color: var(--color-text-maxcontrast);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
.cn-workspace-filter-widget--start .cn-workspace-filter-widget__control,
|
|
913
|
+
.cn-workspace-filter-widget--start > .v-select {
|
|
914
|
+
flex: 0 1 480px;
|
|
915
|
+
min-width: 240px;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
.cn-workspace-filter-widget__link {
|
|
919
|
+
font-weight: 600;
|
|
920
|
+
color: var(--color-primary-element);
|
|
921
|
+
text-decoration: underline;
|
|
922
|
+
white-space: nowrap;
|
|
923
|
+
}
|
|
924
|
+
|
|
468
925
|
.cn-workspace-filter-widget__count {
|
|
469
926
|
margin-inline-start: 6px;
|
|
470
927
|
padding: 0 6px;
|
|
@@ -473,4 +930,29 @@ export default {
|
|
|
473
930
|
color: var(--color-text-maxcontrast);
|
|
474
931
|
font-size: 0.85em;
|
|
475
932
|
}
|
|
933
|
+
|
|
934
|
+
/* On a phone the bar's controls take a row each (the chips already wrap), and
|
|
935
|
+
a switch and a select are 44px touch targets. */
|
|
936
|
+
@media (max-width: 640px) {
|
|
937
|
+
.cn-workspace-filter-widget--bar > .cn-workspace-filter-widget--inline {
|
|
938
|
+
flex: 1 1 100%;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
.cn-workspace-filter-widget--bar > .cn-workspace-filter-widget--end {
|
|
942
|
+
margin-inline-start: 0;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
.cn-workspace-filter-widget--inline .cn-workspace-filter-widget__toggle {
|
|
946
|
+
min-height: 44px;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
.cn-workspace-filter-widget--inline :deep(.v-select) {
|
|
950
|
+
flex: 1 1 auto;
|
|
951
|
+
min-width: 0;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
.cn-workspace-filter-widget--inline :deep(.vs__dropdown-toggle) {
|
|
955
|
+
min-height: 44px;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
476
958
|
</style>
|