@conduction/nextcloud-vue 2.104.0 → 2.106.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/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue.js +1 -1
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js +18 -0
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js.map +1 -1
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js +3 -1
- package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue.js +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +18 -0
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +93 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +6 -3
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +3 -3
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +112 -5
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue.js +9 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue.js.map +1 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue2.js +24 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue2.js.map +1 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue3.js +49 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue3.js.map +1 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +36 -18
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +17 -38
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
- 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/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue.js +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue.js +1 -1
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue2.js +2 -0
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue2.js.map +1 -1
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue3.js +32 -29
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +53 -2
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +119 -111
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue.js +1 -1
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js +62 -1
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue.js +1 -1
- package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue2.js +73 -4
- package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue2.js.map +1 -1
- package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue3.js +74 -27
- package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +208 -46
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +121 -98
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js +24 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js +20 -4
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useSelfFetchList.js +25 -6
- package/dist/esm/components/CnIndexPage/useSelfFetchList.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js +112 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js +100 -44
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
- package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue.js +1 -1
- package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue2.js +67 -4
- package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue3.js +1 -1
- package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue.js +9 -0
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue.js.map +1 -0
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue2.js +88 -0
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue3.js +39 -0
- package/dist/esm/components/CnNoticeWidget/CnNoticeWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue.js +1 -1
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js +295 -12
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js +267 -144
- package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +4 -0
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +3 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +93 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +322 -246
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue.js +1 -1
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js +122 -7
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue3.js +189 -93
- package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue.js +1 -1
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue2.js.map +1 -1
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue3.js +3 -3
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue3.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue.js +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +16 -4
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue.js +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +42 -0
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +38 -19
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTeamWorkloadWidget/CnTeamWorkloadWidget.vue.js +9 -0
- package/dist/esm/components/CnTeamWorkloadWidget/CnTeamWorkloadWidget.vue.js.map +1 -0
- package/dist/esm/components/CnTeamWorkloadWidget/CnTeamWorkloadWidget.vue2.js +258 -0
- package/dist/esm/components/CnTeamWorkloadWidget/CnTeamWorkloadWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnTeamWorkloadWidget/CnTeamWorkloadWidget.vue3.js +69 -0
- package/dist/esm/components/CnTeamWorkloadWidget/CnTeamWorkloadWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue.js +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js +11 -0
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js.map +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js +4 -4
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +16 -14
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +12 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +24 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +24 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +1369 -748
- package/dist/esm/utils/dueText.js +18 -3
- package/dist/esm/utils/dueText.js.map +1 -1
- package/dist/esm/utils/libraryWidgetKeys.js +2 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/nextcloudApps.js +45 -0
- package/dist/esm/utils/nextcloudApps.js.map +1 -0
- package/dist/esm/utils/scopeListLayout.js +9 -2
- package/dist/esm/utils/scopeListLayout.js.map +1 -1
- package/dist/esm/utils/sortOrder.js +11 -1
- package/dist/esm/utils/sortOrder.js.map +1 -1
- 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 +12 -4
- package/dist/esm/utils/visibleWhen.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +8965 -6497
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +1369 -748
- package/l10n/en.json +24 -1
- package/l10n/nl.json +24 -1
- package/package.json +1 -1
- package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +1 -1
- package/src/components/CnCardGrid/CnCardGrid.md +2 -0
- package/src/components/CnCardGrid/CnCardGrid.vue +20 -0
- package/src/components/CnCellRenderer/CnCellRenderer.vue +19 -1
- package/src/components/CnChartWidget/CnChartWidget.md +2 -0
- package/src/components/CnChartWidget/CnChartWidget.vue +93 -1
- package/src/components/CnDashboardPage/CnDashboardPage.vue +9 -6
- package/src/components/CnDetailPage/CnDetailPage.md +3 -2
- package/src/components/CnDetailPage/CnDetailPage.vue +112 -5
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue +60 -0
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +36 -29
- package/src/components/CnFactsWidget/CnFactsWidget.vue +4 -0
- package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +1 -1
- package/src/components/CnFeaturesBoard/CnFeaturesBoard.vue +4 -1
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +70 -4
- package/src/components/CnFlowRunsWidget/CnFlowRunsWidget.vue +62 -1
- package/src/components/CnFlowsPage/CnFlowBoard.vue +132 -8
- package/src/components/CnIndexPage/CnIndexPage.md +8 -5
- package/src/components/CnIndexPage/CnIndexPage.vue +236 -54
- package/src/components/CnIndexPage/CnIndexPageWidgets.vue +36 -1
- package/src/components/CnIndexPage/useSelfFetchList.js +25 -6
- package/src/components/CnIndexSidebar/CnIndexSidebar.md +2 -0
- package/src/components/CnIndexSidebar/CnIndexSidebar.vue +148 -1
- package/src/components/CnNcWidgetWidget/CnNcWidgetWidget.vue +68 -5
- package/src/components/CnNoticeWidget/CnNoticeWidget.vue +153 -0
- package/src/components/CnNoticeWidget/index.js +12 -0
- package/src/components/CnObjectCard/CnObjectCard.md +1 -0
- package/src/components/CnObjectCard/CnObjectCard.vue +354 -13
- package/src/components/CnObjectSidebar/CnFilesTab.vue +6 -0
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +190 -4
- package/src/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue +209 -9
- package/src/components/CnSettingsField/CnSettingsField.vue +4 -1
- package/src/components/CnSetupWizard/CnSetupWizard.vue +9 -1
- package/src/components/CnTabs/CnTabs.vue +11 -0
- package/src/components/CnTabsWidget/CnTabsWidget.vue +91 -18
- package/src/components/CnTeamWorkloadWidget/CnTeamWorkloadWidget.md +11 -0
- package/src/components/CnTeamWorkloadWidget/CnTeamWorkloadWidget.vue +382 -0
- package/src/components/CnTeamWorkloadWidget/index.js +14 -0
- package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +15 -4
- package/src/components/CnWidgetGrid/builtInWidgets.js +2 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +12 -0
- package/src/components/index.js +2 -0
- package/src/css/dialog.css +20 -2
- package/src/css/index-page.css +14 -2
- package/src/css/look-board-detail.css +125 -8
- package/src/css/look-board-index.css +100 -4
- package/src/css/look-board.css +122 -14
- package/src/index.js +2 -1
- package/src/schemas/app-manifest-v2.schema.json +110 -8
- package/src/utils/dueText.js +18 -3
- package/src/utils/libraryWidgetKeys.js +2 -0
- package/src/utils/nextcloudApps.js +50 -0
- package/src/utils/scopeListLayout.js +9 -2
- package/src/utils/sortOrder.js +10 -0
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/visibleWhen.js +12 -4
|
@@ -390,6 +390,7 @@ export default {
|
|
|
390
390
|
| `showViewToggle` | Boolean | `true` | Whether to show the Cards/Table view toggle |
|
|
391
391
|
| `inlineSearch` | Boolean | `false` | Show an inline search field in the actions bar (in addition to / instead of the sidebar search). Fed from the manifest as `pages[].config.inlineSearch`. The field takes the place of the "Showing X of Y" counter unless `showCountWithSearch` is set. |
|
|
392
392
|
| `search` | Boolean | `true` | `false` draws no inline search in the actions bar, also in the board look, which otherwise draws one on every index page (manifest: `config.search`). Wins over `inlineSearch`. |
|
|
393
|
+
| `appConfig` | Object | `{}` | The app config `@config.<key>` tokens resolve against (manifest: `config.appConfig`), as on the dashboard and detail pages, merged over a config an ancestor provides on `cnAppConfig`. A quick filter's `filter` and its `label` / `activeLabel` take the token: `"Residence @config.municipality"` reads "Residence Zuiddrecht" (board DqContacten); the label is translated first, and a key the config does not hold leaves the token as written. |
|
|
393
394
|
| `showCountWithSearch` | Boolean | `false` | Keep the "Showing X of Y" counter visible beside the inline search field, after the search and any `#after-search` controls (only relevant with `inlineSearch`, which otherwise takes the counter's place). Fed from the manifest as `pages[].config.showCountWithSearch`. |
|
|
394
395
|
| `searchInFiles` | Boolean | `false` | "Also search inside files" switch beside the search box (manifest `config.searchInFiles`). On, a search with a term sends `_content_search=true`; rows found through a file show "Found in {file}" (`@self.matchedFile`). State kept in the route as `contentSearch=1`. Emits `content-search`. |
|
|
395
396
|
| `searchPlaceholder` | String | `''` | Placeholder for the inline search field (manifest `config.searchPlaceholder`). |
|
|
@@ -415,7 +416,7 @@ export default {
|
|
|
415
416
|
| `quickFilterMode` | String | `'chips'` | How the quick filters render: `'chips'` (pill strip) or `'dropdown'` (a single `NcSelect`). Fed from `pages[].config.quickFilterMode`. |
|
|
416
417
|
| `quickFilterMultiple` | Boolean | `false` | Allow several quick filters active at once; selected tabs' filters are OR-ed into the fetch (same field → `field[]=` array). Fed from `pages[].config.quickFilterMultiple`. |
|
|
417
418
|
| `quickFilterMaxVisible` | Number | `0` | Chips mode only — how many quick-filter pills render inline before the rest move behind one more chip — a `⋯` pill that opens a panel of the hidden lenses. `0` renders every tab, which wraps the actions bar onto a second line once a page declares more than a handful. The visible set is the first *n* entries of `quickFilters`. Fed from `pages[].config.quickFilterMaxVisible`. |
|
|
418
|
-
| `quickFilterPlacement` | String | `''` | Where the quick-filter chips sit. `'toolbar'` keeps them on one row with the Filter button and the view switch, in whatever width that row has beside a side panel (DqTeamwachtrij): the chips take the room the buttons leave, and those that do not fit move behind the overflow chip. Fed from `pages[].config.quickFilterPlacement`. |
|
|
419
|
+
| `quickFilterPlacement` | String | `''` | Where the quick-filter chips sit. `'toolbar'` keeps them on one row with the Filter button and the view switch, in whatever width that row has beside a side panel (DqTeamwachtrij): the chips take the room the buttons leave, and those that do not fit move behind the overflow chip. Fed from `pages[].config.quickFilterPlacement`. `'row'` puts them on a row of their own above the toolbar, wrapping onto more lines instead of folding into the overflow chip (DqTeamwachtrij); beside a side panel the row sits in the list column. |
|
|
419
420
|
| `cardComponent` | String | `''` | Optional name of a consumer-provided card component (registered in the v2 `registry` — any kind carrying a `component` — or in the legacy `customComponents` map on `CnAppRoot`) to render in place of the default `CnObjectCard` when the page is in card-grid view mode. Resolution priority: `#card` scoped slot → `cardComponent` registry entry → default `CnObjectCard`. Unknown names log `console.warn` once and fall back to the default. |
|
|
420
421
|
| `customComponents` | Object | `null` | Optional explicit `customComponents` registry. Overrides the registry injected from `CnAppRoot` via `cnCustomComponents`. Mostly used by unit tests; production consumers register components on `CnAppRoot` instead. |
|
|
421
422
|
| `subscribe` | Boolean | `true` | Self-fetch mode only. When `register` + `schema` are set (and no `objects` prop), the page subscribes to the collection's `or-collection-{register}-{schema}` live-update scope on mount and refetches on an update event; released on unmount. Set `false` (manifest: `config.subscribe: false`) for static / read-once views. No-op in consumer-managed mode or on stores without live-updates support. |
|
|
@@ -878,9 +879,9 @@ The list view (`view-mode="list"`) and standalone sort dropdown add these props:
|
|
|
878
879
|
| `listIcon` | String | `''` | MDI icon for the list view-toggle option. |
|
|
879
880
|
| `listConfig` | Object | `{}` | Field mapping for the default list rows (`CnObjectRow`). |
|
|
880
881
|
| `listComponent` | String | `''` | Custom row component, resolved against the v2 `registry` (any kind carrying a `component`) and then the legacy `customComponents` map. |
|
|
881
|
-
| `showSortSelect` | Boolean | `false` |
|
|
882
|
-
| `sortSelectOptions` | Array | `[]` |
|
|
883
|
-
| `sortSelectValue` | String | `''` |
|
|
882
|
+
| `showSortSelect` | Boolean | `false` | Deprecated, without effect: the toolbar draws no sort select. The table sorts by its column headers; the list, card and map views by the Sort section in the index sidebar. |
|
|
883
|
+
| `sortSelectOptions` | Array | `[]` | The orders the index sidebar's Sort section offers in the list, card and map views: `{ value, label, order? }`, the order its `order` or its `value` read as one (`"-createdAt"`, `"priority:desc,title"`). Without them the section offers the sortable columns. |
|
|
884
|
+
| `sortSelectValue` | String | `''` | Deprecated, without effect: the Sort section shows the current order. |
|
|
884
885
|
| `defaultOrder` | String, Object or Array | `''` | The order a self-fetch page opens on when neither the address nor `sortKeys`/`sortKey` gives one (manifest `config.defaultOrder`): `"-createdAt"`, `"priority:desc,title"`, an `_order` map `{ "priority": "desc" }` or a `[{ key, order }]` list. |
|
|
885
886
|
|
|
886
887
|
The `#list-item`, `#row-icon`, `#row-badges`, and `#row-actions` slots override the list rows (see [CnObjectList](./cn-object-list.md)). Emits `@sort-change` with the chosen sort value.
|
|
@@ -1096,6 +1097,8 @@ Sources: `register` (fetch the folder list from an OpenRegister `register`/`sche
|
|
|
1096
1097
|
}
|
|
1097
1098
|
```
|
|
1098
1099
|
|
|
1100
|
+
`scopeViews` limits the scope's look (columns, title, count line and the other scope keys) to the view modes it names, e.g. `["table", "list"]`, so a board view keeps the page's generic look (DqWerkbord) while the scope still filters it.
|
|
1101
|
+
|
|
1099
1102
|
`pane: false` draws no pane. The folder still comes from the deep-link filter (`/cases?caseType=<uuid>`) and its scope look (title, count line, columns, quick filters, `afterList` from the folder or its row's `x-index`) still applies, so a list narrowed to one case type looks like that case type's list without a folder column (boards DqWooVerzoeken, DqKlachten):
|
|
1100
1103
|
|
|
1101
1104
|
```json
|
|
@@ -1148,7 +1151,7 @@ columns are right.
|
|
|
1148
1151
|
|
|
1149
1152
|
## Board look
|
|
1150
1153
|
|
|
1151
|
-
With `look: "board"` (the page's `look` prop, `config.look`, or the app's) the index page takes the DqZaken setup: a header with the count line from `countText` (`{shown}`, `{total}`), the buttons Download, Actions, the buildiq square and the primary one in that order, a two-row toolbar (saved-view chips, Filter with a count and the view switch; then search and active filter chips), a bulk band between toolbar and table (`bulkHint`), the table as a white card with one menu button per row, and a footer inside the card (`footerNote`). `cardFields` names the facts of each card in the cards view. Without the look nothing changes.
|
|
1154
|
+
With `look: "board"` (the page's `look` prop, `config.look`, or the app's) the index page takes the DqZaken setup: a header with the count line from `countText` (`{shown}`, `{total}`), the buttons Download, Actions, the buildiq square and the primary one in that order, a two-row toolbar (saved-view chips, Filter with a count and the view switch; then search and active filter chips), a bulk band between toolbar and table (`bulkHint`), the table as a white card with one menu button per row, and a footer inside the card (`footerNote`). `cardFields` names the facts of each card in the cards view, and `cardLayout` draws each card as a record instead: a pill and the number on the head row, the title, a meta line, and a footer with a pill and a date, every part from a field (`{ headPill: { field, colorMap, labels }, number, title, meta: [...], footerPill, footerDate: { field, label } }`). Without the look nothing changes.
|
|
1152
1155
|
|
|
1153
1156
|
`bulkBandAlways` (`config.bulkBandAlways`) draws the board bulk band before a selection too, its buttons
|
|
1154
1157
|
disabled until rows are selected (DqZaken, DqWerkbord).
|
|
@@ -157,6 +157,25 @@
|
|
|
157
157
|
:widgets="sidePanel" />
|
|
158
158
|
|
|
159
159
|
<!-- Actions bar -->
|
|
160
|
+
<!-- `quickFilterPlacement: "row"`: the chips on a row of their own above
|
|
161
|
+
the toolbar, wrapping onto more lines (DqTeamwachtrij). -->
|
|
162
|
+
<div
|
|
163
|
+
v-if="quickFilterPlacement === 'row' && tabStripEntries && tabStripEntries.length > 0"
|
|
164
|
+
class="cn-index-page__quick-filter-row"
|
|
165
|
+
data-testid="cn-index-page-quick-filter-row">
|
|
166
|
+
<CnQuickFilterBar
|
|
167
|
+
inline
|
|
168
|
+
:tabs="tabStripEntries"
|
|
169
|
+
:mode="quickFilterMode"
|
|
170
|
+
:maxVisible="quickFilterMaxVisible"
|
|
171
|
+
:fit="false"
|
|
172
|
+
:multiple="quickFilterMultiple"
|
|
173
|
+
:activeIndex="activeQuickFilterIndex"
|
|
174
|
+
:selectedIndices="selectedQuickFilterIndices"
|
|
175
|
+
:counts="effectiveTabCounts"
|
|
176
|
+
@update:activeIndex="onQuickFilterChange"
|
|
177
|
+
@update:selectedIndices="onQuickFilterMultiChange" />
|
|
178
|
+
</div>
|
|
160
179
|
<CnActionsBar
|
|
161
180
|
:layout="isBoardLook ? 'board' : 'nextcloud'"
|
|
162
181
|
:activeFilterChips="activeFilterChips"
|
|
@@ -189,9 +208,6 @@
|
|
|
189
208
|
:mapLabel="mapLabel"
|
|
190
209
|
:mapIcon="mapIcon"
|
|
191
210
|
:listIcon="listIcon"
|
|
192
|
-
:showSortSelect="showSortSelect"
|
|
193
|
-
:sortOptions="sortSelectOptions"
|
|
194
|
-
:sortValue="effectiveSortSelectValue"
|
|
195
211
|
:showSearch="search !== false && (inlineSearch || isBoardLook)"
|
|
196
212
|
:searchPlacement="searchPlacement"
|
|
197
213
|
:searchValue="effectiveSearchValue"
|
|
@@ -210,7 +226,6 @@
|
|
|
210
226
|
:bulkActions="mergedBulkActions"
|
|
211
227
|
:documentationUrl="documentationUrl"
|
|
212
228
|
:documentationLabel="documentationLabel || undefined"
|
|
213
|
-
@sortChange="onSortSelectChange"
|
|
214
229
|
@add="onAddClick"
|
|
215
230
|
@clearSelection="onSelect([])"
|
|
216
231
|
@removeFilter="onRemoveActiveFilter"
|
|
@@ -365,7 +380,7 @@
|
|
|
365
380
|
(between the view toggle and the actions) when the manifest
|
|
366
381
|
declares `config.quickFilters`. Switching tabs re-fetches with
|
|
367
382
|
the merged filter; @event quick-filter-change. -->
|
|
368
|
-
<template v-if="tabStripEntries && tabStripEntries.length > 0" #filters>
|
|
383
|
+
<template v-if="tabStripEntries && tabStripEntries.length > 0 && quickFilterPlacement !== 'row'" #filters>
|
|
369
384
|
<CnQuickFilterBar
|
|
370
385
|
inline
|
|
371
386
|
:tabs="tabStripEntries"
|
|
@@ -373,7 +388,7 @@
|
|
|
373
388
|
:maxVisible="quickFilterMaxVisible"
|
|
374
389
|
:fit="quickFilterPlacement === 'toolbar'"
|
|
375
390
|
:multiple="quickFilterMultiple"
|
|
376
|
-
:activeIndex="
|
|
391
|
+
:activeIndex="shownQuickFilterIndex"
|
|
377
392
|
:selectedIndices="selectedQuickFilterIndices"
|
|
378
393
|
:counts="effectiveTabCounts"
|
|
379
394
|
@update:activeIndex="onQuickFilterChange"
|
|
@@ -772,7 +787,7 @@
|
|
|
772
787
|
:rowTitle="rowTitle"
|
|
773
788
|
:showUnread="showUnreadRows"
|
|
774
789
|
:filterable="tableHeaderFilters"
|
|
775
|
-
:activeFilters="
|
|
790
|
+
:activeFilters="tableActiveFilters"
|
|
776
791
|
:filterRegister="typeof register === 'string' ? register : ''"
|
|
777
792
|
@columnFilter="onColumnFilterEvent"
|
|
778
793
|
@sort="onSortEvent"
|
|
@@ -1057,6 +1072,8 @@
|
|
|
1057
1072
|
:selectable="selectable"
|
|
1058
1073
|
:clickToView="rowClickOpens"
|
|
1059
1074
|
:cardFields="resolvedCardFields"
|
|
1075
|
+
:cardLayout="cardLayout"
|
|
1076
|
+
:cardFieldColumns="cardFieldColumns"
|
|
1060
1077
|
:accentOf="cardAccent"
|
|
1061
1078
|
:selectedIds="internalSelectedIds"
|
|
1062
1079
|
:rowKey="rowKey"
|
|
@@ -1229,6 +1246,8 @@
|
|
|
1229
1246
|
:showMetadata="resolvedSidebar.showMetadata !== false"
|
|
1230
1247
|
:personalColumns="personalColumns"
|
|
1231
1248
|
:pinnedCount="pinnedColumnCount"
|
|
1249
|
+
:sortOptions="sidebarSortOptions"
|
|
1250
|
+
:currentSort="currentSortKeys"
|
|
1232
1251
|
v-bind="sidebarSearchProps"
|
|
1233
1252
|
@update:open="sidebarOpen = $event"
|
|
1234
1253
|
@search="onSearchEvent"
|
|
@@ -1237,7 +1256,8 @@
|
|
|
1237
1256
|
@pinChange="onPinChange"
|
|
1238
1257
|
@columnsReset="onColumnsReset"
|
|
1239
1258
|
@filterChange="onFilterEvent"
|
|
1240
|
-
@clearFilters="onClearFilters"
|
|
1259
|
+
@clearFilters="onClearFilters"
|
|
1260
|
+
@sortChange="onSidebarSortChange" />
|
|
1241
1261
|
</div>
|
|
1242
1262
|
</template>
|
|
1243
1263
|
|
|
@@ -1285,9 +1305,11 @@ import {
|
|
|
1285
1305
|
refIdOf,
|
|
1286
1306
|
resolveDropValue,
|
|
1287
1307
|
} from '../../utils/boardReferenceColumns.js'
|
|
1308
|
+
import { isColumnSortable } from '../../utils/columnFilters.js'
|
|
1288
1309
|
import { reportBindingProblems } from '../../utils/diagnostics.js'
|
|
1289
1310
|
import { fetchGroupedCounts } from '../../utils/fetchAggregate.js'
|
|
1290
1311
|
import { fetchFilterCounts, fetchListTotal } from '../../utils/fetchFilterCounts.js'
|
|
1312
|
+
import { unwrapAppConfig } from '../../utils/formatMetric.js'
|
|
1291
1313
|
import { buildExportUrl } from '../../utils/indexExportHelpers.js'
|
|
1292
1314
|
import { lensUnavailableText } from '../../utils/lensAvailability.js'
|
|
1293
1315
|
import { isModifiedClick, openRowTarget } from '../../utils/linkNavigation.js'
|
|
@@ -1310,7 +1332,7 @@ import { DEFAULT_ROW_INDICATOR_CAP } from '../../utils/rowIndicators.js'
|
|
|
1310
1332
|
import { buildRouteQueryFromViewState, buildViewCreatePayload, extractViewState, extractViewStateFromRouteQuery, normalizeSharedWith, savedViewScope, viewMatchesScope } from '../../utils/savedViewHelpers.js'
|
|
1311
1333
|
import { columnsFromSchema, fieldsFromSchema } from '../../utils/schema.js'
|
|
1312
1334
|
import { resolveScopeLayout, resolveScopePresentation } from '../../utils/scopeListLayout.js'
|
|
1313
|
-
import { orderToSortKeys
|
|
1335
|
+
import { orderToSortKeys } from '../../utils/sortOrder.js'
|
|
1314
1336
|
import { dispatchObjectCreated } from '../../utils/walkthroughSignals.js'
|
|
1315
1337
|
import { CnActionButtons } from '../CnActionButtons/index.js'
|
|
1316
1338
|
import { CnActionsBar } from '../CnActionsBar/index.js'
|
|
@@ -1349,7 +1371,7 @@ import { orderColumns, personalColumnsKey, reconcilePersonalColumns } from './pe
|
|
|
1349
1371
|
import { createSelfModeActions, resolveRowTarget } from './selfModeActions.js'
|
|
1350
1372
|
import { applyRowPatches, normalisePaneWidth, rowIdOf, splitLayoutFor } from './splitView.js'
|
|
1351
1373
|
import { useNamedSource } from './useNamedSource.js'
|
|
1352
|
-
import { BOARD_PAGE_SIZE, useSelfFetchList } from './useSelfFetchList.js'
|
|
1374
|
+
import { BOARD_PAGE_SIZE, resolveInitialQuickFilterIndex, useSelfFetchList } from './useSelfFetchList.js'
|
|
1353
1375
|
|
|
1354
1376
|
/** Rows fetched for one month in calendar mode. */
|
|
1355
1377
|
const CALENDAR_PAGE_SIZE = 200
|
|
@@ -1677,6 +1699,8 @@ export default {
|
|
|
1677
1699
|
cnCustomComponents: { default: () => ({}) },
|
|
1678
1700
|
/** The permissions the user holds, provided by CnAppRoot; for gated page tabs. */
|
|
1679
1701
|
cnPermissions: { default: () => [] },
|
|
1702
|
+
/** The app config an ancestor provides, for `@config.<key>` in quick-filter labels. */
|
|
1703
|
+
cnAppConfig: { default: null },
|
|
1680
1704
|
/** The app id CnAppRoot provides, for the plural form of `countSubtitle`. */
|
|
1681
1705
|
cnAppId: { default: '' },
|
|
1682
1706
|
/**
|
|
@@ -1931,6 +1955,20 @@ export default {
|
|
|
1931
1955
|
default: null,
|
|
1932
1956
|
},
|
|
1933
1957
|
|
|
1958
|
+
/**
|
|
1959
|
+
* Board look: the record layout of each card in the cards view
|
|
1960
|
+
* (manifest key `config.cardLayout`): `{ headPill, number, title,
|
|
1961
|
+
* meta, footerPill, footerDate }`, each part naming a field. See
|
|
1962
|
+
* CnObjectCard `layout`.
|
|
1963
|
+
*
|
|
1964
|
+
* @type {object}
|
|
1965
|
+
* @spec openspec/changes/board-record-card-layout/specs/board-record-card-layout/spec.md#requirement-a-board-card-can-draw-the-record-layout-from-config
|
|
1966
|
+
*/
|
|
1967
|
+
cardLayout: {
|
|
1968
|
+
type: Object,
|
|
1969
|
+
default: null,
|
|
1970
|
+
},
|
|
1971
|
+
|
|
1934
1972
|
/**
|
|
1935
1973
|
* Gives each card in the card view a status accent: a colored start
|
|
1936
1974
|
* border and icon. See CnObjectCard `accent`.
|
|
@@ -2154,13 +2192,15 @@ export default {
|
|
|
2154
2192
|
* the Filter button and the view switch, in whatever width that row has
|
|
2155
2193
|
* beside a side panel (DqTeamwachtrij): the chips take the room the
|
|
2156
2194
|
* buttons leave, and those that do not fit move into the overflow chip.
|
|
2195
|
+
* `'row'` puts them on a row of their own above the toolbar, wrapping
|
|
2196
|
+
* onto more lines instead of folding into the overflow chip.
|
|
2157
2197
|
*
|
|
2158
|
-
* @type {''|'toolbar'}
|
|
2198
|
+
* @type {''|'toolbar'|'row'}
|
|
2159
2199
|
*/
|
|
2160
2200
|
quickFilterPlacement: {
|
|
2161
2201
|
type: String,
|
|
2162
2202
|
default: '',
|
|
2163
|
-
validator: (v) => ['', 'toolbar'].includes(v),
|
|
2203
|
+
validator: (v) => ['', 'toolbar', 'row'].includes(v),
|
|
2164
2204
|
},
|
|
2165
2205
|
|
|
2166
2206
|
/**
|
|
@@ -3133,6 +3173,19 @@ export default {
|
|
|
3133
3173
|
default: true,
|
|
3134
3174
|
},
|
|
3135
3175
|
|
|
3176
|
+
/**
|
|
3177
|
+
* The app config `@config.<key>` tokens resolve against, in quick-filter
|
|
3178
|
+
* filters and labels (`"Residence @config.municipality"`), as on the
|
|
3179
|
+
* dashboard and detail pages. Merged over a config an ancestor provides
|
|
3180
|
+
* on `cnAppConfig`. Manifest: `config.appConfig`.
|
|
3181
|
+
*
|
|
3182
|
+
* @type {object}
|
|
3183
|
+
*/
|
|
3184
|
+
appConfig: {
|
|
3185
|
+
type: Object,
|
|
3186
|
+
default: () => ({}),
|
|
3187
|
+
},
|
|
3188
|
+
|
|
3136
3189
|
/**
|
|
3137
3190
|
* Keep the "Showing X of Y" counter visible beside the inline search field,
|
|
3138
3191
|
* after any `#after-search` controls (only relevant with `inlineSearch`,
|
|
@@ -3181,9 +3234,11 @@ export default {
|
|
|
3181
3234
|
},
|
|
3182
3235
|
|
|
3183
3236
|
/**
|
|
3184
|
-
*
|
|
3185
|
-
*
|
|
3186
|
-
*
|
|
3237
|
+
* Deprecated, without effect: the toolbar draws no sort select. The
|
|
3238
|
+
* table sorts by its column headers, the list, card and map views by
|
|
3239
|
+
* the Sort section in the index sidebar.
|
|
3240
|
+
*
|
|
3241
|
+
* @deprecated
|
|
3187
3242
|
*/
|
|
3188
3243
|
showSortSelect: {
|
|
3189
3244
|
type: Boolean,
|
|
@@ -3191,7 +3246,11 @@ export default {
|
|
|
3191
3246
|
},
|
|
3192
3247
|
|
|
3193
3248
|
/**
|
|
3194
|
-
*
|
|
3249
|
+
* The orders the index sidebar's Sort section offers in the list, card
|
|
3250
|
+
* and map views (manifest `config.sortSelectOptions`): `{ value, label,
|
|
3251
|
+
* order? }`, the order its `order` (an `orderToSortKeys` form) or its
|
|
3252
|
+
* `value` read as one. Without them the section offers the sortable
|
|
3253
|
+
* columns.
|
|
3195
3254
|
*
|
|
3196
3255
|
* @type {Array<{ value: string, label: string }>}
|
|
3197
3256
|
*/
|
|
@@ -3201,8 +3260,10 @@ export default {
|
|
|
3201
3260
|
},
|
|
3202
3261
|
|
|
3203
3262
|
/**
|
|
3204
|
-
*
|
|
3205
|
-
*
|
|
3263
|
+
* Deprecated, without effect: the toolbar sort select is gone; the
|
|
3264
|
+
* Sort section in the index sidebar shows the current order.
|
|
3265
|
+
*
|
|
3266
|
+
* @deprecated
|
|
3206
3267
|
*/
|
|
3207
3268
|
sortSelectValue: {
|
|
3208
3269
|
type: String,
|
|
@@ -3255,6 +3316,9 @@ export default {
|
|
|
3255
3316
|
* defaults to `field`).
|
|
3256
3317
|
* - `folders` — explicit folder list for `source:'custom'`.
|
|
3257
3318
|
* - `allLabel` / `title` / `allowCreate` — passed to CnFolderSidebar.
|
|
3319
|
+
* - `scopeViews` — the view modes the scope's look (columns, title,
|
|
3320
|
+
* count line and the other scope keys) applies in, e.g. `["table",
|
|
3321
|
+
* "list"]`; other views keep the page's own look. Default: every view.
|
|
3258
3322
|
* - `pane` — `false` draws no pane: the scope still comes from the
|
|
3259
3323
|
* deep-link filter (`?caseType=<id>`) and still applies its look, as
|
|
3260
3324
|
* a list narrowed to one case type does without a folder column.
|
|
@@ -4986,22 +5050,45 @@ export default {
|
|
|
4986
5050
|
},
|
|
4987
5051
|
|
|
4988
5052
|
/**
|
|
4989
|
-
* The
|
|
4990
|
-
*
|
|
4991
|
-
* list's current order (a header click that matches one shows it).
|
|
5053
|
+
* The list's current order, `[{ key, order }]`: the self-fetched list's,
|
|
5054
|
+
* else the `sortKeys` / `sortKey` props.
|
|
4992
5055
|
*
|
|
4993
|
-
* @return {string
|
|
5056
|
+
* @return {Array<{key: string, order: string}>} The order.
|
|
4994
5057
|
*/
|
|
4995
|
-
|
|
4996
|
-
if (this.
|
|
4997
|
-
return this.
|
|
5058
|
+
currentSortKeys() {
|
|
5059
|
+
if (this.isSelfFetchMode && this.list && this.list.sortKeys) {
|
|
5060
|
+
return this.list.sortKeys.value || []
|
|
4998
5061
|
}
|
|
4999
|
-
if (
|
|
5000
|
-
return
|
|
5062
|
+
if (Array.isArray(this.sortKeys) && this.sortKeys.length > 0) {
|
|
5063
|
+
return this.sortKeys
|
|
5001
5064
|
}
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5065
|
+
return this.sortKey ? [{ key: this.sortKey, order: this.sortOrder || 'asc' }] : []
|
|
5066
|
+
},
|
|
5067
|
+
|
|
5068
|
+
/**
|
|
5069
|
+
* The orders the index sidebar's Sort section offers: none in the table
|
|
5070
|
+
* view, which sorts by its column headers; else `sortSelectOptions`,
|
|
5071
|
+
* or else the sortable columns, ascending.
|
|
5072
|
+
*
|
|
5073
|
+
* @return {Array<{value: string, label: string, keys: Array<{key: string, order: string}>}>} The options.
|
|
5074
|
+
*/
|
|
5075
|
+
sidebarSortOptions() {
|
|
5076
|
+
if (this.currentViewMode === 'table') {
|
|
5077
|
+
return []
|
|
5078
|
+
}
|
|
5079
|
+
if (Array.isArray(this.sortSelectOptions) && this.sortSelectOptions.length > 0) {
|
|
5080
|
+
return this.sortSelectOptions
|
|
5081
|
+
.filter((o) => o && o.value !== undefined && o.value !== null)
|
|
5082
|
+
.map((o) => ({
|
|
5083
|
+
value: String(o.value),
|
|
5084
|
+
label: this.cnTranslate(o.label || String(o.value)),
|
|
5085
|
+
keys: orderToSortKeys(o.order !== undefined ? o.order : o.value),
|
|
5086
|
+
}))
|
|
5087
|
+
.filter((o) => o.keys.length > 0)
|
|
5088
|
+
}
|
|
5089
|
+
return (this.tableColumns || [])
|
|
5090
|
+
.filter((c) => c && typeof c === 'object' && c.key && isColumnSortable(c, this.effectiveSchema))
|
|
5091
|
+
.map((c) => ({ value: c.key, label: this.cnTranslate(c.label || c.key), keys: [{ key: c.key, order: 'asc' }] }))
|
|
5005
5092
|
},
|
|
5006
5093
|
|
|
5007
5094
|
/**
|
|
@@ -5033,7 +5120,7 @@ export default {
|
|
|
5033
5120
|
* @spec openspec/changes/index-columns-per-scope/specs/index-page/spec.md
|
|
5034
5121
|
*/
|
|
5035
5122
|
activeScopeLayout() {
|
|
5036
|
-
if (!this.folderSidebar) {
|
|
5123
|
+
if (!this.folderSidebar || !this.scopeShapesView) {
|
|
5037
5124
|
return { columns: null, sortKeys: [], searchFields: [] }
|
|
5038
5125
|
}
|
|
5039
5126
|
return resolveScopeLayout({
|
|
@@ -5043,6 +5130,23 @@ export default {
|
|
|
5043
5130
|
})
|
|
5044
5131
|
},
|
|
5045
5132
|
|
|
5133
|
+
/**
|
|
5134
|
+
* Whether the active scope's look applies in the current view mode:
|
|
5135
|
+
* always, unless `folderSidebar.scopeViews` names the view modes it is
|
|
5136
|
+
* for (`["table", "list"]`), so the board keeps the page's generic
|
|
5137
|
+
* look (DqWerkbord). The scope's filter applies in every view.
|
|
5138
|
+
*
|
|
5139
|
+
* @spec openspec/changes/index-scope-views/specs/index-page/spec.md#requirement-a-scope-look-can-be-limited-to-view-modes
|
|
5140
|
+
* @return {boolean}
|
|
5141
|
+
*/
|
|
5142
|
+
scopeShapesView() {
|
|
5143
|
+
const views = this.folderSidebar && this.folderSidebar.scopeViews
|
|
5144
|
+
if (!Array.isArray(views) || views.length === 0) {
|
|
5145
|
+
return true
|
|
5146
|
+
}
|
|
5147
|
+
return views.includes(this.currentViewMode)
|
|
5148
|
+
},
|
|
5149
|
+
|
|
5046
5150
|
/**
|
|
5047
5151
|
* This page's own value of each presentation key, which a query preset
|
|
5048
5152
|
* may have set: what `presented()` falls back to without a scope.
|
|
@@ -5077,7 +5181,7 @@ export default {
|
|
|
5077
5181
|
* @spec openspec/changes/index-scope-presentation/specs/index-page/spec.md#requirement-a-preset-or-a-scope-sets-the-list-s-presentation
|
|
5078
5182
|
*/
|
|
5079
5183
|
activeScopePresentation() {
|
|
5080
|
-
if (!this.folderSidebar) {
|
|
5184
|
+
if (!this.folderSidebar || !this.scopeShapesView) {
|
|
5081
5185
|
return {}
|
|
5082
5186
|
}
|
|
5083
5187
|
return resolveScopePresentation({ scope: this.activeScope, row: this.activeScopeRow })
|
|
@@ -5319,6 +5423,20 @@ export default {
|
|
|
5319
5423
|
* @return {(Array<object>|null)} The tabs.
|
|
5320
5424
|
* @spec openspec/changes/working-list-row-actions/specs/index-page/spec.md
|
|
5321
5425
|
*/
|
|
5426
|
+
/**
|
|
5427
|
+
* The chip the strip lights: the active tab, else the default tab of
|
|
5428
|
+
* tabs that arrived after setup (`quickFiltersFrom`), which is the
|
|
5429
|
+
* one the fetch applies.
|
|
5430
|
+
*
|
|
5431
|
+
* @return {number|null} The tab index, or null without tabs.
|
|
5432
|
+
*/
|
|
5433
|
+
shownQuickFilterIndex() {
|
|
5434
|
+
if (this.activeQuickFilterIndex !== null && this.activeQuickFilterIndex !== undefined) {
|
|
5435
|
+
return this.activeQuickFilterIndex
|
|
5436
|
+
}
|
|
5437
|
+
return this.quickFilterMultiple ? null : resolveInitialQuickFilterIndex(this.tabStripEntries)
|
|
5438
|
+
},
|
|
5439
|
+
|
|
5322
5440
|
tabStripEntries() {
|
|
5323
5441
|
if (this.lensTabs.length > 0) {
|
|
5324
5442
|
return this.lensTabs
|
|
@@ -5545,6 +5663,22 @@ export default {
|
|
|
5545
5663
|
return specs
|
|
5546
5664
|
},
|
|
5547
5665
|
|
|
5666
|
+
/**
|
|
5667
|
+
* The rendered columns by key, so a card fact shows what its table
|
|
5668
|
+
* cell shows (label, formatter, widget).
|
|
5669
|
+
*
|
|
5670
|
+
* @return {object} Column definitions keyed by property.
|
|
5671
|
+
*/
|
|
5672
|
+
cardFieldColumns() {
|
|
5673
|
+
const byKey = {}
|
|
5674
|
+
for (const col of this.renderedColumns || []) {
|
|
5675
|
+
if (col && typeof col === 'object' && typeof col.key === 'string') {
|
|
5676
|
+
byKey[col.key] = col
|
|
5677
|
+
}
|
|
5678
|
+
}
|
|
5679
|
+
return byKey
|
|
5680
|
+
},
|
|
5681
|
+
|
|
5548
5682
|
/**
|
|
5549
5683
|
* The property keys the board look's card facts show: the page's
|
|
5550
5684
|
* `cardFields`, else the first four list columns. Null without the
|
|
@@ -6394,8 +6528,11 @@ export default {
|
|
|
6394
6528
|
|
|
6395
6529
|
const present = new Set(cols.map((c) => (typeof c === 'string' ? c : c.key)))
|
|
6396
6530
|
const byKey = new Map(this.governedColumns.map((c) => [c.key, c]))
|
|
6531
|
+
// A scope that sets its own columns does not get its folder field back:
|
|
6532
|
+
// every row of the scope holds the same value there.
|
|
6533
|
+
const scopeField = this.activeScopeLayout.columns ? this.folderFilterKey : ''
|
|
6397
6534
|
visible.forEach((key) => {
|
|
6398
|
-
if (present.has(key)) {
|
|
6535
|
+
if (present.has(key) || key === scopeField) {
|
|
6399
6536
|
return
|
|
6400
6537
|
}
|
|
6401
6538
|
const def = byKey.get(key)
|
|
@@ -6678,11 +6815,21 @@ export default {
|
|
|
6678
6815
|
effectiveQuickFilters() {
|
|
6679
6816
|
const own = withPersonalLenses(this.presented('quickFilters') || this.generatedQuickFilters, this.personalLenses)
|
|
6680
6817
|
if (own && own.length > 0) {
|
|
6681
|
-
return own
|
|
6818
|
+
return own.map((tab) => this.withConfigLabels(tab))
|
|
6682
6819
|
}
|
|
6683
6820
|
return (this.isNamedSource && this.namedQuickFilters) || null
|
|
6684
6821
|
},
|
|
6685
6822
|
|
|
6823
|
+
/**
|
|
6824
|
+
* The app config `@config.<key>` tokens resolve against: the `appConfig`
|
|
6825
|
+
* prop over a config an ancestor provides.
|
|
6826
|
+
*
|
|
6827
|
+
* @return {object} The config.
|
|
6828
|
+
*/
|
|
6829
|
+
effectiveAppConfig() {
|
|
6830
|
+
return { ...unwrapAppConfig(this.cnAppConfig), ...(this.appConfig || {}) }
|
|
6831
|
+
},
|
|
6832
|
+
|
|
6686
6833
|
/**
|
|
6687
6834
|
* Whether the Add button renders. A named source that declares
|
|
6688
6835
|
* `showAdd: false` suppresses it (a task is created by a flow, never
|
|
@@ -6860,6 +7007,28 @@ export default {
|
|
|
6860
7007
|
return count > 0 ? `${name}, ${t('nextcloud-vue', '{count} active', { count })}` : name
|
|
6861
7008
|
},
|
|
6862
7009
|
|
|
7010
|
+
/** @return {string} The field the folder sidebar filters by, or ''. */
|
|
7011
|
+
folderFilterKey() {
|
|
7012
|
+
return (this.folderSidebar && (this.folderSidebar.filterField || this.folderSidebar.field)) || ''
|
|
7013
|
+
},
|
|
7014
|
+
|
|
7015
|
+
/**
|
|
7016
|
+
* The filters the table's header filters show: every active filter but
|
|
7017
|
+
* the selected folder's own, which the Active chip already names, so
|
|
7018
|
+
* the table draws no summary chip for it.
|
|
7019
|
+
*
|
|
7020
|
+
* @return {object} The filters.
|
|
7021
|
+
*/
|
|
7022
|
+
tableActiveFilters() {
|
|
7023
|
+
const filters = this.effectiveActiveFilters || {}
|
|
7024
|
+
const key = this.folderFilterKey
|
|
7025
|
+
if (!key || this.selectedFolderId === null || this.selectedFolderId === undefined || !Object.hasOwn(filters, key)) {
|
|
7026
|
+
return filters
|
|
7027
|
+
}
|
|
7028
|
+
const { [key]: _folder, ...rest } = filters
|
|
7029
|
+
return rest
|
|
7030
|
+
},
|
|
7031
|
+
|
|
6863
7032
|
/**
|
|
6864
7033
|
* The active filters as chips for the board toolbar's second row, one
|
|
6865
7034
|
* per filter: "Team: Woo". A filter with no value is not active.
|
|
@@ -7263,6 +7432,8 @@ export default {
|
|
|
7263
7432
|
showMetadata: this.resolvedSidebar.showMetadata !== false,
|
|
7264
7433
|
personalColumns: this.personalColumns,
|
|
7265
7434
|
pinnedCount: this.pinnedColumnCount,
|
|
7435
|
+
sortOptions: this.sidebarSortOptions,
|
|
7436
|
+
currentSort: this.currentSortKeys,
|
|
7266
7437
|
...this.sidebarSearchProps,
|
|
7267
7438
|
}
|
|
7268
7439
|
},
|
|
@@ -8735,35 +8906,45 @@ export default {
|
|
|
8735
8906
|
},
|
|
8736
8907
|
|
|
8737
8908
|
/**
|
|
8738
|
-
*
|
|
8739
|
-
*
|
|
8909
|
+
* An order chosen in the index sidebar's Sort section. It goes the way
|
|
8910
|
+
* a header click goes: the self-fetched list sorts (`_order`, kept in
|
|
8911
|
+
* the address), and `sort` is emitted for a host that sorts itself.
|
|
8740
8912
|
*
|
|
8741
|
-
* @param {
|
|
8742
|
-
* @return {
|
|
8913
|
+
* @param {Array<{key: string, order: string}>} keys The chosen order.
|
|
8914
|
+
* @return {void}
|
|
8743
8915
|
*/
|
|
8744
|
-
|
|
8745
|
-
if (!
|
|
8746
|
-
return
|
|
8916
|
+
onSidebarSortChange(keys) {
|
|
8917
|
+
if (!Array.isArray(keys) || keys.length === 0) {
|
|
8918
|
+
return
|
|
8747
8919
|
}
|
|
8748
|
-
|
|
8920
|
+
this.onSortEvent({ key: keys[0].key, order: keys[0].order, keys })
|
|
8749
8921
|
},
|
|
8750
8922
|
|
|
8751
8923
|
/**
|
|
8752
|
-
* A
|
|
8753
|
-
*
|
|
8754
|
-
*
|
|
8924
|
+
* A quick filter with `@config.<key>` in its `label` or `activeLabel`
|
|
8925
|
+
* (`"Residence @config.municipality"`): the label translated first, then
|
|
8926
|
+
* each token replaced by its configured value. A key the config does
|
|
8927
|
+
* not hold leaves its token in place. Other tabs pass unchanged.
|
|
8755
8928
|
*
|
|
8756
|
-
* @param {
|
|
8757
|
-
* @return {
|
|
8929
|
+
* @param {object} tab A quick-filter tab.
|
|
8930
|
+
* @return {object} The tab, with its labels resolved.
|
|
8758
8931
|
*/
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
if (option && keys.length > 0 && this.isSelfFetchMode && typeof this.list.onSort === 'function') {
|
|
8763
|
-
this.list.onSort({ key: keys[0].key, order: keys[0].order, keys })
|
|
8764
|
-
this.persistViewStateToRoute(this.currentViewState())
|
|
8932
|
+
withConfigLabels(tab) {
|
|
8933
|
+
if (!tab || typeof tab !== 'object') {
|
|
8934
|
+
return tab
|
|
8765
8935
|
}
|
|
8766
|
-
|
|
8936
|
+
const hasToken = (value) => typeof value === 'string' && value.includes('@config.')
|
|
8937
|
+
if (!hasToken(tab.label) && !hasToken(tab.activeLabel)) {
|
|
8938
|
+
return tab
|
|
8939
|
+
}
|
|
8940
|
+
const config = this.effectiveAppConfig
|
|
8941
|
+
const fill = (value) => (hasToken(value)
|
|
8942
|
+
? this.cnTranslate(value).replace(/@config\.([A-Za-z0-9_.-]*[A-Za-z0-9_])/g, (token, key) => {
|
|
8943
|
+
const found = this.getByPath(config, key)
|
|
8944
|
+
return found === undefined || found === null || found === '' ? token : String(found)
|
|
8945
|
+
})
|
|
8946
|
+
: value)
|
|
8947
|
+
return { ...tab, label: fill(tab.label), activeLabel: fill(tab.activeLabel) }
|
|
8767
8948
|
},
|
|
8768
8949
|
|
|
8769
8950
|
/**
|
|
@@ -9924,6 +10105,7 @@ export default {
|
|
|
9924
10105
|
'columns-reset': () => this.onColumnsReset(),
|
|
9925
10106
|
'filter-change': (event) => this.onFilterEvent(event),
|
|
9926
10107
|
'clear-filters': () => this.onClearFilters(),
|
|
10108
|
+
'sort-change': (keys) => this.onSidebarSortChange(keys),
|
|
9927
10109
|
},
|
|
9928
10110
|
}
|
|
9929
10111
|
},
|
|
@@ -30,11 +30,15 @@
|
|
|
30
30
|
:showRefresh="false"
|
|
31
31
|
:headerLink="entry.headerLink"
|
|
32
32
|
:flush="variant === 'stat-row'">
|
|
33
|
+
<template v-if="headerNotes[entry.id]" #actions>
|
|
34
|
+
<span class="cn-index-page-widgets__note" data-testid="cn-index-page-widget-note">{{ headerNotes[entry.id] }}</span>
|
|
35
|
+
</template>
|
|
33
36
|
<component
|
|
34
37
|
:is="entry.renderer"
|
|
35
38
|
:widgetId="entry.id"
|
|
36
39
|
:content="entry.content"
|
|
37
|
-
v-bind="declaredContent(entry)"
|
|
40
|
+
v-bind="declaredContent(entry)"
|
|
41
|
+
@header="onHeader(entry.id, $event)" />
|
|
38
42
|
</CnWidgetWrapper>
|
|
39
43
|
</div>
|
|
40
44
|
</component>
|
|
@@ -85,6 +89,13 @@ export default {
|
|
|
85
89
|
},
|
|
86
90
|
},
|
|
87
91
|
|
|
92
|
+
data() {
|
|
93
|
+
return {
|
|
94
|
+
/** The header note each widget reported (`header` event), by widget id. */
|
|
95
|
+
headerNotes: {},
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
|
|
88
99
|
computed: {
|
|
89
100
|
/**
|
|
90
101
|
* The renderable entries, in the listed order.
|
|
@@ -122,6 +133,23 @@ export default {
|
|
|
122
133
|
},
|
|
123
134
|
|
|
124
135
|
methods: {
|
|
136
|
+
/**
|
|
137
|
+
* Keep the header note a widget reports ("4 van 5 aanwezig"); only a
|
|
138
|
+
* changed note is stored, so a report on render does not loop.
|
|
139
|
+
*
|
|
140
|
+
* @param {string} id The widget id.
|
|
141
|
+
* @param {object} header `{ note?, link? }` from the widget.
|
|
142
|
+
* @return {void}
|
|
143
|
+
* @spec openspec/changes/side-panel-header-note/specs/side-panel-header-note/spec.md#requirement-a-side-panel-card-shows-the-note-its-widget-reports
|
|
144
|
+
*/
|
|
145
|
+
onHeader(id, header) {
|
|
146
|
+
const note = header && typeof header === 'object' && typeof header.note === 'string' ? header.note : ''
|
|
147
|
+
if ((this.headerNotes[id] || '') === note) {
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
this.headerNotes = { ...this.headerNotes, [id]: note }
|
|
151
|
+
},
|
|
152
|
+
|
|
125
153
|
/**
|
|
126
154
|
* The content keys an entry's renderer declares as props. An undeclared
|
|
127
155
|
* key would fall through onto the renderer's root; the whole content
|
|
@@ -158,6 +186,13 @@ export default {
|
|
|
158
186
|
</script>
|
|
159
187
|
|
|
160
188
|
<style scoped>
|
|
189
|
+
.cn-index-page-widgets__note {
|
|
190
|
+
align-self: center;
|
|
191
|
+
color: var(--color-text-maxcontrast);
|
|
192
|
+
font-size: 14px;
|
|
193
|
+
white-space: nowrap;
|
|
194
|
+
}
|
|
195
|
+
|
|
161
196
|
.cn-index-page-widgets--stat-row {
|
|
162
197
|
margin-bottom: var(--cn-board-section-gap, 20px);
|
|
163
198
|
}
|