@conduction/nextcloud-vue 2.62.0 → 2.64.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 (209) hide show
  1. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue.js +10 -0
  2. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue.js.map +1 -0
  3. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js +189 -0
  4. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js.map +1 -0
  5. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js +72 -0
  6. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js.map +1 -0
  7. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +425 -39
  8. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  9. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +119 -42
  10. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  11. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +186 -9
  12. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  13. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +65 -42
  14. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  15. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +61 -16
  16. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
  17. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
  18. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js +20 -0
  19. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js.map +1 -1
  20. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js +3 -2
  21. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js.map +1 -1
  22. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +33 -2
  23. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
  24. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
  25. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
  26. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +53 -37
  27. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
  28. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +29 -0
  29. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  30. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +152 -135
  31. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  32. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js +10 -0
  33. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js.map +1 -0
  34. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js +293 -0
  35. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js.map +1 -0
  36. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js +189 -0
  37. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js.map +1 -0
  38. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +253 -9
  39. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  40. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +126 -50
  41. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  42. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +66 -14
  43. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  44. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +23 -14
  45. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  46. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  47. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +2 -1
  48. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  49. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js +3 -1
  50. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js.map +1 -1
  51. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js +1 -1
  52. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js.map +1 -1
  53. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +234 -9
  54. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  55. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +96 -57
  56. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  57. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +81 -4
  58. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
  59. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +22 -5
  60. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
  61. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +81 -2
  62. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  63. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +7 -3
  64. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  65. package/dist/esm/components/CnIndexPage/selfModeActions.js +3 -3
  66. package/dist/esm/components/CnIndexPage/selfModeActions.js.map +1 -1
  67. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +41 -2
  68. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  69. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +8 -3
  70. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  71. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js +121 -12
  72. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js.map +1 -1
  73. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js +3 -1
  74. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js.map +1 -1
  75. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +326 -1
  76. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
  77. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +112 -26
  78. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
  79. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +63 -2
  80. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
  81. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js +96 -37
  82. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
  83. package/dist/esm/components/CnStagesWidget/stagesModel.js +5 -2
  84. package/dist/esm/components/CnStagesWidget/stagesModel.js.map +1 -1
  85. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +52 -2
  86. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
  87. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +6 -6
  88. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
  89. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +14 -2
  90. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  91. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +2 -1
  92. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  93. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +10 -0
  94. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js.map +1 -0
  95. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +337 -0
  96. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -0
  97. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js +102 -0
  98. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -0
  99. package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js +34 -0
  100. package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js.map +1 -0
  101. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js +131 -8
  102. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js.map +1 -1
  103. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js +40 -38
  104. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js.map +1 -1
  105. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +8 -6
  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/CnWidgetWrapper/CnWidgetWrapper.vue2.js +73 -1
  110. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
  111. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +14 -2
  112. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
  113. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js +19 -0
  114. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js.map +1 -1
  115. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js +1 -1
  116. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js.map +1 -1
  117. package/dist/esm/composables/useDependencyCheck.js +65 -0
  118. package/dist/esm/composables/useDependencyCheck.js.map +1 -0
  119. package/dist/esm/composables/useWalkthrough.js +218 -6
  120. package/dist/esm/composables/useWalkthrough.js.map +1 -1
  121. package/dist/esm/index.js +2 -0
  122. package/dist/esm/index.js.map +1 -1
  123. package/dist/esm/l10n/en.json.js +45 -1
  124. package/dist/esm/l10n/en.json.js.map +1 -1
  125. package/dist/esm/l10n/nl.json.js +45 -1
  126. package/dist/esm/l10n/nl.json.js.map +1 -1
  127. package/dist/esm/nextcloud-vue.css +780 -81
  128. package/dist/esm/store/useObjectStore.js +8 -0
  129. package/dist/esm/store/useObjectStore.js.map +1 -1
  130. package/dist/esm/utils/columnFilters.js +311 -0
  131. package/dist/esm/utils/columnFilters.js.map +1 -0
  132. package/dist/esm/utils/groupAutocomplete.js +123 -0
  133. package/dist/esm/utils/groupAutocomplete.js.map +1 -0
  134. package/dist/esm/utils/libraryWidgetKeys.js +2 -0
  135. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  136. package/dist/esm/utils/pickerOptions.js +198 -0
  137. package/dist/esm/utils/pickerOptions.js.map +1 -0
  138. package/dist/esm/utils/schema.js +83 -7
  139. package/dist/esm/utils/schema.js.map +1 -1
  140. package/dist/esm/utils/schemaRefSlug.js +19 -3
  141. package/dist/esm/utils/schemaRefSlug.js.map +1 -1
  142. package/dist/esm/utils/timelineEvents.js +174 -0
  143. package/dist/esm/utils/timelineEvents.js.map +1 -0
  144. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  145. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  146. package/dist/esm/utils/walkthroughSignals.js +88 -0
  147. package/dist/esm/utils/walkthroughSignals.js.map +1 -0
  148. package/dist/nextcloud-vue.cjs.js +13088 -7937
  149. package/dist/nextcloud-vue.cjs.js.map +2 -2
  150. package/dist/nextcloud-vue.css +780 -81
  151. package/l10n/en.json +45 -0
  152. package/l10n/nl.json +45 -0
  153. package/package.json +1 -1
  154. package/src/components/CnAdminActionCard/CnAdminActionCard.vue +234 -0
  155. package/src/components/CnAdminActionCard/index.js +4 -0
  156. package/src/components/CnAppNav/CnAppNav.vue +568 -43
  157. package/src/components/CnAppRoot/CnAppRoot.md +4 -0
  158. package/src/components/CnAppRoot/CnAppRoot.vue +223 -16
  159. package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +61 -16
  160. package/src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue +22 -1
  161. package/src/components/CnCellRenderer/CnCellRenderer.vue +33 -2
  162. package/src/components/CnChoiceCards/CnChoiceCards.vue +56 -31
  163. package/src/components/CnDashboardPage/CnDashboardPage.vue +45 -4
  164. package/src/components/CnDataTable/CnColumnFilterPopover.vue +524 -0
  165. package/src/components/CnDataTable/CnDataTable.md +3 -0
  166. package/src/components/CnDataTable/CnDataTable.vue +305 -5
  167. package/src/components/CnDetailPage/CnDetailPage.md +4 -0
  168. package/src/components/CnDetailPage/CnDetailPage.vue +60 -1
  169. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +2 -2
  170. package/src/components/CnFieldHelper/CnFieldHelper.vue +4 -2
  171. package/src/components/CnFormDialog/CnFormDialog.vue +290 -31
  172. package/src/components/CnHeaderWidget/CnHeaderWidget.vue +116 -6
  173. package/src/components/CnIndexPage/CnIndexPage.vue +87 -4
  174. package/src/components/CnIndexPage/selfModeActions.js +3 -3
  175. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +46 -2
  176. package/src/components/CnResourceSelect/CnResourceSelect.vue +123 -12
  177. package/src/components/CnSetupWizard/CnSetupWizard.vue +392 -3
  178. package/src/components/CnStagesWidget/CnStagesWidget.vue +180 -2
  179. package/src/components/CnStagesWidget/stagesModel.js +5 -2
  180. package/src/components/CnStatWidget/CnStatWidget.vue +57 -3
  181. package/src/components/CnTabsWidget/CnTabsWidget.vue +15 -2
  182. package/src/components/CnTimelineWidget/CnTimelineWidget.vue +477 -0
  183. package/src/components/CnTimelineWidget/dashboardRegistration.js +32 -0
  184. package/src/components/CnTimelineWidget/index.js +4 -0
  185. package/src/components/CnWalkthrough/CnWalkthrough.vue +143 -10
  186. package/src/components/CnWidgetGrid/builtInWidgets.js +2 -0
  187. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  188. package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +4 -0
  189. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +107 -1
  190. package/src/components/CnWizardDialog/CnWizardDialog.vue +20 -1
  191. package/src/components/index.js +2 -0
  192. package/src/composables/useDependencyCheck.js +61 -0
  193. package/src/composables/useWalkthrough.js +217 -5
  194. package/src/css/dashboard.css +49 -0
  195. package/src/css/detail-page.css +29 -4
  196. package/src/css/kpi-card.css +24 -1
  197. package/src/css/table.css +99 -6
  198. package/src/index.js +2 -0
  199. package/src/schemas/app-manifest-v2.schema.json +135 -3
  200. package/src/store/useObjectStore.js +8 -0
  201. package/src/utils/columnFilters.js +324 -0
  202. package/src/utils/groupAutocomplete.js +119 -0
  203. package/src/utils/libraryWidgetKeys.js +2 -0
  204. package/src/utils/pickerOptions.js +194 -0
  205. package/src/utils/schema.js +83 -7
  206. package/src/utils/schemaRefSlug.js +19 -3
  207. package/src/utils/timelineEvents.js +171 -0
  208. package/src/utils/validateManifestV2.compiled.js +2 -2
  209. package/src/utils/walkthroughSignals.js +94 -0
