@conduction/nextcloud-vue 2.127.0 → 2.128.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 (45) hide show
  1. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  2. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +3 -113
  3. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  4. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +12 -12
  5. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  6. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +34 -1
  7. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  8. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +16 -8
  9. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  10. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +153 -8
  11. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  12. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +169 -58
  13. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  14. package/dist/esm/components/CnTileWidget/CnTileWidget.vue.js +1 -1
  15. package/dist/esm/components/CnTileWidget/CnTileWidget.vue2.js +11 -0
  16. package/dist/esm/components/CnTileWidget/CnTileWidget.vue2.js.map +1 -1
  17. package/dist/esm/components/CnTileWidget/CnTileWidget.vue3.js +14 -4
  18. package/dist/esm/components/CnTileWidget/CnTileWidget.vue3.js.map +1 -1
  19. package/dist/esm/library-style.js +1 -1
  20. package/dist/esm/mixins/pageFilters.js +142 -0
  21. package/dist/esm/mixins/pageFilters.js.map +1 -0
  22. package/dist/esm/nextcloud-vue.css +269 -74
  23. package/dist/esm/utils/actionLink.js +9 -3
  24. package/dist/esm/utils/actionLink.js.map +1 -1
  25. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  26. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  27. package/dist/nextcloud-vue.cjs.js +1176 -828
  28. package/dist/nextcloud-vue.cjs.js.map +2 -2
  29. package/dist/nextcloud-vue.css +269 -74
  30. package/package.json +1 -1
  31. package/src/components/CnDashboardPage/CnDashboardPage.vue +3 -113
  32. package/src/components/CnDataTable/CnDataTable.vue +40 -1
  33. package/src/components/CnDetailPage/CnDetailPage.md +2 -0
  34. package/src/components/CnDetailPage/CnDetailPage.vue +237 -8
  35. package/src/components/CnTileWidget/CnTileWidget.vue +30 -2
  36. package/src/css/detail-page.css +42 -0
  37. package/src/css/dialog.css +13 -0
  38. package/src/css/look-board-detail.css +1 -1
  39. package/src/css/look-board-index.css +8 -0
  40. package/src/css/look-board.css +97 -0
  41. package/src/css/table.css +12 -0
  42. package/src/mixins/pageFilters.js +138 -0
  43. package/src/schemas/app-manifest-v2.schema.json +41 -3
  44. package/src/utils/actionLink.js +9 -3
  45. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -1,4 +1,5 @@
1
1
  import { getRootUrl, generateUrl } from '@nextcloud/router';
2
+ import { interpolateUrlTokens } from './interpolateUrlTokens.js';
2
3
  import { followLinkClick } from './linkNavigation.js';
3
4
 
4
5
  /**
@@ -81,16 +82,21 @@ function resolveManifestHref(href) {
81
82
  * function `handler` is dropped like any other, with a one-time warning.
82
83
  *
83
84
  * @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
85
+ * With `tokenCtx` the `href` first resolves its `@object.<field>`,
86
+ * `@objectId`, `@page.<key>` and `@config.<key>` tokens, so a detail page can
87
+ * link to a URL built from its record (PtPortal "Website bekijken").
88
+ *
84
89
  * @param {object} entry The manifest header action.
90
+ * @param {object|null} [tokenCtx] The token context (`{ objectId?, object?, workspace?, config? }`).
85
91
  * @return {object} The entry, or a copy in link form.
86
92
  */
