@conduction/nextcloud-vue 2.93.0 → 2.94.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 (105) hide show
  1. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js +1 -1
  2. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +2 -1
  4. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
  5. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
  6. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js +28 -8
  7. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
  8. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +37 -2
  9. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
  10. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue.js +1 -1
  11. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js +139 -3
  12. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js.map +1 -1
  13. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js +60 -12
  14. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js.map +1 -1
  15. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  16. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +91 -36
  17. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  18. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +115 -72
  19. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  20. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +32 -3
  21. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  22. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +7 -7
  23. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  24. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +141 -7
  25. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  26. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +5 -2
  27. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  28. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue.js +8 -0
  29. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue.js.map +1 -0
  30. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue2.js +114 -0
  31. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue2.js.map +1 -0
  32. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue3.js +45 -0
  33. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue3.js.map +1 -0
  34. package/dist/esm/components/CnPageHeader/CnPageHeader.vue2.js +38 -2
  35. package/dist/esm/components/CnPageHeader/CnPageHeader.vue2.js.map +1 -1
  36. package/dist/esm/components/CnPageHeader/CnPageHeader.vue3.js +12 -2
  37. package/dist/esm/components/CnPageHeader/CnPageHeader.vue3.js.map +1 -1
  38. package/dist/esm/components/CnPagination/CnPagination.vue2.js.map +1 -1
  39. package/dist/esm/components/CnPagination/CnPagination.vue3.js +56 -51
  40. package/dist/esm/components/CnPagination/CnPagination.vue3.js.map +1 -1
  41. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  42. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +3 -3
  43. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  44. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  45. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue.js +1 -1
  46. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js +24 -0
  47. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js.map +1 -1
  48. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js +3 -1
  49. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js.map +1 -1
  50. package/dist/esm/components/CnTabs/CnTabs.vue.js +1 -1
  51. package/dist/esm/components/CnTabs/CnTabs.vue2.js +39 -2
  52. package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
  53. package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
  54. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
  55. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +85 -8
  56. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  57. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +37 -9
  58. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  59. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue.js +1 -1
  60. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js.map +1 -1
  61. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js +4 -3
  62. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js.map +1 -1
  63. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue.js +1 -1
  64. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +20 -0
  65. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
  66. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +31 -20
  67. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
  68. package/dist/esm/composables/indexSources.js +9 -0
  69. package/dist/esm/composables/indexSources.js.map +1 -1
  70. package/dist/esm/library-style.js +1 -1
  71. package/dist/esm/nextcloud-vue.css +402 -262
  72. package/dist/esm/utils/dueText.js +49 -8
  73. package/dist/esm/utils/dueText.js.map +1 -1
  74. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  75. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  76. package/dist/nextcloud-vue.cjs.js +5779 -4827
  77. package/dist/nextcloud-vue.cjs.js.map +2 -2
  78. package/dist/nextcloud-vue.css +402 -262
  79. package/package.json +1 -1
  80. package/src/components/CnActionsMenu/CnActionsMenu.vue +3 -1
  81. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +39 -1
  82. package/src/components/CnCountdownWidget/CnCountdownWidget.vue +222 -6
  83. package/src/components/CnDashboardPage/CnDashboardPage.vue +96 -2
  84. package/src/components/CnDataTable/CnDataTable.md +1 -0
  85. package/src/components/CnDataTable/CnDataTable.vue +39 -10
  86. package/src/components/CnIndexPage/CnIndexPage.vue +144 -7
  87. package/src/components/CnPageHeader/CnHeaderTrail.vue +140 -0
  88. package/src/components/CnPageHeader/CnPageHeader.md +11 -0
  89. package/src/components/CnPageHeader/CnPageHeader.vue +42 -0
  90. package/src/components/CnPagination/CnPagination.vue +10 -2
  91. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +3 -3
  92. package/src/components/CnSettingsPage/CnSettingsPage.vue +26 -0
  93. package/src/components/CnTabs/CnTabs.vue +39 -2
  94. package/src/components/CnTabsWidget/CnTabsWidget.vue +106 -13
  95. package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +4 -3
  96. package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +8 -0
  97. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +31 -2
  98. package/src/composables/indexSources.js +9 -0
  99. package/src/css/dialog.css +14 -0
  100. package/src/css/look-board-index.css +27 -1
  101. package/src/css/look-board.css +27 -0
  102. package/src/css/page-header.css +16 -0
  103. package/src/schemas/app-manifest-v2.schema.json +22 -15
  104. package/src/utils/dueText.js +49 -8
  105. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -467,6 +467,31 @@ var script = {
467
467
  required: true,
468
468
  },
