@conduction/nextcloud-vue 2.112.0 → 2.113.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 (47) hide show
  1. package/dist/esm/components/CnActionButtons/CnActionButtons.vue.js +1 -1
  2. package/dist/esm/components/CnActionButtons/CnActionButtons.vue2.js +4 -6
  3. package/dist/esm/components/CnActionButtons/CnActionButtons.vue2.js.map +1 -1
  4. package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js.map +1 -1
  5. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue.js +1 -1
  6. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
  7. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
  8. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  9. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +18 -3
  10. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  11. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +2 -2
  12. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  13. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +20 -5
  14. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  15. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  16. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +56 -13
  17. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  18. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +5 -3
  19. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  20. package/dist/esm/components/CnReportsPage/CnReportsPage.vue.js +1 -1
  21. package/dist/esm/components/CnReportsPage/CnReportsPage.vue2.js +29 -12
  22. package/dist/esm/components/CnReportsPage/CnReportsPage.vue2.js.map +1 -1
  23. package/dist/esm/components/CnReportsPage/CnReportsPage.vue3.js +3 -1
  24. package/dist/esm/components/CnReportsPage/CnReportsPage.vue3.js.map +1 -1
  25. package/dist/esm/library-style.js +1 -1
  26. package/dist/esm/nextcloud-vue.css +152 -181
  27. package/dist/esm/utils/actionLink.js +104 -1
  28. package/dist/esm/utils/actionLink.js.map +1 -1
  29. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  30. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  31. package/dist/nextcloud-vue.cjs.js +241 -50
  32. package/dist/nextcloud-vue.cjs.js.map +2 -2
  33. package/dist/nextcloud-vue.css +152 -181
  34. package/package.json +1 -1
  35. package/src/components/CnActionButtons/CnActionButtons.vue +4 -6
  36. package/src/components/CnChoiceCards/CnChoiceCards.vue +0 -3
  37. package/src/components/CnDashboardPage/CnDashboardPage.vue +20 -5
  38. package/src/components/CnDetailPage/CnDetailPage.vue +20 -5
  39. package/src/components/CnIndexPage/CnIndexPage.vue +59 -14
  40. package/src/components/CnReportsPage/CnReportsPage.vue +31 -12
  41. package/src/css/badge.css +15 -13
  42. package/src/css/board.css +0 -1
  43. package/src/css/look-board-index.css +3 -17
  44. package/src/css/look-board.css +2 -16
  45. package/src/schemas/app-manifest-v2.schema.json +51 -9
  46. package/src/utils/actionLink.js +103 -0
  47. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -27,8 +27,8 @@ import { createRefLabelResolver } from '../../composables/useRefLabels.js';
27
27
  import { useSavedViewsApi } from '../../composables/useSavedViewsApi.js';
28
28
  import { METADATA_COLUMNS } from '../../constants/metadata.js';
29
29
  import { useObjectStore } from '../../store/useObjectStore.js';
30
- import { routeHref, followItemActionLink, resolveItemActionLink } from '../../utils/actionLink.js';
31
- import { resolveRegisteredHandler, buildOnSuccessRoute } from '../../utils/actionsDispatcher.js';
30
+ import { routeHref, headerActionAsLink, followItemActionLink, resolveItemActionLink } from '../../utils/actionLink.js';
31
+ import { resolveRegisteredHandler, isExternalActionTarget, buildOnSuccessRoute } from '../../utils/actionsDispatcher.js';
32
32
  import { columnFieldsOf, refIdOf, buildValueStages, buildReferenceStages, columnKeyOfRow, resolveDropValue, fullTargetOf, referenceTargetOf, fetchReferenceObjects } from '../../utils/boardReferenceColumns.js';
33
33
  import { isColumnSortable } from '../../utils/columnFilters.js';
34
34
  import { reportBindingProblems } from '../../utils/diagnostics.js';