@@ -1,11 +1,13 @@
1
1
  import { getCurrentUser } from '@nextcloud/auth';
2
2
  import axios__default from '@nextcloud/axios';
3
3
  import { loadState } from '@nextcloud/initial-state';
4
+ import { translate } from '@nextcloud/l10n';
4
5
  import { generateUrl } from '@nextcloud/router';
5
6
  import { NcAppContent, NcAppSettingsDialog, NcAppSettingsSection, NcButton, NcContent, NcEmptyContent, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue';
6
7
  import { shallowRef, watch, computed, reactive } from 'vue';
7
8
  import DatabaseSearchOutline from 'vue-material-design-icons/DatabaseSearchOutline.vue';
8
9
  import OpenInNew from 'vue-material-design-icons/OpenInNew.vue';
10
+ import Play from 'vue-material-design-icons/Play.vue';
9
11
  import Restart from 'vue-material-design-icons/Restart.vue';
10
12
  import __sfc_main$5 from '../CnAiCompanion/CnAiCompanion.vue.js';
11
13
  import __sfc_main$1 from '../CnAppLoading/CnAppLoading.vue.js';
@@ -29,13 +31,14 @@ import { useSetupStatus } from '../../composables/useSetupStatus.js';
29
31
  import { useSupportDialog } from '../../composables/useSupportDialog.js';
30
32
  import { provideTenantContext } from '../../composables/useTenantContext.js';
31
33
  import { useUserPreferences } from '../../composables/useUserPreferences.js';
32
- import { useWalkthrough, readLocalWalkthroughSeenVersion, loadWalkthroughSeenVersion, normaliseSeenVersion, persistWalkthroughSeenVersion } from '../../composables/useWalkthrough.js';
34
+ import { useWalkthrough, readLocalWalkthroughSeenVersion, readLocalWalkthroughProgress, loadWalkthroughSeenVersion, loadWalkthroughProgress, normaliseSeenVersion, persistWalkthroughSeenVersion, persistWalkthroughProgress } from '../../composables/useWalkthrough.js';
33
35
  import { RegistryKindError } from '../../errors/RegistryKindError.js';
34
36
  import { isAppInstalled } from '../../utils/appInstalled.js';
35
37
  import { BUILT_IN_FORMATTERS } from '../../utils/builtInFormatters.js';
36
38
  import { resolveForge, DEFAULT_FORGE } from '../../utils/forge.js';
37
39
  import { BUILT_IN_KB_PROVIDERS } from '../../utils/kbSearchProviders.js';
38
40
  import { installModalStack, uninstallModalStack } from '../../utils/modalStack.js';
41
+ import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js';
39
42
  import { passesContextPredicates } from '../../utils/visibleIfContext.js';
40
43
  import { useObjectStore } from '../../store/useObjectStore.js';
41
44
 
@@ -106,6 +109,7 @@ var script = {
106
109
  NcNoteCard,
107
110
  DatabaseSearchOutline,
108
111
  OpenInNew,
112
+ Play,
109
113
  Restart,
110
114
  CnAppNav: __sfc_main,
111
115
  CnAppLoading: __sfc_main$1,
@@ -385,6 +389,13 @@ var script = {
385
389
  * the counts.
386
390
  */
387
391
  cnMenuCounts: this.cnMenuCounts,
392
+ /**
393
+ * Reactive `{ [menuItemId]: number }` totals for menu entries
394
+ * whose `count` is an object (`{ register, schema, filter? }`),
395
+ * populated by `_hydrateMenuItemCounts()`. Read by
396
+ * `CnAppNav.resolveCount()`.
397
+ */
398
+ cnMenuItemCounts: this.cnMenuItemCounts,
388
399
  }
389
400
  },
390
401
 
@@ -528,6 +539,19 @@ var script = {
528
539
  required: true,
529
540
  },
530
541
 
542
+ /**
543
+ * Render no app navigation at all: neither the default CnAppNav nor
544
+ * the `#menu` slot, so the content starts at the left edge (a start
545
+ * page without a menu). Off by default; the navigation renders as it
546
+ * always has.
547
+ *
548
+ * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-an-app-root-can-hide-its-menu
549
+ */
550
+ hideMenu: {
551
+ type: Boolean,
552
+ default: false,
553
+ },
554
+
531
555
  /**
532
556
  * Human-readable name shown in the Nextcloud top bar. When set it
533
557
  * overrides the technical `appId` so a virtual app shows its own name
@@ -1043,6 +1067,13 @@ var script = {
1043
1067
  * picked up by CnAppNav's reactive render.
1044
1068
  */
1045
1069
  cnMenuCounts: reactive({}),
1070
+ /**
1071
+ * Reactive `{ [menuItemId]: number }` map of filtered totals, one
1072
+ * per menu entry whose `count` is an object. Provided to
1073
+ * descendants as `cnMenuItemCounts`. Populated by
1074
+ * `_hydrateMenuItemCounts()` at mount.
1075
+ */
1076
+ cnMenuItemCounts: reactive({}),
1046
1077
  /**
1047
1078
  * Open state of the host NcAppSettingsDialog. Toggled
1048
1079
  * to `true` by the provided `cnOpenUserSettings()`
@@ -1133,6 +1164,15 @@ var script = {
1133
1164
  * @type {string}
1134
1165
  */
1135
1166
  walkthroughSeenVersionValue: readLocalWalkthroughSeenVersion(this.appId),
1167
+ /**
1168
+ * Where the user is in an unfinished tour (`{ tourId, stepId,
1169
+ * index, version }`), or null. Seeded from the local mirror, then
1170
+ * replaced by the per-user `<completionConfigKey>-progress`
1171
+ * preference. The tour resumes at this step on the next visit.
1172
+ *
1173
+ * @type {object|null}
1174
+ */
1175
+ walkthroughProgressValue: readLocalWalkthroughProgress(this.appId),
1136
1176
  /**
1137
1177
  * Whether `walkthroughSeenVersionValue` is settled. Starts `true`
1138
1178
  * when the manifest declares no `completionConfigKey` (the local
@@ -1886,13 +1926,15 @@ var script = {
1886
1926
  try {
1887
1927
  const p = new URLSearchParams(window.location.search);
1888
1928
  const tourId = p.get('cn_resume_tour');
1889
- if (!tourId) {
1890
- return null
1929
+ if (tourId) {
1930
+ return { tourId, stepId: p.get('cn_resume_step') || '' }
1891
1931
  }
1892
- return { tourId, stepId: p.get('cn_resume_step') || '' }
1893
1932
  } catch {
1894
- return null
1933
+ // No URL token; fall through to the remembered progress.
1895
1934
  }
1935
+ // An unfinished tour continues at the step the user reached.
1936
+ const progress = this.walkthroughProgressValue;
1937
+ return progress ? { tourId: progress.tourId, stepId: progress.stepId } : null
1896
1938
  },
1897
1939
 
1898
1940
  phase() {
@@ -2135,6 +2177,24 @@ var script = {
2135
2177
  return this.translate('Restart walkthrough')
2136
2178
  },
2137
2179
 
2180
+ /**
2181
+ * Label for continuing an unfinished tour at the remembered step.
2182
+ *
2183
+ * @return {string}
2184
+ */
2185
+ continueWalkthroughLabel() {
2186
+ return translate('nextcloud-vue', 'Continue where you left off')
2187
+ },
2188
+
2189
+ /**
2190
+ * Label for restarting an unfinished tour from the first step.
2191
+ *
2192
+ * @return {string}
2193
+ */
2194
+ startOverWalkthroughLabel() {
2195
+ return translate('nextcloud-vue', 'Start over')
2196
+ },
2197
+
2138
2198
  /**
2139
2199
  * Resolve the active modal's Vue component from the registry.
2140
2200
  * Returns null when no modal is open or the key no longer resolves.
@@ -2232,6 +2292,7 @@ var script = {
2232
2292
  this._validateRegistry();
2233
2293
  this._warnCustomComponentsDeprecation();
2234
2294
  this._hydrateMenuCounts();
2295
+ this._hydrateMenuItemCounts();
2235
2296
  return
2236
2297
  }
2237
2298
 
@@ -2260,6 +2321,7 @@ var script = {
2260
2321
  this._validateRegistry();
2261
2322
  this._warnCustomComponentsDeprecation();
2262
2323
  this._hydrateMenuCounts();
2324
+ this._hydrateMenuItemCounts();
2263
2325
  },
2264
2326
 
2265
2327
  beforeUnmount() {
@@ -2638,10 +2700,12 @@ var script = {
2638
2700
  return
2639
2701
  }
2640
2702
  try {
2641
- this.walkthroughSeenVersionValue = await loadWalkthroughSeenVersion(
2642
- this.appId,
2643
- this.walkthroughConfigKey,
2644
- );
2703
+ const [seen, progress] = await Promise.all([
2704
+ loadWalkthroughSeenVersion(this.appId, this.walkthroughConfigKey),
2705
+ loadWalkthroughProgress(this.appId, this.walkthroughConfigKey),
2706
+ ]);
2707
+ this.walkthroughSeenVersionValue = seen;
2708
+ this.walkthroughProgressValue = progress;
2645
2709
  } finally {
2646
2710
  this.walkthroughSeenResolved = true;
2647
2711
  }
@@ -2665,12 +2729,68 @@ var script = {
2665
2729
  // Fire-and-forget: the loader never rejects and the local mirror is
2666
2730
  // already written, so a failed PUT must not surface as an error.
2667
2731
  persistWalkthroughSeenVersion(this.appId, this.walkthroughConfigKey, v);
2732
+ // A finished or skipped tour has nothing to continue.
2733
+ if (this.walkthroughProgressValue) {
2734
+ this.walkthroughProgressValue = null;
2735
+ persistWalkthroughProgress(this.appId, this.walkthroughConfigKey, null);
2736
+ }
2668
2737
  /**
2669
2738
  * @event walkthrough-complete Emitted when the walkthrough finishes or is dismissed.
2670
2739
  */
2671
2740
  this.$emit('walkthrough-complete');
2672
2741
  },
