@conduction/nextcloud-vue 2.80.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/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +3 -3
- 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 +140 -10
- 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 +17 -3
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +63 -52
- 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 +3 -2
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +72 -0
- 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/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.vue2.js +131 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js +80 -5
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js +282 -69
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js.map +1 -1
- 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/CnFormPage/CnFormPage.vue2.js +60 -0
- 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 +29 -2
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +48 -4
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- 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/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.vue2.js +30 -6
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +34 -25
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
- 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/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/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.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 +47 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +16 -14
- 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 +7 -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 +197 -6
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js +96 -50
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.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 +17 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +9 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +55 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +1041 -12
- package/dist/esm/utils/contentHeaderLink.js +51 -0
- package/dist/esm/utils/contentHeaderLink.js.map +1 -0
- 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 +7 -1
- package/dist/esm/utils/fillTemplate.js.map +1 -1
- package/dist/esm/utils/initials.js +32 -0
- package/dist/esm/utils/initials.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +7 -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/resolveFilterTokens.js +1 -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/sentinelTokens.js +19 -1
- 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 +1 -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 +13589 -7833
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +1041 -12
- package/l10n/en.json +9 -1
- package/l10n/nl.json +55 -1
- package/package.json +2 -1
- package/scripts/check-docs-mdx.mjs +108 -0
- package/src/components/CnActionsBar/CnActionsBar.vue +6 -1
- package/src/components/CnAppRoot/CnAppRoot.md +4 -2
- package/src/components/CnAppRoot/CnAppRoot.vue +151 -59
- package/src/components/CnBannerWidget/CnBannerWidget.vue +205 -20
- package/src/components/CnCellRenderer/CnCellRenderer.md +2 -0
- package/src/components/CnCellRenderer/CnCellRenderer.vue +47 -4
- 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 +21 -12
- package/src/components/CnDetailPage/CnDetailPage.vue +89 -3
- package/src/components/CnDocumentReviewList/CnDocumentReviewWidget.vue +1 -1
- package/src/components/CnFacetSidebar/CnFacetSidebar.vue +7 -7
- package/src/components/CnFactsWidget/CnFactsWidget.vue +142 -2
- package/src/components/CnFieldListWidget/CnFieldListWidget.vue +268 -6
- 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/CnFormPage/CnFormPage.vue +81 -0
- package/src/components/CnIndexPage/CnIndexPage.vue +56 -4
- 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/CnRadioCardsWidget/CnRadioCardsWidget.vue +313 -0
- package/src/components/CnRadioCardsWidget/index.js +27 -0
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +55 -6
- package/src/components/CnSavedViewsWidget/CnSavedViewsWidget.vue +296 -0
- package/src/components/CnSavedViewsWidget/index.js +29 -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/CnStatWidget/CnStatWidget.vue +87 -6
- 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 +82 -3
- 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 +7 -0
- package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +7 -2
- package/src/components/CnWidgetObjectTable/dashboardRegistration.js +5 -0
- package/src/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue +309 -11
- package/src/components/index.js +15 -0
- package/src/composables/useListView.js +4 -4
- package/src/css/look-board-detail.css +36 -2
- package/src/css/look-board-index.css +39 -8
- package/src/css/look-board.css +72 -0
- package/src/index.js +15 -0
- package/src/schemas/app-manifest-v2.schema.json +93 -9
- package/src/utils/contentHeaderLink.js +48 -0
- package/src/utils/facets.js +74 -2
- package/src/utils/fetchFilterCounts.js +39 -4
- package/src/utils/fillTemplate.js +7 -1
- package/src/utils/initials.js +29 -0
- package/src/utils/libraryWidgetKeys.js +7 -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/resolveFilterTokens.js +3 -1
- package/src/utils/resolveManifestTokens.js +2 -0
- package/src/utils/sentinelTokens.js +19 -1
- 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 +1 -1
- package/src/utils/widgetVisibility.js +7 -56
|
@@ -6,7 +6,13 @@
|
|
|
6
6
|
<template>
|
|
7
7
|
<div
|
|
8
8
|
class="cn-workspace-filter-widget"
|
|
9
|
-
:class="{
|
|
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
|
+
}"
|
|
10
16
|
data-testid="cn-workspace-filter-widget">
|
|
11
17
|
<!-- The start card (`layout: "start"`): a title and one line of
|
|
12
18
|
guidance beside the control, as the "Contact starten" card. -->
|
|
@@ -19,14 +25,24 @@
|
|
|
19
25
|
</p>
|
|
20
26
|
</div>
|
|
21
27
|
|
|
22
|
-
|
|
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">
|
|
23
39
|
{{ label }}
|
|
24
40
|
</p>
|
|
25
41
|
|
|
26
42
|
<!-- An object picker (`objectSource`): searches OpenRegister on the
|
|
27
43
|
server, so it reaches every object, not a fetched page. -->
|
|
28
44
|
<CnResourceSelect
|
|
29
|
-
v-if="objectSource"
|
|
45
|
+
v-if="!isBar && objectSource"
|
|
30
46
|
class="cn-workspace-filter-widget__control"
|
|
31
47
|
:register="objectSource.register"
|
|
32
48
|
:schema="objectSource.schema"
|
|
@@ -44,19 +60,45 @@
|
|
|
44
60
|
{{ loadingLabel }}
|
|
45
61
|
</div>
|
|
46
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
|
+
|
|
47
87
|
<!-- Select style -->
|
|
48
88
|
<NcSelect
|
|
49
89
|
v-else-if="style === 'select'"
|
|
50
90
|
:modelValue="selectedOption"
|
|
51
91
|
:options="displayOptions"
|
|
52
92
|
:clearable="false"
|
|
53
|
-
:inputLabel="label || writeKey"
|
|
93
|
+
:inputLabel="content.inline ? '' : (label || writeKey)"
|
|
94
|
+
:labelOutside="content.inline === true"
|
|
95
|
+
:ariaLabelCombobox="label || writeKey"
|
|
54
96
|
label="label"
|
|
55
97
|
data-testid="cn-workspace-filter-select"
|
|
56
98
|
@update:modelValue="onSelect" />
|
|
57
99
|
|
|
58
100
|
<!-- Radio-list style (default) -->
|
|
59
|
-
<ul v-else
|
|
101
|
+
<ul v-else-if="!isBar"
|
|
60
102
|
class="cn-workspace-filter-widget__list"
|
|
61
103
|
role="radiogroup"
|
|
62
104
|
:aria-label="label || writeKey">
|
|
@@ -92,10 +134,13 @@
|
|
|
92
134
|
</template>
|
|
93
135
|
|
|
94
136
|
<script>
|
|
137
|
+
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
|
|
95
138
|
import { translate as t } from '@nextcloud/l10n'
|
|
96
139
|
import { NcCheckboxRadioSwitch, NcSelect } from '@nextcloud/vue'
|
|
97
140
|
import CnResourceSelect from '../CnResourceSelect/CnResourceSelect.vue'
|
|
141
|
+
import CnSegmentedControl from '../CnSegmentedControl/CnSegmentedControl.vue'
|
|
98
142
|
import { fetchEndpointSource } from '../../composables/useEndpointSource.js'
|
|
143
|
+
import { fetchListTotal } from '../../utils/fetchFilterCounts.js'
|
|
99
144
|
import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
100
145
|
|
|
101
146
|
/**
|
|
@@ -126,7 +171,7 @@ import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
|
126
171
|
* content: {
|
|
127
172
|
* label: 'Queue',
|
|
128
173
|
* writes: '@workspace.queue',
|
|
129
|
-
* style: 'radio', // 'radio' (default) | 'select'
|
|
174
|
+
* style: 'radio', // 'radio' (default) | 'select' | 'chips'
|
|
130
175
|
* allLabel: 'All',
|
|
131
176
|
* showCounts: true,
|
|
132
177
|
* source: { register: 'pipelinq', schema: 'werkitem', groupBy: 'queue' },
|
|
@@ -136,7 +181,7 @@ import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
|
136
181
|
export default {
|
|
137
182
|
name: 'CnWorkspaceFilterWidget',
|
|
138
183
|
|
|
139
|
-
components: { CnResourceSelect, NcSelect, NcCheckboxRadioSwitch },
|
|
184
|
+
components: { CnResourceSelect, CnSegmentedControl, NcSelect, NcCheckboxRadioSwitch },
|
|
140
185
|
|
|
141
186
|
inject: {
|
|
142
187
|
/**
|
|
@@ -162,7 +207,19 @@ export default {
|
|
|
162
207
|
* server and writes the picked object's id; without a selection and
|
|
163
208
|
* without `allLabel` it selects the first object.
|
|
164
209
|
*
|
|
165
|
-
*
|
|
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}}
|
|
166
223
|
*/
|
|
167
224
|
content: {
|
|
168
225
|
type: Object,
|
|
@@ -180,6 +237,8 @@ export default {
|
|
|
180
237
|
loading: false,
|
|
181
238
|
/** The currently-selected value (mirrors the workspace key). */
|
|
182
239
|
selected: undefined,
|
|
240
|
+
/** Counted totals of the options that ask (`countFrom`), by option position. */
|
|
241
|
+
optionCounts: {},
|
|
183
242
|
}
|
|
184
243
|
},
|
|
185
244
|
|
|
@@ -233,9 +292,73 @@ export default {
|
|
|
233
292
|
return src && typeof src === 'object' && src.register && src.schema ? src : null
|
|
234
293
|
},
|
|
235
294
|
|
|
236
|
-
/** Choice style: 'select' or 'radio' (default). */
|
|
295
|
+
/** Choice style: 'chips', 'select' or 'radio' (default). */
|
|
237
296
|
style() {
|
|
238
|
-
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 : ''
|
|
239
362
|
},
|
|
240
363
|
|
|
241
364
|
/** Whether to render per-option counts. */
|
|
@@ -316,17 +439,115 @@ export default {
|
|
|
316
439
|
// Seed the selection: existing workspace value → content.default → the
|
|
317
440
|
// "All" clear option (empty) when present, else the first option once
|
|
318
441
|
// loaded (handled in loadOptions).
|
|
442
|
+
const fromAddress = this.readAddress()
|
|
319
443
|
const existing = this.readWorkspace()
|
|
320
|
-
if (
|
|
444
|
+
if (fromAddress !== undefined) {
|
|
445
|
+
this.selected = fromAddress
|
|
446
|
+
this.writeWorkspace(fromAddress)
|
|
447
|
+
} else if (existing !== undefined) {
|
|
321
448
|
this.selected = existing
|
|
322
449
|
} else if (this.content.default !== undefined) {
|
|
323
450
|
this.selected = this.content.default
|
|
324
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)
|
|
325
456
|
}
|
|
326
457
|
this.loadOptions()
|
|
327
458
|
},
|
|
328
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
|
+
|
|
329
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
|
+
|
|
330
551
|
/**
|
|
331
552
|
* Normalise a raw option into `{ value, label, count? }`. Accepts
|
|
332
553
|
* `{ value, label, count }`, `{ id, name }`, `{ key, count }` (OR
|
|
@@ -503,6 +724,17 @@ export default {
|
|
|
503
724
|
this.applySelection(option.value)
|
|
504
725
|
},
|
|
505
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
|
+
|
|
506
738
|
/**
|
|
507
739
|
* NcSelect input handler.
|
|
508
740
|
*
|
|
@@ -523,6 +755,7 @@ export default {
|
|
|
523
755
|
applySelection(value) {
|
|
524
756
|
this.selected = value
|
|
525
757
|
this.writeWorkspace(value)
|
|
758
|
+
this.writeAddress(value)
|
|
526
759
|
/**
|
|
527
760
|
* @event change Emitted when the selection changes. Payload: `{ key, value }`.
|
|
528
761
|
*/
|
|
@@ -610,6 +843,46 @@ export default {
|
|
|
610
843
|
gap: 2px;
|
|
611
844
|
}
|
|
612
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
|
+
|
|
613
886
|
/* The start card: text left, control (and link) right, as PqDashboard's "Contact starten". */
|
|
614
887
|
.cn-workspace-filter-widget--start {
|
|
615
888
|
flex-direction: row;
|
|
@@ -657,4 +930,29 @@ export default {
|
|
|
657
930
|
color: var(--color-text-maxcontrast);
|
|
658
931
|
font-size: 0.85em;
|
|
659
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
|
+
}
|
|
660
958
|
</style>
|
package/src/components/index.js
CHANGED
|
@@ -219,7 +219,21 @@ export { CnTasksWidgetForm } from './CnTasksWidgetForm/index.js'
|
|
|
219
219
|
export { CnSectionsWidget } from './CnSectionsWidget/index.js'
|
|
220
220
|
export { CnFactsWidget } from './CnFactsWidget/index.js'
|
|
221
221
|
export { CnFieldListWidget } from './CnFieldListWidget/index.js'
|
|
222
|
+
export { CnSettingsFormWidget } from './CnSettingsFormWidget/index.js'
|
|
223
|
+
export { CnSwitchRowsWidget } from './CnSwitchRowsWidget/index.js'
|
|
224
|
+
export { CnRadioCardsWidget } from './CnRadioCardsWidget/index.js'
|
|
225
|
+
export { CnChipsFieldWidget } from './CnChipsFieldWidget/index.js'
|
|
226
|
+
export { CnToggleTableWidget } from './CnToggleTableWidget/index.js'
|
|
227
|
+
export { CnChoicePickerWidget } from './CnChoicePickerWidget/index.js'
|
|
222
228
|
export { CnRecordListWidget } from './CnRecordListWidget/index.js'
|
|
229
|
+
export { CnBannerWidget } from './CnBannerWidget/index.js'
|
|
230
|
+
export { default as CnConversationWidget } from './CnConversationThread/CnConversationWidget.vue'
|
|
231
|
+
export { default as CnDocumentReviewWidget } from './CnDocumentReviewList/CnDocumentReviewWidget.vue'
|
|
232
|
+
export { default as CnNextStepWidget } from './CnNextStepCard/CnNextStepWidget.vue'
|
|
233
|
+
export { default as CnAuditTrailWidget } from './CnAuditTrailWidget/CnAuditTrailWidget.vue'
|
|
234
|
+
export { CnKbSearchWidget } from './CnKbSearchWidget/index.js'
|
|
235
|
+
export { CnInteractionFormWidget } from './CnInteractionFormWidget/index.js'
|
|
236
|
+
export { CnWorkspaceFilterWidget } from './CnWorkspaceFilterWidget/index.js'
|
|
223
237
|
export { CnFilePreview } from './CnFilePreview/index.js'
|
|
224
238
|
export { CnTaskFormDialog } from './CnTaskFormDialog/index.js'
|
|
225
239
|
export { CnChildRecordsField } from './CnChildRecordsField/index.js'
|
|
@@ -228,6 +242,7 @@ export { CnMarkdownWidget } from './CnMarkdownWidget/index.js'
|
|
|
228
242
|
export { CnMarkdownWidgetForm } from './CnMarkdownWidgetForm/index.js'
|
|
229
243
|
export { CnObjectListWidget } from './CnObjectListWidget/index.js'
|
|
230
244
|
export { CnObjectListWidgetForm } from './CnObjectListWidgetForm/index.js'
|
|
245
|
+
export { CnSavedViewsWidget } from './CnSavedViewsWidget/index.js'
|
|
231
246
|
export { CnSavedViewWidget } from './CnSavedViewWidget/index.js'
|
|
232
247
|
export { CnSavedViewWidgetForm } from './CnSavedViewWidgetForm/index.js'
|
|
233
248
|
export { CnChartWidgetForm } from './CnChartWidgetForm/index.js'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { computed, isRef, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
2
2
|
import { useObjectStore } from '../store/index.js'
|
|
3
|
+
import { facetFilterParams } from '../utils/facets.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Composable for managing list view state with full objectStore integration.
|
|
@@ -163,10 +164,9 @@ export function useListView(objectTypeOrOptions, options) {
|
|
|
163
164
|
}
|
|
164
165
|
|
|
165
166
|
for (const [key, values] of Object.entries(activeFilters.value)) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
167
|
+
// Single-value arrays are unwrapped to scalar params; the
|
|
168
|
+
// missing-value option becomes `<key>_isnull=true`.
|
|
169
|
+
Object.assign(params, facetFilterParams(key, values))
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
// Fixed filters (e.g. a route-param-scoped `pages[].config.filter`) are
|
|
@@ -202,6 +202,15 @@
|
|
|
202
202
|
gap: 4px;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
/* No inner scroller: tabs that do not fit the width wrap onto a second row
|
|
206
|
+
instead of scrolling sideways (the library's default strip), so the strip
|
|
207
|
+
has no scrollbar, no clipped tab and no fade or chevron to find the rest. */
|
|
208
|
+
.cn-look-board .cn-tabs--board .cn-tabs__nav {
|
|
209
|
+
flex-wrap: wrap;
|
|
210
|
+
overflow: visible;
|
|
211
|
+
row-gap: 4px;
|
|
212
|
+
}
|
|
213
|
+
|
|
205
214
|
.cn-look-board .cn-tabs--board .cn-tabs__nav-item {
|
|
206
215
|
background-color: var(--color-background-dark);
|
|
207
216
|
border: 1px solid var(--color-border-dark);
|
|
@@ -347,12 +356,28 @@
|
|
|
347
356
|
padding: 0 0 10px;
|
|
348
357
|
}
|
|
349
358
|
|
|
350
|
-
|
|
351
|
-
|
|
359
|
+
/* Outranks the component's own `.cn-object-data-widget__label[data-v-...]`
|
|
360
|
+
(weight 500, 0.85em, which has the same specificity as the look's rule and
|
|
361
|
+
wins on source order wherever a bundle, such as a companion app's, loads
|
|
362
|
+
after this stylesheet), through the grid the labels sit in. Measured live:
|
|
363
|
+
the labels read bold and dark where the boards (DqContact, PqKlant, ShKlant)
|
|
364
|
+
draw them 13px, regular weight and light grey.
|
|
365
|
+
|
|
366
|
+
The colour carries `!important`: a theme (nldesign's element overrides) sets
|
|
367
|
+
the ink of every `div` outside the header with a selector that has an id in
|
|
368
|
+
its `:not()`, which no class rule outranks. */
|
|
369
|
+
.cn-look-board .cn-object-data-widget__grid .cn-object-data-widget__label {
|
|
370
|
+
color: var(--color-text-maxcontrast) !important;
|
|
352
371
|
font-size: 13px;
|
|
353
372
|
font-weight: 400;
|
|
354
373
|
}
|
|
355
374
|
|
|
375
|
+
/* The facts card's labels: the same light grey, regular weight. */
|
|
376
|
+
.cn-look-board .cn-facts-widget .cn-facts-widget__label {
|
|
377
|
+
color: var(--color-text-maxcontrast);
|
|
378
|
+
font-weight: 400;
|
|
379
|
+
}
|
|
380
|
+
|
|
356
381
|
.cn-look-board .cn-object-data-widget__value {
|
|
357
382
|
font-weight: 500;
|
|
358
383
|
}
|
|
@@ -610,3 +635,12 @@
|
|
|
610
635
|
font-size: 13px;
|
|
611
636
|
margin: 2px 0 0;
|
|
612
637
|
}
|
|
638
|
+
|
|
639
|
+
/* The sidebar's own open toggle (NcAppSidebar's `.app-sidebar__toggle`, drawn
|
|
640
|
+
when the sidebar is closed) is positioned over the content's top-right
|
|
641
|
+
corner, which in this look is the header's last button: a stray square icon
|
|
642
|
+
on "More". The board draws none, so it is hidden on a detail page and the
|
|
643
|
+
header menu offers "Open sidebar" instead. */
|
|
644
|
+
.cn-look-board:has(.cn-detail-page) > .app-sidebar__toggle {
|
|
645
|
+
display: none;
|
|
646
|
+
}
|
|
@@ -249,7 +249,8 @@
|
|
|
249
249
|
}
|
|
250
250
|
|
|
251
251
|
/* Filter: a labelled secondary button, 36px, radius 8, with the active count. */
|
|
252
|
-
.cn-look-board .cn-actions-bar__filter-button.button-vue
|
|
252
|
+
.cn-look-board .cn-actions-bar__filter-button.button-vue,
|
|
253
|
+
.cn-look-board .cn-actions-bar__filter-menu .button-vue {
|
|
253
254
|
min-height: 36px;
|
|
254
255
|
height: 36px;
|
|
255
256
|
border-radius: 8px;
|
|
@@ -499,11 +500,16 @@
|
|
|
499
500
|
max-width: calc(100% - 26px);
|
|
500
501
|
}
|
|
501
502
|
|
|
502
|
-
/* The selection column:
|
|
503
|
+
/* The selection column: 18px checkboxes, 28px of content after 16px of padding.
|
|
504
|
+
The box model is set with `!important` and the widths include the padding:
|
|
505
|
+
Nextcloud's server.css sets `box-sizing: border-box` on everything under
|
|
506
|
+
`#content[class*="app-"]`, an id selector no class rule outranks, so a plain
|
|
507
|
+
`content-box` here was ignored and the cell left 12px for the checkbox (the
|
|
508
|
+
header's checkbox showed as a stray bracket). */
|
|
503
509
|
.cn-look-board .cn-table-container--board .cn-data-table .cn-table-col--checkbox {
|
|
504
|
-
box-sizing:
|
|
505
|
-
width:
|
|
506
|
-
min-width:
|
|
510
|
+
box-sizing: border-box !important;
|
|
511
|
+
width: 44px;
|
|
512
|
+
min-width: 44px;
|
|
507
513
|
padding-inline: 16px 0;
|
|
508
514
|
text-align: start;
|
|
509
515
|
}
|
|
@@ -551,6 +557,29 @@
|
|
|
551
557
|
font-size: 13px;
|
|
552
558
|
}
|
|
553
559
|
|
|
560
|
+
/* An avatar in the title column (PtAccounts): a 32px chip circle, 10px before
|
|
561
|
+
the name, the e-mail under the name beside it. The name keeps the title's
|
|
562
|
+
weight and size, and its underline: an inline-flex box is atomic, so the
|
|
563
|
+
cell's own underline does not reach it. */
|
|
564
|
+
.cn-look-board .cn-table-container--board .cn-data-table .cn-cell-renderer__avatar {
|
|
565
|
+
gap: 10px;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.cn-look-board .cn-table-container--board .cn-data-table .cn-cell-renderer__avatar-initials {
|
|
569
|
+
background: var(--color-background-dark);
|
|
570
|
+
color: var(--color-main-text);
|
|
571
|
+
font-size: 12px;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.cn-look-board .cn-table-container--board .cn-data-table td.cn-table-col--title .cn-cell-renderer__avatar-name {
|
|
575
|
+
text-decoration: underline;
|
|
576
|
+
text-underline-offset: 2px;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.cn-look-board .cn-table-container--board.cn-table-container--title-plain .cn-data-table td.cn-table-col--title .cn-cell-renderer__avatar-name {
|
|
580
|
+
text-decoration: none;
|
|
581
|
+
}
|
|
582
|
+
|
|
554
583
|
/* A status pill: 3px 10px, radius 12, 13px weight 600. The colours stay the
|
|
555
584
|
status colour map's. */
|
|
556
585
|
.cn-look-board .cn-table-container--board .cn-data-table .cn-status-badge {
|
|
@@ -561,10 +590,12 @@
|
|
|
561
590
|
line-height: 1.4;
|
|
562
591
|
}
|
|
563
592
|
|
|
564
|
-
/* The row menu column holds one 34px button
|
|
593
|
+
/* The row menu column holds one 34px button between 16px of padding, so 66px
|
|
594
|
+
border to border (see the selection column for why the box model is forced). */
|
|
565
595
|
.cn-look-board .cn-table-container--board .cn-data-table .cn-table-col--actions {
|
|
566
|
-
|
|
567
|
-
|
|
596
|
+
box-sizing: border-box !important;
|
|
597
|
+
width: 66px;
|
|
598
|
+
min-width: 66px;
|
|
568
599
|
padding-inline: 16px;
|
|
569
600
|
text-align: end;
|
|
570
601
|
}
|