@conduction/nextcloud-vue 2.99.0 → 2.101.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.
Files changed (180) hide show
  1. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
  2. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js +6 -1
  3. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
  4. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +2 -1
  5. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
  6. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue.js +1 -1
  7. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js +22 -1
  8. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
  9. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +26 -16
  10. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
  11. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  12. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +51 -7
  13. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  14. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +104 -73
  15. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  16. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +25 -8
  17. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  18. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +5 -3
  19. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  20. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
  21. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +11 -8
  22. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  23. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +13 -4
  24. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  25. package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue.js +9 -0
  26. package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue.js.map +1 -0
  27. package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue2.js +139 -0
  28. package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue2.js.map +1 -0
  29. package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue3.js +76 -0
  30. package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue3.js.map +1 -0
  31. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
  32. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +54 -3
  33. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
  34. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +16 -2
  35. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
  36. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
  37. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +160 -2
  38. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  39. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +206 -94
  40. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  41. package/dist/esm/components/CnFilesBrowser/filesReview.js +61 -0
  42. package/dist/esm/components/CnFilesBrowser/filesReview.js.map +1 -0
  43. package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue.js +1 -1
  44. package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue2.js +42 -7
  45. package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue2.js.map +1 -1
  46. package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue3.js +121 -57
  47. package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue3.js.map +1 -1
  48. package/dist/esm/components/CnFlowsPage/CnFlowEditorPage.vue2.js +10 -0
  49. package/dist/esm/components/CnFlowsPage/CnFlowEditorPage.vue2.js.map +1 -1
  50. package/dist/esm/components/CnFlowsPage/CnFlowEditorPage.vue3.js +2 -1
  51. package/dist/esm/components/CnFlowsPage/CnFlowEditorPage.vue3.js.map +1 -1
  52. package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue.js +9 -0
  53. package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue.js.map +1 -0
  54. package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue2.js +279 -0
  55. package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue2.js.map +1 -0
  56. package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue3.js +122 -0
  57. package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue3.js.map +1 -0
  58. package/dist/esm/components/CnGroupedCardsWidget/index.js +29 -0
  59. package/dist/esm/components/CnGroupedCardsWidget/index.js.map +1 -0
  60. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +387 -78
  61. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  62. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +317 -209
  63. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  64. package/dist/esm/components/CnIndexPage/useNamedSource.js +4 -1
  65. package/dist/esm/components/CnIndexPage/useNamedSource.js.map +1 -1
  66. package/dist/esm/components/CnMapWidget/CnMapWidget.vue.js +1 -1
  67. package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js +15 -0
  68. package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js.map +1 -1
  69. package/dist/esm/components/CnMapWidget/CnMapWidget.vue3.js.map +1 -1
  70. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue.js +1 -1
  71. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +14 -1
  72. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  73. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +14 -6
  74. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  75. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue.js +1 -1
  76. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +10 -0
  77. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  78. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +6 -1
  79. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  80. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue.js +1 -1
  81. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js +91 -4
  82. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js.map +1 -1
  83. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js +63 -38
  84. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js.map +1 -1
  85. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  86. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +68 -7
  87. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  88. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +256 -240
  89. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  90. package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js +9 -0
  91. package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js.map +1 -0
  92. package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue2.js +175 -0
  93. package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue2.js.map +1 -0
  94. package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue3.js +77 -0
  95. package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue3.js.map +1 -0
  96. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue.js +1 -1
  97. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue2.js +38 -9
  98. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue2.js.map +1 -1
  99. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue3.js.map +1 -1
  100. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue.js +1 -1
  101. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +51 -4
  102. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
  103. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +40 -25
  104. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
  105. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +4 -0
  106. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
  107. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  108. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  109. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue.js +1 -1
  110. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js +7 -7
  111. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js.map +1 -1
  112. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js.map +1 -1
  113. package/dist/esm/composables/indexSources.js +167 -20
  114. package/dist/esm/composables/indexSources.js.map +1 -1
  115. package/dist/esm/composables/useEndpointSource.js +28 -6
  116. package/dist/esm/composables/useEndpointSource.js.map +1 -1
  117. package/dist/esm/index.js +1 -0
  118. package/dist/esm/index.js.map +1 -1
  119. package/dist/esm/l10n/en.json.js +43 -1
  120. package/dist/esm/l10n/en.json.js.map +1 -1
  121. package/dist/esm/l10n/nl.json.js +41 -1
  122. package/dist/esm/l10n/nl.json.js.map +1 -1
  123. package/dist/esm/library-style.js +1 -1
  124. package/dist/esm/nextcloud-vue.css +1101 -396
  125. package/dist/esm/utils/languageMapText.js +50 -0
  126. package/dist/esm/utils/languageMapText.js.map +1 -0
  127. package/dist/esm/utils/libraryWidgetKeys.js +3 -0
  128. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  129. package/dist/esm/utils/mapList.js +71 -0
  130. package/dist/esm/utils/mapList.js.map +1 -0
  131. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  132. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  133. package/dist/nextcloud-vue.cjs.js +9996 -7378
  134. package/dist/nextcloud-vue.cjs.js.map +2 -2
  135. package/dist/nextcloud-vue.css +1101 -396
  136. package/l10n/en.json +43 -1
  137. package/l10n/nl.json +41 -1
  138. package/package.json +1 -1
  139. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +7 -1
  140. package/src/components/CnChoiceCards/CnChoiceCards.md +39 -0
  141. package/src/components/CnChoiceCards/CnChoiceCards.vue +93 -16
  142. package/src/components/CnDashboardPage/CnDashboardPage.vue +89 -20
  143. package/src/components/CnDetailPage/CnDetailPage.vue +28 -9
  144. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +13 -4
  145. package/src/components/CnExportsWidget/CnExportsWidget.vue +233 -0
  146. package/src/components/CnExportsWidget/index.js +7 -0
  147. package/src/components/CnFactsWidget/CnFactsWidget.vue +65 -3
  148. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +324 -0
  149. package/src/components/CnFilesBrowser/filesReview.js +57 -0
  150. package/src/components/CnFlowsPage/CnFlowBoard.vue +77 -2
  151. package/src/components/CnFlowsPage/CnFlowEditorPage.vue +11 -0
  152. package/src/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue +433 -0
  153. package/src/components/CnGroupedCardsWidget/index.js +28 -0
  154. package/src/components/CnIndexPage/CnIndexPage.vue +376 -11
  155. package/src/components/CnIndexPage/useNamedSource.js +4 -1
  156. package/src/components/CnMapWidget/CnMapWidget.vue +37 -0
  157. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +29 -1
  158. package/src/components/CnObjectSidebar/CnFilesTab.vue +15 -0
  159. package/src/components/CnOrderedListField/CnOrderedListField.vue +151 -5
  160. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +114 -7
  161. package/src/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue +272 -0
  162. package/src/components/CnSavedViewAlertWidget/index.js +7 -0
  163. package/src/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue +38 -9
  164. package/src/components/CnSetupWizard/CnSetupWizard.vue +72 -5
  165. package/src/components/CnWidgetGrid/builtInWidgets.js +4 -0
  166. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  167. package/src/components/CnWizardDialog/CnWizardDialog.vue +7 -7
  168. package/src/components/index.js +3 -0
  169. package/src/composables/indexSources.js +166 -19
  170. package/src/composables/useEndpointSource.js +28 -6
  171. package/src/css/detail-page.css +15 -0
  172. package/src/css/dialog.css +48 -0
  173. package/src/css/index-page.css +117 -0
  174. package/src/css/look-board.css +127 -1
  175. package/src/index.js +1 -0
  176. package/src/schemas/app-manifest-v2.schema.json +55 -1
  177. package/src/utils/languageMapText.js +46 -0
  178. package/src/utils/libraryWidgetKeys.js +3 -0
  179. package/src/utils/mapList.js +67 -0
  180. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -14,11 +14,12 @@ import ImportIcon from 'vue-material-design-icons/Import.vue';