@@ -2589,11 +2589,16 @@ var script = {
2589
2589
  * (unless the handler is the `'none'` keyword) emits
2590
2590
  * `@header-action({ action: id, id })`.
2591
2591
  *
2592
+ * An entry with `href` instead renders as a real link and is never
2593
+ * dispatched or emitted: an absolute `http(s)`, `mailto:`, `tel:` or
2594
+ * `//host/...` URL is used as written, an instance path (leading `/`) goes through
2595
+ * `generateUrl()`. `target: '_blank'` opens it in a new tab.
2596
+ *
2592
2597
  * Reserved ids (those used by built-ins on the bar — `refresh`,
2593
2598
  * `import`, `export`, `copy`, `delete`) are dropped from the
2594
2599
  * merged list with a `console.warn`.
2595
2600
  *
2596
- * @type {Array<{ id: string, label: string, icon?: string, handler?: string|(() => void), route?: string, disabled?: boolean }>}
2601
+ * @type {Array<{ id: string, label: string, icon?: string, handler?: string|(() => void), route?: string, href?: string, target?: ('_blank'|'_self'), disabled?: boolean }>}
2597
2602
  */
2598
2603
  headerActions: {
2599
2604
  type: Array,
@@ -3046,7 +3051,7 @@ var script = {
3046
3051
  /**
3047
3052
  * The header actions that open a dialog: `type: "open-form"` (the
3048
3053
  * schema-driven create form, as the navigation's primary action opens
3049
- * it) or `type: "open-modal"`, without a `handler` of their own.
3054
+ * it) or `type: "open-modal"`, without a `handler` or `href` of their own.
3050
3055
  * Reserved ids are left out, as in `mergedHeaderActions`.
3051
3056
  *
3052
3057
  * @spec openspec/changes/index-header-open-form/specs/index-header/spec.md#requirement-an-index-header-action-can-open-the-create-form
@@ -3058,9 +3063,18 @@ var script = {
3058
3063
  && typeof entry.id === 'string'
3059
3064
  && !reserved.has(entry.id)
3060
3065
  && (entry.handler === undefined || entry.handler === null || entry.handler === '')
3066
+ && !entry.href
3061
3067
  && (entry.type === 'open-form' || entry.type === 'open-modal'))
3062
3068
  },
3063
3069
 
3070
+ /**
3071
+ * The header actions without reserved ids, each through
3072
+ * `resolveHeaderHandler` (a manifest `href` entry becomes a link with
3073
+ * `_dispatchSuppress`, so the page neither runs nor emits it).
3074
+ *
3075
+ * @spec openspec/changes/header-action-href/specs/header-action-href/spec.md#requirement-a-header-action-with-href-is-a-link-that-runs-and-emits-nothing
3076
+ * @return {Array<object>}
3077
+ */
3064
3078
  mergedHeaderActions() {
3065
3079
  const reserved = new Set(['refresh', 'import', 'export', 'copy', 'delete']);
3066
3080
  const merged = [];
@@ -6099,11 +6113,13 @@ var script = {
6099
6113
  *
6100
6114
  * @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-an-index-page-can-take-the-board-header
6101
6115
  * @spec openspec/changes/screens-index-header-buttons-parity/specs/index-list-board-look/spec.md#requirement-the-add-header-button-carries-a-plus
6102
- * @return {Array<{key: string, label: string, action: string, variant: string, icon: string, format: string}>}
6116
+ * @spec openspec/changes/header-action-href/specs/header-action-href/spec.md#requirement-a-header-action-with-href-is-a-link-that-runs-and-emits-nothing
6117
+ * @return {Array<{key: string, label: string, action: string, variant: string, icon: string, format: string, link: ({href: string, target: (string|undefined)}|null)}>}
6103
6118
  */
6104
6119
  resolvedHeaderButtons() {
6105
6120
  const headerButtons = this.presented('headerButtons');
6106
6121
  const declared = Array.isArray(headerButtons) ? headerButtons : [];
6122
+ const builtInActions = new Set(['add', 'export', 'import', 'refresh', 'save-view', 'actions-menu']);
6107
6123
  return declared
6108
6124
  .filter((button) => button && typeof button === 'object' && typeof button.action === 'string' && button.action !== '')
6109
6125
  .map((button, index) => {
@@ -6130,6 +6146,13 @@ var script = {
6130
6146
  if (label === '' && button.action === 'save-view') {
6131
6147
  label = translate('nextcloud-vue', 'Save view');
6132
6148
  }
6149
+ const run = typeof button.run === 'string' ? button.run : '';
6150
+ // A button that runs a manifest `href` header action is that link;
6151
+ // a `type: "navigate"` or function-handler entry keeps dispatching.
6152
+ const actionId = button.action === 'export' ? run : (builtInActions.has(button.action) ? '' : button.action);
6153
+ const linked = actionId
6154
+ ? this.mergedHeaderActions.find((entry) => entry && entry.id === actionId && entry.href && entry._dispatchSuppress && (!entry.type || entry.type === 'handler'))
6155
+ : null;
6133
6156
  return {
6134
6157
  key: String(button.id || button.action || index),
6135
6158
  label,
@@ -6137,7 +6160,8 @@ var script = {
6137
6160
  variant: button.variant === 'primary' ? 'primary' : 'secondary',
6138
6161
  icon,
6139
6162
  format: button.format === 'excel' ? 'excel' : 'csv',
6140
- run: typeof button.run === 'string' ? button.run : '',
6163
+ run,
6164
+ link: linked ? { href: linked.href, target: linked.linkTarget || undefined } : null,
6141
6165
  items: Array.isArray(button.items)
6142
6166
  ? button.items.filter((item) => (typeof item === 'string' && item !== '')
6143
6167
  || (item && typeof item === 'object' && typeof item.heading === 'string' && item.heading !== ''))
@@ -7795,8 +7819,11 @@ var script = {
7795
7819
  * manifest-actions-dispatch — `navigate`, `emit`, `none`, or a
7796
7820
  * registry name (resolved through `resolveRegisteredHandler`).
7797
7821
  *
7822
+ * @spec openspec/changes/header-action-href/specs/header-action-href/spec.md#requirement-a-header-action-with-href-is-a-link-that-runs-and-emits-nothing
7798
7823
  * @param {object} entry Raw headerActions entry.
7799
- * @return {object} Possibly-mutated copy: function-typed
7824
+ * @return {object} Possibly-mutated copy: an `href` becomes a
7825
+ * resolved link with `linkTarget`, no handler (a function one
7826
+ * included) and `_dispatchSuppress: true`; function-typed
7800
7827
  * handlers untouched; `'emit'` and unknown registry names
7801
7828
  * strip the `handler` (emit-only fall-through); `'navigate'`
7802
7829
  * becomes a `$router.push` thunk (with the entry's literal
@@ -7808,14 +7835,23 @@ var script = {
7808
7835
  if (!entry) {
7809
7836
  return entry
7810
7837
  }
7838
+ // An `href` makes the entry a link, which only navigates: it
7839
+ // carries no handler, and the page emits nothing for it.
7840
+ if (typeof entry.href === 'string' && entry.href !== '') {
7841
+ const link = headerActionAsLink(entry);
7842
+ return link.href ? { ...link, linkTarget: link.target, _dispatchSuppress: true } : link
7843
+ }
7811
7844
  const handler = entry.handler;
7812
7845
  if (typeof handler === 'function') {
7813
7846
  return { ...entry }
7814
7847
  }
7815
7848
  // `type: "navigate"` with a `target` URL is a link: the bar and the
7816
- // header's Actions menu render it as a real anchor in a new tab.
7849
+ // header's Actions menu render it as a real anchor, an external URL
7850
+ // in a new tab.
7817
7851
  if (typeof handler !== 'string' && entry.type === 'navigate' && typeof entry.target === 'string' && entry.target !== '' && !entry.href) {
7818
- return { ...entry, href: entry.target }
7852
+ return isExternalActionTarget(entry.target)
7853
+ ? { ...entry, href: entry.target, linkTarget: '_blank' }
7854
+ : { ...entry, href: entry.target }
7819
7855
  }
7820
7856
  if (typeof handler !== 'string') {
7821
7857
  // No handler declared — emit-only fall-through.
@@ -7986,8 +8022,9 @@ var script = {
7986
8022
  *
7987
8023
  * @spec openspec/changes/screens-index-header-actions-menu/specs/index-header/spec.md#requirement-the-header-actions-menu-lists-what-its-items-name
7988
8024
  * @spec openspec/changes/screens-index-header-menu-headings/specs/index-header/spec.md#requirement-the-header-actions-menu-can-draw-group-headings-and-separators
8025
+ * @spec openspec/changes/header-action-href/specs/header-action-href/spec.md#requirement-a-header-action-with-href-is-a-link-that-runs-and-emits-nothing
7989
8026
  * @param {{items?: Array<(string|{heading: string})>|null, format?: string}} button The resolved header button.
7990
- * @return {Array<{key: string, label: string, kind?: ('heading'|'separator'), icon?: string, href?: string, disabled?: boolean, title?: string, iconComponent?: object, run?: Function}>}
8027
+ * @return {Array<{key: string, label: string, kind?: ('heading'|'separator'), icon?: string, href?: string, linkTarget?: string, disabled?: boolean, title?: string, iconComponent?: object, run?: () => void}>}
7991
8028
  */
7992
8029
  headerMenuEntries(button) {
7993
8030
  const fromAction = (entry) => ({
@@ -7995,6 +8032,7 @@ var script = {
7995
8032
  label: entry.label ? this.cnTranslate(entry.label) : '',
7996
8033
  icon: entry.icon && typeof entry.icon === 'string' && !entry.icon.startsWith('icon-') ? entry.icon : '',
7997
8034
  href: typeof entry.href === 'string' && entry.href !== '' ? entry.href : '',
8035
+ linkTarget: entry.linkTarget || '',
7998
8036
  // A `handler: "navigate"` entry whose route resolves carries `to`
7999
8037
  // (resolveHeaderHandler drops its handler): the menu draws it as
8000
8038
  // an in-app link, as the actions bar does, so it navigates.
@@ -8028,7 +8066,7 @@ var script = {
8028
8066
  }),
8029
8067
 
8030
8068
  documentation: () => (this.documentationUrl
8031
- ? { key: 'documentation', label: this.documentationLabel || translate('nextcloud-vue', 'Documentation'), icon: 'BookOpenVariantOutline', href: this.documentationUrl }
8069
+ ? { key: 'documentation', label: this.documentationLabel || translate('nextcloud-vue', 'Documentation'), icon: 'BookOpenVariantOutline', href: this.documentationUrl, linkTarget: '_blank' }
8032
8070
  : null),
8033
8071
  };
8034
8072
  const entries = [];
@@ -8124,13 +8162,18 @@ var script = {
8124
8162
 
8125
8163
  /**
8126
8164
  * A header button was clicked: run its built-in action, or dispatch
8127
- * it as the `headerActions` entry with that id.
8165
+ * it as the `headerActions` entry with that id. A button that is a
8166
+ * link is left to the browser.
8128
8167
  *
8129
8168
  * @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-an-index-page-can-take-the-board-header
8130
- * @param {{action: string, format: string}} button The resolved button.
8169
+ * @spec openspec/changes/header-action-href/specs/header-action-href/spec.md#requirement-a-header-action-with-href-is-a-link-that-runs-and-emits-nothing
8170
+ * @param {{action: string, format: string, link?: object}} button The resolved button.
8131
8171
  * @return {void}
8132
8172
  */
8133
8173
  onHeaderButton(button) {
8174
+ if (button.link) {
8175
+ return
8176
+ }
8134
8177
  if (button.action === 'add') {
8135
8178
  this.onAddClick();
8136
8179
  } else if (button.action === 'export') {