@conduction/nextcloud-vue 2.56.0-beta.13 → 2.56.0-beta.15

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 (90) hide show
  1. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +19 -0
  2. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +10 -3
  4. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
  5. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +2 -2
  6. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  7. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  8. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js +37 -26
  9. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js.map +1 -1
  10. package/dist/esm/components/CnContextMenu/CnContextMenu.vue3.js +3 -3
  11. package/dist/esm/components/CnContextMenu/CnContextMenu.vue3.js.map +1 -1
  12. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +4 -4
  13. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  14. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  15. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +89 -49
  16. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  17. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +337 -315
  18. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  19. package/dist/esm/components/CnIndexPage/defaultActions.js +6 -7
  20. package/dist/esm/components/CnIndexPage/defaultActions.js.map +1 -1
  21. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js +33 -34
  22. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js.map +1 -1
  23. package/dist/esm/components/CnRowActions/CnRowActions.vue3.js +3 -3
  24. package/dist/esm/components/CnRowActions/CnRowActions.vue3.js.map +1 -1
  25. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +5 -11
  26. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
  27. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
  28. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +3 -2
  29. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -1
  30. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -1
  31. package/dist/esm/composables/useContextMenu.js +4 -2
  32. package/dist/esm/composables/useContextMenu.js.map +1 -1
  33. package/dist/esm/composables/useDependencyCheck.js +44 -1
  34. package/dist/esm/composables/useDependencyCheck.js.map +1 -1
  35. package/dist/esm/composables/useListView.js +43 -1
  36. package/dist/esm/composables/useListView.js.map +1 -1
  37. package/dist/esm/composables/useSetupStatus.js +26 -3
  38. package/dist/esm/composables/useSetupStatus.js.map +1 -1
  39. package/dist/esm/l10n/en.json.js +4 -1
  40. package/dist/esm/l10n/en.json.js.map +1 -1
  41. package/dist/esm/l10n/nl.json.js +4 -1
  42. package/dist/esm/l10n/nl.json.js.map +1 -1
  43. package/dist/esm/nextcloud-vue.css +20 -2
  44. package/dist/esm/store/plugins/liveUpdates.js +19 -9
  45. package/dist/esm/store/plugins/liveUpdates.js.map +1 -1
  46. package/dist/esm/store/useObjectStore.js +20 -9
  47. package/dist/esm/store/useObjectStore.js.map +1 -1
  48. package/dist/esm/utils/resolveRowActions.js +130 -0
  49. package/dist/esm/utils/resolveRowActions.js.map +1 -0
  50. package/dist/esm/utils/rowActionItem.js +99 -0
  51. package/dist/esm/utils/rowActionItem.js.map +1 -0
  52. package/dist/esm/utils/timelineEvents.js +44 -1
  53. package/dist/esm/utils/timelineEvents.js.map +1 -1
  54. package/dist/esm/utils/validateManifest.js +59 -3
  55. package/dist/esm/utils/validateManifest.js.map +1 -1
  56. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  57. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  58. package/dist/nextcloud-vue.cjs.js +1325 -781
  59. package/dist/nextcloud-vue.cjs.js.map +2 -2
  60. package/dist/nextcloud-vue.css +20 -2
  61. package/l10n/en.json +4 -1
  62. package/l10n/nl.json +4 -1
  63. package/package.json +1 -1
  64. package/scripts/.jsdoc-baselines.json +2 -2
  65. package/src/components/CnActionsBar/CnActionsBar.md +2 -1
  66. package/src/components/CnActionsBar/CnActionsBar.vue +25 -1
  67. package/src/components/CnAppNav/CnAppNav.vue +2 -2
  68. package/src/components/CnContextMenu/CnContextMenu.vue +40 -29
  69. package/src/components/CnDataTable/CnDataTable.md +1 -1
  70. package/src/components/CnDataTable/CnDataTable.vue +4 -4
  71. package/src/components/CnIndexPage/CnIndexPage.md +23 -1
  72. package/src/components/CnIndexPage/CnIndexPage.vue +108 -52
  73. package/src/components/CnIndexPage/defaultActions.js +6 -7
  74. package/src/components/CnRowActions/CnRowActions.vue +36 -37
  75. package/src/components/CnSetupWizard/CnSetupWizard.vue +5 -11
  76. package/src/components/CnTimelineWidget/CnTimelineWidget.vue +3 -2
  77. package/src/composables/useContextMenu.js +4 -2
  78. package/src/composables/useDependencyCheck.js +43 -0
  79. package/src/composables/useListView.js +43 -1
  80. package/src/composables/useSetupStatus.js +26 -3
  81. package/src/css/actions-bar.css +20 -2
  82. package/src/schemas/app-manifest-v2.schema.json +48 -10
  83. package/src/schemas/app-manifest.schema.json +1 -1
  84. package/src/store/plugins/liveUpdates.js +19 -9
  85. package/src/store/useObjectStore.js +19 -8
  86. package/src/utils/resolveRowActions.js +127 -0
  87. package/src/utils/rowActionItem.js +95 -0
  88. package/src/utils/timelineEvents.js +43 -0
  89. package/src/utils/validateManifest.js +60 -3
  90. package/src/utils/validateManifestV2.compiled.js +2 -2