469
469
 
470
+ /**
471
+ * A breadcrumb under the title (manifest `config.breadcrumb`): one
472
+ * crumb `{ label, route?, params?, href?, icon?, separator? }` or a
473
+ * list; the title follows as the current crumb. Drawn as the detail
474
+ * header's breadcrumb row. Null (the default) draws none.
475
+ *
476
+ * @type {object|Array<object>|null}
477
+ * @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
478
+ */
479
+ breadcrumb: {
480
+ type: [Object, Array],
481
+ default: null,
482
+ },
483
+
484
+ /**
485
+ * A note after the breadcrumb and a middle dot (manifest `config.headerMeta`),
486
+ * such as "{total} open": `{total}` and `{shown}` are the list's counts.
487
+ *
488
+ * @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
489
+ */
490
+ headerMeta: {
491
+ type: String,
492
+ default: '',
493
+ },
494
+
470
495
  /** Optional description shown below the title */
471
496
  description: {
472
497
  type: String,
@@ -1090,7 +1115,7 @@ var script = {
1090
1115
  * can open is an ordinary segment; one it cannot (no board columns, no
1091
1116
  * map configured) is drawn disabled, named "<mode>: not available on
1092
1117
  * this list". Fed from `pages[].config.viewSwitch`. Ignored without the
1093
- * board look, and absent the switch is as before.
1118
+ * board look; absent, the board look draws all four.
1094
1119
  *
1095
1120
  * @type {Array<'table' | 'cards' | 'board' | 'map'>}
1096
1121
  * @spec openspec/changes/screens-view-switch-parity/specs/view-switch-board-look/spec.md#requirement-the-manifest-can-draw-segments-the-page-cannot-open
@@ -2413,6 +2438,8 @@ var script = {
2413
2438
  data() {
2414
2439
  return {
2415
2440
  currentViewMode: this.viewMode,
2441
+ /** Whether `?_view=` names a mode the page did not offer yet, to open once it does. */
2442
+ routeViewPending: false,
2416
2443
  /** The column field the reader picked in the board's column switch; '' = the default. */
2417
2444
  boardColumnFieldChoice: '',
2418
2445
  /** The rows a reference column field is built from, by field. */
@@ -2976,11 +3003,14 @@ var script = {
2976
3003
  * @spec openspec/changes/screens-view-switch-parity/specs/view-switch-board-look/spec.md#requirement-the-manifest-can-draw-segments-the-page-cannot-open
2977
3004
  */
2978
3005
  viewSwitchDisabledModes() {
2979
- if (!this.isBoardLook || !Array.isArray(this.viewSwitch)) {
3006
+ if (!this.isBoardLook) {
2980
3007
  return []
2981
3008
  }
3009
+ // The index boards draw all four segments, so the board look does
3010
+ // too unless the manifest names its own list.
3011
+ const listed = Array.isArray(this.viewSwitch) ? this.viewSwitch : ['table', 'cards', 'board', 'map'];
2982
3012
  const offered = [...this.effectiveToggleModes, ...(this.showMapSegment ? ['map'] : [])];
2983
- return this.viewSwitch.filter((mode) => ['table', 'cards', 'board', 'map'].includes(mode) && !offered.includes(mode))
3013
+ return listed.filter((mode) => ['table', 'cards', 'board', 'map'].includes(mode) && !offered.includes(mode))
2984
3014
  },
2985
3015
 
2986
3016
  /**
@@ -3018,6 +3048,17 @@ var script = {
3018
3048
  })
3019
3049
  },
3020
3050
 
3051
+ /**
3052
+ * The modes `?_view=` can open: the toggle's modes plus the map when
3053
+ * the page offers it.
3054
+ *
3055
+ * @return {Array<string>} The modes.
3056
+ * @spec openspec/changes/screens-index-board-gaps/specs/index-list-board-look/spec.md#requirement-the-address-opens-a-view-mode-that-arrives-later
3057
+ */
3058
+ routeViewModes() {
3059
+ return [...this.effectiveToggleModes, ...(this.showMapSegment ? ['map'] : [])]
3060
+ },
3061
+
3021
3062
  /**
3022
3063
  * The column fields the board offers (`board.columnFields`), for the
3023
3064
  * column switch (screens-board-reference-columns).
@@ -4238,6 +4279,21 @@ var script = {
4238
4279
  return this.isSelfFetchMode ? this.list.pagination.value : this.pagination
4239
4280
  },
4240
4281
 
4282
+ /**
4283
+ * Whether the table marks unread rows. The boards draw every row alike,
4284
+ * so under the board look only a page that offers the Unread lens
4285
+ * (`personalLenses`) marks them; the Nextcloud look always does.
4286
+ *
4287
+ * @spec openspec/changes/screens-index-board-gaps/specs/index-list-board-look/spec.md#requirement-unread-rows-are-marked-only-where-the-reader-asked-for-them
4288
+ * @return {boolean} True when unread rows read in bold with the dot.
4289
+ */
4290
+ showUnreadRows() {
4291
+ if (!this.isBoardLook) {
4292
+ return true
4293
+ }
4294
+ return Array.isArray(this.personalLenses) && this.personalLenses.includes('unread')
4295
+ },
4296
+
4241
4297
  /** Resolved schema OBJECT (for column generation / icons / labels). */
4242
4298
  /**
4243
4299
  * Whether the table shows its header filters. A self-fetching page
@@ -4860,8 +4916,9 @@ var script = {
4860
4916
  }
4861
4917
  // The board's header: Export reads "Download" with its icon and
4862
4918
  // the Actions menu reads "Actions", without the manifest saying so.
4863
- if (this.isBoardLook && label === '' && button.action === 'export') {
4864
- label = translate('nextcloud-vue', 'Download');
4919
+ // A labelled Export keeps the icon too, unless it names its own.
4920
+ if (this.isBoardLook && button.action === 'export') {
4921
+ label = label || translate('nextcloud-vue', 'Download');
4865
4922
  icon = icon || 'Download';
4866
4923
  }
4867
4924
  if (label === '' && button.action === 'actions-menu') {
@@ -5144,6 +5201,22 @@ var script = {
5144
5201
  * @spec openspec/changes/screens-table-footer-and-system-dates-parity/specs/index-list-board-look/spec.md#requirement-the-count-reads-in-the-users-language
5145
5202
  * @return {string}
5146
5203
  */
5204
+ /**
5205
+ * The header meta note with the list's counts filled in.
5206
+ *
5207
+ * @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
5208
+ * @return {string}
5209
+ */
5210
+ headerMetaText() {
5211
+ if (!this.headerMeta) {
5212
+ return ''
5213
+ }
5214
+ const total = this.effectivePagination?.total;
5215
+ return this.cnTranslate(this.headerMeta)
5216
+ .replace('{shown}', String(this.effectiveObjects.length))
5217
+ .replace('{total}', typeof total === 'number' ? String(total) : '')
5218
+ },
5219
+
5147
5220
  headerDescription() {
5148
5221
  const total = this.effectivePagination?.total;
5149
5222
  // Board look: the count line is a template over the rows on this page
@@ -5334,6 +5407,12 @@ var script = {
5334
5407
  this.applyViewModeFromRoute();
5335
5408
  },
5336
5409
 
5410
+ routeViewModes() {
5411
+ if (this.routeViewPending) {
5412
+ this.applyViewModeFromRoute();
5413
+ }
5414
+ },
5415
+
5337
5416
  boardFetchKey: {
5338
5417
  immediate: true,
5339
5418
  handler(key) {
@@ -5766,6 +5845,10 @@ var script = {
5766
5845
  */
5767
5846
  async loadFilterCounts() {
5768
5847
  const requestKey = this.countRequestKey;
5848
+ if (this.isNamedSource) {
5849
+ await this.loadNamedSourceCounts(requestKey);
5850
+ return
5851
+ }
5769
5852
  const schema = this.exportSchemaSlug;
5770
5853
  if (requestKey === '' || !this.register || !schema) {
5771
5854
  this.tabCounts = null;
@@ -5797,6 +5880,46 @@ var script = {
5797
5880
  this.savedViewCounts = viewCounts;
5798
5881
  },
5799
5882
 
5883
+ /**
5884
+ * The quick-filter counts of a named source (`entitySource`): each tab
5885
+ * that asks is counted by the source's own `count(config)`, with the
5886
+ * tab's filter over `sourceConfig`. A source without `count` shows
5887
+ * none; a failed count leaves that tab without a number.
5888
+ *
5889
+ * @param {string} requestKey The `countRequestKey` this load answers.
5890
+ * @return {Promise<void>}
5891
+ * @spec openspec/changes/screens-index-board-gaps/specs/index-list-board-look/spec.md#requirement-a-named-source-counts-its-quick-filters
5892
+ */
5893
+ async loadNamedSourceCounts(requestKey) {
5894
+ const count = this.namedSource ? this.namedSource.count : null;
5895
+ if (requestKey === '' || typeof count !== 'function') {
5896
+ this.tabCounts = null;
5897
+ this.savedViewCounts = null;
5898
+ return
5899
+ }
5900
+ const params = (this.$route && this.$route.params) || {};
5901
+ const ctx = typeof this.selfFetchTokenCtx === 'function' ? this.selfFetchTokenCtx() : {};
5902
+ const tabCounts = {};
5903
+ await Promise.all(this.countEntries
5904
+ .filter((entry) => entry.key.startsWith('tab:'))
5905
+ .map(async (entry) => {
5906
+ const config = resolveFilterMap({ ...(this.sourceConfig || {}), ...(entry.filter || {}) }, params, ctx);
5907
+ try {
5908
+ const total = await count(config);
5909
+ if (Number.isFinite(total)) {
5910
+ tabCounts[Number(entry.key.slice(4))] = total;
5911
+ }
5912
+ } catch {
5913
+ // No number for this tab.
5914
+ }
5915
+ }));
5916
+ if (requestKey !== this.countRequestKey) {
5917
+ return
5918
+ }
5919
+ this.tabCounts = tabCounts;
5920
+ this.savedViewCounts = null;
5921
+ },
5922
+
5800
5923
  // ── Split view (case-page-and-list-as-a-place) ──────────────────
5801
5924
 
5802
5925
  /**
@@ -8061,6 +8184,7 @@ var script = {
8061
8184
  * @param {string} mode 'table' or 'cards'
8062
8185
  */
8063
8186
  onViewModeChange(mode) {
8187
+ this.routeViewPending = false;
8064
8188
  this.currentViewMode = mode;
8065
8189
  this.$emit('view-mode-change', mode);
8066
8190
  },
@@ -8070,16 +8194,26 @@ var script = {
8070
8194
  * offers it. The key starts with `_`, like `_search` and `_page`, so it
8071
8195
  * is never read as a list filter. A menu entry's `query` can so open a
8072
8196
  * list as its board, on the one page that lists the schema
8073
- * (screens-board-reference-columns).
8197
+ * (screens-board-reference-columns). A mode the page offers only later
8198
+ * (the map, once rows with a geometry are in) opens when it arrives,
8199
+ * unless the reader picked a view first.
8074
8200
  *
8075
8201
  * @return {void}
8076
8202
  * @spec openspec/changes/screens-board-reference-columns/specs/board-view/spec.md#requirement-the-address-can-open-a-list-in-a-view-mode
8203
+ * @spec openspec/changes/screens-index-board-gaps/specs/index-list-board-look/spec.md#requirement-the-address-opens-a-view-mode-that-arrives-later
8077
8204
  */
8078
8205
  applyViewModeFromRoute() {
8079
8206
  const wanted = this.$route?.query?._view;
8080
- if (typeof wanted === 'string' && wanted !== this.currentViewMode && this.effectiveToggleModes.includes(wanted)) {
8207
+ if (typeof wanted !== 'string' || wanted === '' || wanted === this.currentViewMode) {
8208
+ this.routeViewPending = false;
8209
+ return
8210
+ }
8211
+ if (this.routeViewModes.includes(wanted)) {
8081
8212
  this.currentViewMode = wanted;
8213
+ this.routeViewPending = false;
8214
+ return
8082
8215
  }
8216
+ this.routeViewPending = true;
8083
8217
  },
8084
8218
 
8085
8219
  /**