87
- function headerActionAsLink(entry) {
93
+ function headerActionAsLink(entry, tokenCtx = null) {
88
94
  if (!entry || typeof entry !== 'object') {
89
95
  return entry
90
96
  }
91
97
  let resolved = entry;
92
98
  if (Array.isArray(entry.children)) {
93
- const children = entry.children.map(headerActionAsLink);
99
+ const children = entry.children.map((child) => headerActionAsLink(child, tokenCtx));
94
100
  if (children.some((child, index) => child !== entry.children[index])) {
95
101
  resolved = { ...entry, children };
96
102
  }
@@ -100,7 +106,7 @@ function headerActionAsLink(entry) {
100
106
  }
101
107
  const { href: declared, ...withoutHref } = resolved;
102
108
  const { handler: _handler, ...rest } = withoutHref;
103
- const href = resolveManifestHref(declared);
109
+ const href = resolveManifestHref(tokenCtx ? interpolateUrlTokens(declared, tokenCtx) : declared);
104
110
  if (!href) {
105
111
  if (!warnedHrefs.has(declared)) {
106
112
  warnedHrefs.add(declared);
@@ -1 +1 @@
1
- {"version":3,"file":"actionLink.js","sources":["../../../src/utils/actionLink.js"],"sourcesContent":["/**\n * SPDX-License-Identifier: EUPL-1.2\n * SPDX-FileCopyrightText: 2026 Conduction B.V.\n *\n * actionLink — render a menu/bar action that only navigates as a real link.\n *\n * An action descriptor may carry `href` (a URL) or `to` (a vue-router\n * location), each either a value or a function of the item the menu acts on.\n * The rendering component turns it into an `<a href>`; a plain click on an\n * in-app `to` is routed through the router, anything else is the browser's.\n *\n * A manifest `headerActions[]` entry may carry `href` too; the page turns it\n * into the final URL with {@link headerActionAsLink} before it renders.\n *\n * @module utils/actionLink\n */\n\nimport { generateUrl, getRootUrl } from '@nextcloud/router'\nimport { followLinkClick } from './linkNavigation.js'\n\n/** An absolute URL a manifest link may name, matching the schema's lowercase pattern. */\nconst ABSOLUTE_HREF = /^(?:https?:\\/\\/|mailto:|tel:)/\n\n/** An instance path that already names a Nextcloud entry point, so generateUrl() must not add `/index.php`. */\nconst ROUTED_PATH = /^\\/(?:index\\.php|remote\\.php|public\\.php|ocs)(?:[/?#]|$)/\n\n/** Bad hrefs already warned about, so a recomputing page warns once per value. */\nconst warnedHrefs = new Set()\n\n/**\n * Entries whose function handler was dropped for their href, warned about\n * once. Keyed by `id`, else by the declared href and label (behind a NUL, so\n * no real id collides), so entries without an id each get their own warning\n * and a recomputing page does not repeat it.\n */\nconst warnedHandlers = new Set()\n\n/**\n * The URL a manifest `href` points at: an absolute `http(s)`, `mailto:` or\n * `tel:` URL as written, `//host/...` as written, an instance path that\n * names an entry point (`/index.php/`, `/remote.php/`, `/public.php/`,\n * `/ocs/`) under `getRootUrl()` (as written when it already starts with the\n * root), any other instance path (leading `/`) through `generateUrl()`.\n *\n * @spec openspec/changes/header-action-href/specs/header-action-href/spec.md#requirement-a-header-action-href-resolves-to-a-url-on-this-instance-or-an-allowed-scheme\n * @param {unknown} href The manifest `href`.\n * @return {string} The URL, or '' for anything else (a relative path, another scheme).\n */\nexport function resolveManifestHref(href) {\n\tif (typeof href !== 'string') {\n\t\treturn ''\n\t}\n\tconst value = href.trim()\n\tif (ABSOLUTE_HREF.test(value) || value.startsWith('//')) {\n\t\treturn value\n\t}\n\tconst root = getRootUrl()\n\tif (root && value.startsWith(root) && ROUTED_PATH.test(value.slice(root.length))) {\n\t\treturn value\n\t}\n\tif (ROUTED_PATH.test(value)) {\n\t\treturn root + value\n\t}\n\tif (value.startsWith('/')) {\n\t\treturn generateUrl(value)\n\t}\n\treturn ''\n}\n\n/**\n * A manifest header action in its link form. An entry with `href` gets the\n * resolved URL and an anchor `target` (`_blank` when the manifest says so,\n * else `_self`), and loses its `handler`: a link only navigates. Its\n * `children` are resolved the same way. An `href` that resolves to nothing is\n * dropped with a warning, along with a handler name, so the page renders its\n * usual button for the entry (an index or reports page still emits\n * `header-action` for it); a function `handler` (JS composition) is kept\n * then and still runs. An entry with nothing to resolve, a function-valued\n * `href` included, is returned as is. When the `href` does resolve, a\n * function `handler` is dropped like any other, with a one-time warning.\n *\n * @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\n * @param {object} entry The manifest header action.\n * @return {object} The entry, or a copy in link form.\n */\nexport function headerActionAsLink(entry) {\n\tif (!entry || typeof entry !== 'object') {\n\t\treturn entry\n\t}\n\tlet resolved = entry\n\tif (Array.isArray(entry.children)) {\n\t\tconst children = entry.children.map(headerActionAsLink)\n\t\tif (children.some((child, index) => child !== entry.children[index])) {\n\t\t\tresolved = { ...entry, children }\n\t\t}\n\t}\n\tif (typeof entry.href !== 'string' || entry.href === '') {\n\t\treturn resolved\n\t}\n\tconst { href: declared, ...withoutHref } = resolved\n\tconst { handler: _handler, ...rest } = withoutHref\n\tconst href = resolveManifestHref(declared)\n\tif (!href) {\n\t\tif (!warnedHrefs.has(declared)) {\n\t\t\twarnedHrefs.add(declared)\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(`headerActions[].id \"${entry.id}\": href \"${declared}\" is neither an http(s), mailto or tel URL nor an instance path starting with \"/\"; the entry renders without a link`)\n\t\t}\n\t\treturn typeof entry.handler === 'function' ? withoutHref : rest\n\t}\n\tconst handlerKey = entry.id ?? `\\u0000${declared}|${entry.label ?? ''}`\n\tif (typeof entry.handler === 'function' && !warnedHandlers.has(handlerKey)) {\n\t\twarnedHandlers.add(handlerKey)\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.warn(`headerActions[].id \"${entry.id}\": an entry with href never runs a handler, so its function handler is dropped`)\n\t}\n\treturn { ...rest, href, target: entry.target === '_blank' ? '_blank' : '_self' }\n}\n\n/**\n * The href of an in-app router location. A string is a route PATH and goes\n * through the router as well, so a hash-history app gets its `#`.\n *\n * @param {string|object|null|undefined} to A route path or vue-router location.\n * @param {object} [router] The app's router.\n * @return {string} The href, or '' when there is no router or it cannot resolve.\n */\nexport function routeHref(to, router) {\n\tif (!to || !router || typeof router.resolve !== 'function') {\n\t\treturn ''\n\t}\n\t// A path string, unlike resolveHref's finished URL; resolved as a string so its query survives.\n\ttry {\n\t\treturn router.resolve(to).href || ''\n\t} catch {\n\t\treturn ''\n\t}\n}\n\n/**\n * The link an action descriptor renders as for one item, or null when it\n * renders as a button: no `href` / `to`, or a `to` the router cannot resolve.\n *\n * @param {object} action The action descriptor (`href`, `to`, `linkTarget`).\n * @param {unknown} item The row / target item a function-valued field is called with.\n * @param {object} [router] The app's router.\n * @return {{href: string, to: (string|object|null), target: (string|undefined)}|null} The link, or null.\n */\nexport function resolveItemActionLink(action, item, router) {\n\tif (!action) {\n\t\treturn null\n\t}\n\tconst target = action.linkTarget || undefined\n\tconst href = typeof action.href === 'function' ? action.href(item) : action.href\n\tif (typeof href === 'string' && href.length > 0) {\n\t\treturn { href, to: null, target }\n\t}\n\tconst to = typeof action.to === 'function' ? action.to(item) : action.to\n\tconst resolved = routeHref(to, router)\n\treturn resolved ? { href: resolved, to, target } : null\n}\n\n/**\n * Click handler for a link from {@link resolveItemActionLink}: a plain click\n * on an in-app link that opens in place goes through the router; a URL, a\n * new-tab target or a modified click is left to the browser.\n *\n * Hand-rolled rather than `NcActionRouter` / `NcButton :to`: the menus and\n * bars using it must still emit their own events on click, and without an\n * installed router `NcButton :to` falls back to a button that goes nowhere,\n * while an `<a href>` still navigates.\n *\n * @param {MouseEvent} event The click event.\n * @param {{to: (string|object|null), target: (string|undefined)}} link The resolved link.\n * @param {object} [router] The app's router.\n * @return {boolean} True when the router navigated.\n */\nexport function followItemActionLink(event, link, router) {\n\tif (!link || !link.to || (link.target && link.target !== '_self')) {\n\t\treturn false\n\t}\n\treturn followLinkClick(event, link.to, router)\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"actionLink.js","sources":["../../../src/utils/actionLink.js"],"sourcesContent":["/**\n * SPDX-License-Identifier: EUPL-1.2\n * SPDX-FileCopyrightText: 2026 Conduction B.V.\n *\n * actionLink — render a menu/bar action that only navigates as a real link.\n *\n * An action descriptor may carry `href` (a URL) or `to` (a vue-router\n * location), each either a value or a function of the item the menu acts on.\n * The rendering component turns it into an `<a href>`; a plain click on an\n * in-app `to` is routed through the router, anything else is the browser's.\n *\n * A manifest `headerActions[]` entry may carry `href` too; the page turns it\n * into the final URL with {@link headerActionAsLink} before it renders.\n *\n * @module utils/actionLink\n */\n\nimport { generateUrl, getRootUrl } from '@nextcloud/router'\nimport { interpolateUrlTokens } from './interpolateUrlTokens.js'\nimport { followLinkClick } from './linkNavigation.js'\n\n/** An absolute URL a manifest link may name, matching the schema's lowercase pattern. */\nconst ABSOLUTE_HREF = /^(?:https?:\\/\\/|mailto:|tel:)/\n\n/** An instance path that already names a Nextcloud entry point, so generateUrl() must not add `/index.php`. */\nconst ROUTED_PATH = /^\\/(?:index\\.php|remote\\.php|public\\.php|ocs)(?:[/?#]|$)/\n\n/** Bad hrefs already warned about, so a recomputing page warns once per value. */\nconst warnedHrefs = new Set()\n\n/**\n * Entries whose function handler was dropped for their href, warned about\n * once. Keyed by `id`, else by the declared href and label (behind a NUL, so\n * no real id collides), so entries without an id each get their own warning\n * and a recomputing page does not repeat it.\n */\nconst warnedHandlers = new Set()\n\n/**\n * The URL a manifest `href` points at: an absolute `http(s)`, `mailto:` or\n * `tel:` URL as written, `//host/...` as written, an instance path that\n * names an entry point (`/index.php/`, `/remote.php/`, `/public.php/`,\n * `/ocs/`) under `getRootUrl()` (as written when it already starts with the\n * root), any other instance path (leading `/`) through `generateUrl()`.\n *\n * @spec openspec/changes/header-action-href/specs/header-action-href/spec.md#requirement-a-header-action-href-resolves-to-a-url-on-this-instance-or-an-allowed-scheme\n * @param {unknown} href The manifest `href`.\n * @return {string} The URL, or '' for anything else (a relative path, another scheme).\n */\nexport function resolveManifestHref(href) {\n\tif (typeof href !== 'string') {\n\t\treturn ''\n\t}\n\tconst value = href.trim()\n\tif (ABSOLUTE_HREF.test(value) || value.startsWith('//')) {\n\t\treturn value\n\t}\n\tconst root = getRootUrl()\n\tif (root && value.startsWith(root) && ROUTED_PATH.test(value.slice(root.length))) {\n\t\treturn value\n\t}\n\tif (ROUTED_PATH.test(value)) {\n\t\treturn root + value\n\t}\n\tif (value.startsWith('/')) {\n\t\treturn generateUrl(value)\n\t}\n\treturn ''\n}\n\n/**\n * A manifest header action in its link form. An entry with `href` gets the\n * resolved URL and an anchor `target` (`_blank` when the manifest says so,\n * else `_self`), and loses its `handler`: a link only navigates. Its\n * `children` are resolved the same way. An `href` that resolves to nothing is\n * dropped with a warning, along with a handler name, so the page renders its\n * usual button for the entry (an index or reports page still emits\n * `header-action` for it); a function `handler` (JS composition) is kept\n * then and still runs. An entry with nothing to resolve, a function-valued\n * `href` included, is returned as is. When the `href` does resolve, a\n * function `handler` is dropped like any other, with a one-time warning.\n *\n * @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\n * With `tokenCtx` the `href` first resolves its `@object.<field>`,\n * `@objectId`, `@page.<key>` and `@config.<key>` tokens, so a detail page can\n * link to a URL built from its record (PtPortal \"Website bekijken\").\n *\n * @param {object} entry The manifest header action.\n * @param {object|null} [tokenCtx] The token context (`{ objectId?, object?, workspace?, config? }`).\n * @return {object} The entry, or a copy in link form.\n */\nexport function headerActionAsLink(entry, tokenCtx = null) {\n\tif (!entry || typeof entry !== 'object') {\n\t\treturn entry\n\t}\n\tlet resolved = entry\n\tif (Array.isArray(entry.children)) {\n\t\tconst children = entry.children.map((child) => headerActionAsLink(child, tokenCtx))\n\t\tif (children.some((child, index) => child !== entry.children[index])) {\n\t\t\tresolved = { ...entry, children }\n\t\t}\n\t}\n\tif (typeof entry.href !== 'string' || entry.href === '') {\n\t\treturn resolved\n\t}\n\tconst { href: declared, ...withoutHref } = resolved\n\tconst { handler: _handler, ...rest } = withoutHref\n\tconst href = resolveManifestHref(tokenCtx ? interpolateUrlTokens(declared, tokenCtx) : declared)\n\tif (!href) {\n\t\tif (!warnedHrefs.has(declared)) {\n\t\t\twarnedHrefs.add(declared)\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(`headerActions[].id \"${entry.id}\": href \"${declared}\" is neither an http(s), mailto or tel URL nor an instance path starting with \"/\"; the entry renders without a link`)\n\t\t}\n\t\treturn typeof entry.handler === 'function' ? withoutHref : rest\n\t}\n\tconst handlerKey = entry.id ?? `\\u0000${declared}|${entry.label ?? ''}`\n\tif (typeof entry.handler === 'function' && !warnedHandlers.has(handlerKey)) {\n\t\twarnedHandlers.add(handlerKey)\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.warn(`headerActions[].id \"${entry.id}\": an entry with href never runs a handler, so its function handler is dropped`)\n\t}\n\treturn { ...rest, href, target: entry.target === '_blank' ? '_blank' : '_self' }\n}\n\n/**\n * The href of an in-app router location. A string is a route PATH and goes\n * through the router as well, so a hash-history app gets its `#`.\n *\n * @param {string|object|null|undefined} to A route path or vue-router location.\n * @param {object} [router] The app's router.\n * @return {string} The href, or '' when there is no router or it cannot resolve.\n */\nexport function routeHref(to, router) {\n\tif (!to || !router || typeof router.resolve !== 'function') {\n\t\treturn ''\n\t}\n\t// A path string, unlike resolveHref's finished URL; resolved as a string so its query survives.\n\ttry {\n\t\treturn router.resolve(to).href || ''\n\t} catch {\n\t\treturn ''\n\t}\n}\n\n/**\n * The link an action descriptor renders as for one item, or null when it\n * renders as a button: no `href` / `to`, or a `to` the router cannot resolve.\n *\n * @param {object} action The action descriptor (`href`, `to`, `linkTarget`).\n * @param {unknown} item The row / target item a function-valued field is called with.\n * @param {object} [router] The app's router.\n * @return {{href: string, to: (string|object|null), target: (string|undefined)}|null} The link, or null.\n */\nexport function resolveItemActionLink(action, item, router) {\n\tif (!action) {\n\t\treturn null\n\t}\n\tconst target = action.linkTarget || undefined\n\tconst href = typeof action.href === 'function' ? action.href(item) : action.href\n\tif (typeof href === 'string' && href.length > 0) {\n\t\treturn { href, to: null, target }\n\t}\n\tconst to = typeof action.to === 'function' ? action.to(item) : action.to\n\tconst resolved = routeHref(to, router)\n\treturn resolved ? { href: resolved, to, target } : null\n}\n\n/**\n * Click handler for a link from {@link resolveItemActionLink}: a plain click\n * on an in-app link that opens in place goes through the router; a URL, a\n * new-tab target or a modified click is left to the browser.\n *\n * Hand-rolled rather than `NcActionRouter` / `NcButton :to`: the menus and\n * bars using it must still emit their own events on click, and without an\n * installed router `NcButton :to` falls back to a button that goes nowhere,\n * while an `<a href>` still navigates.\n *\n * @param {MouseEvent} event The click event.\n * @param {{to: (string|object|null), target: (string|undefined)}} link The resolved link.\n * @param {object} [router] The app's router.\n * @return {boolean} True when the router navigated.\n */\nexport function followItemActionLink(event, link, router) {\n\tif (!link || !link.to || (link.target && link.target !== '_self')) {\n\t\treturn false\n\t}\n\treturn followLinkClick(event, link.to, router)\n}\n"],"names":[],"mappings":"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"}