14
14
  import TrashCanOutline from 'vue-material-design-icons/TrashCanOutline.vue';
15
15
  import Tune from 'vue-material-design-icons/Tune.vue';
16
16
  import ViewColumnOutline from 'vue-material-design-icons/ViewColumnOutline.vue';
17
- import __sfc_main$x from '../../dialogs/CnConfirmDialog.vue.js';
18
- import __sfc_main$y from '../../dialogs/CnQuickEditDialog.vue.js';
19
- import __sfc_main$1 from '../CnBuildiqEditButton/CnBuildiqEditButton.vue.js';
20
- import __sfc_main$3 from '../CnEmptyContent/CnEmptyContent.vue.js';
21
- import __sfc_main$2 from '../CnFollowToggle/CnFollowToggle.vue.js';
17
+ import __sfc_main$y from '../../dialogs/CnConfirmDialog.vue.js';
18
+ import __sfc_main$z from '../../dialogs/CnQuickEditDialog.vue.js';
19
+ import __sfc_main$2 from '../CnBuildiqEditButton/CnBuildiqEditButton.vue.js';
20
+ import __sfc_main$4 from '../CnEmptyContent/CnEmptyContent.vue.js';
21
+ import __sfc_main$3 from '../CnFollowToggle/CnFollowToggle.vue.js';
22
+ import __sfc_main$1 from '../CnStatusBadge/CnStatusBadge.vue.js';
22
23
  import __sfc_main from './CnIndexPageWidgets.vue.js';
23
24
  import { useLook } from '../../composables/useLook.js';
24
25
  import { copyKindsOf } from '../../composables/useObjectCopy.js';
@@ -37,6 +38,7 @@ import { lensUnavailableText } from '../../utils/lensAvailability.js';
37
38
  import { isModifiedClick, openRowTarget } from '../../utils/linkNavigation.js';
38
39
  import { resolveClaimedTeams, splitViewsIntoTabs, viewAsTab, resolveClaimTokens, viewIdOf } from '../../utils/listLenses.js';
39
40
  import { LIST_SHORTCUTS, listPaletteCommands, shortcutFor } from '../../utils/listShortcuts.js';
41
+ import { mapListItems } from '../../utils/mapList.js';
40
42
  import { multiKeySort } from '../../utils/multiKeySort.js';
41
43
  import { fetchGroups } from '../../utils/nextcloudDirectory.js';
42
44
  import { OBJECTS_CHANGED_EVENT } from '../../utils/objectSignals.js';