2673
2742
 
2743
+ /**
2744
+ * Remember where the user is in the tour, so a reload or a restart
2745
+ * entry continues there (local mirror + per-user preference).
2746
+ *
2747
+ * @spec openspec/changes/walkthrough-advance-pause-resume/specs/cn-walkthrough/spec.md
2748
+ * @param {object} progress `{ tourId, stepId, index }` from CnWalkthrough.
2749
+ * @return {void}
2750
+ */
2751
+ onWalkthroughProgress(progress) {
2752
+ if (!progress || !progress.tourId) {
2753
+ return
2754
+ }
2755
+ // The first step of a fresh tour is where a restart lands anyway,
2756
+ // so it costs no request.
2757
+ if (progress.index === 0 && !this.walkthroughProgressValue) {
2758
+ return
2759
+ }
2760
+ const value = {
2761
+ tourId: progress.tourId,
2762
+ stepId: progress.stepId || '',
2763
+ index: progress.index || 0,
2764
+ version: String((this.manifest && this.manifest.version) || ''),
2765
+ };
2766
+ this.walkthroughProgressValue = value;
2767
+ persistWalkthroughProgress(this.appId, this.walkthroughConfigKey, value);
2768
+ },
2769
+
2770
+ /**
2771
+ * Continue an unfinished tour from the user-settings dialog: show a
2772
+ * paused tour again, or start the remembered tour at its step.
2773
+ *
2774
+ * @spec openspec/changes/walkthrough-advance-pause-resume/specs/cn-walkthrough/spec.md
2775
+ * @return {void}
2776
+ */
2777
+ continueWalkthroughFromSettings() {
2778
+ this.userSettingsOpen = false;
2779
+ if (!this.walkthroughEnabled) {
2780
+ return
2781
+ }
2782
+ setTimeout(() => {
2783
+ const wt = useWalkthrough(this.appId, this.manifest);
2784
+ if (wt.resumePaused()) {
2785
+ return
2786
+ }
2787
+ const progress = this.walkthroughProgressValue;
2788
+ if (progress) {
2789
+ wt.resumeAt(progress.tourId, progress.stepId);
2790
+ }
2791
+ }, 50);
2792
+ },
2793
+
2674
2794
  /**
2675
2795
  * Replay the product tour from the user-settings dialog. Closes the
2676
2796
  * dialog first, then restarts the first declared tour on the next tick
@@ -2858,6 +2978,63 @@ var script = {
2858
2978
  });
2859
2979
  },
2860
2980
 
2981
+ /**
2982
+ * Fetch the total of every menu entry (top level and children) whose
2983
+ * `count` is an object `{ register, schema, filter? }`: one
2984
+ * `GET /api/objects/{register}/{schema}?_limit=1` per entry with the
2985
+ * filter's tokens (`@me`, `@today`, ...) resolved at fetch time, the
2986
+ * response `total` written to `cnMenuItemCounts[item.id]`. The
2987
+ * request goes straight through axios rather than the object store,
2988
+ * so the index page's whole-schema total in the store is left alone.
2989
+ * Failures leave the badge unrendered.
2990
+ *
2991
+ * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-a-menu-entry-counts-a-filtered-list
2992
+ * @return {void}
2993
+ * @private
2994
+ */
2995
+ _hydrateMenuItemCounts() {
2996
+ const collect = (items) => {
2997
+ const out = [];
2998
+ for (const item of items ?? []) {
2999
+ const count = item?.count;
3000
+ if (count && typeof count === 'object' && typeof item.id === 'string' && count.register && count.schema) {
3001
+ out.push(item);
3002
+ }
3003
+ if (Array.isArray(item?.children)) {
3004
+ out.push(...collect(item.children));
3005
+ }
3006
+ }
3007
+ return out
3008
+ };
3009
+ for (const item of collect(this.manifest?.menu)) {
3010
+ this._fetchMenuItemCount(item);
3011
+ }
3012
+ },
3013
+
3014
+ /**
3015
+ * One filtered-count request for a menu entry; see
3016
+ * `_hydrateMenuItemCounts`.
3017
+ *
3018
+ * @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-a-menu-entry-counts-a-filtered-list
3019
+ * @param {{ id: string, count: { register: string, schema: string, filter?: object } }} item The menu entry.
3020
+ * @return {Promise<void>}
3021
+ * @private
3022
+ */
3023
+ async _fetchMenuItemCount(item) {
3024
+ try {
3025
+ const { register, schema, filter } = item.count;
3026
+ const resolved = resolveFilterTokens(filter && typeof filter === 'object' ? filter : {}, {});
3027
+ const url = generateUrl(`/apps/openregister/api/objects/${encodeURIComponent(register)}/${encodeURIComponent(schema)}`);
3028
+ const { data } = await axios__default.get(url, { params: { _limit: 1, ...resolved } });
3029
+ const total = data?.total;
3030
+ if (typeof total === 'number' && total >= 0) {
3031
+ this.cnMenuItemCounts[item.id] = total;
3032
+ }
3033
+ } catch {
3034
+ // Non-fatal: the badge stays unrendered.
3035
+ }
3036
+ },
3037
+
2861
3038
  /**
2862
3039
  * Hydrate all menu counts with a single `POST /api/objects/counts`
2863
3040
  * (OpenRegister batched-counts endpoint). Distributes each returned