@conduction/nextcloud-vue 2.63.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 (100) hide show
  1. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +154 -7
  2. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  3. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +119 -42
  4. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  5. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +87 -0
  6. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  7. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +26 -24
  8. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  9. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +61 -16
  10. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
  11. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
  12. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js +20 -0
  13. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js.map +1 -1
  14. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js +3 -2
  15. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js.map +1 -1
  16. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +33 -2
  17. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
  18. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
  19. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +29 -0
  20. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  21. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +150 -133
  22. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  23. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +37 -1
  24. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  25. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +12 -4
  26. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  27. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +66 -14
  28. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  29. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +23 -14
  30. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  31. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +81 -4
  32. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
  33. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +22 -5
  34. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
  35. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +30 -0
  36. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  37. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +2 -2
  38. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  39. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +5 -1
  40. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  41. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -2
  42. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  43. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +63 -2
  44. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
  45. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js +96 -37
  46. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
  47. package/dist/esm/components/CnStagesWidget/stagesModel.js +5 -2
  48. package/dist/esm/components/CnStagesWidget/stagesModel.js.map +1 -1
  49. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +52 -2
  50. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
  51. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +6 -6
  52. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
  53. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +14 -2
  54. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  55. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +2 -1
  56. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  57. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +73 -1
  58. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
  59. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +14 -2
  60. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
  61. package/dist/esm/l10n/en.json.js +2 -1
  62. package/dist/esm/l10n/en.json.js.map +1 -1
  63. package/dist/esm/l10n/nl.json.js +2 -1
  64. package/dist/esm/l10n/nl.json.js.map +1 -1
  65. package/dist/esm/nextcloud-vue.css +331 -81
  66. package/dist/esm/utils/schemaRefSlug.js +19 -3
  67. package/dist/esm/utils/schemaRefSlug.js.map +1 -1
  68. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  69. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  70. package/dist/nextcloud-vue.cjs.js +6933 -5958
  71. package/dist/nextcloud-vue.cjs.js.map +2 -2
  72. package/dist/nextcloud-vue.css +331 -81
  73. package/l10n/en.json +2 -0
  74. package/l10n/nl.json +2 -0
  75. package/package.json +1 -1
  76. package/src/components/CnAppNav/CnAppNav.vue +297 -11
  77. package/src/components/CnAppRoot/CnAppRoot.md +4 -0
  78. package/src/components/CnAppRoot/CnAppRoot.vue +94 -1
  79. package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +61 -16
  80. package/src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue +22 -1
  81. package/src/components/CnCellRenderer/CnCellRenderer.vue +33 -2
  82. package/src/components/CnDashboardPage/CnDashboardPage.vue +43 -2
  83. package/src/components/CnDataTable/CnDataTable.vue +45 -1
  84. package/src/components/CnDetailPage/CnDetailPage.md +4 -0
  85. package/src/components/CnDetailPage/CnDetailPage.vue +60 -1
  86. package/src/components/CnHeaderWidget/CnHeaderWidget.vue +116 -6
  87. package/src/components/CnIndexPage/CnIndexPage.vue +32 -2
  88. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +7 -1
  89. package/src/components/CnStagesWidget/CnStagesWidget.vue +180 -2
  90. package/src/components/CnStagesWidget/stagesModel.js +5 -2
  91. package/src/components/CnStatWidget/CnStatWidget.vue +57 -3
  92. package/src/components/CnTabsWidget/CnTabsWidget.vue +15 -2
  93. package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +4 -0
  94. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +107 -1
  95. package/src/css/detail-page.css +10 -4
  96. package/src/css/kpi-card.css +24 -1
  97. package/src/css/table.css +18 -6
  98. package/src/schemas/app-manifest-v2.schema.json +113 -3
  99. package/src/utils/schemaRefSlug.js +19 -3
  100. package/src/utils/validateManifestV2.compiled.js +2 -2
@@ -38,6 +38,7 @@ import { BUILT_IN_FORMATTERS } from '../../utils/builtInFormatters.js';
38
38
  import { resolveForge, DEFAULT_FORGE } from '../../utils/forge.js';
39
39
  import { BUILT_IN_KB_PROVIDERS } from '../../utils/kbSearchProviders.js';
40
40
  import { installModalStack, uninstallModalStack } from '../../utils/modalStack.js';
41
+ import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js';
41
42
  import { passesContextPredicates } from '../../utils/visibleIfContext.js';
42
43
  import { useObjectStore } from '../../store/useObjectStore.js';
43
44
 
@@ -388,6 +389,13 @@ var script = {
388
389
  * the counts.
389
390
  */
390
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,
391
399
  }
392
400
  },
393
401
 
@@ -531,6 +539,19 @@ var script = {
531
539
  required: true,
532
540
  },
533
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
+
534
555
  /**
535
556
  * Human-readable name shown in the Nextcloud top bar. When set it
536
557
  * overrides the technical `appId` so a virtual app shows its own name
@@ -1046,6 +1067,13 @@ var script = {
1046
1067
  * picked up by CnAppNav's reactive render.
1047
1068
  */
1048
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({}),
1049
1077
  /**
1050
1078
  * Open state of the host NcAppSettingsDialog. Toggled
1051
1079
  * to `true` by the provided `cnOpenUserSettings()`
@@ -2264,6 +2292,7 @@ var script = {
2264
2292
  this._validateRegistry();
2265
2293
  this._warnCustomComponentsDeprecation();
2266
2294
  this._hydrateMenuCounts();
2295
+ this._hydrateMenuItemCounts();
2267
2296
  return
2268
2297
  }
2269
2298
 
@@ -2292,6 +2321,7 @@ var script = {
2292
2321
  this._validateRegistry();
2293
2322
  this._warnCustomComponentsDeprecation();
2294
2323
  this._hydrateMenuCounts();
2324
+ this._hydrateMenuItemCounts();
2295
2325
  },
2296
2326
 
2297
2327
  beforeUnmount() {
@@ -2948,6 +2978,63 @@ var script = {
2948
2978
  });
2949
2979
  },
2950
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
+
2951
3038
  /**
2952
3039
  * Hydrate all menu counts with a single `POST /api/objects/counts`
2953
3040
  * (OpenRegister batched-counts endpoint). Distributes each returned