@@ -53,38 +55,38 @@ import { viewMatchesScope, extractViewState, buildRouteQueryFromViewState, extra
53
55
  import { fieldsFromSchema, columnsFromSchema } from '../../utils/schema.js';
54
56
  import { resolveScopeLayout, resolveScopePresentation } from '../../utils/scopeListLayout.js';
55
57
  import { dispatchObjectCreated } from '../../utils/walkthroughSignals.js';
56
- import __sfc_main$6 from '../CnActionButtons/CnActionButtons.vue.js';
57
- import __sfc_main$7 from '../CnActionsBar/CnActionsBar.vue.js';
58
- import __sfc_main$q from '../CnAdvancedFormDialog/CnAdvancedFormDialog.vue.js';
58
+ import __sfc_main$7 from '../CnActionButtons/CnActionButtons.vue.js';
59
+ import __sfc_main$8 from '../CnActionsBar/CnActionsBar.vue.js';
60
+ import __sfc_main$r from '../CnAdvancedFormDialog/CnAdvancedFormDialog.vue.js';
59
61
  import '../CnAdvancedFormDialog/CnMetadataTab.vue.js';
60
62
  import '../CnAdvancedFormDialog/CnPropertiesTab.vue.js';
61
63
  import '../CnAdvancedFormDialog/CnPropertyValueCell.vue.js';
62
- import __sfc_main$b from '../CnBoardView/CnBoardView.vue.js';
63
- import __sfc_main$a from '../CnCardGrid/CnCardGrid.vue.js';
64
- import __sfc_main$r from '../CnContextMenu/CnContextMenu.vue.js';
65
- import __sfc_main$o from '../CnCopyDialog/CnCopyDialog.vue.js';
66
- import __sfc_main$9 from '../CnDataTable/CnDataTable.vue.js';
67
- import __sfc_main$c from '../CnDateAxisView/CnDateAxisView.vue.js';
68
- import __sfc_main$n from '../CnDeleteDialog/CnDeleteDialog.vue.js';
69
- import __sfc_main$g from '../CnFolderSidebar/CnFolderSidebar.vue.js';
70
- import __sfc_main$p from '../CnFormDialog/CnFormDialog.vue.js';
71
- import __sfc_main$8 from '../CnIcon/CnIcon.vue.js';
72
- import __sfc_main$s from '../CnIndexSidebar/CnIndexSidebar.vue.js';
73
- import __sfc_main$e from '../CnMapWidget/CnMapWidget.vue.js';
74
- import __sfc_main$k from '../CnMassCopyDialog/CnMassCopyDialog.vue.js';
75
- import __sfc_main$j from '../CnMassDeleteDialog/CnMassDeleteDialog.vue.js';
76
- import __sfc_main$l from '../CnMassExportDialog/CnMassExportDialog.vue.js';
77
- import __sfc_main$m from '../CnMassImportDialog/CnMassImportDialog.vue.js';
78
- import __sfc_main$d from '../CnObjectCalendar/CnObjectCalendar.vue.js';
79
- import __sfc_main$f from '../CnObjectList/CnObjectList.vue.js';
80
- import __sfc_main$4 from '../CnPageHeader/CnPageHeader.vue.js';
81
- import __sfc_main$h from '../CnPagination/CnPagination.vue.js';
82
- import __sfc_main$5 from '../CnQuickFilterBar/CnQuickFilterBar.vue.js';
83
- import __sfc_main$i from '../CnRowActions/CnRowActions.vue.js';
84
- import __sfc_main$u from '../CnSavedViewPresentationDialog/CnSavedViewPresentationDialog.vue.js';
85
- import __sfc_main$t from '../CnSavedViewsControl/CnSavedViewsControl.vue.js';
86
- import __sfc_main$v from '../CnSavedViewShareDialog/CnSavedViewShareDialog.vue.js';
87
- import __sfc_main$w from '../CnSaveViewDialog/CnSaveViewDialog.vue.js';
64
+ import __sfc_main$c from '../CnBoardView/CnBoardView.vue.js';
65
+ import __sfc_main$b from '../CnCardGrid/CnCardGrid.vue.js';
66
+ import __sfc_main$s from '../CnContextMenu/CnContextMenu.vue.js';
67
+ import __sfc_main$p from '../CnCopyDialog/CnCopyDialog.vue.js';
68
+ import __sfc_main$a from '../CnDataTable/CnDataTable.vue.js';
69
+ import __sfc_main$d from '../CnDateAxisView/CnDateAxisView.vue.js';
70
+ import __sfc_main$o from '../CnDeleteDialog/CnDeleteDialog.vue.js';
71
+ import __sfc_main$h from '../CnFolderSidebar/CnFolderSidebar.vue.js';
72
+ import __sfc_main$q from '../CnFormDialog/CnFormDialog.vue.js';
73
+ import __sfc_main$9 from '../CnIcon/CnIcon.vue.js';
74
+ import __sfc_main$t from '../CnIndexSidebar/CnIndexSidebar.vue.js';
75
+ import __sfc_main$f from '../CnMapWidget/CnMapWidget.vue.js';
76
+ import __sfc_main$l from '../CnMassCopyDialog/CnMassCopyDialog.vue.js';
77
+ import __sfc_main$k from '../CnMassDeleteDialog/CnMassDeleteDialog.vue.js';
78
+ import __sfc_main$m from '../CnMassExportDialog/CnMassExportDialog.vue.js';
79
+ import __sfc_main$n from '../CnMassImportDialog/CnMassImportDialog.vue.js';
80
+ import __sfc_main$e from '../CnObjectCalendar/CnObjectCalendar.vue.js';
81
+ import __sfc_main$g from '../CnObjectList/CnObjectList.vue.js';
82
+ import __sfc_main$5 from '../CnPageHeader/CnPageHeader.vue.js';
83
+ import __sfc_main$i from '../CnPagination/CnPagination.vue.js';
84
+ import __sfc_main$6 from '../CnQuickFilterBar/CnQuickFilterBar.vue.js';
85
+ import __sfc_main$j from '../CnRowActions/CnRowActions.vue.js';
86
+ import __sfc_main$v from '../CnSavedViewPresentationDialog/CnSavedViewPresentationDialog.vue.js';
87
+ import __sfc_main$u from '../CnSavedViewsControl/CnSavedViewsControl.vue.js';
88
+ import __sfc_main$w from '../CnSavedViewShareDialog/CnSavedViewShareDialog.vue.js';
89
+ import __sfc_main$x from '../CnSaveViewDialog/CnSaveViewDialog.vue.js';
88
90
  import { applyAiContext } from './aiContext.js';
89
91
  import { buildDefaultActions } from './defaultActions.js';
90
92
  import { dispatchAction } from './manifestActionDispatch.js';
@@ -326,11 +328,12 @@ var script = {
326
328
 
327
329
  components: {
328
330
  CnIndexPageWidgets: __sfc_main,
331
+ CnStatusBadge: __sfc_main$1,
329
332
  NcNoteCard,
330
- CnBuildiqEditButton: __sfc_main$1,
331
- CnFollowToggle: __sfc_main$2,
333
+ CnBuildiqEditButton: __sfc_main$2,
334
+ CnFollowToggle: __sfc_main$3,
332
335
  NcLoadingIcon,
333
- CnEmptyContent: __sfc_main$3,
336
+ CnEmptyContent: __sfc_main$4,
334
337
  NcActions,
335
338
  NcActionLink,
336
339
  NcActionButton,
@@ -347,38 +350,38 @@ var script = {
347
350
  Tune,
348
351
  ViewColumnOutline,
349
352
  NcCheckboxRadioSwitch,
350
- CnPageHeader: __sfc_main$4,
351
- CnQuickFilterBar: __sfc_main$5,
352
- CnActionButtons: __sfc_main$6,
353
- CnActionsBar: __sfc_main$7,
353
+ CnPageHeader: __sfc_main$5,
354
+ CnQuickFilterBar: __sfc_main$6,
355
+ CnActionButtons: __sfc_main$7,
356
+ CnActionsBar: __sfc_main$8,
354
357
  DotsHorizontal,
355
- CnIcon: __sfc_main$8,
356
- CnDataTable: __sfc_main$9,
357
- CnCardGrid: __sfc_main$a,
358
- CnBoardView: __sfc_main$b,
359
- CnDateAxisView: __sfc_main$c,
360
- CnObjectCalendar: __sfc_main$d,
361
- CnMapWidget: __sfc_main$e,
362
- CnObjectList: __sfc_main$f,
363
- CnFolderSidebar: __sfc_main$g,
364
- CnPagination: __sfc_main$h,
365
- CnRowActions: __sfc_main$i,
366
- CnMassDeleteDialog: __sfc_main$j,
367
- CnMassCopyDialog: __sfc_main$k,
368
- CnMassExportDialog: __sfc_main$l,
369
- CnMassImportDialog: __sfc_main$m,
370
- CnDeleteDialog: __sfc_main$n,
371
- CnCopyDialog: __sfc_main$o,
372
- CnFormDialog: __sfc_main$p,
373
- CnAdvancedFormDialog: __sfc_main$q,
374
- CnContextMenu: __sfc_main$r,
375
- CnIndexSidebar: __sfc_main$s,
376
- CnSavedViewsControl: __sfc_main$t,
377
- CnSavedViewPresentationDialog: __sfc_main$u,
378
- CnSavedViewShareDialog: __sfc_main$v,
379
- CnSaveViewDialog: __sfc_main$w,
380
- CnConfirmDialog: __sfc_main$x,
381
- CnQuickEditDialog: __sfc_main$y,
358
+ CnIcon: __sfc_main$9,
359
+ CnDataTable: __sfc_main$a,
360
+ CnCardGrid: __sfc_main$b,
361
+ CnBoardView: __sfc_main$c,
362
+ CnDateAxisView: __sfc_main$d,
363
+ CnObjectCalendar: __sfc_main$e,
364
+ CnMapWidget: __sfc_main$f,
365
+ CnObjectList: __sfc_main$g,
366
+ CnFolderSidebar: __sfc_main$h,
367
+ CnPagination: __sfc_main$i,
368
+ CnRowActions: __sfc_main$j,
369
+ CnMassDeleteDialog: __sfc_main$k,
370
+ CnMassCopyDialog: __sfc_main$l,
371
+ CnMassExportDialog: __sfc_main$m,
372
+ CnMassImportDialog: __sfc_main$n,
373
+ CnDeleteDialog: __sfc_main$o,
374
+ CnCopyDialog: __sfc_main$p,
375
+ CnFormDialog: __sfc_main$q,
376
+ CnAdvancedFormDialog: __sfc_main$r,
377
+ CnContextMenu: __sfc_main$s,
378
+ CnIndexSidebar: __sfc_main$t,
379
+ CnSavedViewsControl: __sfc_main$u,
380
+ CnSavedViewPresentationDialog: __sfc_main$v,
381
+ CnSavedViewShareDialog: __sfc_main$w,
382
+ CnSaveViewDialog: __sfc_main$x,
383
+ CnConfirmDialog: __sfc_main$y,
384
+ CnQuickEditDialog: __sfc_main$z,
382
385
  },
383
386
 
384
387
  /**
@@ -394,8 +397,33 @@ var script = {
394
397
  * Falls back to an empty object so `CnIndexPage` works standalone
395
398
  * (unit tests, isolated mount) without `CnAppRoot`.
396
399
  */
400
+ /**
401
+ * The list a side-panel widget reads (`cnIndexList`): the applied saved
402
+ * view, the list's total, and a way to hand back a view that changed
403
+ * (the saved-view alert widget). Getters, so a widget follows the page.
404
+ *
405
+ * @return {object}
406
+ */
407
+ provide() {
408
+ return {
409
+ cnIndexList: Object.defineProperties({}, {
410
+ appliedView: { enumerable: true, get: () => this.appliedSavedView },
411
+ total: {
412
+ enumerable: true,
413
+ get: () => {
414
+ const total = this.effectivePagination && this.effectivePagination.total;
415
+ return typeof total === 'number' ? total : undefined
416
+ },
417
+ },
418
+ replaceSavedView: { enumerable: true, value: (view) => this.replaceSavedView(view) },
419
+ }),
420
+ }
421
+ },
422
+
397
423
  inject: {
398
424
  cnCustomComponents: { default: () => ({}) },
425
+ /** The permissions the user holds, provided by CnAppRoot; for gated page tabs. */
426
+ cnPermissions: { default: () => [] },
399
427
  /** The app id CnAppRoot provides, for the plural form of `countSubtitle`. */
400
428
  cnAppId: { default: '' },
401
429
  /**
@@ -486,7 +514,9 @@ var script = {
486
514
 
487
515
  /**
488
516
  * A note after the breadcrumb and a middle dot (manifest `config.headerMeta`),
489
- * such as "{total} open": `{total}` and `{shown}` are the list's counts.
517
+ * such as "{total} open": `{total}` and `{shown}` are the list's counts,
518
+ * and `{count:<name>}` the count of a list named in `headerMetaCounts`
519
+ * ("{total} contracten bij {count:suppliers} leveranciers").
490
520
  *
491
521
  * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note
492
522
  */
@@ -495,12 +525,29 @@ var script = {
495
525
  default: '',
496
526
  },
497
527
 
528
+ /**
529
+ * The other lists `headerMeta` counts (manifest `config.headerMetaCounts`):
530
+ * `{ <name>: { register, schema, filter? } }`, each read as one list
531
+ * total and filled in for `{count:<name>}`. While a count loads, or when
532
+ * it fails, the note is left out rather than shown with a gap.
533
+ *
534
+ * @type {Record<string, {register: string, schema: string, filter?: object}>|null}
535
+ */
536
+ headerMetaCounts: {
537
+ type: Object,
538
+ default: null,
539
+ },
540
+
498
541
  /**
499
542
  * Tabs to sibling pages above the toolbar (manifest `config.pageTabs`),
500
543
  * each `{ id?, label, route?, params?, query?, href?, countFrom?: {
501
- * register, schema, filter? } }`: DqPrivacy's "AVG-verzoeken |
502
- * Datalekken". The current page's tab is marked; `countFrom` adds the
503
- * count of that list. Wins over a named source's own page tabs.
544
+ * register, schema, filter? }, adminOnly?, permission? }`: DqPrivacy's
545
+ * "AVG-verzoeken | Datalekken". The current page's tab is marked;
546
+ * `countFrom` adds the count of that list. A tab with `adminOnly` shows
547
+ * only to an instance admin, one with `permission` only to a user who
548
+ * holds it. That hides the tab and nothing more: the page it points to
549
+ * must still refuse the user on the server. Wins over a named source's
550
+ * own page tabs.
504
551
  *
505
552
  * @type {Array<object>|null}
506
553
  * @spec openspec/changes/index-page-tabs-notice/specs/index-page/spec.md#requirement-an-index-page-can-link-its-sibling-pages-as-tabs
@@ -670,7 +717,9 @@ var script = {
670
717
  * variant?, icon?, format?, id? }`: `action` is `add` (the Add flow;
671
718
  * its label defaults to the Add label), `export` (the export leaf in
672
719
  * `format`, `csv` by default, else the export dialog), `import`,
673
- * `refresh`, or the id of a `headerActions` entry; `variant` is
720
+ * `refresh`, `save-view` (the save-current-view dialog: the board's
721
+ * "Zoekopdracht opslaan", label "Save view" by default), or the id of a
722
+ * `headerActions` entry; `variant` is
674
723
  * `primary` or `secondary` (the default). Shown only with
675
724
  * `showTitle`. When they show, the actions bar drops its Views and
676
725
  * Actions menus, and the Add button and Export menu when a button
@@ -982,6 +1031,16 @@ var script = {
982
1031
  default: true,
983
1032
  },
984
1033
 
1034
+ /**
1035
+ * Draw the table without its column-header row (manifest
1036
+ * `config.hideTableHeader`), for a list the board draws as plain rows
1037
+ * (DqTeamwachtrij). Pair it with `selectable: false` for no checkboxes.
1038
+ */
1039
+ hideTableHeader: {
1040
+ type: Boolean,
1041
+ default: false,
1042
+ },
1043
+
985
1044
  /**
986
1045
  * When true, a row/card click emits `row-click` (to open/navigate) even
987
1046
  * while `selectable` — selection then happens via the checkbox only.
@@ -1125,8 +1184,15 @@ var script = {
1125
1184
  * - `popupField` — object property rendered in the marker popup.
1126
1185
  * - `center` — optional `[lat, lng]` fallback centre when the filtered set
1127
1186
  * has no plottable rows.
1187
+ * - `zoom` — the map's initial zoom level.
1188
+ * - `list` — a numbered list beside the map, map and list in one card
1189
+ * (DqZakenKaart): `{ title, sub?, pills?: [{ path?, text?, map?,
1190
+ * colorMap? }], due? }`, field templates read per row. The pins carry the
1191
+ * list's numbers, the row under the pointer is marked on both, the rows
1192
+ * without a place are counted under the list with a link to the table,
1193
+ * and the page's count line adds how many are on the map.
1128
1194
  *
1129
- * @type {{ latField?: string, lngField?: string, geoField?: string, popupField?: string, center?: [number, number] }}
1195
+ * @type {{ latField?: string, lngField?: string, geoField?: string, popupField?: string, center?: [number, number], zoom?: number, list?: object }}
1130
1196
  */
1131
1197
  mapConfig: {
1132
1198
  type: Object,
@@ -2540,6 +2606,10 @@ var script = {
2540
2606
  filterStripCounts: null,
2541
2607
  /** The `countFrom` counts of the manifest page tabs, by index. */
2542
2608
  pageTabCounts: {},
2609
+ /** The `headerMetaCounts` totals, by name; a failed one is null. */
2610
+ headerMetaCountValues: {},
2611
+ /** The row the pointer is on in the map list, by key; '' for none. */
2612
+ activeMapKey: '',
2543
2613
  /** The tabs `quickFiltersFrom` produced, or null before they load. */
2544
2614
  generatedQuickFilters: null,
2545
2615
  /** Count per saved-view id, for the views control; null = none. */
@@ -4298,6 +4368,8 @@ var script = {
4298
4368
  */
4299
4369
  mapMarkers() {
4300
4370
  const features = [];
4371
+ // With the list beside the map, a pin carries the row's number there.
4372
+ const numbers = this.mapListEnabled ? new Map(this.mapList.items.map((item) => [item.row, item.n])) : null;
4301
4373
  for (const row of this.displayObjects) {
4302
4374
  const geometry = this.resolveRowGeometry(row);
4303
4375
  if (!geometry) {
@@ -4309,6 +4381,7 @@ var script = {
4309
4381
  properties: {
4310
4382
  [this.rowKey]: row[this.rowKey],
4311
4383
  ...(this.mapConfig.popupField ? { [this.mapConfig.popupField]: row[this.mapConfig.popupField] } : {}),
4384
+ ...(numbers && numbers.has(row) ? { markerNumber: numbers.get(row), markerActive: this.activeMapKey === String(row[this.rowKey]) } : {}),
4312
4385
  },
4313
4386
  });
4314
4387
  }
@@ -4335,6 +4408,57 @@ var script = {
4335
4408
  return this.mapConfig.clustering !== false
4336
4409
  },
4337
4410
 
4411
+ /** @return {number|undefined} The map's initial zoom (`mapConfig.zoom`), when a number. */
4412
+ mapZoom() {
4413
+ const zoom = this.mapConfig && this.mapConfig.zoom;
4414
+ return typeof zoom === 'number' && Number.isFinite(zoom) ? zoom : undefined
4415
+ },
4416
+
4417
+ /** @return {boolean} Whether the map draws its numbered list (`mapConfig.list`). */
4418
+ mapListEnabled() {
4419
+ const list = this.mapConfig && this.mapConfig.list;
4420
+ return Boolean(list && typeof list === 'object' && typeof list.title === 'string' && list.title !== '')
4421
+ },
4422
+
4423
+ /**
4424
+ * The map list's entries, numbered as the pins, and the rows without a
4425
+ * place. Templates go through the host's translate first.
4426
+ *
4427
+ * @return {{items: Array<object>, missing: Array<object>}}
4428
+ */
4429
+ mapList() {
4430
+ if (!this.mapListEnabled) {
4431
+ return { items: [], missing: [] }
4432
+ }
4433
+ const list = this.mapConfig.list;
4434
+ const translated = {
4435
+ ...list,
4436
+ title: this.cnTranslate(list.title),
4437
+ sub: list.sub ? this.cnTranslate(list.sub) : '',
4438
+ due: list.due ? this.cnTranslate(list.due) : '',
4439
+ };
4440
+ return mapListItems(this.displayObjects, translated, {
4441
+ rowKey: this.rowKey,
4442
+ located: (row) => Boolean(this.resolveRowGeometry(row)),
4443
+ translate: (text) => this.cnTranslate(text),
4444
+ })
4445
+ },
4446
+
4447
+ /** @return {string} The list's accessible name. */
4448
+ mapListLabel() {
4449
+ return translate('nextcloud-vue', 'On the map')
4450
+ },
4451
+
4452
+ /** @return {string} The card under the list, for the rows without a place. */
4453
+ mapMissingTitle() {
4454
+ return translatePlural('nextcloud-vue', '%n without an address', '%n without an address', this.mapList.missing.length)
4455
+ },
4456
+
4457
+ /** @return {string} The link from that card to the table. */
4458
+ mapMissingLink() {
4459
+ return translate('nextcloud-vue', 'Show them in the table')
4460
+ },
4461
+
4338
4462
  /**
4339
4463
  * Extra (non-background) map layers — WMS / WFS / GeoJSON overlays declared in
4340
4464
  * `mapConfig.layers`. The background map comes from `mapBasemaps` instead, so
@@ -4435,9 +4559,51 @@ var script = {
4435
4559
  if (this.selfFetchFailed) {
4436
4560
  return { ...this.list.pagination.value, total: 0, page: 1, pages: 1 }
4437
4561
  }
4562
+ // A named source that reports its own total (the search source)
4563
+ // gives the count line its number.
4564
+ if (this.isNamedSource && this.namedSource && typeof this.namedSource.total === 'function') {
4565
+ return { ...(this.pagination || {}), total: this.namedSource.total() }
4566
+ }
4438
4567
  return this.isSelfFetchMode ? this.list.pagination.value : this.pagination
4439
4568
  },
4440
4569
 
4570
+ /**
4571
+ * The saved view the page has applied, or null.
4572
+ *
4573
+ * @return {object|null}
4574
+ */
4575
+ appliedSavedView() {
4576
+ const id = this.appliedSavedViewId;
4577
+ if (!id) {
4578
+ return null
4579
+ }
4580
+ return (this.savedViews || []).find((view) => view && (String(view.id) === id || String(view.slug) === id || String(view.uuid) === id)) || null
4581
+ },
4582
+
4583
+ /**
4584
+ * The term a named source searched for, for `{term}` in the title and
4585
+ * the count line ("Zoeken: Lindelaan"), or ''.
4586
+ *
4587
+ * @return {string}
4588
+ */
4589
+ sourceTerm() {
4590
+ return this.isNamedSource && this.namedSource && typeof this.namedSource.term === 'function' ? String(this.namedSource.term() || '') : ''
4591
+ },
4592
+
4593
+ /**
4594
+ * The page title with `{term}` filled in.
4595
+ *
4596
+ * @return {string}
4597
+ */
4598
+ shownTitle() {
4599
+ const title = this.presented('title');
4600
+ // A title with the term is translated here, before the term goes in,
4601
+ // so its catalogue entry is found ("Zoeken: {term}").
4602
+ return typeof title === 'string' && title.includes('{term}')
4603
+ ? this.cnTranslate(title).replace(/\{term\}/g, this.sourceTerm)
4604
+ : title
4605
+ },
4606
+
4441
4607
  /**
4442
4608
  * Whether the table marks unread rows. The boards draw every row alike,
4443
4609
  * so under the board look only a page that offers the Unread lens
@@ -5020,9 +5186,13 @@ var script = {
5020
5186
  if (!Array.isArray(this.pageTabs) || this.pageTabs.length === 0) {
5021
5187
  return this.sourcePageTabs
5022
5188
  }
5189
+ // The index is the tab's place in `pageTabs`, which is how its count
5190
+ // is keyed, so the tabs are numbered before any is left out.
5023
5191
  return this.pageTabs
5024
- .filter((tab) => tab && typeof tab.label === 'string' && tab.label !== '' && (tab.route || tab.to || tab.href))
5025
- .map((tab, index) => {
5192
+ .map((tab, index) => ({ tab, index }))
5193
+ .filter(({ tab }) => tab && typeof tab.label === 'string' && tab.label !== '' && (tab.route || tab.to || tab.href))
5194
+ .filter(({ tab }) => this.pageTabVisible(tab))
5195
+ .map(({ tab, index }) => {
5026
5196
  const to = tab.route
5027
5197
  ? { name: tab.route, ...(tab.params ? { params: tab.params } : {}), ...(tab.query ? { query: tab.query } : {}) }
5028
5198
  : (tab.to || tab.href);
@@ -5174,6 +5344,9 @@ var script = {
5174
5344
  if (label === '' && button.action === 'actions-menu') {
5175
5345
  label = translate('nextcloud-vue', 'Actions');
5176
5346
  }
5347
+ if (label === '' && button.action === 'save-view') {
5348
+ label = translate('nextcloud-vue', 'Save view');
5349
+ }
5177
5350
  return {
5178
5351
  key: String(button.id || button.action || index),
5179
5352
  label,
@@ -5464,12 +5637,60 @@ var script = {
5464
5637
  return ''
5465
5638
  }
5466
5639
  const total = this.effectivePagination?.total;
5467
- return this.cnTranslate(headerMeta)
5640
+ let missing = false;
5641
+ const text = this.cnTranslate(headerMeta)
5468
5642
  .replace('{shown}', String(this.effectiveObjects.length))
5469
5643
  .replace('{total}', typeof total === 'number' ? String(total) : '')
5644
+ .replace(/\{count:([\w-]+)\}/g, (match, name) => {
5645
+ const value = this.headerMetaCountValues[name];
5646
+ if (typeof value !== 'number') {
5647
+ missing = true;
5648
+ return ''
5649
+ }
5650
+ return String(value)
5651
+ });
5652
+ return missing ? '' : text
5653
+ },
5654
+
5655
+ /**
5656
+ * Whether the header note carries a count, so the board leaves out its
5657
+ * own "{shown} of {total}" line (DqPrivacy, DqContracten).
5658
+ *
5659
+ * @return {boolean}
5660
+ */
5661
+ headerMetaCarriesCount() {
5662
+ const headerMeta = this.presented('headerMeta');
5663
+ return typeof headerMeta === 'string' && /\{(shown|total|count:[\w-]+)\}/.test(headerMeta)
5470
5664
  },
5471
5665
 
5666
+ /**
5667
+ * What the header note's other counts depend on, as one key.
5668
+ *
5669
+ * @return {string}
5670
+ */
5671
+ headerMetaCountKey() {
5672
+ const sources = this.headerMetaCounts && typeof this.headerMetaCounts === 'object' ? this.headerMetaCounts : {};
5673
+ const valid = Object.entries(sources).filter(([, from]) => from && from.register && from.schema);
5674
+ return valid.length > 0 ? JSON.stringify(valid) : ''
5675
+ },
5676
+
5677
+ /**
5678
+ * The header's description line, and on the map with its list the
5679
+ * number of rows on the map after a middle dot ("· 5 met een adres op
5680
+ * de kaart", DqZakenKaart).
5681
+ *
5682
+ * @return {string}
5683
+ */
5472
5684
  headerDescription() {
5685
+ const base = this.headerDescriptionBase;
5686
+ if (this.currentViewMode !== 'map' || !this.mapListEnabled) {
5687
+ return base
5688
+ }
5689
+ const onMap = translatePlural('nextcloud-vue', '%n with an address on the map', '%n with an address on the map', this.mapList.items.length);
5690
+ return base ? `${base} · ${onMap}` : onMap
5691
+ },
5692
+
5693
+ headerDescriptionBase() {
5473
5694
  const total = this.effectivePagination?.total;
5474
5695
  // Board look: the count line is a template over the rows on this page
5475
5696
  // and all rows, "{shown} of {total}" unless the page says otherwise.
@@ -5479,6 +5700,10 @@ var script = {
5479
5700
  // reads "14 van 14" in Dutch; a page's own template goes
5480
5701
  // through the app's label lookup.
5481
5702
  const countText = this.presented('countText');
5703
+ // The note after the breadcrumb already says how many there are.
5704
+ if (!countText && !this.countSubtitle && this.headerMetaCarriesCount) {
5705
+ return this.description
5706
+ }
5482
5707
  if (!countText && !this.countSubtitle) {
5483
5708
  return translate('nextcloud-vue', '{shown} of {total}', { shown, total })
5484
5709
  }
@@ -5486,6 +5711,7 @@ var script = {
5486
5711
  return this.cnTranslate(countText)
5487
5712
  .replace('{shown}', String(shown))
5488
5713
  .replace('{total}', String(total))
5714
+ .replace(/\{term\}/g, this.sourceTerm)
5489
5715
  }
5490
5716
  return this.countLine(this.countSubtitle, total, shown)
5491
5717
  }
@@ -5725,6 +5951,13 @@ var script = {
5725
5951
  },
5726
5952
  },
5727
5953
 
5954
+ headerMetaCountKey: {
5955
+ immediate: true,
5956
+ handler() {
5957
+ this.loadHeaderMetaCounts();
5958
+ },
5959
+ },
5960
+
5728
5961
  pageTabCountKey: {
5729
5962
  immediate: true,
5730
5963
  /** @spec openspec/changes/index-page-tabs-notice/specs/index-page/spec.md#requirement-an-index-page-can-link-its-sibling-pages-as-tabs */
@@ -6144,6 +6377,65 @@ var script = {
6144
6377
  ];
6145
6378
  },
6146
6379
 
6380
+ /**
6381
+ * Whether Nextcloud says the user administers this instance; false
6382
+ * when the user cannot be read.
6383
+ *
6384
+ * @return {boolean}
6385
+ */
6386
+ viewerIsAdmin() {
6387
+ try {
6388
+ return getCurrentUser()?.isAdmin === true
6389
+ } catch {
6390
+ return false
6391
+ }
6392
+ },
6393
+
6394
+ /**
6395
+ * Whether a manifest page tab shows to this user: an `adminOnly` tab to
6396
+ * an instance admin, a tab with a `permission` to a user who holds it
6397
+ * (as a menu entry: with no permissions known, it shows). This only
6398
+ * decides whether the tab is drawn. It is not access control; the
6399
+ * page behind the tab must enforce its own access on the server.
6400
+ *
6401
+ * @param {object} tab The tab declaration.
6402
+ * @return {boolean} True when the tab is drawn.
6403
+ */
6404
+ pageTabVisible(tab) {
6405
+ if (tab.adminOnly === true && !this.viewerIsAdmin()) {
6406
+ return false
6407
+ }
6408
+ if (tab.permission) {
6409
+ const held = Array.isArray(this.cnPermissions) ? this.cnPermissions : [];
6410
+ if (held.length > 0 && !held.includes(tab.permission)) {
6411
+ return false
6412
+ }
6413
+ }
6414
+ return true
6415
+ },
6416
+
6417
+ /**
6418
+ * Read the totals of the lists `headerMetaCounts` names, one list
6419
+ * request each. A failed count is null and leaves the note out.
6420
+ *
6421
+ * @return {Promise<void>}
6422
+ */
6423
+ async loadHeaderMetaCounts() {
6424
+ const key = this.headerMetaCountKey;
6425
+ if (key === '') {
6426
+ this.headerMetaCountValues = {};
6427
+ return
6428
+ }
6429
+ const ctx = typeof this.selfFetchTokenCtx === 'function' ? this.selfFetchTokenCtx() : {};
6430
+ const values = {};
6431
+ await Promise.all(JSON.parse(key).map(async ([name, from]) => {
6432
+ values[name] = await fetchListTotal(from.register, from.schema, from.filter || {}, ctx).catch(() => null);
6433
+ }));
6434
+ if (key === this.headerMetaCountKey) {
6435
+ this.headerMetaCountValues = values;
6436
+ }
6437
+ },
6438
+
6147
6439
  /**
6148
6440
  * Count the lists behind the manifest page tabs (`countFrom`), one list
6149
6441
  * request each. A failed count shows no number.
@@ -6866,6 +7158,8 @@ var script = {
6866
7158
  this.showImportDialog = true;
6867
7159
  } else if (button.action === 'refresh') {
6868
7160
  this.onRefreshEvent();
7161
+ } else if (button.action === 'save-view') {
7162
+ this.showSaveViewDialog = true;
6869
7163
  } else {
6870
7164
  this.onHeaderAction({ action: button.action, id: button.action });
6871
7165
  }
@@ -8129,7 +8423,7 @@ var script = {
8129
8423
  this.cnIndexSidebarConfig.value = {
8130
8424
  // markRaw: the holder is CnAppRoot `data()`, so it is deeply
8131
8425
  // reactive and would proxy the component definition itself.
8132
- component: markRaw(__sfc_main$s),
8426
+ component: markRaw(__sfc_main$t),
8133
8427
  props: this.hoistedSidebarProps,
8134
8428
  listeners: {
8135
8429
  'update:open': (val) => {
@@ -8876,6 +9170,21 @@ var script = {
8876
9170
  }
8877
9171
  },
8878
9172
 
9173
+ /**
9174
+ * Put a saved view that changed elsewhere (its alert) back in the list,
9175
+ * matched on its id or uuid.
9176
+ *
9177
+ * @param {object} view The saved view as the server returned it.
9178
+ * @return {void}
9179
+ */
9180
+ replaceSavedView(view) {
9181
+ if (!view || typeof view !== 'object') {
9182
+ return
9183
+ }
9184
+ const same = (other) => other && ((view.id !== undefined && other.id === view.id) || (view.uuid && other.uuid === view.uuid));
9185
+ this.savedViews = (this.savedViews || []).map((other) => (same(other) ? view : other));
9186
+ },
9187
+
8879
9188
  async onSaveViewConfirm({ name, isPublic, sharedWith, presentation }) {
8880
9189
  const state = this.isSelfFetchMode
8881
9190
  ? this.currentViewState()