@@ -2,6 +2,7 @@ import { getCurrentUser } from '@nextcloud/auth';
2
2
  import { translate } from '@nextcloud/l10n';
3
3
  import { NcLoadingIcon, NcEmptyContent, NcActions, NcActionButton, NcActionCaption, NcActionCheckbox, NcButton } from '@nextcloud/vue';
4
4
  import { getCurrentInstance, ref, markRaw, inject } from 'vue';
5
+ import AlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue';
5
6
  import Close from 'vue-material-design-icons/Close.vue';
6
7
  import Cog from 'vue-material-design-icons/Cog.vue';
7
8
  import DatabaseSearch from 'vue-material-design-icons/DatabaseSearch.vue';
@@ -22,8 +23,10 @@ import { resolveClaimedTeams, splitViewsIntoTabs, viewAsTab, resolveClaimTokens,
22
23
  import { LIST_SHORTCUTS, listPaletteCommands, shortcutFor } from '../../utils/listShortcuts.js';
23
24
  import { multiKeySort } from '../../utils/multiKeySort.js';
24
25
  import { resolveDeepTokens, resolveFilterValue } from '../../utils/resolveFilterTokens.js';
26
+ import { resolveRowActions } from '../../utils/resolveRowActions.js';
25
27
  import { resolveFilterMap } from '../../utils/routeFilters.js';
26
28
  import { DEFAULT_ROW_ACTION_FIELD, availableRowActions, refusalReasonFor, undeclaredRowActions } from '../../utils/rowActionAvailability.js';
29
+ import { isRowActionVisible, rowActionPayload } from '../../utils/rowActionItem.js';
27
30
  import { isNewTabClick, preventMiddleClickAutoscroll, isRowMiddleClick, isNewTabHandled, markNewTabHandled } from '../../utils/rowAuxClick.js';
28
31
  import { DEFAULT_ROW_INDICATOR_CAP } from '../../utils/rowIndicators.js';
29
32
  import { viewMatchesScope, extractViewState, buildRouteQueryFromViewState, extractViewStateFromRouteQuery, buildViewCreatePayload, savedViewScope } from '../../utils/savedViewHelpers.js';
@@ -285,6 +288,7 @@ var script = {
285
288
  NcActionCaption,
286
289
  NcActionCheckbox,
287
290
  NcButton,
291
+ AlertCircleOutline,
288
292
  Close,
289
293
  Cog,
290
294
  DatabaseSearch,
@@ -900,7 +904,11 @@ var script = {
900
904
  default: () => ({}),
901
905
  },
902
906
 
903
- /** Row action definitions (app-provided, merged with built-in actions) */
907
+ /**
908
+ * Row action definitions, merged with the built-in View / Edit / Copy / Delete.
909
+ * Objects are app actions.
910
+ * A `"builtin:view"`, `"builtin:edit"`, `"builtin:copy"` or `"builtin:delete"` string places that built-in at its position when its `show*Action` toggle is on; enabled built-ins not placed are appended in that order.
911
+ */
904
912
  actions: {
905
913
  type: Array,
906
914
  default: () => [],
@@ -1265,6 +1273,17 @@ var script = {
1265
1273
  default: false,
1266
1274
  },
1267
1275
 
1276
+ /**
1277
+ * Keep the "Showing X of Y" counter visible beside the inline search field,
1278
+ * after any `#after-search` controls (only relevant with `inlineSearch`,
1279
+ * which otherwise takes the counter's place). Fed from the manifest as
1280
+ * `pages[].config.showCountWithSearch`.
1281
+ */
1282
+ showCountWithSearch: {
1283
+ type: Boolean,
1284
+ default: false,
1285
+ },
1286
+
1268
1287
  /** Placeholder for the inline search field (manifest `config.searchPlaceholder`) */
1269
1288
  searchPlaceholder: {
1270
1289
  type: String,
@@ -1963,6 +1982,8 @@ var script = {
1963
1982
  folderRowLayouts: {},
1964
1983
  /** The row the keyboard is on, or -1. */
1965
1984
  focusedRowIndex: -1,
1985
+ // The row the context menu shows: set on open, never cleared on close, so a closing menu keeps its entries and a late close cannot null a reopened one.
1986
+ contextMenuShownRow: null,
1966
1987
  /** The row a quick edit is open on, or null. */
1967
1988
  quickEditRow: null,
1968
1989
  /** The row as the server holds it, after a stale save. */
@@ -2165,11 +2186,23 @@ var script = {
2165
2186
  return this.isSelfFetch && !!this.list
2166
2187
  },
2167
2188
 
2189
+ /**
2190
+ * Whether the latest self-fetch failed. The store keeps the previous
2191
+ * rows and pagination on a failed fetch, so while this holds the page
2192
+ * shows its error state instead of results for an earlier query.
2193
+ */
2194
+ selfFetchFailed() {
2195
+ return this.isSelfFetchMode && !!this.list.error?.value
2196
+ },
2197
+
2168
2198
  /** Rows: store collection in self-fetch mode, else the `objects` prop. */
2169
2199
  effectiveObjects() {
2170
2200
  if (this.isNamedSource) {
2171
2201
  return this.namedRows
2172
2202
  }
2203
+ if (this.selfFetchFailed) {
2204
+ return []
2205
+ }
2173
2206
  return this.isSelfFetchMode ? (this.list.objects.value || []) : this.objects
2174
2207
  },
2175
2208
 
@@ -2573,7 +2606,9 @@ var script = {
2573
2606
  s: this.exportSchemaSlug,
2574
2607
  f: this.filter || null,
2575
2608
  e: this.countEntries,
2576
- t: Number(this.effectivePagination?.total ?? 0),
2609
+ // The store's total, not the error override in effectivePagination,
2610
+ // so a failed fetch and its recovery do not refetch the counts.
2611
+ t: Number((this.isSelfFetchMode ? this.list.pagination.value : this.effectivePagination)?.total ?? 0),
2577
2612
  })
2578
2613
  },
2579
2614
 
@@ -2661,7 +2696,7 @@ var script = {
2661
2696
  if (this.quickEditFields.length > 0) {
2662
2697
  handlers['row-quick-edit'] = () => this.focusedRow && this.openQuickEdit(this.focusedRow);
2663
2698
  }
2664
- if (this.focusedRow && this.rowActionsFor(this.focusedRow).length > 0) {
2699
+ if (this.focusedRow && this.primaryRowActionFor(this.focusedRow)) {
2665
2700
  handlers['row-primary'] = () => this.runPrimaryRowAction();
2666
2701
  }
2667
2702
  return handlers
@@ -2979,6 +3014,9 @@ var script = {
2979
3014
 
2980
3015
  /** Pagination: store pagination in self-fetch mode, else the `pagination` prop. */
2981
3016
  effectivePagination() {
3017
+ if (this.selfFetchFailed) {
3018
+ return { ...this.list.pagination.value, total: 0, page: 1, pages: 1 }
3019
+ }
2982
3020
  return this.isSelfFetchMode ? this.list.pagination.value : this.pagination
2983
3021
  },
2984
3022
 
@@ -3339,7 +3377,8 @@ var script = {
3339
3377
  },
3340
3378
 
3341
3379
  /**
3342
- * Merged actions: app-provided first, then built-in defaults.
3380
+ * Merged actions: the declared entries in order, each `"builtin:<id>"` placeholder replaced by that built-in when its toggle is on, then the enabled built-ins not placed.
3381
+ * See `resolveRowActions`.
3343
3382
  *
3344
3383
  * REQ-MAD-3 / REQ-MAD-4 / REQ-MAD-5 / REQ-MAD-6 / REQ-MAD-7
3345
3384
  * (manifest-actions-dispatch) — for any action whose `handler`
@@ -3355,58 +3394,41 @@ var script = {
3355
3394
  registry: this.effectiveRegistry,
3356
3395
  customComponents: this.effectiveCustomComponents,
3357
3396
  };
3358
- // Drop anything that is not an action OBJECT. A bare string — the
3359
- // shorthand `"edit"` an author reasonably expects to mean "show the
3360
- // built-in Edit" — has no `label` and no `icon`, so it rendered as a
3361
- // full-height NcActionButton with nothing in it: an invisible,
3362
- // clickable, inert row in the overflow menu. Observed on dossiq,
3363
- // where `config.actions: ["create", "edit", "delete", {…}]` put three
3364
- // blank rows above the real ones on four different index pages.
3365
- //
3366
- // Named, not silently swallowed: a dropped action is a capability the
3367
- // author asked for and did not get, and the manifest schema now
3368
- // rejects the shape at authoring time (`config.actions` is governed by
3369
- // the same `action` definition as `pages[].actions`). Built-ins are
3370
- // turned on with the `show*Action` toggles, not by naming them here.
3371
3397
  // A named source may supply its own row actions, on the same
3372
3398
  // precedence as its columns: what the manifest declares wins, and the
3373
- // source is the DEFAULT for a page that declares none. Without this
3374
- // the source's `rowActions` were declared and never read — the third
3375
- // field of the same adapter to be wired late, after `columns` and
3376
- // `addLabel`.
3377
- //
3378
- // Note what this still cannot do: these are MERGED with the built-ins
3379
- // below, so a source can add an action but cannot say "these and no
3380
- // others". Suppressing a built-in is the `show*Action` toggles' job.
3399
+ // source is the DEFAULT for a page that declares none.
3400
+ // Either list may place built-ins with `"builtin:<id>"`; turning one on or off stays the `show*Action` toggles' job.
3381
3401
  const manifestDeclared = this.actions && this.actions.length > 0;
3382
3402
  const declaredActions = manifestDeclared
3383
3403
  ? this.actions
3384
3404
  : ((this.isNamedSource && this.namedSource && this.namedSource.rowActions) || []);
3385
3405
 
3386
- const declared = [];
3387
- for (const a of declaredActions) {
3388
- if (a && typeof a === 'object' && !Array.isArray(a)) {
3406
+ const { actions, warnings } = resolveRowActions(declaredActions, this.defaultActions, {
3407
+ prepare: (a) => {
3389
3408
  // A SOURCE action may say `action: 'open'`: open this row the
3390
3409
  // way a row click does — the source's own navigation
3391
3410
  // (`openRow`/`detailRoute`), with `edit-open` emitted so a
3392
3411
  // host that configured a row target (`config.rowRoute`) wins.
3393
- // Resolved here because a source is a composable with no
3394
- // router; the flows source declared exactly this action and
3395
- // it rendered as a dead menu entry, because `action` was a
3396
- // key nothing read (dispatch reads `handler` and `type`).
3397
- // Source-declared actions only: the manifest grammar for
3398
- // navigation is `type`/`handler`, and stays so.
3412
+ // Resolved here because a source is a composable with no router.
3413
+ // Source-declared actions only: the manifest grammar for navigation is `type`/`handler`, and stays so.
3399
3414
  if (!manifestDeclared && a.action === 'open' && typeof a.handler !== 'function') {
3400
- declared.push({ ...a, handler: (row) => this.openSourceRow(row) });
3401
- continue
3415
+ return { ...a, handler: (row) => this.openSourceRow(row) }
3402
3416
  }
3403
- declared.push(dispatchAction(a, ctx));
3417
+ return dispatchAction(a, ctx)
3418
+ },
3419
+ });
3420
+ for (const warning of warnings) {
3421
+ // A toggle turned off at runtime (permissions, readOnly) legitimately silences a placeholder; the validator flags a statically-off one.
3422
+ if (warning.code === 'disabled-placeholder') {
3404
3423
  continue
3405
3424
  }
3406
- // eslint-disable-next-line no-console
3407
- console.warn(`[CnIndexPage] Ignoring action ${JSON.stringify(a)}: actions must be objects with an id and a label. To show a built-in action use the showViewAction / showEditAction / showCopyAction / showDeleteAction props.`);
3425
+ // A dropped entry is always named; the placement hints are dev-only.
3426
+ if (warning.code === 'invalid-entry' || process.env.NODE_ENV !== 'production') {
3427
+ // eslint-disable-next-line no-console
3428
+ console.warn(`[CnIndexPage] "${this.title}": ${warning.message}`);
3429
+ }
3408
3430
  }
3409
- return [...declared, ...this.defaultActions]
3431
+ return actions
3410
3432
  },
3411
3433
 
3412
3434
  hasRowActions() {
@@ -4652,9 +4674,20 @@ var script = {
4652
4674
  },
4653
4675
 
4654
4676
  /**
4655
- * Run the first action the focused row offers. "First" is the page's
4656
- * order, narrowed by what the server allows on that record, so the
4657
- * primary action is never one this caller may not run.
4677
+ * The first action a row's menu shows and enables: the page's order, narrowed by what the server allows, by `visible` / `visibleWhen`, and by `disabled`.
4678
+ * The keyboard therefore never runs what the menu hides or greys out.
4679
+ *
4680
+ * @param {object} row The row.
4681
+ * @return {(object|null)} The action, or null.
4682
+ * @spec openspec/changes/row-action-builtin-placement/specs/index-page/spec.md
4683
+ */
4684
+ primaryRowActionFor(row) {
4685
+ return this.rowActionsFor(row).find((action) => isRowActionVisible(action, row)
4686
+ && !(typeof action.disabled === 'function' ? action.disabled(row) : action.disabled)) || null
4687
+ },
4688
+
4689
+ /**
4690
+ * Run the focused row's primary action (see `primaryRowActionFor`).
4658
4691
  *
4659
4692
  * @return {void}
4660
4693
  * @spec openspec/changes/working-list-row-actions/specs/index-page/spec.md
@@ -4664,14 +4697,14 @@ var script = {
4664
4697
  if (!row) {
4665
4698
  return
4666
4699
  }
4667
- const [first] = this.rowActionsFor(row);
4700
+ const first = this.primaryRowActionFor(row);
4668
4701
  if (!first) {
4669
4702
  return
4670
4703
  }
4671
4704
  if (typeof first.handler === 'function') {
4672
4705
  first.handler(row);
4673
4706
  }
4674
- this.$emit('action', { action: first.label, row });
4707
+ this.onRowAction(rowActionPayload(first, row));
4675
4708
  },
4676
4709
 
4677
4710
  /**
@@ -4988,16 +5021,22 @@ var script = {
4988
5021
  },
4989
5022
 
4990
5023
  /**
4991
- * Intercepts CnRowActions' bubbled `@action` so `handler: "none"`
4992
- * actions are dropped before re-emit.
5024
+ * Intercepts CnRowActions' and CnContextMenu's bubbled `@action` so `handler: "none"` actions are dropped before re-emit.
5025
+ * A built-in is matched by its id, an app action by its label.
4993
5026
  *
4994
- * @param {{action: string, row: object}} payload The bubbled action payload.
5027
+ * @param {{action: string, row: object, id?: string, builtin?: boolean}} payload The bubbled action payload.
4995
5028
  */
4996
5029
  onRowAction(payload) {
4997
- const matched = this.mergedActions.find((a) => a.label === payload.action);
5030
+ const matched = payload.builtin === true
5031
+ ? this.mergedActions.find((a) => a.builtin === true && a.id === payload.id)
5032
+ : this.mergedActions.find((a) => a.builtin !== true && a.label === payload.action);
4998
5033
  if (matched && matched._dispatchSuppress) {
4999
5034
  return
5000
5035
  }
5036
+ /**
5037
+ * @event action A row action was chosen from a row's actions menu, its right-click menu or the keyboard primary action. Payload: `action` (the label), the row, the action's `id` when it has one, and `builtin: true` for a built-in View / Edit / Copy / Delete. Its handler has already run.
5038
+ * @type {{ action: string, row: object, id?: string, builtin?: boolean }}
5039
+ */
5001
5040
  this.$emit('action', payload);
5002
5041
  },
5003
5042
 
@@ -5943,6 +5982,7 @@ var script = {
5943
5982
  // --- Context menu handlers ---
5944
5983
 
5945
5984
  onRowContextMenu({ row, event }) {
5985
+ this.contextMenuShownRow = row;
5946
5986
  this.openContextMenu({ item: row, event });
5947
5987
  },
5948
5988