@conduction/nextcloud-vue 2.75.0 → 2.76.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 (67) hide show
  1. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js +6 -0
  2. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js.map +1 -1
  3. package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js +3 -2
  4. package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js.map +1 -1
  5. package/dist/esm/components/CnCredentials/CnCredentials.vue2.js +11 -10
  6. package/dist/esm/components/CnCredentials/CnCredentials.vue2.js.map +1 -1
  7. package/dist/esm/components/CnCredentials/CnCredentials.vue3.js.map +1 -1
  8. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +8 -5
  9. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  10. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  11. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +144 -6
  12. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  13. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +12 -11
  14. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  15. package/dist/esm/components/CnIndexPage/selfModeActions.js +90 -14
  16. package/dist/esm/components/CnIndexPage/selfModeActions.js.map +1 -1
  17. package/dist/esm/components/CnIndexPage/useSelfFetchList.js +15 -3
  18. package/dist/esm/components/CnIndexPage/useSelfFetchList.js.map +1 -1
  19. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js +26 -0
  20. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js.map +1 -1
  21. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js +26 -9
  22. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js.map +1 -1
  23. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +19 -3
  24. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  25. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  26. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js +153 -38
  27. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js.map +1 -1
  28. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue3.js +74 -56
  29. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue3.js.map +1 -1
  30. package/dist/esm/composables/useObjectLock.js +41 -10
  31. package/dist/esm/composables/useObjectLock.js.map +1 -1
  32. package/dist/esm/index.js +1 -0
  33. package/dist/esm/index.js.map +1 -1
  34. package/dist/esm/l10n/en.json.js +7 -1
  35. package/dist/esm/l10n/en.json.js.map +1 -1
  36. package/dist/esm/l10n/nl.json.js +8 -2
  37. package/dist/esm/l10n/nl.json.js.map +1 -1
  38. package/dist/esm/nextcloud-vue.css +88 -1
  39. package/dist/esm/store/useObjectStore.js +37 -9
  40. package/dist/esm/store/useObjectStore.js.map +1 -1
  41. package/dist/esm/utils/objectSignals.js +44 -0
  42. package/dist/esm/utils/objectSignals.js.map +1 -0
  43. package/dist/nextcloud-vue.cjs.js +871 -328
  44. package/dist/nextcloud-vue.cjs.js.map +2 -2
  45. package/dist/nextcloud-vue.css +88 -1
  46. package/l10n/en.json +7 -1
  47. package/l10n/nl.json +8 -2
  48. package/package.json +1 -1
  49. package/src/components/CnCardGrid/CnCardGrid.md +1 -0
  50. package/src/components/CnCardGrid/CnCardGrid.vue +7 -0
  51. package/src/components/CnCredentials/CnCredentials.vue +17 -16
  52. package/src/components/CnDetailPage/CnDetailPage.vue +8 -5
  53. package/src/components/CnIndexPage/CnIndexPage.md +15 -0
  54. package/src/components/CnIndexPage/CnIndexPage.vue +155 -16
  55. package/src/components/CnIndexPage/selfModeActions.js +89 -13
  56. package/src/components/CnIndexPage/useSelfFetchList.js +15 -3
  57. package/src/components/CnObjectCard/CnObjectCard.md +1 -0
  58. package/src/components/CnObjectCard/CnObjectCard.vue +89 -1
  59. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +19 -3
  60. package/src/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue +181 -38
  61. package/src/composables/__tests__/useObjectLock.endpoints.spec.js +83 -0
  62. package/src/composables/useObjectLock.js +41 -10
  63. package/src/css/look-board-index.css +35 -1
  64. package/src/index.js +1 -0
  65. package/src/store/useObjectStore.js +37 -9
  66. package/src/utils/index.js +1 -0
  67. package/src/utils/objectSignals.js +41 -0
@@ -5021,9 +5021,10 @@ const baseActions = {
5021
5021
  * @param {object} [slugs] Optional slug hints for live-updates transport
5022
5022
  * @param {string|null} [slugs.registerSlug] Canonical register slug (e.g. 'zaken')
5023
5023
  * @param {string|null} [slugs.schemaSlug] Canonical schema slug (e.g. 'meldingen')
5024
+ * @param {string} [slugs.collectionUrl] Endpoint `fetchCollection` lists from instead of `/register/schema`; every other call keeps the pair URL
5024
5025
  */
5025
5026
  registerObjectType(slug, schemaId, registerId, slugs = {}) {
5026
- const { registerSlug = null, schemaSlug = null } = slugs;
5027
+ const { registerSlug = null, schemaSlug = null, collectionUrl = null } = slugs;
5027
5028
  // Replace entire objects so Vue 2 reactivity detects the change
5028
5029
  // (Vue 2 cannot track new properties added to existing reactive objects)
5029
5030
  this.objectTypeRegistry = {
@@ -5033,6 +5034,7 @@ const baseActions = {
5033
5034
  register: registerId,
5034
5035
  registerSlug,
5035
5036
  schemaSlug,
5037
+ ...(collectionUrl ? { collectionUrl } : {}),
5036
5038
  },
5037
5039
  };
5038
5040
  this.collections = { ...this.collections, [slug]: [] };
@@ -5277,6 +5279,31 @@ const baseActions = {
5277
5279
  return url
5278
5280
  },
5279
5281
 
5282
+ /**
5283
+ * Build the list URL for a type registered with a `collectionUrl`. `_order`
5284
+ * goes in the bracket form (`_order[key]=dir`) every PHP endpoint parses.
5285
+ *
5286
+ * @param {object} config The type config
5287
+ * @param {object} [params] Query parameters
5288
+ * @return {string} Full URL including query string
5289
+ */
5290
+ _buildCollectionUrl(config, params = {}) {
5291
+ const { _order: order, ...rest } = params;
5292
+ const merged = { ...rest };
5293
+ if (order && typeof order === 'object') {
5294
+ for (const [key, dir] of Object.entries(order)) {
5295
+ merged[`_order[${key}]`] = dir;
5296
+ }
5297
+ }
5298
+ const lang = this._resolveLanguage();
5299
+ if (lang) {
5300
+ merged._lang = lang;
5301
+ }
5302
+ const url = prefixUrl(config.collectionUrl);
5303
+ const query = buildQueryString(merged);
5304
+ return query && url.includes('?') ? url + '&' + query.slice(1) : url + query
5305
+ },
5306
+
5280
5307
  /**
5281
5308
  * Fetch for a type, retrying ONCE with its `schemaFallback` when the
5282
5309
  * schema path segment answers 404. A type without a fallback (every type
@@ -5466,14 +5493,15 @@ const baseActions = {
5466
5493
  }
5467
5494
  }
5468
5495
 
5469
- const response = await this._fetchWithSchemaFallback(
5470
- type,
5471
- (schema) => this._buildUrlWithParams(type, fetchParams, null, schema),
5472
- {
5473
- method: 'GET',
5474
- headers: this._buildHeaders(),
5475
- },
5476
- );
5496
+ const config = this._getTypeConfig(type);
5497
+ const init = { method: 'GET', headers: this._buildHeaders() };
5498
+ const response = config.collectionUrl
5499
+ ? await trackedFetch(this._buildCollectionUrl(config, fetchParams), init)
5500
+ : await this._fetchWithSchemaFallback(
5501
+ type,
5502
+ (schema) => this._buildUrlWithParams(type, fetchParams, null, schema),
5503
+ init,
5504
+ );
5477
5505
 
5478
5506
  if (!response.ok) {
5479
5507
  const failure = await parseResponseError(response, type);
@@ -11476,7 +11504,7 @@ const _hoisted_6$47 = { class: "cn-conversation-thread__bubble" };
11476
11504
  const _hoisted_7$3F = { class: "cn-conversation-thread__meta" };
11477
11505
  const _hoisted_8$3l = { class: "cn-conversation-thread__author" };
11478
11506
  const _hoisted_9$33 = ["datetime"];
11479
- const _hoisted_10$2J = { class: "cn-conversation-thread__text" };
11507
+ const _hoisted_10$2K = { class: "cn-conversation-thread__text" };
11480
11508
  const _hoisted_11$2k = ["for"];
11481
11509
  const _hoisted_12$23 = ["id", "placeholder", "disabled", "aria-describedby"];
11482
11510
  const _hoisted_13$1W = ["id"];
@@ -11524,7 +11552,7 @@ function render$76(_ctx, _cache, $props, $setup, $data, $options) {
11524
11552
  }, vue$1.toDisplayString(row.timeLabel), 9 /* TEXT, PROPS */, _hoisted_9$33))
11525
11553
  : vue$1.createCommentVNode("v-if", true)
11526
11554
  ]),
11527
- vue$1.createElementVNode("span", _hoisted_10$2J, vue$1.toDisplayString(row.text), 1 /* TEXT */)
11555
+ vue$1.createElementVNode("span", _hoisted_10$2K, vue$1.toDisplayString(row.text), 1 /* TEXT */)
11528
11556
  ])
11529
11557
  ], 10 /* CLASS, PROPS */, _hoisted_4$55))
11530
11558
  }), 128 /* KEYED_FRAGMENT */))
@@ -17424,7 +17452,7 @@ const _hoisted_6$43 = {
17424
17452
  const _hoisted_7$3C = { class: "cn-column-filter__options" };
17425
17453
  const _hoisted_8$3i = { class: "cn-column-filter__sr-only" };
17426
17454
  const _hoisted_9$30 = ["value", "checked", "onChange"];
17427
- const _hoisted_10$2I = {
17455
+ const _hoisted_10$2J = {
17428
17456
  key: 0,
17429
17457
  class: "cn-column-filter__hint"
17430
17458
  };
@@ -17511,7 +17539,7 @@ function render$6T(_ctx, _cache, $props, $setup, $data, $options) {
17511
17539
  ]))
17512
17540
  }), 128 /* KEYED_FRAGMENT */)),
17513
17541
  ($options.listOptions.length === 0 && !$data.referenceLoading)
17514
- ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_10$2I, vue$1.toDisplayString($options.noOptionsLabel), 1 /* TEXT */))
17542
+ ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_10$2J, vue$1.toDisplayString($options.noOptionsLabel), 1 /* TEXT */))
17515
17543
  : vue$1.createCommentVNode("v-if", true)
17516
17544
  ])
17517
17545
  ], 64 /* STABLE_FRAGMENT */))
@@ -20705,7 +20733,7 @@ const _hoisted_9$2$ = {
20705
20733
  class: "cn-cell-renderer__avatar-picture",
20706
20734
  "aria-hidden": "true"
20707
20735
  };
20708
- const _hoisted_10$2H = ["title"];
20736
+ const _hoisted_10$2I = ["title"];
20709
20737
  const _hoisted_11$2i = {
20710
20738
  key: 1,
20711
20739
  class: "cn-cell-renderer__dash"
@@ -20868,7 +20896,7 @@ function render$6R(_ctx, _cache, $props, $setup, $data, $options) {
20868
20896
  vue$1.createElementVNode("span", {
20869
20897
  class: "cn-cell-renderer__avatar-name",
20870
20898
  title: $options.avatarName || $options.avatarUserId
20871
- }, vue$1.toDisplayString($options.avatarName || $options.avatarUserId), 9 /* TEXT, PROPS */, _hoisted_10$2H)
20899
+ }, vue$1.toDisplayString($options.avatarName || $options.avatarUserId), 9 /* TEXT, PROPS */, _hoisted_10$2I)
20872
20900
  ]))
20873
20901
  : (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_11$2i, "—"))
20874
20902
  ], 64 /* STABLE_FRAGMENT */))
@@ -23080,7 +23108,7 @@ const _hoisted_6$41 = {
23080
23108
  const _hoisted_7$3A = ["tabindex", "role", "aria-label"];
23081
23109
  const _hoisted_8$3g = { key: 0 };
23082
23110
  const _hoisted_9$2_ = ["tabindex", "aria-sort", "data-filtered", "title", "onClick", "onKeydown"];
23083
- const _hoisted_10$2G = {
23111
+ const _hoisted_10$2H = {
23084
23112
  key: 0,
23085
23113
  class: "cn-table-sort-indicator"
23086
23114
  };
@@ -23256,7 +23284,7 @@ function render$6O(_ctx, _cache, $props, $setup, $data, $options) {
23256
23284
  class: vue$1.normalizeClass(col.description ? 'cn-table-header--described' : '')
23257
23285
  }, vue$1.toDisplayString($options.translateLabel(col.label)), 3 /* TEXT, CLASS */),
23258
23286
  (col.sortable && $options.sortKeyIndex(col.key) !== -1)
23259
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$2G, vue$1.toDisplayString($options.effectiveSortKeys[$options.sortKeyIndex(col.key)].order === 'asc' ? '▲' : '▼'), 1 /* TEXT */))
23287
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$2H, vue$1.toDisplayString($options.effectiveSortKeys[$options.sortKeyIndex(col.key)].order === 'asc' ? '▲' : '▼'), 1 /* TEXT */))
23260
23288
  : vue$1.createCommentVNode("v-if", true),
23261
23289
  (col.sortable && $options.sortBadgeFor(col.key) !== null)
23262
23290
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_11$2h, vue$1.toDisplayString($options.sortBadgeFor(col.key)), 1 /* TEXT */))
@@ -24034,7 +24062,7 @@ const _hoisted_6$40 = { class: "cn-child-records-field__sr" };
24034
24062
  const _hoisted_7$3z = { key: 0 };
24035
24063
  const _hoisted_8$3f = ["colspan"];
24036
24064
  const _hoisted_9$2Z = { key: 1 };
24037
- const _hoisted_10$2F = {
24065
+ const _hoisted_10$2G = {
24038
24066
  key: 0,
24039
24067
  class: "cn-child-records-field__actions"
24040
24068
  };
@@ -24124,7 +24152,7 @@ function render$6M(_ctx, _cache, $props, $setup, $data, $options) {
24124
24152
  ]))
24125
24153
  }), 128 /* KEYED_FRAGMENT */)),
24126
24154
  (!$props.disabled)
24127
- ? (vue$1.openBlock(), vue$1.createElementBlock("td", _hoisted_10$2F, [
24155
+ ? (vue$1.openBlock(), vue$1.createElementBlock("td", _hoisted_10$2G, [
24128
24156
  vue$1.createVNode(_component_NcButton, {
24129
24157
  variant: "tertiary",
24130
24158
  "aria-label": $options.t('nextcloud-vue', 'Edit row {n}', { n: index + 1 }),
@@ -25829,7 +25857,7 @@ const _hoisted_9$2Y = {
25829
25857
  key: 1,
25830
25858
  class: "cn-file-field__item-note"
25831
25859
  };
25832
- const _hoisted_10$2E = {
25860
+ const _hoisted_10$2F = {
25833
25861
  key: 3,
25834
25862
  class: "cn-file-field__name",
25835
25863
  "data-testid": "cn-file-field-name"
@@ -25957,7 +25985,7 @@ function render$6G(_ctx, _cache, $props, $setup, $data, $options) {
25957
25985
  ]))
25958
25986
  : vue$1.createCommentVNode("v-if", true),
25959
25987
  (!$props.multiple && $options.displayName)
25960
- ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_10$2E, vue$1.toDisplayString($options.displayName), 1 /* TEXT */))
25988
+ ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_10$2F, vue$1.toDisplayString($options.displayName), 1 /* TEXT */))
25961
25989
  : vue$1.createCommentVNode("v-if", true),
25962
25990
  ($options.shownError)
25963
25991
  ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_11$2f, vue$1.toDisplayString($options.shownError), 1 /* TEXT */))
@@ -59099,7 +59127,7 @@ const _hoisted_6$3Z = ["d"];
59099
59127
  const _hoisted_7$3x = { class: "cn-icon-browser-panel__preview-label" };
59100
59128
  const _hoisted_8$3d = ["title", "aria-label"];
59101
59129
  const _hoisted_9$2X = ["aria-label"];
59102
- const _hoisted_10$2D = ["id", "aria-selected", "aria-controls", "tabindex", "onClick", "onKeydown"];
59130
+ const _hoisted_10$2E = ["id", "aria-selected", "aria-controls", "tabindex", "onClick", "onKeydown"];
59103
59131
  const _hoisted_11$2e = ["id", "role", "aria-labelledby"];
59104
59132
  const _hoisted_12$1_ = ["placeholder", "aria-label"];
59105
59133
  const _hoisted_13$1R = {
@@ -59230,7 +59258,7 @@ function render$6D(_ctx, _cache, $props, $setup, $data, $options) {
59230
59258
  class: vue$1.normalizeClass(["cn-icon-browser-panel__tab", { 'cn-icon-browser-panel__tab--active': $data.mode === tab.key }]),
59231
59259
  onClick: $event => ($data.mode = tab.key),
59232
59260
  onKeydown: $event => ($options.onTabKeydown($event, index))
59233
- }, vue$1.toDisplayString(tab.label), 43 /* TEXT, CLASS, PROPS, NEED_HYDRATION */, _hoisted_10$2D))
59261
+ }, vue$1.toDisplayString(tab.label), 43 /* TEXT, CLASS, PROPS, NEED_HYDRATION */, _hoisted_10$2E))
59234
59262
  }), 128 /* KEYED_FRAGMENT */))
59235
59263
  ], 8 /* PROPS */, _hoisted_9$2X))
59236
59264
  : vue$1.createCommentVNode("v-if", true),
@@ -69538,6 +69566,48 @@ function foldAuditTrailEntries(entries) {
69538
69566
  return { oldState, newState }
69539
69567
  }
69540
69568
 
69569
+ /**
69570
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
69571
+ * SPDX-License-Identifier: EUPL-1.2
69572
+ *
69573
+ * Signal that objects changed outside the surface showing them, such as files
69574
+ * uploaded or an object saved from an app's own modal. CnIndexPage listens and
69575
+ * refreshes its list when the register and schema match.
69576
+ *
69577
+ * @module utils/objectSignals
69578
+ */
69579
+
69580
+ const OBJECTS_CHANGED_EVENT = 'cn:objects-changed';
69581
+
69582
+ /**
69583
+ * Announce that objects of a register and schema changed.
69584
+ *
69585
+ * Pass the same register and schema identifiers (slug or id) the listing page
69586
+ * uses. Leaving one out matches every page on that part.
69587
+ *
69588
+ * @param {object} [payload] What changed.
69589
+ * @param {string|number} [payload.register] The register slug or id.
69590
+ * @param {string|number} [payload.schema] The schema slug or id.
69591
+ * @param {string} [payload.id] The changed object's id, when there is one.
69592
+ * @return {boolean} True when the event was dispatched.
69593
+ */
69594
+ function dispatchObjectsChanged({ register, schema, id } = {}) {
69595
+ if (typeof window === 'undefined') {
69596
+ return false
69597
+ }
69598
+ const detail = {
69599
+ register: register === undefined || register === null || register === '' ? null : String(register),
69600
+ schema: schema === undefined || schema === null || schema === '' ? null : String(schema),
69601
+ id: id ? String(id) : null,
69602
+ };
69603
+ try {
69604
+ window.dispatchEvent(new CustomEvent(OBJECTS_CHANGED_EVENT, { detail }));
69605
+ return true
69606
+ } catch {
69607
+ return false
69608
+ }
69609
+ }
69610
+
69541
69611
  const VALID_SURFACES$j = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity'];
69542
69612
  const COMPACT_LIMIT$b = 4;
69543
69613
 
@@ -69857,7 +69927,7 @@ const _hoisted_8$3c = {
69857
69927
  class: "cn-activity-card__headline"
69858
69928
  };
69859
69929
  const _hoisted_9$2W = { class: "cn-activity-card__headline-line" };
69860
- const _hoisted_10$2C = {
69930
+ const _hoisted_10$2D = {
69861
69931
  key: 0,
69862
69932
  class: "cn-activity-card__headline-recent"
69863
69933
  };
@@ -69925,7 +69995,7 @@ function render$6w(_ctx, _cache, $props, $setup, $data, $options) {
69925
69995
  vue$1.createElementVNode("strong", null, vue$1.toDisplayString($options.headlineLabel), 1 /* TEXT */)
69926
69996
  ]),
69927
69997
  ($options.mostRecent)
69928
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2C, [
69998
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2D, [
69929
69999
  (vue$1.openBlock(), vue$1.createBlock(vue$1.resolveDynamicComponent($options.iconFor($options.mostRecent)), { size: 14 })),
69930
70000
  vue$1.createElementVNode("span", _hoisted_11$2d, vue$1.toDisplayString($options.actorFor($options.mostRecent)), 1 /* TEXT */),
69931
70001
  _cache[1] || (_cache[1] = vue$1.createElementVNode("span", { class: "cn-activity-card__chip-sep" }, "·", -1 /* CACHED */)),
@@ -70848,7 +70918,7 @@ const _hoisted_7$3u = {
70848
70918
  };
70849
70919
  const _hoisted_8$3b = ["aria-label"];
70850
70920
  const _hoisted_9$2V = ["aria-pressed", "data-testid", "onClick"];
70851
- const _hoisted_10$2B = ["data-testid"];
70921
+ const _hoisted_10$2C = ["data-testid"];
70852
70922
  const _hoisted_11$2c = { class: "cn-activity-tab__filter-row" };
70853
70923
  const _hoisted_12$1Y = {
70854
70924
  key: 0,
@@ -70918,8 +70988,8 @@ const _hoisted_42$2 = {
70918
70988
  "aria-hidden": "true"
70919
70989
  };
70920
70990
  const _hoisted_43$2 = { class: "cn-activity-tab__event-body" };
70921
- const _hoisted_44$1 = { class: "cn-activity-tab__event-line" };
70922
- const _hoisted_45$1 = { class: "cn-activity-tab__event-meta" };
70991
+ const _hoisted_44$2 = { class: "cn-activity-tab__event-line" };
70992
+ const _hoisted_45$2 = { class: "cn-activity-tab__event-meta" };
70923
70993
  const _hoisted_46$1 = {
70924
70994
  key: 0,
70925
70995
  class: "cn-activity-tab__footer"
@@ -71022,7 +71092,7 @@ function render$6v(_ctx, _cache, $props, $setup, $data, $options) {
71022
71092
  vue$1.createElementVNode("span", {
71023
71093
  class: "cn-activity-tab__kind-count",
71024
71094
  "data-testid": `cn-activity-kind-count-${kind}`
71025
- }, vue$1.toDisplayString($options.kindCount(kind)), 9 /* TEXT, PROPS */, _hoisted_10$2B)
71095
+ }, vue$1.toDisplayString($options.kindCount(kind)), 9 /* TEXT, PROPS */, _hoisted_10$2C)
71026
71096
  ], 10 /* CLASS, PROPS */, _hoisted_9$2V))
71027
71097
  }), 128 /* KEYED_FRAGMENT */))
71028
71098
  ], 8 /* PROPS */, _hoisted_8$3b))
@@ -71181,11 +71251,11 @@ function render$6v(_ctx, _cache, $props, $setup, $data, $options) {
71181
71251
  (vue$1.openBlock(), vue$1.createBlock(vue$1.resolveDynamicComponent($options.iconFor(entry)), { size: 18 }))
71182
71252
  ]),
71183
71253
  vue$1.createElementVNode("div", _hoisted_43$2, [
71184
- vue$1.createElementVNode("p", _hoisted_44$1, [
71254
+ vue$1.createElementVNode("p", _hoisted_44$2, [
71185
71255
  vue$1.createElementVNode("strong", null, vue$1.toDisplayString($options.splitSubject(entry).verb), 1 /* TEXT */),
71186
71256
  vue$1.createTextVNode(vue$1.toDisplayString($options.splitSubject(entry).rest), 1 /* TEXT */)
71187
71257
  ]),
71188
- vue$1.createElementVNode("p", _hoisted_45$1, vue$1.toDisplayString($options.eventMeta(entry)), 1 /* TEXT */)
71258
+ vue$1.createElementVNode("p", _hoisted_45$2, vue$1.toDisplayString($options.eventMeta(entry)), 1 /* TEXT */)
71189
71259
  ]),
71190
71260
  ($props.showVisibility)
71191
71261
  ? (vue$1.openBlock(), vue$1.createBlock(_component_CnVisibilityChip, {
@@ -71647,7 +71717,7 @@ const _hoisted_8$3a = {
71647
71717
  class: "cn-analytics-card__headline-recent"
71648
71718
  };
71649
71719
  const _hoisted_9$2U = ["href"];
71650
- const _hoisted_10$2A = {
71720
+ const _hoisted_10$2B = {
71651
71721
  key: 1,
71652
71722
  class: "cn-analytics-card__view-all"
71653
71723
  };
@@ -71727,7 +71797,7 @@ function render$6u(_ctx, _cache, $props, $setup, $data, $options) {
71727
71797
  ]))
71728
71798
  : vue$1.createCommentVNode("v-if", true),
71729
71799
  ($data.reports.length > 1)
71730
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2A, [
71800
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2B, [
71731
71801
  vue$1.createElementVNode("a", {
71732
71802
  href: $props.analyticsAppUrl,
71733
71803
  target: "_blank",
@@ -72610,7 +72680,7 @@ const _hoisted_9$2S = {
72610
72680
  key: 0,
72611
72681
  class: "cn-analytics-tab__subheader"
72612
72682
  };
72613
- const _hoisted_10$2z = {
72683
+ const _hoisted_10$2A = {
72614
72684
  key: 1,
72615
72685
  class: "cn-analytics-tab__when"
72616
72686
  };
@@ -72718,7 +72788,7 @@ function render$6r(_ctx, _cache, $props, $setup, $data, $options) {
72718
72788
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_9$2S, vue$1.toDisplayString($options.reportSubheader(report)), 1 /* TEXT */))
72719
72789
  : vue$1.createCommentVNode("v-if", true),
72720
72790
  ($options.modifiedAt(report))
72721
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$2z, " · " + vue$1.toDisplayString($options.formatWhen($options.modifiedAt(report))), 1 /* TEXT */))
72791
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$2A, " · " + vue$1.toDisplayString($options.formatWhen($options.modifiedAt(report))), 1 /* TEXT */))
72722
72792
  : vue$1.createCommentVNode("v-if", true)
72723
72793
  ])
72724
72794
  ]),
@@ -73991,7 +74061,7 @@ const _hoisted_9$2R = {
73991
74061
  key: 0,
73992
74062
  class: "cn-audit-details__row"
73993
74063
  };
73994
- const _hoisted_10$2y = {
74064
+ const _hoisted_10$2z = {
73995
74065
  key: 1,
73996
74066
  class: "cn-audit-details__row"
73997
74067
  };
@@ -74131,7 +74201,7 @@ function render$6n(_ctx, _cache, $props, $setup, $data, $options) {
74131
74201
  ]))
74132
74202
  : vue$1.createCommentVNode("v-if", true),
74133
74203
  (entry.session)
74134
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2y, [
74204
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2z, [
74135
74205
  _cache[9] || (_cache[9] = vue$1.createElementVNode("span", { class: "cn-audit-details__label" }, "Session", -1 /* CACHED */)),
74136
74206
  vue$1.createElementVNode("span", _hoisted_11$29, vue$1.toDisplayString(entry.session), 1 /* TEXT */)
74137
74207
  ]))
@@ -74496,7 +74566,7 @@ const _hoisted_8$36 = {
74496
74566
  class: "cn-bookmarks-card__headline"
74497
74567
  };
74498
74568
  const _hoisted_9$2Q = { class: "cn-bookmarks-card__headline-line" };
74499
- const _hoisted_10$2x = {
74569
+ const _hoisted_10$2y = {
74500
74570
  key: 0,
74501
74571
  class: "cn-bookmarks-card__headline-recent"
74502
74572
  };
@@ -74589,7 +74659,7 @@ function render$6m(_ctx, _cache, $props, $setup, $data, $options) {
74589
74659
  vue$1.createElementVNode("strong", null, vue$1.toDisplayString($options.countHeadline), 1 /* TEXT */)
74590
74660
  ]),
74591
74661
  ($options.mostRecent)
74592
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2x, [
74662
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2y, [
74593
74663
  ($options.faviconUrl($options.mostRecent))
74594
74664
  ? (vue$1.openBlock(), vue$1.createElementBlock("img", {
74595
74665
  key: 0,
@@ -75027,7 +75097,7 @@ const _hoisted_9$2P = {
75027
75097
  key: 0,
75028
75098
  class: "cn-bookmark-picker__row-description"
75029
75099
  };
75030
- const _hoisted_10$2w = {
75100
+ const _hoisted_10$2x = {
75031
75101
  key: 1,
75032
75102
  class: "cn-bookmark-picker__tags"
75033
75103
  };
@@ -75129,7 +75199,7 @@ function render$6k(_ctx, _cache, $props, $setup, $data, $options) {
75129
75199
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_9$2P, vue$1.toDisplayString(bookmark.description), 1 /* TEXT */))
75130
75200
  : vue$1.createCommentVNode("v-if", true),
75131
75201
  ($options.displayTags(bookmark).length > 0)
75132
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$2w, [
75202
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$2x, [
75133
75203
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.displayTags(bookmark), (tag) => {
75134
75204
  return (vue$1.openBlock(), vue$1.createElementBlock("span", {
75135
75205
  key: tag,
@@ -75462,7 +75532,7 @@ const _hoisted_7$3m = {
75462
75532
  };
75463
75533
  const _hoisted_8$34 = ["onClick"];
75464
75534
  const _hoisted_9$2O = { class: "cn-bookmarks-tab__list" };
75465
- const _hoisted_10$2v = { class: "cn-bookmarks-tab__row-icon" };
75535
+ const _hoisted_10$2w = { class: "cn-bookmarks-tab__row-icon" };
75466
75536
  const _hoisted_11$27 = ["title"];
75467
75537
  const _hoisted_12$1U = { class: "cn-bookmarks-tab__url-text" };
75468
75538
  const _hoisted_13$1L = {
@@ -75582,7 +75652,7 @@ function render$6j(_ctx, _cache, $props, $setup, $data, $options) {
75582
75652
  onClick: $event => ($options.onBookmarkClick(bookmark, $event))
75583
75653
  }, {
75584
75654
  icon: vue$1.withCtx(() => [
75585
- vue$1.createElementVNode("span", _hoisted_10$2v, [
75655
+ vue$1.createElementVNode("span", _hoisted_10$2w, [
75586
75656
  vue$1.createVNode(_component_Bookmark, { size: 20 })
75587
75657
  ])
75588
75658
  ]),
@@ -75967,7 +76037,7 @@ const _hoisted_6$3N = {
75967
76037
  const _hoisted_7$3l = { class: "cn-calendar-card__row-icon" };
75968
76038
  const _hoisted_8$33 = { class: "cn-calendar-card__row-main" };
75969
76039
  const _hoisted_9$2N = { class: "cn-calendar-card__title" };
75970
- const _hoisted_10$2u = { class: "cn-calendar-card__meta" };
76040
+ const _hoisted_10$2v = { class: "cn-calendar-card__meta" };
75971
76041
  const _hoisted_11$26 = {
75972
76042
  key: 0,
75973
76043
  class: "cn-calendar-card__when"
@@ -76034,7 +76104,7 @@ function render$6i(_ctx, _cache, $props, $setup, $data, $options) {
76034
76104
  ]),
76035
76105
  vue$1.createElementVNode("div", _hoisted_8$33, [
76036
76106
  vue$1.createElementVNode("span", _hoisted_9$2N, vue$1.toDisplayString(ev.summary || $props.untitledLabel), 1 /* TEXT */),
76037
- vue$1.createElementVNode("div", _hoisted_10$2u, [
76107
+ vue$1.createElementVNode("div", _hoisted_10$2v, [
76038
76108
  (ev.dtstart)
76039
76109
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_11$26, vue$1.toDisplayString($options.formatShort(ev.dtstart)), 1 /* TEXT */))
76040
76110
  : vue$1.createCommentVNode("v-if", true),
@@ -76588,7 +76658,7 @@ const _hoisted_9$2M = {
76588
76658
  key: 1,
76589
76659
  class: "cn-calendar-event-picker__step"
76590
76660
  };
76591
- const _hoisted_10$2t = { class: "cn-calendar-event-picker__breadcrumb" };
76661
+ const _hoisted_10$2u = { class: "cn-calendar-event-picker__breadcrumb" };
76592
76662
  const _hoisted_11$25 = { class: "cn-calendar-event-picker__breadcrumb-calendar" };
76593
76663
  const _hoisted_12$1S = {
76594
76664
  key: 1,
@@ -76683,7 +76753,7 @@ function render$6g(_ctx, _cache, $props, $setup, $data, $options) {
76683
76753
  ]))
76684
76754
  : ($data.step === 'events')
76685
76755
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_9$2M, [
76686
- vue$1.createElementVNode("div", _hoisted_10$2t, [
76756
+ vue$1.createElementVNode("div", _hoisted_10$2u, [
76687
76757
  vue$1.createVNode(_component_NcButton, {
76688
76758
  variant: "tertiary",
76689
76759
  onClick: $options.backToCalendars
@@ -77164,7 +77234,7 @@ const _hoisted_9$2L = {
77164
77234
  class: "cn-calendar-tab__date",
77165
77235
  "aria-hidden": "true"
77166
77236
  };
77167
- const _hoisted_10$2s = { class: "cn-calendar-tab__date-month" };
77237
+ const _hoisted_10$2t = { class: "cn-calendar-tab__date-month" };
77168
77238
  const _hoisted_11$24 = { class: "cn-calendar-tab__date-day" };
77169
77239
  const _hoisted_12$1R = { class: "cn-calendar-tab__main" };
77170
77240
  const _hoisted_13$1I = { class: "cn-calendar-tab__title-row" };
@@ -77277,7 +77347,7 @@ function render$6f(_ctx, _cache, $props, $setup, $data, $options) {
77277
77347
  class: "cn-calendar-tab__event"
77278
77348
  }, [
77279
77349
  vue$1.createElementVNode("div", _hoisted_9$2L, [
77280
- vue$1.createElementVNode("span", _hoisted_10$2s, vue$1.toDisplayString($options.monthOf(ev)), 1 /* TEXT */),
77350
+ vue$1.createElementVNode("span", _hoisted_10$2t, vue$1.toDisplayString($options.monthOf(ev)), 1 /* TEXT */),
77281
77351
  vue$1.createElementVNode("span", _hoisted_11$24, vue$1.toDisplayString($options.dayOf(ev)), 1 /* TEXT */)
77282
77352
  ]),
77283
77353
  vue$1.createElementVNode("div", _hoisted_12$1R, [
@@ -77851,7 +77921,7 @@ const _hoisted_9$2K = {
77851
77921
  key: 2,
77852
77922
  class: "cn-collectives-card__headline"
77853
77923
  };
77854
- const _hoisted_10$2r = { class: "cn-collectives-card__headline-line" };
77924
+ const _hoisted_10$2s = { class: "cn-collectives-card__headline-line" };
77855
77925
  const _hoisted_11$23 = {
77856
77926
  key: 0,
77857
77927
  class: "cn-collectives-card__headline-recent"
@@ -77952,7 +78022,7 @@ function render$6e(_ctx, _cache, $props, $setup, $data, $options) {
77952
78022
  : ($data.pages.length === 0)
77953
78023
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_8$30, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
77954
78024
  : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_9$2K, [
77955
- vue$1.createElementVNode("div", _hoisted_10$2r, [
78025
+ vue$1.createElementVNode("div", _hoisted_10$2s, [
77956
78026
  vue$1.createElementVNode("strong", null, vue$1.toDisplayString($options.countHeadline), 1 /* TEXT */)
77957
78027
  ]),
77958
78028
  ($options.mostRecent)
@@ -78884,7 +78954,7 @@ const _hoisted_9$2I = {
78884
78954
  class: "cn-collectives-tab__emoji",
78885
78955
  "aria-hidden": true
78886
78956
  };
78887
- const _hoisted_10$2q = { class: "cn-collectives-tab__subname" };
78957
+ const _hoisted_10$2r = { class: "cn-collectives-tab__subname" };
78888
78958
  const _hoisted_11$22 = {
78889
78959
  key: 0,
78890
78960
  class: "cn-collectives-tab__subname-line"
@@ -79009,7 +79079,7 @@ function render$6b(_ctx, _cache, $props, $setup, $data, $options) {
79009
79079
  ])
79010
79080
  ]),
79011
79081
  subname: vue$1.withCtx(() => [
79012
- vue$1.createElementVNode("span", _hoisted_10$2q, [
79082
+ vue$1.createElementVNode("span", _hoisted_10$2r, [
79013
79083
  ($options.sublineLabel(page))
79014
79084
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_11$22, vue$1.toDisplayString($options.sublineLabel(page)), 1 /* TEXT */))
79015
79085
  : vue$1.createCommentVNode("v-if", true),
@@ -79292,7 +79362,7 @@ const _hoisted_9$2H = {
79292
79362
  key: 0,
79293
79363
  class: "cn-contactmoment-card__summary"
79294
79364
  };
79295
- const _hoisted_10$2p = { class: "cn-contactmoment-card__meta" };
79365
+ const _hoisted_10$2q = { class: "cn-contactmoment-card__meta" };
79296
79366
  const _hoisted_11$21 = { key: 0 };
79297
79367
  const _hoisted_12$1O = { key: 1 };
79298
79368
  const _hoisted_13$1G = {
@@ -79330,7 +79400,7 @@ function render$6a(_ctx, _cache, $props, $setup, $data, $options) {
79330
79400
  (item.summary)
79331
79401
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_9$2H, vue$1.toDisplayString(item.summary), 1 /* TEXT */))
79332
79402
  : vue$1.createCommentVNode("v-if", true),
79333
- vue$1.createElementVNode("div", _hoisted_10$2p, [
79403
+ vue$1.createElementVNode("div", _hoisted_10$2q, [
79334
79404
  (item.agent)
79335
79405
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_11$21, vue$1.toDisplayString(item.agent), 1 /* TEXT */))
79336
79406
  : vue$1.createCommentVNode("v-if", true),
@@ -79664,7 +79734,7 @@ const _hoisted_9$2G = {
79664
79734
  key: 1,
79665
79735
  class: "cn-contacts-card__error"
79666
79736
  };
79667
- const _hoisted_10$2o = {
79737
+ const _hoisted_10$2p = {
79668
79738
  key: 2,
79669
79739
  class: "cn-contacts-card__empty"
79670
79740
  };
@@ -79727,7 +79797,7 @@ function render$68(_ctx, _cache, $props, $setup, $data, $options) {
79727
79797
  vue$1.createElementVNode("span", null, vue$1.toDisplayString($props.errorLabel), 1 /* TEXT */)
79728
79798
  ]))
79729
79799
  : ($options.contactsArray.length === 0)
79730
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2o, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
79800
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2p, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
79731
79801
  : (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_11$20, [
79732
79802
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.displayedContacts, (item) => {
79733
79803
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
@@ -80417,7 +80487,7 @@ const _hoisted_9$2F = {
80417
80487
  class: "cn-contact-picker__kind",
80418
80488
  "data-testid": "cn-contact-picker-user-badge"
80419
80489
  };
80420
- const _hoisted_10$2n = {
80490
+ const _hoisted_10$2o = {
80421
80491
  key: 0,
80422
80492
  class: "cn-contact-picker__email"
80423
80493
  };
@@ -80528,7 +80598,7 @@ function render$66(_ctx, _cache, $props, $setup, $data, $options) {
80528
80598
  : vue$1.createCommentVNode("v-if", true)
80529
80599
  ]),
80530
80600
  (row.email)
80531
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2n, vue$1.toDisplayString(row.email), 1 /* TEXT */))
80601
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2o, vue$1.toDisplayString(row.email), 1 /* TEXT */))
80532
80602
  : vue$1.createCommentVNode("v-if", true),
80533
80603
  (row.org)
80534
80604
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_11$1$, vue$1.toDisplayString(row.org), 1 /* TEXT */))
@@ -81069,7 +81139,7 @@ const _hoisted_6$3E = { class: "cn-contacts-tab__list" };
81069
81139
  const _hoisted_7$3c = ["onClick"];
81070
81140
  const _hoisted_8$2W = { class: "cn-contacts-tab__avatar" };
81071
81141
  const _hoisted_9$2E = { class: "cn-contacts-tab__details" };
81072
- const _hoisted_10$2m = { class: "cn-contacts-tab__name-row" };
81142
+ const _hoisted_10$2n = { class: "cn-contacts-tab__name-row" };
81073
81143
  const _hoisted_11$1_ = { class: "cn-contacts-tab__name" };
81074
81144
  const _hoisted_12$1L = {
81075
81145
  key: 0,
@@ -81200,7 +81270,7 @@ function render$65(_ctx, _cache, $props, $setup, $data, $options) {
81200
81270
  }, null, 8 /* PROPS */, ["displayName", "user", "url"])
81201
81271
  ]),
81202
81272
  vue$1.createElementVNode("div", _hoisted_9$2E, [
81203
- vue$1.createElementVNode("div", _hoisted_10$2m, [
81273
+ vue$1.createElementVNode("div", _hoisted_10$2n, [
81204
81274
  vue$1.createElementVNode("span", _hoisted_11$1_, vue$1.toDisplayString(contact.displayName || $props.unknownLabel), 1 /* TEXT */),
81205
81275
  (contact.role)
81206
81276
  ? (vue$1.openBlock(), vue$1.createBlock(_component_CnStatusBadge, {
@@ -81641,7 +81711,7 @@ const _hoisted_8$2V = {
81641
81711
  class: "cn-cospend-card__totals"
81642
81712
  };
81643
81713
  const _hoisted_9$2D = { class: "cn-cospend-card__totals-label" };
81644
- const _hoisted_10$2l = { class: "cn-cospend-card__totals-amount" };
81714
+ const _hoisted_10$2m = { class: "cn-cospend-card__totals-amount" };
81645
81715
  const _hoisted_11$1Z = {
81646
81716
  key: 1,
81647
81717
  class: "cn-cospend-card__headline-recent"
@@ -81719,7 +81789,7 @@ function render$64(_ctx, _cache, $props, $setup, $data, $options) {
81719
81789
  vue$1.createVNode(_component_CurrencyEur, { size: 12 }),
81720
81790
  vue$1.createTextVNode(" " + vue$1.toDisplayString(bucket.currency), 1 /* TEXT */)
81721
81791
  ]),
81722
- vue$1.createElementVNode("span", _hoisted_10$2l, vue$1.toDisplayString(bucket.amountLabel), 1 /* TEXT */)
81792
+ vue$1.createElementVNode("span", _hoisted_10$2m, vue$1.toDisplayString(bucket.amountLabel), 1 /* TEXT */)
81723
81793
  ]))
81724
81794
  }), 128 /* KEYED_FRAGMENT */))
81725
81795
  ]))
@@ -82560,7 +82630,7 @@ const _hoisted_9$2C = {
82560
82630
  key: 0,
82561
82631
  class: "cn-cospend-tab__subline-text"
82562
82632
  };
82563
- const _hoisted_10$2k = {
82633
+ const _hoisted_10$2l = {
82564
82634
  key: 0,
82565
82635
  class: "cn-cospend-tab__totals"
82566
82636
  };
@@ -82716,7 +82786,7 @@ function render$61(_ctx, _cache, $props, $setup, $data, $options) {
82716
82786
  }), 128 /* KEYED_FRAGMENT */))
82717
82787
  ]),
82718
82788
  ($options.totals.length > 0)
82719
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2k, [
82789
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2l, [
82720
82790
  vue$1.createElementVNode("span", _hoisted_11$1Y, vue$1.toDisplayString(_ctx.t('nextcloud-vue', 'Total')), 1 /* TEXT */),
82721
82791
  vue$1.createElementVNode("ul", _hoisted_12$1J, [
82722
82792
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.totals, (bucket) => {
@@ -83087,7 +83157,7 @@ const _hoisted_9$2B = {
83087
83157
  key: 0,
83088
83158
  class: "cn-deck-card__distribution"
83089
83159
  };
83090
- const _hoisted_10$2j = { class: "cn-deck-card__distribution-label" };
83160
+ const _hoisted_10$2k = { class: "cn-deck-card__distribution-label" };
83091
83161
  const _hoisted_11$1X = { class: "cn-deck-card__distribution-count" };
83092
83162
  const _hoisted_12$1I = {
83093
83163
  key: 1,
@@ -83162,7 +83232,7 @@ function render$60(_ctx, _cache, $props, $setup, $data, $options) {
83162
83232
  key: bucket.key,
83163
83233
  class: "cn-deck-card__distribution-row"
83164
83234
  }, [
83165
- vue$1.createElementVNode("span", _hoisted_10$2j, vue$1.toDisplayString(bucket.label), 1 /* TEXT */),
83235
+ vue$1.createElementVNode("span", _hoisted_10$2k, vue$1.toDisplayString(bucket.label), 1 /* TEXT */),
83166
83236
  vue$1.createElementVNode("span", _hoisted_11$1X, vue$1.toDisplayString(bucket.count), 1 /* TEXT */)
83167
83237
  ]))
83168
83238
  }), 128 /* KEYED_FRAGMENT */))
@@ -83675,7 +83745,7 @@ const _hoisted_8$2S = {
83675
83745
  class: "cn-deck-card-picker__list"
83676
83746
  };
83677
83747
  const _hoisted_9$2A = ["onClick"];
83678
- const _hoisted_10$2i = { class: "cn-deck-card-picker__row-label" };
83748
+ const _hoisted_10$2j = { class: "cn-deck-card-picker__row-label" };
83679
83749
  const _hoisted_11$1W = {
83680
83750
  key: 3,
83681
83751
  class: "cn-deck-card-picker__panel"
@@ -83807,7 +83877,7 @@ function render$5_(_ctx, _cache, $props, $setup, $data, $options) {
83807
83877
  class: "cn-deck-card-picker__row-button",
83808
83878
  onClick: $event => ($options.pickStack(stack))
83809
83879
  }, [
83810
- vue$1.createElementVNode("span", _hoisted_10$2i, vue$1.toDisplayString(stack.title), 1 /* TEXT */)
83880
+ vue$1.createElementVNode("span", _hoisted_10$2j, vue$1.toDisplayString(stack.title), 1 /* TEXT */)
83811
83881
  ], 8 /* PROPS */, _hoisted_9$2A)
83812
83882
  ], 2 /* CLASS */))
83813
83883
  }), 128 /* KEYED_FRAGMENT */))
@@ -84273,7 +84343,7 @@ const _hoisted_6$3y = {
84273
84343
  const _hoisted_7$36 = { class: "cn-deck-tab__column-header" };
84274
84344
  const _hoisted_8$2R = { class: "cn-deck-tab__column-title" };
84275
84345
  const _hoisted_9$2z = { class: "cn-deck-tab__column-count" };
84276
- const _hoisted_10$2h = { class: "cn-deck-tab__column-list" };
84346
+ const _hoisted_10$2i = { class: "cn-deck-tab__column-list" };
84277
84347
  const _hoisted_11$1V = {
84278
84348
  key: 0,
84279
84349
  class: "cn-deck-tab__card-labels"
@@ -84375,7 +84445,7 @@ function render$5Z(_ctx, _cache, $props, $setup, $data, $options) {
84375
84445
  vue$1.createElementVNode("span", _hoisted_8$2R, vue$1.toDisplayString(stack.label), 1 /* TEXT */),
84376
84446
  vue$1.createElementVNode("span", _hoisted_9$2z, vue$1.toDisplayString(stack.cards.length), 1 /* TEXT */)
84377
84447
  ]),
84378
- vue$1.createElementVNode("ul", _hoisted_10$2h, [
84448
+ vue$1.createElementVNode("ul", _hoisted_10$2i, [
84379
84449
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList(stack.cards, (card) => {
84380
84450
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
84381
84451
  key: $options.cardKey(card),
@@ -84771,7 +84841,7 @@ const _hoisted_6$3x = { class: "cn-email-card__subject" };
84771
84841
  const _hoisted_7$35 = { class: "cn-email-card__when" };
84772
84842
  const _hoisted_8$2Q = { class: "cn-email-card__row-body" };
84773
84843
  const _hoisted_9$2y = { class: "cn-email-card__sender" };
84774
- const _hoisted_10$2g = {
84844
+ const _hoisted_10$2h = {
84775
84845
  key: 0,
84776
84846
  class: "cn-email-card__snippet"
84777
84847
  };
@@ -84820,7 +84890,7 @@ function render$5Y(_ctx, _cache, $props, $setup, $data, $options) {
84820
84890
  vue$1.createElementVNode("span", _hoisted_9$2y, vue$1.toDisplayString(row.sender), 1 /* TEXT */)
84821
84891
  ]),
84822
84892
  (row.snippet)
84823
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2g, vue$1.toDisplayString(row.snippet), 1 /* TEXT */))
84893
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$2h, vue$1.toDisplayString(row.snippet), 1 /* TEXT */))
84824
84894
  : vue$1.createCommentVNode("v-if", true)
84825
84895
  ])
84826
84896
  ]),
@@ -85110,7 +85180,7 @@ const _hoisted_9$2x = {
85110
85180
  key: 2,
85111
85181
  class: "cn-email-picker__panel"
85112
85182
  };
85113
- const _hoisted_10$2f = {
85183
+ const _hoisted_10$2g = {
85114
85184
  key: 2,
85115
85185
  class: "cn-email-picker__list"
85116
85186
  };
@@ -85255,7 +85325,7 @@ function render$5X(_ctx, _cache, $props, $setup, $data, $options) {
85255
85325
  name: $options.t('nextcloud-vue', 'No mailboxes'),
85256
85326
  description: $options.t('nextcloud-vue', 'This account has no mailboxes to browse.')
85257
85327
  }, null, 8 /* PROPS */, ["name", "description"]))
85258
- : (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_10$2f, [
85328
+ : (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_10$2g, [
85259
85329
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($data.mailboxes, (mb) => {
85260
85330
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
85261
85331
  key: mb.id,
@@ -85710,7 +85780,7 @@ const _hoisted_6$3v = {
85710
85780
  const _hoisted_7$33 = { class: "cn-email-tab__body" };
85711
85781
  const _hoisted_8$2O = { class: "cn-email-tab__line" };
85712
85782
  const _hoisted_9$2w = ["title"];
85713
- const _hoisted_10$2e = { class: "cn-email-tab__date" };
85783
+ const _hoisted_10$2f = { class: "cn-email-tab__date" };
85714
85784
  const _hoisted_11$1T = ["title"];
85715
85785
  const _hoisted_12$1E = ["title"];
85716
85786
 
@@ -85785,7 +85855,7 @@ function render$5W(_ctx, _cache, $props, $setup, $data, $options) {
85785
85855
  class: "cn-email-tab__subject",
85786
85856
  title: row.subject
85787
85857
  }, vue$1.toDisplayString(row.subject), 9 /* TEXT, PROPS */, _hoisted_9$2w),
85788
- vue$1.createElementVNode("span", _hoisted_10$2e, [
85858
+ vue$1.createElementVNode("span", _hoisted_10$2f, [
85789
85859
  (row.dateValid)
85790
85860
  ? (vue$1.openBlock(), vue$1.createBlock(_component_NcDateTime, {
85791
85861
  key: 0,
@@ -87144,7 +87214,7 @@ const _hoisted_6$3u = { class: "cn-offline-queue__row-main" };
87144
87214
  const _hoisted_7$32 = { class: "cn-offline-queue__operation" };
87145
87215
  const _hoisted_8$2N = ["data-testid"];
87146
87216
  const _hoisted_9$2v = { class: "cn-offline-queue__meta" };
87147
- const _hoisted_10$2d = ["data-testid"];
87217
+ const _hoisted_10$2e = ["data-testid"];
87148
87218
  const _hoisted_11$1S = ["data-testid"];
87149
87219
  const _hoisted_12$1D = ["data-testid"];
87150
87220
  const _hoisted_13$1w = {
@@ -87206,7 +87276,7 @@ function render$5V(_ctx, _cache, $props, $setup, $data, $options) {
87206
87276
  key: 0,
87207
87277
  class: "cn-offline-queue__error",
87208
87278
  "data-testid": `cn-offline-queue-error-${operation.id}`
87209
- }, vue$1.toDisplayString(operation.lastError), 9 /* TEXT, PROPS */, _hoisted_10$2d))
87279
+ }, vue$1.toDisplayString(operation.lastError), 9 /* TEXT, PROPS */, _hoisted_10$2e))
87210
87280
  : vue$1.createCommentVNode("v-if", true),
87211
87281
  ($options.isPermissionLost(operation))
87212
87282
  ? (vue$1.openBlock(), vue$1.createElementBlock("p", {
@@ -88189,7 +88259,7 @@ const _hoisted_8$2M = {
88189
88259
  "data-testid": "cn-fi-checklist"
88190
88260
  };
88191
88261
  const _hoisted_9$2u = { class: "cn-field-inspection__checklist-head" };
88192
- const _hoisted_10$2c = {
88262
+ const _hoisted_10$2d = {
88193
88263
  key: 0,
88194
88264
  class: "cn-field-inspection__progress",
88195
88265
  "data-testid": "cn-fi-progress"
@@ -88329,7 +88399,7 @@ function render$5U(_ctx, _cache, $props, $setup, $data, $options) {
88329
88399
  vue$1.createElementVNode("strong", null, vue$1.toDisplayString($options.itemTitle($data.activeItem)), 1 /* TEXT */)
88330
88400
  ]),
88331
88401
  ($data.activeTemplate)
88332
- ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_10$2c, vue$1.toDisplayString($options.t('nextcloud-vue', '{done} of {total} questions completed', { done: $options.progress.done, total: $options.progress.total })), 1 /* TEXT */))
88402
+ ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_10$2d, vue$1.toDisplayString($options.t('nextcloud-vue', '{done} of {total} questions completed', { done: $options.progress.done, total: $options.progress.total })), 1 /* TEXT */))
88333
88403
  : vue$1.createCommentVNode("v-if", true),
88334
88404
  ($data.activeTemplate)
88335
88405
  ? (vue$1.openBlock(), vue$1.createElementBlock("form", {
@@ -88685,7 +88755,7 @@ const _hoisted_9$2t = {
88685
88755
  class: "cn-field-inspection-tab__queue",
88686
88756
  "data-testid": "cn-fi-tab-queue"
88687
88757
  };
88688
- const _hoisted_10$2b = { class: "cn-field-inspection-tab__queue-heading" };
88758
+ const _hoisted_10$2c = { class: "cn-field-inspection-tab__queue-heading" };
88689
88759
 
88690
88760
  function render$5T(_ctx, _cache, $props, $setup, $data, $options) {
88691
88761
  const _component_Sync = vue$1.resolveComponent("Sync");
@@ -88760,7 +88830,7 @@ function render$5T(_ctx, _cache, $props, $setup, $data, $options) {
88760
88830
  }), 128 /* KEYED_FRAGMENT */))
88761
88831
  ])),
88762
88832
  vue$1.createElementVNode("section", _hoisted_9$2t, [
88763
- vue$1.createElementVNode("h4", _hoisted_10$2b, vue$1.toDisplayString($options.t('nextcloud-vue', 'Waiting to send')), 1 /* TEXT */),
88833
+ vue$1.createElementVNode("h4", _hoisted_10$2c, vue$1.toDisplayString($options.t('nextcloud-vue', 'Waiting to send')), 1 /* TEXT */),
88764
88834
  vue$1.createVNode(_component_CnOfflineQueue, {
88765
88835
  deviceId: $data.deviceId,
88766
88836
  onRequeued: $options.loadLocal
@@ -91574,7 +91644,7 @@ const _hoisted_7$2$ = {
91574
91644
  };
91575
91645
  const _hoisted_8$2K = { class: "hidden-visually" };
91576
91646
  const _hoisted_9$2s = ["aria-sort", "data-testid"];
91577
- const _hoisted_10$2a = ["onClick"];
91647
+ const _hoisted_10$2b = ["onClick"];
91578
91648
  const _hoisted_11$1Q = {
91579
91649
  class: "cn-files-browser__col-actions",
91580
91650
  scope: "col"
@@ -91848,7 +91918,7 @@ function render$5O(_ctx, _cache, $props, $setup, $data, $options) {
91848
91918
  size: 16
91849
91919
  }))
91850
91920
  : vue$1.createCommentVNode("v-if", true)
91851
- ], 8 /* PROPS */, _hoisted_10$2a))
91921
+ ], 8 /* PROPS */, _hoisted_10$2b))
91852
91922
  : (vue$1.openBlock(), vue$1.createElementBlock(vue$1.Fragment, { key: 1 }, [
91853
91923
  vue$1.createTextVNode(vue$1.toDisplayString($options.columnLabel(column)), 1 /* TEXT */)
91854
91924
  ], 64 /* STABLE_FRAGMENT */))
@@ -93483,7 +93553,7 @@ const _hoisted_8$2J = {
93483
93553
  class: "cn-flow-card__headline-recent"
93484
93554
  };
93485
93555
  const _hoisted_9$2r = ["href"];
93486
- const _hoisted_10$29 = {
93556
+ const _hoisted_10$2a = {
93487
93557
  key: 0,
93488
93558
  class: "cn-flow-card__headline-entity"
93489
93559
  };
@@ -93559,7 +93629,7 @@ function render$5M(_ctx, _cache, $props, $setup, $data, $options) {
93559
93629
  rel: "noopener"
93560
93630
  }, vue$1.toDisplayString($options.opTitle($options.mostRecent)), 9 /* TEXT, PROPS */, _hoisted_9$2r),
93561
93631
  ($options.entityLabel($options.mostRecent))
93562
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$29, " · " + vue$1.toDisplayString($options.entityLabel($options.mostRecent)), 1 /* TEXT */))
93632
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$2a, " · " + vue$1.toDisplayString($options.entityLabel($options.mostRecent)), 1 /* TEXT */))
93563
93633
  : vue$1.createCommentVNode("v-if", true)
93564
93634
  ]))
93565
93635
  : vue$1.createCommentVNode("v-if", true)
@@ -94225,7 +94295,7 @@ const _hoisted_9$2q = {
94225
94295
  key: 0,
94226
94296
  class: "cn-flow-tab__events"
94227
94297
  };
94228
- const _hoisted_10$28 = {
94298
+ const _hoisted_10$29 = {
94229
94299
  key: 1,
94230
94300
  class: "cn-flow-tab__meta"
94231
94301
  };
@@ -94342,7 +94412,7 @@ function render$5K(_ctx, _cache, $props, $setup, $data, $options) {
94342
94412
  ]))
94343
94413
  : vue$1.createCommentVNode("v-if", true),
94344
94414
  ($options.opMeta(op))
94345
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$28, vue$1.toDisplayString($options.opMeta(op)), 1 /* TEXT */))
94415
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$29, vue$1.toDisplayString($options.opMeta(op)), 1 /* TEXT */))
94346
94416
  : vue$1.createCommentVNode("v-if", true)
94347
94417
  ])
94348
94418
  ]),
@@ -94813,7 +94883,7 @@ const _hoisted_9$2p = {
94813
94883
  key: 0,
94814
94884
  class: "cn-forms-card__headline-recent"
94815
94885
  };
94816
- const _hoisted_10$27 = ["href"];
94886
+ const _hoisted_10$28 = ["href"];
94817
94887
  const _hoisted_11$1O = {
94818
94888
  key: 0,
94819
94889
  class: "cn-forms-card__empty"
@@ -94884,7 +94954,7 @@ function render$5J(_ctx, _cache, $props, $setup, $data, $options) {
94884
94954
  href: $options.formUrl($options.mostRecent),
94885
94955
  target: "_blank",
94886
94956
  rel: "noopener"
94887
- }, vue$1.toDisplayString($options.formTitle($options.mostRecent)), 9 /* TEXT, PROPS */, _hoisted_10$27)
94957
+ }, vue$1.toDisplayString($options.formTitle($options.mostRecent)), 9 /* TEXT, PROPS */, _hoisted_10$28)
94888
94958
  ]))
94889
94959
  : vue$1.createCommentVNode("v-if", true)
94890
94960
  ]))
@@ -95357,7 +95427,7 @@ const _hoisted_7$2V = {
95357
95427
  };
95358
95428
  const _hoisted_8$2G = { class: "cn-form-picker__row-meta" };
95359
95429
  const _hoisted_9$2o = { class: "cn-form-picker__row-count" };
95360
- const _hoisted_10$26 = {
95430
+ const _hoisted_10$27 = {
95361
95431
  key: 0,
95362
95432
  class: "cn-form-picker__row-linked"
95363
95433
  };
@@ -95469,7 +95539,7 @@ function render$5H(_ctx, _cache, $props, $setup, $data, $options) {
95469
95539
  vue$1.createElementVNode("div", _hoisted_8$2G, [
95470
95540
  vue$1.createElementVNode("span", _hoisted_9$2o, vue$1.toDisplayString($options.submissionCountLabel(form)), 1 /* TEXT */),
95471
95541
  (form.linked)
95472
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$26, vue$1.toDisplayString($props.alreadyLinkedLabel), 1 /* TEXT */))
95542
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$27, vue$1.toDisplayString($props.alreadyLinkedLabel), 1 /* TEXT */))
95473
95543
  : vue$1.createCommentVNode("v-if", true)
95474
95544
  ])
95475
95545
  ], 10 /* CLASS, PROPS */, _hoisted_3$4E))
@@ -96448,7 +96518,7 @@ const _hoisted_8$2E = {
96448
96518
  class: "cn-maps-card__headline"
96449
96519
  };
96450
96520
  const _hoisted_9$2n = { class: "cn-maps-card__headline-line" };
96451
- const _hoisted_10$25 = {
96521
+ const _hoisted_10$26 = {
96452
96522
  key: 0,
96453
96523
  class: "cn-maps-card__headline-recent"
96454
96524
  };
@@ -96548,7 +96618,7 @@ function render$5F(_ctx, _cache, $props, $setup, $data, $options) {
96548
96618
  vue$1.createElementVNode("strong", null, vue$1.toDisplayString($options.countHeadline), 1 /* TEXT */)
96549
96619
  ]),
96550
96620
  ($options.mostRecent)
96551
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$25, [
96621
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$26, [
96552
96622
  vue$1.createElementVNode("a", {
96553
96623
  href: $options.pointUrl($options.mostRecent),
96554
96624
  target: "_blank",
@@ -97406,7 +97476,7 @@ const _hoisted_9$2l = {
97406
97476
  key: 0,
97407
97477
  class: "cn-maps-tab__category"
97408
97478
  };
97409
- const _hoisted_10$24 = { class: "cn-maps-tab__subname" };
97479
+ const _hoisted_10$25 = { class: "cn-maps-tab__subname" };
97410
97480
  const _hoisted_11$1L = {
97411
97481
  key: 0,
97412
97482
  class: "cn-maps-tab__address"
@@ -97523,7 +97593,7 @@ function render$5C(_ctx, _cache, $props, $setup, $data, $options) {
97523
97593
  : vue$1.createCommentVNode("v-if", true)
97524
97594
  ]),
97525
97595
  subname: vue$1.withCtx(() => [
97526
- vue$1.createElementVNode("span", _hoisted_10$24, [
97596
+ vue$1.createElementVNode("span", _hoisted_10$25, [
97527
97597
  ($options.addressLabel(point))
97528
97598
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_11$1L, vue$1.toDisplayString($options.addressLabel(point)), 1 /* TEXT */))
97529
97599
  : vue$1.createCommentVNode("v-if", true),
@@ -99667,7 +99737,7 @@ const _hoisted_6$3e = {
99667
99737
  const _hoisted_7$2P = ["aria-label"];
99668
99738
  const _hoisted_8$2A = { class: "cn-notes-card__note-header" };
99669
99739
  const _hoisted_9$2j = { class: "cn-notes-card__author" };
99670
- const _hoisted_10$23 = {
99740
+ const _hoisted_10$24 = {
99671
99741
  key: 1,
99672
99742
  class: "cn-notes-card__author cn-notes-card__author--self"
99673
99743
  };
@@ -99790,7 +99860,7 @@ function render$5y(_ctx, _cache, $props, $setup, $data, $options) {
99790
99860
  ]),
99791
99861
  _: 2 /* DYNAMIC */
99792
99862
  }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["userId", "displayName"]))
99793
- : (vue$1.openBlock(), vue$1.createElementBlock("strong", _hoisted_10$23, vue$1.toDisplayString($options.getNoteAuthorName(row.note)), 1 /* TEXT */)),
99863
+ : (vue$1.openBlock(), vue$1.createElementBlock("strong", _hoisted_10$24, vue$1.toDisplayString($options.getNoteAuthorName(row.note)), 1 /* TEXT */)),
99794
99864
  vue$1.createElementVNode("span", _hoisted_11$1K, vue$1.toDisplayString($options.formatDate(row.note.creationDateTime || row.note.created)), 1 /* TEXT */)
99795
99865
  ]),
99796
99866
  ($options.visibilityShown)
@@ -100539,7 +100609,7 @@ const _hoisted_9$2i = {
100539
100609
  class: "cn-notes-tab__quote",
100540
100610
  "data-testid": "cn-note-quote"
100541
100611
  };
100542
- const _hoisted_10$22 = {
100612
+ const _hoisted_10$23 = {
100543
100613
  key: 0,
100544
100614
  class: "cn-notes-tab__edited",
100545
100615
  "data-testid": "cn-note-edited"
@@ -100658,7 +100728,7 @@ function render$5w(_ctx, _cache, $props, $setup, $data, $options) {
100658
100728
  details: vue$1.withCtx(() => [
100659
100729
  vue$1.createTextVNode(vue$1.toDisplayString($options.formatDate(row.note.creationDateTime || row.note.created)) + " ", 1 /* TEXT */),
100660
100730
  ($options.wasEdited(row.note))
100661
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$22, vue$1.toDisplayString($options.editedLine(row.note)), 1 /* TEXT */))
100731
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$23, vue$1.toDisplayString($options.editedLine(row.note)), 1 /* TEXT */))
100662
100732
  : vue$1.createCommentVNode("v-if", true)
100663
100733
  ]),
100664
100734
  _: 2 /* DYNAMIC */
@@ -101168,7 +101238,7 @@ const _hoisted_8$2y = {
101168
101238
  class: "cn-openproject-card__headline"
101169
101239
  };
101170
101240
  const _hoisted_9$2h = { class: "cn-openproject-card__headline-line" };
101171
- const _hoisted_10$21 = { class: "cn-openproject-card__auth-badge cn-openproject-card__auth-badge--ok" };
101241
+ const _hoisted_10$22 = { class: "cn-openproject-card__auth-badge cn-openproject-card__auth-badge--ok" };
101172
101242
  const _hoisted_11$1J = {
101173
101243
  key: 0,
101174
101244
  class: "cn-openproject-card__distribution"
@@ -101265,7 +101335,7 @@ function render$5v(_ctx, _cache, $props, $setup, $data, $options) {
101265
101335
  : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_8$2y, [
101266
101336
  vue$1.createElementVNode("div", _hoisted_9$2h, [
101267
101337
  vue$1.createElementVNode("strong", null, vue$1.toDisplayString($options.countHeadline), 1 /* TEXT */),
101268
- vue$1.createElementVNode("span", _hoisted_10$21, [
101338
+ vue$1.createElementVNode("span", _hoisted_10$22, [
101269
101339
  vue$1.createVNode(_component_CheckCircleOutline, { size: 13 }),
101270
101340
  vue$1.createTextVNode(" " + vue$1.toDisplayString($props.authConfiguredLabel), 1 /* TEXT */)
101271
101341
  ])
@@ -101781,7 +101851,7 @@ const _hoisted_9$2g = {
101781
101851
  key: 1,
101782
101852
  class: "cn-openproject-picker__status"
101783
101853
  };
101784
- const _hoisted_10$20 = {
101854
+ const _hoisted_10$21 = {
101785
101855
  key: 2,
101786
101856
  class: "cn-openproject-picker__project-name"
101787
101857
  };
@@ -101919,7 +101989,7 @@ function render$5t(_ctx, _cache, $props, $setup, $data, $options) {
101919
101989
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_9$2g, "· " + vue$1.toDisplayString(wp.status), 1 /* TEXT */))
101920
101990
  : vue$1.createCommentVNode("v-if", true),
101921
101991
  (wp.project)
101922
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$20, "· " + vue$1.toDisplayString(wp.project), 1 /* TEXT */))
101992
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$21, "· " + vue$1.toDisplayString(wp.project), 1 /* TEXT */))
101923
101993
  : vue$1.createCommentVNode("v-if", true)
101924
101994
  ])
101925
101995
  ])
@@ -102421,7 +102491,7 @@ const _hoisted_9$2f = {
102421
102491
  key: 7,
102422
102492
  class: "cn-openproject-tab__list"
102423
102493
  };
102424
- const _hoisted_10$1$ = ["title"];
102494
+ const _hoisted_10$20 = ["title"];
102425
102495
  const _hoisted_11$1I = { class: "cn-openproject-tab__subline" };
102426
102496
  const _hoisted_12$1t = {
102427
102497
  key: 0,
@@ -102589,7 +102659,7 @@ function render$5s(_ctx, _cache, $props, $setup, $data, $options) {
102589
102659
  key: 3,
102590
102660
  size: 18
102591
102661
  }))
102592
- ], 10 /* CLASS, PROPS */, _hoisted_10$1$)
102662
+ ], 10 /* CLASS, PROPS */, _hoisted_10$20)
102593
102663
  ]),
102594
102664
  subname: vue$1.withCtx(() => [
102595
102665
  vue$1.createElementVNode("span", _hoisted_11$1I, [
@@ -103012,7 +103082,7 @@ const _hoisted_9$2e = {
103012
103082
  key: 0,
103013
103083
  class: "cn-photos-card__photo-total"
103014
103084
  };
103015
- const _hoisted_10$1_ = {
103085
+ const _hoisted_10$1$ = {
103016
103086
  key: 0,
103017
103087
  class: "cn-photos-card__headline-album"
103018
103088
  };
@@ -103102,7 +103172,7 @@ function render$5r(_ctx, _cache, $props, $setup, $data, $options) {
103102
103172
  : vue$1.createCommentVNode("v-if", true)
103103
103173
  ]),
103104
103174
  ($options.firstAlbum)
103105
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1_, [
103175
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1$, [
103106
103176
  vue$1.createElementVNode("div", _hoisted_11$1H, [
103107
103177
  ($options.coverUrl($options.firstAlbum))
103108
103178
  ? (vue$1.openBlock(), vue$1.createElementBlock("img", {
@@ -103870,7 +103940,7 @@ const _hoisted_6$37 = {
103870
103940
  const _hoisted_7$2I = ["href", "title"];
103871
103941
  const _hoisted_8$2u = { class: "cn-photos-tab__cover" };
103872
103942
  const _hoisted_9$2d = ["src", "alt", "onError"];
103873
- const _hoisted_10$1Z = {
103943
+ const _hoisted_10$1_ = {
103874
103944
  key: 1,
103875
103945
  class: "cn-photos-tab__cover-placeholder"
103876
103946
  };
@@ -103979,7 +104049,7 @@ function render$5o(_ctx, _cache, $props, $setup, $data, $options) {
103979
104049
  loading: "lazy",
103980
104050
  onError: $event => ($options.onCoverError(album))
103981
104051
  }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_9$2d))
103982
- : (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$1Z, [
104052
+ : (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$1_, [
103983
104053
  vue$1.createVNode(_component_ImageMultiple, {
103984
104054
  size: 36,
103985
104055
  class: "cn-photos-tab__cover-fallback"
@@ -104436,7 +104506,7 @@ const _hoisted_9$2c = {
104436
104506
  key: 0,
104437
104507
  class: "cn-polls-card__headline-recent"
104438
104508
  };
104439
- const _hoisted_10$1Y = ["href"];
104509
+ const _hoisted_10$1Z = ["href"];
104440
104510
  const _hoisted_11$1F = {
104441
104511
  key: 0,
104442
104512
  class: "cn-polls-card__headline-leader"
@@ -104522,7 +104592,7 @@ function render$5n(_ctx, _cache, $props, $setup, $data, $options) {
104522
104592
  href: $options.pollUrl($options.mostRecent),
104523
104593
  target: "_blank",
104524
104594
  rel: "noopener"
104525
- }, vue$1.toDisplayString($options.pollTitle($options.mostRecent)), 9 /* TEXT, PROPS */, _hoisted_10$1Y),
104595
+ }, vue$1.toDisplayString($options.pollTitle($options.mostRecent)), 9 /* TEXT, PROPS */, _hoisted_10$1Z),
104526
104596
  ($options.leadingOption($options.mostRecent))
104527
104597
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_11$1F, " · " + vue$1.toDisplayString($options.leadingOption($options.mostRecent)), 1 /* TEXT */))
104528
104598
  : vue$1.createCommentVNode("v-if", true)
@@ -105448,7 +105518,7 @@ const _hoisted_6$33 = {
105448
105518
  const _hoisted_7$2F = { class: "cn-polls-tab__row-header" };
105449
105519
  const _hoisted_8$2r = ["title", "aria-label"];
105450
105520
  const _hoisted_9$2a = ["href"];
105451
- const _hoisted_10$1X = { class: "cn-polls-tab__meta" };
105521
+ const _hoisted_10$1Y = { class: "cn-polls-tab__meta" };
105452
105522
  const _hoisted_11$1E = { class: "cn-polls-tab__meta-item" };
105453
105523
  const _hoisted_12$1p = {
105454
105524
  key: 0,
@@ -105593,7 +105663,7 @@ function render$5k(_ctx, _cache, $props, $setup, $data, $options) {
105593
105663
  _: 1 /* STABLE */
105594
105664
  }, 8 /* PROPS */, ["aria-label", "onClick"])
105595
105665
  ]),
105596
- vue$1.createElementVNode("div", _hoisted_10$1X, [
105666
+ vue$1.createElementVNode("div", _hoisted_10$1Y, [
105597
105667
  vue$1.createElementVNode("span", _hoisted_11$1E, [
105598
105668
  vue$1.createVNode(_component_AccountMultiple, {
105599
105669
  size: 14,
@@ -106045,7 +106115,7 @@ const _hoisted_9$29 = {
106045
106115
  key: 0,
106046
106116
  class: "cn-shares-card__empty"
106047
106117
  };
106048
- const _hoisted_10$1W = {
106118
+ const _hoisted_10$1X = {
106049
106119
  key: 1,
106050
106120
  class: "cn-shares-card__empty"
106051
106121
  };
@@ -106116,7 +106186,7 @@ function render$5j(_ctx, _cache, $props, $setup, $data, $options) {
106116
106186
  ($data.degraded)
106117
106187
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_9$29, vue$1.toDisplayString($data.degraded), 1 /* TEXT */))
106118
106188
  : ($data.shares.length === 0)
106119
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1W, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
106189
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1X, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
106120
106190
  : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_11$1D, [
106121
106191
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.groupedShares, (group) => {
106122
106192
  return (vue$1.openBlock(), vue$1.createElementBlock("section", {
@@ -106385,7 +106455,7 @@ const _hoisted_9$28 = {
106385
106455
  key: 3,
106386
106456
  class: "cn-share-create__field"
106387
106457
  };
106388
- const _hoisted_10$1V = { class: "cn-share-create__field" };
106458
+ const _hoisted_10$1W = { class: "cn-share-create__field" };
106389
106459
  const _hoisted_11$1C = { class: "cn-share-create__label" };
106390
106460
 
106391
106461
  function render$5i(_ctx, _cache, $props, $setup, $data, $options) {
@@ -106528,7 +106598,7 @@ function render$5i(_ctx, _cache, $props, $setup, $data, $options) {
106528
106598
  }, null, 8 /* PROPS */, ["modelValue", "label"])
106529
106599
  ]))
106530
106600
  : vue$1.createCommentVNode("v-if", true),
106531
- vue$1.createElementVNode("label", _hoisted_10$1V, [
106601
+ vue$1.createElementVNode("label", _hoisted_10$1W, [
106532
106602
  vue$1.createElementVNode("span", _hoisted_11$1C, vue$1.toDisplayString($options.t('nextcloud-vue', 'Expiration (optional)')), 1 /* TEXT */),
106533
106603
  vue$1.withDirectives(vue$1.createElementVNode("input", {
106534
106604
  "onUpdate:modelValue": _cache[6] || (_cache[6] = $event => (($data.expiration) = $event)),
@@ -106917,7 +106987,7 @@ const _hoisted_6$30 = {
106917
106987
  const _hoisted_7$2C = { class: "cn-shares-tab__group-header" };
106918
106988
  const _hoisted_8$2o = { class: "cn-shares-tab__group-label" };
106919
106989
  const _hoisted_9$27 = { class: "cn-shares-tab__group-count" };
106920
- const _hoisted_10$1U = { class: "cn-shares-tab__list" };
106990
+ const _hoisted_10$1V = { class: "cn-shares-tab__list" };
106921
106991
  const _hoisted_11$1B = {
106922
106992
  class: "cn-shares-tab__avatar",
106923
106993
  "aria-hidden": true
@@ -107001,7 +107071,7 @@ function render$5h(_ctx, _cache, $props, $setup, $data, $options) {
107001
107071
  vue$1.createElementVNode("span", _hoisted_8$2o, vue$1.toDisplayString(group.label), 1 /* TEXT */),
107002
107072
  vue$1.createElementVNode("span", _hoisted_9$27, vue$1.toDisplayString(group.rows.length), 1 /* TEXT */)
107003
107073
  ]),
107004
- vue$1.createElementVNode("ul", _hoisted_10$1U, [
107074
+ vue$1.createElementVNode("ul", _hoisted_10$1V, [
107005
107075
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList(group.rows, (share) => {
107006
107076
  return (vue$1.openBlock(), vue$1.createBlock(_component_NcListItem, {
107007
107077
  key: $options.shareKey(share),
@@ -107872,7 +107942,7 @@ const _hoisted_9$26 = {
107872
107942
  key: 0,
107873
107943
  class: "cn-talk-card__headline-recent"
107874
107944
  };
107875
- const _hoisted_10$1T = ["href"];
107945
+ const _hoisted_10$1U = ["href"];
107876
107946
  const _hoisted_11$1A = {
107877
107947
  key: 0,
107878
107948
  class: "cn-talk-card__headline-preview"
@@ -107953,7 +108023,7 @@ function render$5e(_ctx, _cache, $props, $setup, $data, $options) {
107953
108023
  href: $options.roomUrl($options.mostRecent),
107954
108024
  target: "_blank",
107955
108025
  rel: "noopener"
107956
- }, vue$1.toDisplayString($options.roomTitle($options.mostRecent)), 9 /* TEXT, PROPS */, _hoisted_10$1T),
108026
+ }, vue$1.toDisplayString($options.roomTitle($options.mostRecent)), 9 /* TEXT, PROPS */, _hoisted_10$1U),
107957
108027
  ($options.roomPreview($options.mostRecent))
107958
108028
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_11$1A, " · " + vue$1.toDisplayString($options.roomPreview($options.mostRecent)), 1 /* TEXT */))
107959
108029
  : vue$1.createCommentVNode("v-if", true)
@@ -112880,7 +112950,7 @@ const _hoisted_6$2X = ["href"];
112880
112950
  const _hoisted_7$2y = { class: "cn-flow-tasks__meta" };
112881
112951
  const _hoisted_8$2l = { class: "cn-flow-tasks__state" };
112882
112952
  const _hoisted_9$25 = { class: "cn-flow-tasks__verbs" };
112883
- const _hoisted_10$1S = {
112953
+ const _hoisted_10$1T = {
112884
112954
  key: 2,
112885
112955
  class: "cn-flow-tasks__error",
112886
112956
  role: "alert",
@@ -113027,7 +113097,7 @@ function render$5a(_ctx, _cache, $props, $setup, $data, $options) {
113027
113097
  }, null, 8 /* PROPS */, ["options", "inputLabel", "onSearch", "onUpdate:modelValue"]))
113028
113098
  : vue$1.createCommentVNode("v-if", true),
113029
113099
  ($data.rowErrors[$options.uuidOf(task)])
113030
- ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_10$1S, vue$1.toDisplayString($data.rowErrors[$options.uuidOf(task)]), 1 /* TEXT */))
113100
+ ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_10$1T, vue$1.toDisplayString($data.rowErrors[$options.uuidOf(task)]), 1 /* TEXT */))
113031
113101
  : vue$1.createCommentVNode("v-if", true)
113032
113102
  ], 8 /* PROPS */, _hoisted_5$3c))
113033
113103
  }), 128 /* KEYED_FRAGMENT */))
@@ -113854,7 +113924,7 @@ const _hoisted_8$2j = {
113854
113924
  class: "cn-tasks-card__assignee"
113855
113925
  };
113856
113926
  const _hoisted_9$23 = { class: "cn-tasks-card__assignee-name" };
113857
- const _hoisted_10$1R = {
113927
+ const _hoisted_10$1S = {
113858
113928
  key: 1,
113859
113929
  class: "cn-tasks-card__assignee-name cn-tasks-card__assignee-name--self"
113860
113930
  };
@@ -113930,7 +114000,7 @@ function render$58(_ctx, _cache, $props, $setup, $data, $options) {
113930
114000
  ]),
113931
114001
  _: 2 /* DYNAMIC */
113932
114002
  }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["userId", "displayName"]))
113933
- : (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$1R, vue$1.toDisplayString(task.assignee), 1 /* TEXT */))
114003
+ : (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$1S, vue$1.toDisplayString(task.assignee), 1 /* TEXT */))
113934
114004
  ]))
113935
114005
  : (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_11$1y, vue$1.toDisplayString($props.unassignedLabel), 1 /* TEXT */)),
113936
114006
  (task.dueDate)
@@ -114362,7 +114432,7 @@ const _hoisted_9$22 = {
114362
114432
  key: 1,
114363
114433
  class: "cn-time-tracker-card__distribution"
114364
114434
  };
114365
- const _hoisted_10$1Q = { class: "cn-time-tracker-card__distribution-label" };
114435
+ const _hoisted_10$1R = { class: "cn-time-tracker-card__distribution-label" };
114366
114436
  const _hoisted_11$1x = { class: "cn-time-tracker-card__distribution-count" };
114367
114437
  const _hoisted_12$1k = {
114368
114438
  key: 2,
@@ -114444,7 +114514,7 @@ function render$57(_ctx, _cache, $props, $setup, $data, $options) {
114444
114514
  key: bucket.key,
114445
114515
  class: "cn-time-tracker-card__distribution-row"
114446
114516
  }, [
114447
- vue$1.createElementVNode("span", _hoisted_10$1Q, [
114517
+ vue$1.createElementVNode("span", _hoisted_10$1R, [
114448
114518
  vue$1.createElementVNode("span", {
114449
114519
  class: vue$1.normalizeClass(["cn-time-tracker-card__distribution-dot", `cn-time-tracker-card__distribution-dot--${bucket.key}`])
114450
114520
  }, null, 2 /* CLASS */),
@@ -115320,7 +115390,7 @@ const _hoisted_6$2S = {
115320
115390
  const _hoisted_7$2u = { class: "cn-time-tracker-tab__summary-label" };
115321
115391
  const _hoisted_8$2h = { class: "cn-time-tracker-tab__summary-value" };
115322
115392
  const _hoisted_9$21 = { class: "cn-time-tracker-tab__list" };
115323
- const _hoisted_10$1P = { class: "cn-time-tracker-tab__subline" };
115393
+ const _hoisted_10$1Q = { class: "cn-time-tracker-tab__subline" };
115324
115394
  const _hoisted_11$1w = {
115325
115395
  key: 1,
115326
115396
  class: "cn-time-tracker-tab__task-count"
@@ -115452,7 +115522,7 @@ function render$54(_ctx, _cache, $props, $setup, $data, $options) {
115452
115522
  ], 2 /* CLASS */)
115453
115523
  ]),
115454
115524
  subname: vue$1.withCtx(() => [
115455
- vue$1.createElementVNode("span", _hoisted_10$1P, [
115525
+ vue$1.createElementVNode("span", _hoisted_10$1Q, [
115456
115526
  vue$1.createElementVNode("span", {
115457
115527
  class: vue$1.normalizeClass(["cn-time-tracker-tab__kind-chip", $options.kindChipClass(row)])
115458
115528
  }, vue$1.toDisplayString($options.kindLabel(row)), 3 /* TEXT, CLASS */),
@@ -115951,7 +116021,7 @@ const _hoisted_6$2R = { class: "cn-version-history__action" };
115951
116021
  const _hoisted_7$2t = { class: "cn-version-history__when" };
115952
116022
  const _hoisted_8$2g = { class: "cn-version-history__user" };
115953
116023
  const _hoisted_9$20 = { class: "cn-version-history__toolbar" };
115954
- const _hoisted_10$1O = {
116024
+ const _hoisted_10$1P = {
115955
116025
  key: 3,
115956
116026
  class: "cn-version-history__diff"
115957
116027
  };
@@ -116042,7 +116112,7 @@ function render$53(_ctx, _cache, $props, $setup, $data, $options) {
116042
116112
  : vue$1.createCommentVNode("v-if", true)
116043
116113
  ])
116044
116114
  ]))
116045
- : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1O, [
116115
+ : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1P, [
116046
116116
  vue$1.createElementVNode("div", _hoisted_11$1v, [
116047
116117
  vue$1.createVNode(_component_NcButton, {
116048
116118
  variant: "tertiary",
@@ -116537,7 +116607,7 @@ const _hoisted_9$1$ = {
116537
116607
  key: 1,
116538
116608
  class: "cn-xwiki-card__count cn-xwiki-card__count--muted"
116539
116609
  };
116540
- const _hoisted_10$1N = ["title"];
116610
+ const _hoisted_10$1O = ["title"];
116541
116611
  const _hoisted_11$1u = {
116542
116612
  key: 0,
116543
116613
  class: "cn-xwiki-card__recent"
@@ -116619,7 +116689,7 @@ function render$52(_ctx, _cache, $props, $setup, $data, $options) {
116619
116689
  vue$1.createElementVNode("span", {
116620
116690
  class: vue$1.normalizeClass(["cn-xwiki-card__auth-badge", `cn-xwiki-card__auth-badge--${$options.authBadge.kind}`]),
116621
116691
  title: $options.authBadge.title
116622
- }, vue$1.toDisplayString($options.authBadge.label), 11 /* TEXT, CLASS, PROPS */, _hoisted_10$1N)
116692
+ }, vue$1.toDisplayString($options.authBadge.label), 11 /* TEXT, CLASS, PROPS */, _hoisted_10$1O)
116623
116693
  ]),
116624
116694
  (!$data.degraded && $options.mostRecent)
116625
116695
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_11$1u, [
@@ -124377,7 +124447,7 @@ const _hoisted_8$2c = {
124377
124447
  class: "cn-form-dialog__textarea-wrapper"
124378
124448
  };
124379
124449
  const _hoisted_9$1Z = ["for"];
124380
- const _hoisted_10$1M = ["id", "value", "disabled", "placeholder", "onInput"];
124450
+ const _hoisted_10$1N = ["id", "value", "disabled", "placeholder", "onInput"];
124381
124451
  const _hoisted_11$1t = {
124382
124452
  key: 3,
124383
124453
  class: "cn-form-dialog__select-wrapper"
@@ -124824,7 +124894,7 @@ function render$4_(_ctx, _cache, $props, $setup, $data, $options) {
124824
124894
  placeholder: field.description,
124825
124895
  rows: "4",
124826
124896
  onInput: $event => ($options.updateField(field.key, $event.target.value))
124827
- }), null, 16 /* FULL_PROPS */, _hoisted_10$1M),
124897
+ }), null, 16 /* FULL_PROPS */, _hoisted_10$1N),
124828
124898
  vue$1.createVNode(_component_CnFieldHelper, {
124829
124899
  id: $options.helpId(field),
124830
124900
  text: field.description,
@@ -125666,7 +125736,7 @@ const _hoisted_8$2b = {
125666
125736
  class: "cn-pagination__nav"
125667
125737
  };
125668
125738
  const _hoisted_9$1Y = { class: "cn-pagination__numbers" };
125669
- const _hoisted_10$1L = {
125739
+ const _hoisted_10$1M = {
125670
125740
  key: 4,
125671
125741
  class: "cn-pagination__page-size"
125672
125742
  };
@@ -125823,7 +125893,7 @@ function render$4Z(_ctx, _cache, $props, $setup, $data, $options) {
125823
125893
  ]))
125824
125894
  : vue$1.createCommentVNode("v-if", true),
125825
125895
  (!$props.compact && !$options.isBoardVariant)
125826
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1L, [
125896
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1M, [
125827
125897
  vue$1.createElementVNode("label", { for: $options.pageSizeId }, vue$1.toDisplayString($props.itemsPerPageLabel), 9 /* TEXT, PROPS */, _hoisted_11$1s),
125828
125898
  vue$1.createVNode(_component_NcSelect, {
125829
125899
  inputId: $options.pageSizeId,
@@ -126503,7 +126573,8 @@ var script$4X = {
126503
126573
  * Host translate function provided by CnAppRoot as
126504
126574
  * `cnTranslate: this.translate` (bound to the host app's id). The
126505
126575
  * manifest-authored `content.emptyText` is run through it for this
126506
- * component's OWN empty state, and so is `content.prompt`. Defaults to an identity function so
126576
+ * component's OWN empty state, and so are `content.prompt` and
126577
+ * `content.addLabel`. Defaults to an identity function so
126507
126578
  * an untranslated key renders as itself.
126508
126579
  */
126509
126580
  cnTranslate: { default: () => (key) => key },
@@ -127238,9 +127309,24 @@ var script$4X = {
127238
127309
  return (c.formFieldOverrides && typeof c.formFieldOverrides === 'object') ? c.formFieldOverrides : {}
127239
127310
  },
127240
127311
 
127241
- /** Pre-translated Add label (overridable via `content.addLabel`). */
127312
+ /**
127313
+ * The Add label: `content.addLabel` through the app's translate
127314
+ * function, else the library's "Add".
127315
+ *
127316
+ * @spec openspec/changes/r4-object-lock-url-and-credentials-copy/specs/object-list-add-label/spec.md
127317
+ * @return {string}
127318
+ */
127242
127319
  addLabel() {
127243
- return this.content.addLabel || l10n.translate('nextcloud-vue', 'Add')
127320
+ // `content.addLabel` is manifest copy in the APP's catalogue, so it
127321
+ // goes through the host translate function like `emptyText` and
127322
+ // `prompt`. It used to print raw, so a Dutch user read the English
127323
+ // manifest string. A label an app already translated has no key
127324
+ // of its own in the catalogue and comes back unchanged.
127325
+ if (this.content.addLabel) {
127326
+ const fn = typeof this.cnTranslate === 'function' ? this.cnTranslate : (k) => k;
127327
+ return fn(this.content.addLabel)
127328
+ }
127329
+ return l10n.translate('nextcloud-vue', 'Add')
127244
127330
  },
127245
127331
 
127246
127332
  /** Stable signature of the query so the watcher only refetches on real change. */
@@ -128029,7 +128115,7 @@ const _hoisted_7$2n = {
128029
128115
  };
128030
128116
  const _hoisted_8$2a = { class: "cn-object-list-widget__bulk-count" };
128031
128117
  const _hoisted_9$1X = ["onClick"];
128032
- const _hoisted_10$1K = {
128118
+ const _hoisted_10$1L = {
128033
128119
  key: 2,
128034
128120
  class: "cn-object-list-widget__groups"
128035
128121
  };
@@ -128158,7 +128244,7 @@ function render$4X(_ctx, _cache, $props, $setup, $data, $options) {
128158
128244
  ]))
128159
128245
  : vue$1.createCommentVNode("v-if", true),
128160
128246
  ($options.isGrouped)
128161
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1K, [
128247
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1L, [
128162
128248
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.groupedRows, (group) => {
128163
128249
  return (vue$1.openBlock(), vue$1.createElementBlock("div", {
128164
128250
  key: group.key,
@@ -130713,7 +130799,7 @@ const _hoisted_9$1W = {
130713
130799
  key: 1,
130714
130800
  class: "cn-widget-wrapper__floating-meta"
130715
130801
  };
130716
- const _hoisted_10$1J = ["aria-labelledby", "aria-label"];
130802
+ const _hoisted_10$1K = ["aria-labelledby", "aria-label"];
130717
130803
  const _hoisted_11$1q = {
130718
130804
  key: 2,
130719
130805
  class: "cn-widget-wrapper__footer"
@@ -130843,7 +130929,7 @@ function render$4U(_ctx, _cache, $props, $setup, $data, $options) {
130843
130929
  "aria-label": $options.titleVisible ? null : $options.resolvedTitle
130844
130930
  }, [
130845
130931
  vue$1.renderSlot(_ctx.$slots, "default")
130846
- ], 8 /* PROPS */, _hoisted_10$1J),
130932
+ ], 8 /* PROPS */, _hoisted_10$1K),
130847
130933
  (_ctx.$slots.footer || ($props.buttons && $props.buttons.length > 0))
130848
130934
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_11$1q, [
130849
130935
  vue$1.renderSlot(_ctx.$slots, "footer", {}, () => [
@@ -131282,6 +131368,12 @@ var script$4T = {
131282
131368
  groups: [],
131283
131369
  /** Active tab key. */
131284
131370
  activeKey: '',
131371
+ /** Keys of the tabbed sections whose request is still in flight (`objects`, `files`, `relations`). */
131372
+ pendingSections: [],
131373
+ /** Tabbed sections whose request failed: `{ key, label }`. */
131374
+ failedSections: [],
131375
+ /** Bumped per `loadTabs()`; an answer from an older load is dropped. */
131376
+ loadToken: 0,
131285
131377
  /** Key of the inline-expanded row (`{group}-{id}`) for leaves with no owning-app page (e.g. notes). */
131286
131378
  expandedKey: '',
131287
131379
  /** Whether a footer file upload is in flight. */
@@ -131406,6 +131498,22 @@ var script$4T = {
131406
131498
  )
131407
131499
  },
131408
131500
 
131501
+ /**
131502
+ * The line under the panel naming the sections still loading, once
131503
+ * another section is already on screen.
131504
+ *
131505
+ * @return {string}
131506
+ */
131507
+ pendingLabel() {
131508
+ const labels = {
131509
+ objects: this.objectsLabel,
131510
+ files: this.filesLabel,
131511
+ relations: l10n.translate('nextcloud-vue', 'Linked items'),
131512
+ };
131513
+ const names = this.pendingSections.map((key) => labels[key] || key).join(', ');
131514
+ return l10n.translate('nextcloud-vue', 'Still loading: {sections}', { sections: names })
131515
+ },
131516
+
131409
131517
  /** Placeholder shown in the body while the first fetch is in flight. */
131410
131518
  loadingLabel() {
131411
131519
  return l10n.translate('nextcloud-vue', 'Loading …')
@@ -131902,16 +132010,27 @@ var script$4T = {
131902
132010
  * @return {Promise<object|null>}
131903
132011
  */
131904
132012
  async fetchSubResource(suffix) {
132013
+ return (await this.fetchSection(suffix)).data
132014
+ },
132015
+
132016
+ /**
132017
+ * GET an OpenRegister sub-resource and say whether it answered, so a
132018
+ * section can tell "nothing linked" from "could not load".
132019
+ *
132020
+ * @param {string} suffix - The sub-resource suffix.
132021
+ * @return {Promise<{ ok: boolean, data: object|null }>}
132022
+ */
132023
+ async fetchSection(suffix) {
131905
132024
  try {
131906
132025
  // `no-store`: relations change as the user links content; a stale
131907
132026
  // cached empty response would wrongly show the empty state on load.
131908
132027
  const response = await fetch(this.relatedUrl(suffix), { method: 'GET', headers: buildHeaders(), cache: 'no-store' });
131909
132028
  if (!response.ok) {
131910
- return null
132029
+ return { ok: false, data: null }
131911
132030
  }
131912
- return await response.json()
132031
+ return { ok: true, data: await response.json() }
131913
132032
  } catch {
131914
- return null
132033
+ return { ok: false, data: null }
131915
132034
  }
131916
132035
  },
131917
132036
 
@@ -132115,56 +132234,138 @@ var script$4T = {
132115
132234
  },
132116
132235
 
132117
132236
  /**
132118
- * Fetch every group directly from OpenRegister and build the tabs.
132237
+ * Fetch every group directly from OpenRegister and build the tabs,
132238
+ * one section at a time.
132239
+ *
132240
+ * 🔴 EACH SECTION SHOWS WHEN ITS OWN REQUEST RETURNS. This used to wait
132241
+ * for relations, uses, used, contracts and files together behind one
132242
+ * `Promise.all`, so the relations call (0.45 s on pipelinq's lead page)
132243
+ * sat behind uses/used (about 9 s) and the card said "Loading …" the
132244
+ * whole time. Now the groups are laid out up front in their fixed order
132245
+ * and filled in place as each answer arrives, so a slow section never
132246
+ * reorders or hides a fast one. A section still in flight is named in
132247
+ * `pendingSections`; one whose request failed in `failedSections`.
132119
132248
  *
132249
+ * @spec openspec/changes/r4-object-lock-url-and-credentials-copy/specs/related-objects-progressive/spec.md
132120
132250
  * @return {Promise<void>}
132121
132251
  */
132122
132252
  async loadTabs() {
132253
+ const token = ++this.loadToken;
132254
+ const current = () => token === this.loadToken;
132123
132255
  this.loading = true;
132124
- try {
132125
- const [relations, uses, used, contracts, files] = await Promise.all([
132126
- this.fetchSubResource('relations'),
132127
- this.showObjects ? this.fetchSubResource('uses') : null,
132128
- this.showObjects ? this.fetchSubResource('used') : null,
132129
- (this.showObjects && this.showContracts) ? this.fetchSubResource('contracts') : null,
132130
- this.showFiles ? this.fetchSubResource('files') : null,
132131
- ]);
132256
+ this.failedSections = [];
132132
132257
 
132133
- const groups = [];
132258
+ const objectSuffixes = this.showObjects
132259
+ ? ['uses', 'used', ...(this.showContracts ? ['contracts'] : [])]
132260
+ : [];
132261
+ const sections = [
132262
+ ...(this.showObjects ? [{ key: 'objects', label: this.objectsLabel }] : []),
132263
+ ...(this.showFiles ? [{ key: 'files', label: this.filesLabel }] : []),
132264
+ { key: 'relations', label: l10n.translate('nextcloud-vue', 'Linked items') },
132265
+ ];
132266
+ this.pendingSections = sections.map((section) => section.key);
132134
132267
 
132135
- if (this.showObjects) {
132136
- await this.resolveSchemaTitles([uses, used, contracts]);
132137
- const objectItems = this.mergeObjectResults([uses, used, contracts]);
132138
- groups.push({ key: 'objects', label: this.objectsLabel, icon: 'FileTreeOutline', integrationId: '', items: objectItems, total: objectItems.length });
132139
- }
132268
+ // Lay out every group now, in its fixed order, empty. visibleGroups
132269
+ // hides an empty group, so nothing shows until a section fills it.
132270
+ const groups = [];
132271
+ if (this.showObjects) {
132272
+ groups.push({ key: 'objects', label: this.objectsLabel, icon: 'FileTreeOutline', integrationId: '', items: [], total: 0 });
132273
+ }
132274
+ if (this.showFiles) {
132275
+ groups.push({ key: 'files', label: this.filesLabel, icon: 'Paperclip', integrationId: 'files', items: [], total: 0 });
132276
+ }
132277
+ for (const def of LEAF_GROUPS) {
132278
+ groups.push({
132279
+ key: def.key,
132280
+ label: this.leafLabel(def.key),
132281
+ // Prefer the registered integration's icon so it matches the
132282
+ // sidebar/linked-apps; fall back to the known-good default.
132283
+ icon: this.integrationIcon(def.integrationId) || def.icon,
132284
+ integrationId: def.integrationId,
132285
+ requiredApp: def.requiredApp,
132286
+ items: [],
132287
+ total: 0,
132288
+ });
132289
+ }
132290
+ this.groups = groups;
132140
132291
 
132141
- if (this.showFiles) {
132142
- const fileResults = (files && files.results) || [];
132143
- groups.push({ key: 'files', label: this.filesLabel, icon: 'Paperclip', integrationId: 'files', items: fileResults.map((f) => this.toFileRow(f)), total: files ? (files.total ?? fileResults.length) : 0 });
132292
+ const setGroup = (key, items, total) => {
132293
+ const index = this.groups.findIndex((group) => group.key === key);
132294
+ if (index === -1) {
132295
+ return
132296
+ }
132297
+ const next = this.groups.slice();
132298
+ next[index] = { ...next[index], items, total };
132299
+ this.groups = next;
132300
+ };
132301
+ const settle = (key, ok) => {
132302
+ this.pendingSections = this.pendingSections.filter((k) => k !== key);
132303
+ if (!ok) {
132304
+ const section = sections.find((s) => s.key === key);
132305
+ this.failedSections = [...this.failedSections, { key, label: section ? section.label : key }];
132144
132306
  }
132307
+ // Keep the tab the reader saw first: pin it, so a slower section
132308
+ // that sorts before it does not take the panel away.
132309
+ if (!this.activeKey && this.visibleGroups.length) {
132310
+ this.activeKey = this.visibleGroups[0].key;
132311
+ }
132312
+ };
132145
132313
 
132314
+ const loadRelations = this.fetchSection('relations').then(({ ok, data }) => {
132315
+ if (!current()) {
132316
+ return
132317
+ }
132146
132318
  for (const def of LEAF_GROUPS) {
132147
- const block = relations && relations[def.responseKey];
132319
+ const block = data && data[def.responseKey];
132148
132320
  const results = (block && block.results) || [];
132149
- groups.push({
132150
- key: def.key,
132151
- label: this.leafLabel(def.key),
132152
- // Prefer the registered integration's icon so it matches the
132153
- // sidebar/linked-apps; fall back to the known-good default.
132154
- icon: this.integrationIcon(def.integrationId) || def.icon,
132155
- integrationId: def.integrationId,
132156
- requiredApp: def.requiredApp,
132157
- items: results.map((r, i) => this.toLeafRow(r, i)),
132158
- total: block ? (block.total ?? results.length) : 0,
132159
- });
132321
+ setGroup(def.key, results.map((r, i) => this.toLeafRow(r, i)), block ? (block.total ?? results.length) : 0);
132160
132322
  }
132323
+ settle('relations', ok);
132324
+ });
132161
132325
 
132162
- this.groups = groups;
132163
- if (!this.activeGroup && this.visibleGroups.length) {
132164
- this.activeKey = this.visibleGroups[0].key;
132165
- }
132326
+ const loadFiles = this.showFiles
132327
+ ? this.fetchSection('files').then(({ ok, data }) => {
132328
+ if (!current()) {
132329
+ return
132330
+ }
132331
+ const fileResults = (data && data.results) || [];
132332
+ setGroup('files', fileResults.map((f) => this.toFileRow(f)), data ? (data.total ?? fileResults.length) : 0);
132333
+ settle('files', ok);
132334
+ })
132335
+ : null;
132336
+
132337
+ // uses, used and contracts merge into one Objects group: each answer
132338
+ // re-merges what has arrived so far, and the group stays pending
132339
+ // until the last of them is in.
132340
+ const envelopes = objectSuffixes.map(() => null);
132341
+ let objectsOk = true;
132342
+ const loadObjects = objectSuffixes.length
132343
+ ? Promise.all(objectSuffixes.map((suffix, i) => this.fetchSection(suffix).then(async ({ ok, data }) => {
132344
+ if (!current()) {
132345
+ return
132346
+ }
132347
+ objectsOk = objectsOk && ok;
132348
+ envelopes[i] = data;
132349
+ await this.resolveSchemaTitles([data]);
132350
+ if (!current()) {
132351
+ return
132352
+ }
132353
+ const objectItems = this.mergeObjectResults(envelopes);
132354
+ setGroup('objects', objectItems, objectItems.length);
132355
+ }))).then(() => {
132356
+ if (current()) {
132357
+ settle('objects', objectsOk);
132358
+ }
132359
+ })
132360
+ : null;
132361
+
132362
+ try {
132363
+ await Promise.all([loadRelations, loadFiles, loadObjects]);
132166
132364
  } finally {
132167
- this.loading = false;
132365
+ if (current()) {
132366
+ this.loading = false;
132367
+ this.pendingSections = [];
132368
+ }
132168
132369
  }
132169
132370
  },
132170
132371
 
@@ -132318,7 +132519,7 @@ const _hoisted_7$2l = {
132318
132519
  };
132319
132520
  const _hoisted_8$28 = { class: "cn-related-objects-widget__list" };
132320
132521
  const _hoisted_9$1V = ["href"];
132321
- const _hoisted_10$1I = { class: "cn-related-objects-widget__label" };
132522
+ const _hoisted_10$1J = { class: "cn-related-objects-widget__label" };
132322
132523
  const _hoisted_11$1p = {
132323
132524
  key: 0,
132324
132525
  class: "cn-related-objects-widget__meta"
@@ -132335,59 +132536,66 @@ const _hoisted_15$W = {
132335
132536
  };
132336
132537
  const _hoisted_16$N = {
132337
132538
  key: 2,
132539
+ class: "cn-related-objects-widget__section-status",
132540
+ "data-testid": "cn-related-pending",
132541
+ role: "status"
132542
+ };
132543
+ const _hoisted_17$G = ["data-section"];
132544
+ const _hoisted_18$B = {
132545
+ key: 3,
132338
132546
  class: "cn-related-objects-widget__empty"
132339
132547
  };
132340
- const _hoisted_17$G = {
132548
+ const _hoisted_19$x = {
132341
132549
  key: 0,
132342
132550
  class: "cn-related-objects-widget__group"
132343
132551
  };
132344
- const _hoisted_18$B = { class: "cn-related-objects-widget__group-title" };
132345
- const _hoisted_19$x = { class: "cn-related-objects-widget__count" };
132346
- const _hoisted_20$t = { class: "cn-related-objects-widget__list" };
132347
- const _hoisted_21$r = ["onClick", "onKeydown"];
132348
- const _hoisted_22$r = { class: "cn-related-objects-widget__label" };
132349
- const _hoisted_23$m = {
132552
+ const _hoisted_20$t = { class: "cn-related-objects-widget__group-title" };
132553
+ const _hoisted_21$r = { class: "cn-related-objects-widget__count" };
132554
+ const _hoisted_22$r = { class: "cn-related-objects-widget__list" };
132555
+ const _hoisted_23$m = ["onClick", "onKeydown"];
132556
+ const _hoisted_24$j = { class: "cn-related-objects-widget__label" };
132557
+ const _hoisted_25$h = {
132350
132558
  key: 0,
132351
132559
  class: "cn-related-objects-widget__meta"
132352
132560
  };
132353
- const _hoisted_24$j = {
132561
+ const _hoisted_26$f = {
132354
132562
  key: 1,
132355
132563
  class: "cn-related-objects-widget__group"
132356
132564
  };
132357
- const _hoisted_25$h = { class: "cn-related-objects-widget__group-title" };
132358
- const _hoisted_26$f = { class: "cn-related-objects-widget__count" };
132359
- const _hoisted_27$a = { class: "cn-related-objects-widget__list" };
132360
- const _hoisted_28$a = ["onClick", "onKeydown"];
132361
- const _hoisted_29$9 = { class: "cn-related-objects-widget__label" };
132362
- const _hoisted_30$8 = {
132565
+ const _hoisted_27$a = { class: "cn-related-objects-widget__group-title" };
132566
+ const _hoisted_28$a = { class: "cn-related-objects-widget__count" };
132567
+ const _hoisted_29$9 = { class: "cn-related-objects-widget__list" };
132568
+ const _hoisted_30$8 = ["onClick", "onKeydown"];
132569
+ const _hoisted_31$8 = { class: "cn-related-objects-widget__label" };
132570
+ const _hoisted_32$8 = {
132363
132571
  key: 0,
132364
132572
  class: "cn-related-objects-widget__meta"
132365
132573
  };
132366
- const _hoisted_31$8 = {
132574
+ const _hoisted_33$7 = {
132367
132575
  key: 0,
132368
132576
  class: "cn-related-objects-widget__group-title"
132369
132577
  };
132370
- const _hoisted_32$8 = { class: "cn-related-objects-widget__count" };
132371
- const _hoisted_33$7 = {
132578
+ const _hoisted_34$7 = { class: "cn-related-objects-widget__count" };
132579
+ const _hoisted_35$7 = {
132372
132580
  key: 1,
132373
132581
  class: "cn-related-objects-widget__list"
132374
132582
  };
132375
- const _hoisted_34$7 = ["onClick", "onKeydown"];
132376
- const _hoisted_35$7 = { class: "cn-related-objects-widget__label" };
132377
- const _hoisted_36$7 = {
132583
+ const _hoisted_36$7 = ["onClick", "onKeydown"];
132584
+ const _hoisted_37$5 = { class: "cn-related-objects-widget__label" };
132585
+ const _hoisted_38$4 = {
132378
132586
  key: 2,
132379
132587
  class: "cn-related-objects-widget__group"
132380
132588
  };
132381
- const _hoisted_37$5 = { class: "cn-related-objects-widget__group-title" };
132382
- const _hoisted_38$4 = { class: "cn-related-objects-widget__list cn-related-objects-widget__list--apps" };
132383
- const _hoisted_39$3 = ["onClick", "onKeydown"];
132384
- const _hoisted_40$3 = { class: "cn-related-objects-widget__label" };
132385
- const _hoisted_41$1 = {
132589
+ const _hoisted_39$3 = { class: "cn-related-objects-widget__group-title" };
132590
+ const _hoisted_40$3 = { class: "cn-related-objects-widget__list cn-related-objects-widget__list--apps" };
132591
+ const _hoisted_41$1 = ["onClick", "onKeydown"];
132592
+ const _hoisted_42$1 = { class: "cn-related-objects-widget__label" };
132593
+ const _hoisted_43$1 = {
132386
132594
  key: 3,
132387
132595
  class: "cn-related-objects-widget__empty"
132388
132596
  };
132389
- const _hoisted_42$1 = { class: "cn-related-objects-widget__footer" };
132390
- const _hoisted_43$1 = {
132597
+ const _hoisted_44$1 = { class: "cn-related-objects-widget__footer" };
132598
+ const _hoisted_45$1 = {
132391
132599
  key: 2,
132392
132600
  class: "cn-related-objects-widget__add-error"
132393
132601
  };
@@ -132460,7 +132668,7 @@ function render$4T(_ctx, _cache, $props, $setup, $data, $options) {
132460
132668
  size: 20,
132461
132669
  class: "cn-related-objects-widget__icon"
132462
132670
  }, null, 8 /* PROPS */, ["name"]),
132463
- vue$1.createElementVNode("span", _hoisted_10$1I, vue$1.toDisplayString(item.label), 1 /* TEXT */),
132671
+ vue$1.createElementVNode("span", _hoisted_10$1J, vue$1.toDisplayString(item.label), 1 /* TEXT */),
132464
132672
  (item.meta)
132465
132673
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_11$1p, vue$1.toDisplayString(item.meta), 1 /* TEXT */))
132466
132674
  : vue$1.createCommentVNode("v-if", true)
@@ -132491,11 +132699,22 @@ function render$4T(_ctx, _cache, $props, $setup, $data, $options) {
132491
132699
  ])
132492
132700
  ]))
132493
132701
  : vue$1.createCommentVNode("v-if", true),
132702
+ ($options.visibleGroups.length && $data.pendingSections.length)
132703
+ ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_16$N, vue$1.toDisplayString($options.pendingLabel), 1 /* TEXT */))
132704
+ : vue$1.createCommentVNode("v-if", true),
132705
+ (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($data.failedSections, (failed) => {
132706
+ return (vue$1.openBlock(), vue$1.createElementBlock("p", {
132707
+ key: `failed-${failed.key}`,
132708
+ class: "cn-related-objects-widget__section-error",
132709
+ "data-testid": "cn-related-section-error",
132710
+ "data-section": failed.key
132711
+ }, vue$1.toDisplayString($options.t('nextcloud-vue', 'Could not load {section}.', { section: failed.label })), 9 /* TEXT, PROPS */, _hoisted_17$G))
132712
+ }), 128 /* KEYED_FRAGMENT */)),
132494
132713
  ($data.loading && !$options.visibleGroups.length)
132495
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_16$N, vue$1.toDisplayString($options.loadingLabel), 1 /* TEXT */))
132714
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$B, vue$1.toDisplayString($options.loadingLabel), 1 /* TEXT */))
132496
132715
  : ($data.hasLoaded && !$options.visibleGroups.length)
132497
132716
  ? (vue$1.openBlock(), vue$1.createBlock(_component_CnEmptyContent, {
132498
- key: 3,
132717
+ key: 4,
132499
132718
  class: "cn-related-objects-widget__empty-state",
132500
132719
  name: $options.resolvedEmptyLabel
132501
132720
  }, {
@@ -132511,12 +132730,12 @@ function render$4T(_ctx, _cache, $props, $setup, $data, $options) {
132511
132730
  ], 64 /* STABLE_FRAGMENT */))
132512
132731
  : (vue$1.openBlock(), vue$1.createElementBlock(vue$1.Fragment, { key: 1 }, [
132513
132732
  ($props.showObjects && $data.objectItems.length)
132514
- ? (vue$1.openBlock(), vue$1.createElementBlock("section", _hoisted_17$G, [
132515
- vue$1.createElementVNode("h4", _hoisted_18$B, [
132733
+ ? (vue$1.openBlock(), vue$1.createElementBlock("section", _hoisted_19$x, [
132734
+ vue$1.createElementVNode("h4", _hoisted_20$t, [
132516
132735
  vue$1.createTextVNode(vue$1.toDisplayString($props.objectsLabel) + " ", 1 /* TEXT */),
132517
- vue$1.createElementVNode("span", _hoisted_19$x, vue$1.toDisplayString($data.objectItems.length), 1 /* TEXT */)
132736
+ vue$1.createElementVNode("span", _hoisted_21$r, vue$1.toDisplayString($data.objectItems.length), 1 /* TEXT */)
132518
132737
  ]),
132519
- vue$1.createElementVNode("ul", _hoisted_20$t, [
132738
+ vue$1.createElementVNode("ul", _hoisted_22$r, [
132520
132739
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($data.objectItems, (item) => {
132521
132740
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
132522
132741
  key: `obj-${item.id}`,
@@ -132530,22 +132749,22 @@ function render$4T(_ctx, _cache, $props, $setup, $data, $options) {
132530
132749
  class: "cn-related-objects-widget__icon",
132531
132750
  size: 20
132532
132751
  }),
132533
- vue$1.createElementVNode("span", _hoisted_22$r, vue$1.toDisplayString(item.label), 1 /* TEXT */),
132752
+ vue$1.createElementVNode("span", _hoisted_24$j, vue$1.toDisplayString(item.label), 1 /* TEXT */),
132534
132753
  (item.meta)
132535
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_23$m, vue$1.toDisplayString(item.meta), 1 /* TEXT */))
132754
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_25$h, vue$1.toDisplayString(item.meta), 1 /* TEXT */))
132536
132755
  : vue$1.createCommentVNode("v-if", true)
132537
- ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_21$r))
132756
+ ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_23$m))
132538
132757
  }), 128 /* KEYED_FRAGMENT */))
132539
132758
  ])
132540
132759
  ]))
132541
132760
  : vue$1.createCommentVNode("v-if", true),
132542
132761
  ($props.showFiles && $data.fileItems.length)
132543
- ? (vue$1.openBlock(), vue$1.createElementBlock("section", _hoisted_24$j, [
132544
- vue$1.createElementVNode("h4", _hoisted_25$h, [
132762
+ ? (vue$1.openBlock(), vue$1.createElementBlock("section", _hoisted_26$f, [
132763
+ vue$1.createElementVNode("h4", _hoisted_27$a, [
132545
132764
  vue$1.createTextVNode(vue$1.toDisplayString($props.filesLabel) + " ", 1 /* TEXT */),
132546
- vue$1.createElementVNode("span", _hoisted_26$f, vue$1.toDisplayString($data.fileItems.length), 1 /* TEXT */)
132765
+ vue$1.createElementVNode("span", _hoisted_28$a, vue$1.toDisplayString($data.fileItems.length), 1 /* TEXT */)
132547
132766
  ]),
132548
- vue$1.createElementVNode("ul", _hoisted_27$a, [
132767
+ vue$1.createElementVNode("ul", _hoisted_29$9, [
132549
132768
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($data.fileItems, (item) => {
132550
132769
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
132551
132770
  key: `file-${item.id}`,
@@ -132559,11 +132778,11 @@ function render$4T(_ctx, _cache, $props, $setup, $data, $options) {
132559
132778
  class: "cn-related-objects-widget__icon",
132560
132779
  size: 20
132561
132780
  }),
132562
- vue$1.createElementVNode("span", _hoisted_29$9, vue$1.toDisplayString(item.label), 1 /* TEXT */),
132781
+ vue$1.createElementVNode("span", _hoisted_31$8, vue$1.toDisplayString(item.label), 1 /* TEXT */),
132563
132782
  (item.meta)
132564
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_30$8, vue$1.toDisplayString(item.meta), 1 /* TEXT */))
132783
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_32$8, vue$1.toDisplayString(item.meta), 1 /* TEXT */))
132565
132784
  : vue$1.createCommentVNode("v-if", true)
132566
- ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_28$a))
132785
+ ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_30$8))
132567
132786
  }), 128 /* KEYED_FRAGMENT */))
132568
132787
  ])
132569
132788
  ]))
@@ -132574,13 +132793,13 @@ function render$4T(_ctx, _cache, $props, $setup, $data, $options) {
132574
132793
  class: "cn-related-objects-widget__group"
132575
132794
  }, [
132576
132795
  ((section.items || []).length)
132577
- ? (vue$1.openBlock(), vue$1.createElementBlock("h4", _hoisted_31$8, [
132796
+ ? (vue$1.openBlock(), vue$1.createElementBlock("h4", _hoisted_33$7, [
132578
132797
  vue$1.createTextVNode(vue$1.toDisplayString(section.label) + " ", 1 /* TEXT */),
132579
- vue$1.createElementVNode("span", _hoisted_32$8, vue$1.toDisplayString(section.items.length), 1 /* TEXT */)
132798
+ vue$1.createElementVNode("span", _hoisted_34$7, vue$1.toDisplayString(section.items.length), 1 /* TEXT */)
132580
132799
  ]))
132581
132800
  : vue$1.createCommentVNode("v-if", true),
132582
132801
  ((section.items || []).length)
132583
- ? (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_33$7, [
132802
+ ? (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_35$7, [
132584
132803
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList(section.items, (item, i) => {
132585
132804
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
132586
132805
  key: `extra-${section.key}-${i}`,
@@ -132598,17 +132817,17 @@ function render$4T(_ctx, _cache, $props, $setup, $data, $options) {
132598
132817
  class: "cn-related-objects-widget__icon"
132599
132818
  }, null, 8 /* PROPS */, ["name"]))
132600
132819
  : vue$1.createCommentVNode("v-if", true),
132601
- vue$1.createElementVNode("span", _hoisted_35$7, vue$1.toDisplayString(item.label || item.title || item.name), 1 /* TEXT */)
132602
- ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_34$7))
132820
+ vue$1.createElementVNode("span", _hoisted_37$5, vue$1.toDisplayString(item.label || item.title || item.name), 1 /* TEXT */)
132821
+ ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_36$7))
132603
132822
  }), 128 /* KEYED_FRAGMENT */))
132604
132823
  ]))
132605
132824
  : vue$1.createCommentVNode("v-if", true)
132606
132825
  ]))
132607
132826
  }), 128 /* KEYED_FRAGMENT */)),
132608
132827
  ($props.showIntegrations && $options.linkedApps.length)
132609
- ? (vue$1.openBlock(), vue$1.createElementBlock("section", _hoisted_36$7, [
132610
- vue$1.createElementVNode("h4", _hoisted_37$5, vue$1.toDisplayString($props.linkedAppsLabel), 1 /* TEXT */),
132611
- vue$1.createElementVNode("ul", _hoisted_38$4, [
132828
+ ? (vue$1.openBlock(), vue$1.createElementBlock("section", _hoisted_38$4, [
132829
+ vue$1.createElementVNode("h4", _hoisted_39$3, vue$1.toDisplayString($props.linkedAppsLabel), 1 /* TEXT */),
132830
+ vue$1.createElementVNode("ul", _hoisted_40$3, [
132612
132831
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.linkedApps, (app) => {
132613
132832
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
132614
132833
  key: `app-${app.id}`,
@@ -132623,18 +132842,18 @@ function render$4T(_ctx, _cache, $props, $setup, $data, $options) {
132623
132842
  size: 20,
132624
132843
  class: "cn-related-objects-widget__icon"
132625
132844
  }, null, 8 /* PROPS */, ["name"]),
132626
- vue$1.createElementVNode("span", _hoisted_40$3, vue$1.toDisplayString(app.label), 1 /* TEXT */),
132845
+ vue$1.createElementVNode("span", _hoisted_42$1, vue$1.toDisplayString(app.label), 1 /* TEXT */),
132627
132846
  vue$1.createVNode(_component_ChevronRight, {
132628
132847
  class: "cn-related-objects-widget__chevron",
132629
132848
  size: 20
132630
132849
  })
132631
- ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_39$3))
132850
+ ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_41$1))
132632
132851
  }), 128 /* KEYED_FRAGMENT */))
132633
132852
  ])
132634
132853
  ]))
132635
132854
  : vue$1.createCommentVNode("v-if", true),
132636
132855
  ($data.loading && $options.isEmpty)
132637
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_41$1, vue$1.toDisplayString($options.loadingLabel), 1 /* TEXT */))
132856
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_43$1, vue$1.toDisplayString($options.loadingLabel), 1 /* TEXT */))
132638
132857
  : ($data.hasLoaded && $options.isEmpty)
132639
132858
  ? (vue$1.openBlock(), vue$1.createBlock(_component_CnEmptyContent, {
132640
132859
  key: 4,
@@ -132668,7 +132887,7 @@ function render$4T(_ctx, _cache, $props, $setup, $data, $options) {
132668
132887
  ? {
132669
132888
  name: "footer",
132670
132889
  fn: vue$1.withCtx(() => [
132671
- vue$1.createElementVNode("div", _hoisted_42$1, [
132890
+ vue$1.createElementVNode("div", _hoisted_44$1, [
132672
132891
  ($options.soleAddable && $options.soleAddable.key === 'files')
132673
132892
  ? (vue$1.openBlock(), vue$1.createBlock(_component_NcButton, {
132674
132893
  key: 0,
@@ -132751,7 +132970,7 @@ function render$4T(_ctx, _cache, $props, $setup, $data, $options) {
132751
132970
  _: 1 /* STABLE */
132752
132971
  }, 8 /* PROPS */, ["menuName"])),
132753
132972
  ($data.addError)
132754
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_43$1, vue$1.toDisplayString($data.addError), 1 /* TEXT */))
132973
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_45$1, vue$1.toDisplayString($data.addError), 1 /* TEXT */))
132755
132974
  : vue$1.createCommentVNode("v-if", true),
132756
132975
  vue$1.createElementVNode("input", {
132757
132976
  ref: $options.fileInputRef,
@@ -135165,7 +135384,7 @@ const _hoisted_6$2H = {
135165
135384
  const _hoisted_7$2k = ["data-testid"];
135166
135385
  const _hoisted_8$27 = ["data-testid"];
135167
135386
  const _hoisted_9$1U = ["data-testid"];
135168
- const _hoisted_10$1H = ["data-testid"];
135387
+ const _hoisted_10$1I = ["data-testid"];
135169
135388
 
135170
135389
  function render$4N(_ctx, _cache, $props, $setup, $data, $options) {
135171
135390
  const _component_CnResourceSelect = vue$1.resolveComponent("CnResourceSelect");
@@ -135332,7 +135551,7 @@ function render$4N(_ctx, _cache, $props, $setup, $data, $options) {
135332
135551
  key: key,
135333
135552
  class: "cn-transition-input__field-error",
135334
135553
  "data-testid": `cn-transition-input-error-${key}`
135335
- }, vue$1.toDisplayString($options.undeclaredMessage(key)), 9 /* TEXT, PROPS */, _hoisted_10$1H))
135554
+ }, vue$1.toDisplayString($options.undeclaredMessage(key)), 9 /* TEXT, PROPS */, _hoisted_10$1I))
135336
135555
  }), 128 /* KEYED_FRAGMENT */))
135337
135556
  ])
135338
135557
  ]),
@@ -137446,7 +137665,7 @@ const _hoisted_7$2i = {
137446
137665
  };
137447
137666
  const _hoisted_8$25 = ["data-testid"];
137448
137667
  const _hoisted_9$1T = ["data-testid"];
137449
- const _hoisted_10$1G = {
137668
+ const _hoisted_10$1H = {
137450
137669
  key: 0,
137451
137670
  class: "cn-timeline-stages__subtitle"
137452
137671
  };
@@ -137563,7 +137782,7 @@ function render$4L(_ctx, _cache, $props, $setup, $data, $options) {
137563
137782
  "data-testid": `cn-stages-widget-stage-${stage.id}`
137564
137783
  }, vue$1.toDisplayString(stage.label), 9 /* TEXT, PROPS */, _hoisted_9$1T),
137565
137784
  (stage.subtitle)
137566
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$1G, vue$1.toDisplayString(stage.subtitle), 1 /* TEXT */))
137785
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$1H, vue$1.toDisplayString(stage.subtitle), 1 /* TEXT */))
137567
137786
  : vue$1.createCommentVNode("v-if", true),
137568
137787
  (stage.reason)
137569
137788
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", {
@@ -137954,7 +138173,7 @@ const _hoisted_6$2E = { class: "cn-stages-form__row" };
137954
138173
  const _hoisted_7$2h = { class: "cn-stages-form__hint" };
137955
138174
  const _hoisted_8$24 = { class: "cn-stages-form__row" };
137956
138175
  const _hoisted_9$1S = { class: "cn-stages-form__row" };
137957
- const _hoisted_10$1F = { class: "cn-stages-form__row" };
138176
+ const _hoisted_10$1G = { class: "cn-stages-form__row" };
137958
138177
  const _hoisted_11$1n = { class: "cn-stages-form__hint" };
137959
138178
  const _hoisted_12$1b = { class: "cn-stages-form__section" };
137960
138179
  const _hoisted_13$16 = {
@@ -138106,7 +138325,7 @@ function render$4K(_ctx, _cache, $props, $setup, $data, $options) {
138106
138325
  "onUpdate:modelValue": _cache[13] || (_cache[13] = $event => ($options.setPath('stagesSource.labelField', $event)))
138107
138326
  }, null, 8 /* PROPS */, ["modelValue", "label"])
138108
138327
  ]),
138109
- vue$1.createElementVNode("div", _hoisted_10$1F, [
138328
+ vue$1.createElementVNode("div", _hoisted_10$1G, [
138110
138329
  vue$1.createVNode(_component_NcTextField, {
138111
138330
  modelValue: $data.draft.stagesSource.descriptionField || '',
138112
138331
  label: $options.t('nextcloud-vue', 'Description property'),
@@ -138580,7 +138799,7 @@ const _hoisted_7$2g = {
138580
138799
  };
138581
138800
  const _hoisted_8$23 = { class: "cn-kpi-card__value cn-stats-block__count-value" };
138582
138801
  const _hoisted_9$1R = { class: "cn-kpi-card__label cn-stats-block__count-label" };
138583
- const _hoisted_10$1E = {
138802
+ const _hoisted_10$1F = {
138584
138803
  key: 2,
138585
138804
  class: "cn-stats-block__loading"
138586
138805
  };
@@ -138653,7 +138872,7 @@ function render$4J(_ctx, _cache, $props, $setup, $data, $options) {
138653
138872
  vue$1.createElementVNode("span", _hoisted_9$1R, vue$1.toDisplayString($props.countLabel ? $options.tl($props.countLabel) : $props.countLabel), 1 /* TEXT */)
138654
138873
  ]))
138655
138874
  : ($props.loading)
138656
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1E, [
138875
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1F, [
138657
138876
  vue$1.createVNode(_component_NcLoadingIcon, { size: 16 }),
138658
138877
  vue$1.createTextVNode(" " + vue$1.toDisplayString($props.loadingLabel), 1 /* TEXT */)
138659
138878
  ]))
@@ -142919,7 +143138,7 @@ const _hoisted_6$2B = {
142919
143138
  const _hoisted_7$2f = ["tabindex", "role", "aria-label", "onClick", "onKeydown"];
142920
143139
  const _hoisted_8$22 = ["src", "alt"];
142921
143140
  const _hoisted_9$1Q = ["aria-label"];
142922
- const _hoisted_10$1D = {
143141
+ const _hoisted_10$1E = {
142923
143142
  key: 2,
142924
143143
  class: "cn-object-data-widget__mini-table-wrap"
142925
143144
  };
@@ -143253,7 +143472,7 @@ function render$4B(_ctx, _cache, $props, $setup, $data, $options) {
143253
143472
  "aria-label": $options.t('nextcloud-vue', 'Loading')
143254
143473
  }, null, 8 /* PROPS */, _hoisted_9$1Q))
143255
143474
  : ($options.fieldValueKind(field) === 'object-array')
143256
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1D, [
143475
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1E, [
143257
143476
  vue$1.createElementVNode("table", _hoisted_11$1l, [
143258
143477
  vue$1.createElementVNode("thead", null, [
143259
143478
  vue$1.createElementVNode("tr", null, [
@@ -145260,7 +145479,7 @@ const _hoisted_6$2y = {
145260
145479
  const _hoisted_7$2c = ["title"];
145261
145480
  const _hoisted_8$1$ = { class: "cn-banner-widget__unchecked-text" };
145262
145481
  const _hoisted_9$1O = { class: "cn-banner-widget__unchecked-reason" };
145263
- const _hoisted_10$1C = {
145482
+ const _hoisted_10$1D = {
145264
145483
  key: 2,
145265
145484
  class: "cn-banner-widget"
145266
145485
  };
@@ -145318,7 +145537,7 @@ function render$4x(_ctx, _cache, $props, $setup, $data, $options) {
145318
145537
  vue$1.createElementVNode("span", _hoisted_9$1O, vue$1.toDisplayString($options.failureTooltip), 1 /* TEXT */)
145319
145538
  ], 8 /* PROPS */, _hoisted_7$2c))
145320
145539
  : ($options.visible)
145321
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1C, [
145540
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_10$1D, [
145322
145541
  vue$1.createVNode(_component_NcNoteCard, {
145323
145542
  type: $options.resolvedVariant,
145324
145543
  class: "cn-banner-widget__card"
@@ -147446,7 +147665,7 @@ const _hoisted_6$2x = { class: "cn-integration-widget__tabbar" };
147446
147665
  const _hoisted_7$2b = ["aria-label"];
147447
147666
  const _hoisted_8$1_ = ["id", "aria-selected", "tabindex", "aria-controls", "data-testid", "onClick", "onKeydown"];
147448
147667
  const _hoisted_9$1N = { class: "cn-integration-widget__tab-label" };
147449
- const _hoisted_10$1B = { class: "cn-integration-widget__header-actions" };
147668
+ const _hoisted_10$1C = { class: "cn-integration-widget__header-actions" };
147450
147669
  const _hoisted_11$1k = ["id", "aria-labelledby"];
147451
147670
 
147452
147671
  function render$4s(_ctx, _cache, $props, $setup, $data, $options) {
@@ -147542,7 +147761,7 @@ function render$4s(_ctx, _cache, $props, $setup, $data, $options) {
147542
147761
  ], 46 /* CLASS, STYLE, PROPS, NEED_HYDRATION */, _hoisted_8$1_))
147543
147762
  }), 128 /* KEYED_FRAGMENT */))
147544
147763
  ], 8 /* PROPS */, _hoisted_7$2b),
147545
- vue$1.createElementVNode("div", _hoisted_10$1B, [
147764
+ vue$1.createElementVNode("div", _hoisted_10$1C, [
147546
147765
  vue$1.createVNode(_component_CnActionsMenu, {
147547
147766
  documentationUrl: $props.documentationUrl,
147548
147767
  widgetId: $options.resolvedWidgetId,
@@ -149195,7 +149414,7 @@ const _hoisted_9$1M = {
149195
149414
  key: 0,
149196
149415
  class: "cn-timeline-widget__badge"
149197
149416
  };
149198
- const _hoisted_10$1A = { class: "cn-timeline-widget__label" };
149417
+ const _hoisted_10$1B = { class: "cn-timeline-widget__label" };
149199
149418
  const _hoisted_11$1j = {
149200
149419
  key: 1,
149201
149420
  class: "cn-timeline-widget__detail"
@@ -149256,7 +149475,7 @@ function render$4p(_ctx, _cache, $props, $setup, $data, $options) {
149256
149475
  (event.upcoming)
149257
149476
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_9$1M, vue$1.toDisplayString($options.upcomingLabel), 1 /* TEXT */))
149258
149477
  : vue$1.createCommentVNode("v-if", true),
149259
- vue$1.createElementVNode("p", _hoisted_10$1A, vue$1.toDisplayString($options.translate(event.label)), 1 /* TEXT */),
149478
+ vue$1.createElementVNode("p", _hoisted_10$1B, vue$1.toDisplayString($options.translate(event.label)), 1 /* TEXT */),
149260
149479
  (event.detail)
149261
149480
  ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_11$1j, vue$1.toDisplayString(event.detail), 1 /* TEXT */))
149262
149481
  : vue$1.createCommentVNode("v-if", true)
@@ -149273,6 +149492,8 @@ script$4p.__scopeId = "data-v-621fcccf";
149273
149492
  script$4p.__file = "src/components/CnTimelineWidget/CnTimelineWidget.vue";
149274
149493
  const __sfc_main$4j = script$4p;
149275
149494
 
149495
+ const ACCENT_VARIANTS = ['success', 'warning', 'error', 'info', 'primary'];
149496
+
149276
149497
  /**
149277
149498
  * CnObjectCard — Schema-configuration-driven card for object display.
149278
149499
  *
@@ -149389,6 +149610,20 @@ var script$4o = {
149389
149610
  default: null,
149390
149611
  },
149391
149612
 
149613
+ /**
149614
+ * A status accent: a colored border at the start of the card and,
149615
+ * with `icon`, a colored icon before the title. `variant` is one of
149616
+ * `success`, `warning`, `error`, `info` or `primary`; `icon` is a
149617
+ * name registered with CnIcon; `label` names the status for screen
149618
+ * readers and as the icon's tooltip.
149619
+ *
149620
+ * @type {{variant: string, icon?: string, label?: string}}
149621
+ */
149622
+ accent: {
149623
+ type: Object,
149624
+ default: null,
149625
+ },
149626
+
149392
149627
  /**
149393
149628
  * The property keys the facts list shows, in order (manifest key
149394
149629
  * `config.cardFields`). Without it the card shows the first
@@ -149452,6 +149687,16 @@ var script$4o = {
149452
149687
  return null
149453
149688
  },
149454
149689
 
149690
+ /**
149691
+ * The accent variant when it is a known one, else ''.
149692
+ *
149693
+ * @return {string}
149694
+ */
149695
+ accentVariant() {
149696
+ const variant = this.accent?.variant;
149697
+ return ACCENT_VARIANTS.includes(variant) ? variant : ''
149698
+ },
149699
+
149455
149700
  config() {
149456
149701
  return this.schema?.configuration || {}
149457
149702
  },
@@ -149629,16 +149874,17 @@ const _hoisted_2$44 = { class: "cn-object-card__header" };
149629
149874
  const _hoisted_3$3E = ["src", "alt"];
149630
149875
  const _hoisted_4$3c = { class: "cn-object-card__title-area" };
149631
149876
  const _hoisted_5$2H = { class: "cn-object-card__title" };
149632
- const _hoisted_6$2u = {
149877
+ const _hoisted_6$2u = ["role", "aria-label", "aria-hidden", "title"];
149878
+ const _hoisted_7$28 = {
149633
149879
  key: 0,
149634
149880
  class: "cn-object-card__description"
149635
149881
  };
149636
- const _hoisted_7$28 = {
149882
+ const _hoisted_8$1Y = {
149637
149883
  key: 0,
149638
149884
  class: "cn-object-card__badges"
149639
149885
  };
149640
- const _hoisted_8$1Y = { class: "cn-object-card__meta-label" };
149641
- const _hoisted_9$1L = {
149886
+ const _hoisted_9$1L = { class: "cn-object-card__meta-label" };
149887
+ const _hoisted_10$1A = {
149642
149888
  key: 0,
149643
149889
  class: "cn-object-card__footer-meta"
149644
149890
  };
@@ -149652,7 +149898,7 @@ function render$4o(_ctx, _cache, $props, $setup, $data, $options) {
149652
149898
  const _component_NcButton = vue$1.resolveComponent("NcButton");
149653
149899
 
149654
149900
  return (vue$1.openBlock(), vue$1.createElementBlock("div", {
149655
- class: vue$1.normalizeClass(["cn-object-card", { 'cn-object-card--selected': $props.selected, 'cn-object-card--board': $options.isBoardLook }]),
149901
+ class: vue$1.normalizeClass(["cn-object-card", [{ 'cn-object-card--selected': $props.selected, 'cn-object-card--board': $options.isBoardLook }, $options.accentVariant && ['cn-object-card--accent', `cn-object-card--accent-${$options.accentVariant}`]]]),
149656
149902
  onMousedown: _cache[10] || (_cache[10] = (...args) => ($options.onCardMouseDown && $options.onCardMouseDown(...args))),
149657
149903
  onClick: _cache[11] || (_cache[11] = $event => ($options.onCardClick($event))),
149658
149904
  onAuxclick: _cache[12] || (_cache[12] = $event => ($options.onCardAuxClick($event)))
@@ -149704,10 +149950,26 @@ function render$4o(_ctx, _cache, $props, $setup, $data, $options) {
149704
149950
  object: $props.object,
149705
149951
  size: 16
149706
149952
  }, null, 8 /* PROPS */, ["object"]),
149953
+ ($options.accentVariant && $props.accent.icon)
149954
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", {
149955
+ key: 0,
149956
+ class: "cn-object-card__accent-icon",
149957
+ "data-testid": "cn-object-card-accent-icon",
149958
+ role: $props.accent.label ? 'img' : null,
149959
+ "aria-label": $props.accent.label || null,
149960
+ "aria-hidden": $props.accent.label ? null : 'true',
149961
+ title: $props.accent.label || null
149962
+ }, [
149963
+ vue$1.createVNode(_component_CnIcon, {
149964
+ name: $props.accent.icon,
149965
+ size: 16
149966
+ }, null, 8 /* PROPS */, ["name"])
149967
+ ], 8 /* PROPS */, _hoisted_6$2u))
149968
+ : vue$1.createCommentVNode("v-if", true),
149707
149969
  vue$1.createTextVNode(" " + vue$1.toDisplayString($options.title), 1 /* TEXT */)
149708
149970
  ]),
149709
149971
  ($options.description)
149710
- ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_6$2u, vue$1.toDisplayString($options.truncatedDescription), 1 /* TEXT */))
149972
+ ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_7$28, vue$1.toDisplayString($options.truncatedDescription), 1 /* TEXT */))
149711
149973
  : vue$1.createCommentVNode("v-if", true)
149712
149974
  ]),
149713
149975
  ($options.isBoardLook)
@@ -149734,7 +149996,7 @@ function render$4o(_ctx, _cache, $props, $setup, $data, $options) {
149734
149996
  : vue$1.createCommentVNode("v-if", true)
149735
149997
  ]),
149736
149998
  (_ctx.$slots.badges)
149737
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_7$28, [
149999
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_8$1Y, [
149738
150000
  vue$1.renderSlot(_ctx.$slots, "badges", { object: $props.object })
149739
150001
  ]))
149740
150002
  : vue$1.createCommentVNode("v-if", true),
@@ -149752,7 +150014,7 @@ function render$4o(_ctx, _cache, $props, $setup, $data, $options) {
149752
150014
  key: field.key,
149753
150015
  class: "cn-object-card__meta-item"
149754
150016
  }, [
149755
- vue$1.createElementVNode("span", _hoisted_8$1Y, vue$1.toDisplayString(field.label), 1 /* TEXT */),
150017
+ vue$1.createElementVNode("span", _hoisted_9$1L, vue$1.toDisplayString(field.label), 1 /* TEXT */),
149756
150018
  vue$1.createVNode(_component_CnCellRenderer, {
149757
150019
  value: field.value,
149758
150020
  property: field.property,
@@ -149772,7 +150034,7 @@ function render$4o(_ctx, _cache, $props, $setup, $data, $options) {
149772
150034
  onAuxclick: _cache[7] || (_cache[7] = vue$1.withModifiers(() => {}, ["stop"]))
149773
150035
  }, [
149774
150036
  ($props.footerAction.meta)
149775
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_9$1L, vue$1.toDisplayString($props.footerAction.meta), 1 /* TEXT */))
150037
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_10$1A, vue$1.toDisplayString($props.footerAction.meta), 1 /* TEXT */))
149776
150038
  : vue$1.createCommentVNode("v-if", true),
149777
150039
  vue$1.createVNode(_component_NcButton, {
149778
150040
  variant: "secondary",
@@ -233771,7 +234033,7 @@ const PROVIDERS_PATH = '/apps/openregister/api/credentials/providers';
233771
234033
  * Hardcoded per-provider presentation. Keyed by the OpenRegister catalogue
233772
234034
  * identifier. `colour` drives the tile; `setupHelp`/`setupUrl` explain how to
233773
234035
  * obtain the secret; `secretLabel` names the field. Providers not listed here
233774
- * still work — they render a neutral tile from their identifier.
234036
+ * still work, they render a neutral tile from their identifier.
233775
234037
  */
233776
234038
  const PROVIDER_META = {
233777
234039
  github: {
@@ -233841,7 +234103,7 @@ var script$2p = {
233841
234103
  },
233842
234104
 
233843
234105
  /**
233844
- * The current app's manifest `credentials[]` declarations — the
234106
+ * The current app's manifest `credentials[]` declarations: the
233845
234107
  * providers this app can reach through the broker. Shape:
233846
234108
  * `[{ provider, reason, scopes }]`. Rendered read-only under the intro.
233847
234109
  *
@@ -233906,15 +234168,16 @@ var script$2p = {
233906
234168
  },
233907
234169
 
233908
234170
  /**
233909
- * Reframed intro copy per scope.
234171
+ * Reframed intro copy per scope. No em-dashes, sentences under 16 words.
233910
234172
  *
234173
+ * @spec openspec/changes/r4-object-lock-url-and-credentials-copy/specs/credentials-settings/spec.md
233911
234174
  * @return {string} Intro text.
233912
234175
  */
233913
234176
  introText() {
233914
234177
  if (this.scope === 'organisation') {
233915
- return l10n.translate('nextcloud-vue', 'Organisation credentials let apps act on behalf of your organisation. The secret is stored in Keepiq — Nextcloud\'s native credential vault — never in the app. You choose which apps may use each credential.')
234178
+ return l10n.translate('nextcloud-vue', 'Organisation credentials let apps act for your organisation. Keepiq, the credential vault of Nextcloud, keeps the secret. The app never holds it. You choose which apps may use each credential.')
233916
234179
  }
233917
- return l10n.translate('nextcloud-vue', 'Apps sometimes need to act on your behalf against an external service. So they never hold your secrets, you give a secret to Nextcloud once and it is kept in Keepiq — a native, encrypted credential vault. Apps then make the call through Keepiq and never see the secret. You decide which apps may use each credential — share one across apps, or keep one per app.')
234180
+ return l10n.translate('nextcloud-vue', 'Apps sometimes act for you on an external service. You give the secret to Nextcloud once, and Keepiq keeps it in an encrypted vault. Apps make the call through Keepiq and never see the secret. You choose which apps may use each credential. Share one across apps, or keep one per app.')
233918
234181
  },
233919
234182
 
233920
234183
  /**
@@ -233940,7 +234203,7 @@ var script$2p = {
233940
234203
  const serverIds = this.providers.map((p) => p.identifier);
233941
234204
  let ids = serverIds.length ? serverIds : Object.keys(PROVIDER_META);
233942
234205
  // When the app declares which providers it uses (appCredentials),
233943
- // only offer those — an app should not let you add a credential for
234206
+ // only offer those, an app should not let you add a credential for
233944
234207
  // a provider it has no code path to use.
233945
234208
  if (this.supportedProviders.size > 0) {
233946
234209
  ids = ids.filter((id) => this.supportedProviders.has(id));
@@ -233950,7 +234213,7 @@ var script$2p = {
233950
234213
 
233951
234214
  /**
233952
234215
  * Provider identifiers the app declares it uses, derived from
233953
- * `appCredentials`. Empty when the app declares nothing — filtering is
234216
+ * `appCredentials`. Empty when the app declares nothing, filtering is
233954
234217
  * then a no-op, so consumers that don't declare providers are unchanged.
233955
234218
  *
233956
234219
  * @return {Set<string>} Supported provider identifiers.
@@ -233962,7 +234225,7 @@ var script$2p = {
233962
234225
  },
233963
234226
 
233964
234227
  /**
233965
- * Stored credentials to display — filtered to the app's supported
234228
+ * Stored credentials to display: filtered to the app's supported
233966
234229
  * providers when it declares any, so you can only see and authorise
233967
234230
  * credentials the app can actually use; otherwise all of them.
233968
234231
  *
@@ -234005,7 +234268,7 @@ var script$2p = {
234005
234268
  },
234006
234269
 
234007
234270
  /**
234008
- * Whether the add form can be submitted — name, provider and a secret
234271
+ * Whether the add form can be submitted: name, provider and a secret
234009
234272
  * are required (the whole point is to store a secret).
234010
234273
  *
234011
234274
  * @return {boolean} True when submittable.
@@ -234229,7 +234492,7 @@ var script$2p = {
234229
234492
  },
234230
234493
 
234231
234494
  /**
234232
- * Human-readable provider title — hardcoded catalogue first, then the
234495
+ * Human-readable provider title: hardcoded catalogue first, then the
234233
234496
  * server title, then the raw identifier.
234234
234497
  *
234235
234498
  * @param {string} identifier The provider identifier.
@@ -240430,6 +240693,12 @@ var script$2h = {
240430
240693
  default: null,
240431
240694
  },
240432
240695
 
240696
+ /** `(object) => { variant, icon?, label? }` for each card's status accent. See CnObjectCard `accent`. */
240697
+ accentOf: {
240698
+ type: Function,
240699
+ default: null,
240700
+ },
240701
+
240433
240702
  /** Text shown when there are no objects */
240434
240703
  emptyText: {
240435
240704
  type: String,
@@ -240578,7 +240847,8 @@ function render$2h(_ctx, _cache, $props, $setup, $data, $options) {
240578
240847
  cardFields: $props.cardFields,
240579
240848
  status: $props.statusOf ? $props.statusOf(object) : null,
240580
240849
  leading: $props.leadingOf ? $props.leadingOf(object) : null,
240581
- footerAction: $props.footerActionOf ? $props.footerActionOf(object) : null
240850
+ footerAction: $props.footerActionOf ? $props.footerActionOf(object) : null,
240851
+ accent: $props.accentOf ? $props.accentOf(object) : null
240582
240852
  }, vue$1.toHandlers($options.cardListeners(object))), vue$1.createSlots({ _: 2 /* DYNAMIC */ }, [
240583
240853
  (_ctx.$slots['card-actions'])
240584
240854
  ? {
@@ -240598,7 +240868,7 @@ function render$2h(_ctx, _cache, $props, $setup, $data, $options) {
240598
240868
  key: "1"
240599
240869
  }
240600
240870
  : undefined
240601
- ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["object", "schema", "selectable", "clickToView", "selected", "cardFields", "status", "leading", "footerAction"])
240871
+ ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["object", "schema", "selectable", "clickToView", "selected", "cardFields", "status", "leading", "footerAction", "accent"])
240602
240872
  ])
240603
240873
  ]))
240604
240874
  }), 128 /* KEYED_FRAGMENT */))
@@ -250259,14 +250529,14 @@ class PermissionError extends Error {
250259
250529
  * other path that keeps `objectStore.objects[type][id]` fresh).
250260
250530
  *
250261
250531
  * @param {object} objectStore Pinia store instance (`useObjectStore()` result).
250262
- * @param {string|import('vue').Ref<string>} register OR register slug.
250263
- * @param {string|import('vue').Ref<string>} schema OR schema slug (also the GraphQL field name).
250264
- * @param {string|import('vue').Ref<string>} id Object UUID.
250532
+ * @param {string|import('vue').Ref<string>|function(): string} register OR register slug.
250533
+ * @param {string|import('vue').Ref<string>|function(): string} schema OR schema slug (also the GraphQL field name).
250534
+ * @param {string|import('vue').Ref<string>|function(): string} id Object UUID.
250265
250535
  * @param {object} [options] Optional config.
250266
250536
  * @param {boolean} [options.autoRenew] Renew the lock on a fixed interval while editing + visible.
250267
250537
  * @param {number} [options.renewIntervalMs] Renew every N ms (default 10 min).
250268
250538
  * @param {number} [options.lockDurationSec] Server-side TTL requested on acquire (default 30 min).
250269
- * @param {string|import('vue').Ref<string>} [options.schemaSlug] The schema slug for the LOCK URL, when `schema` is the object-cache key rather than the slug (CnDetailPage passes `<register>-<schema>` as the key). Defaults to `schema`.
250539
+ * @param {string|import('vue').Ref<string>|function(): string} [options.schemaSlug] The schema slug for the LOCK URL, when `schema` is the object-cache key rather than the slug (CnDetailPage passes `<register>-<schema>` as the key). Defaults to `schema`.
250270
250540
  * @return {{
250271
250541
  * locked: import('vue').ComputedRef<boolean>,
250272
250542
  * lockedByMe: import('vue').ComputedRef<boolean>,
@@ -250275,6 +250545,7 @@ class PermissionError extends Error {
250275
250545
  * acquire: () => Promise<void>,
250276
250546
  * release: () => Promise<void>
250277
250547
  * }} Reactive lock state + actions.
250548
+ * @spec openspec/changes/r4-object-lock-url-and-credentials-copy/specs/object-lock/spec.md
250278
250549
  */
250279
250550
  function useObjectLock(objectStore, register, schema, id, options = {}) {
250280
250551
  const autoRenew = options.autoRenew !== false;
@@ -250287,14 +250558,23 @@ function useObjectLock(objectStore, register, schema, id, options = {}) {
250287
250558
  const isVisible = () => typeof document === 'undefined' || document.visibilityState !== 'hidden';
250288
250559
  let renewTimer = null;
250289
250560
 
250561
+ /*
250562
+ * 🔴 `toValue`, NOT `unref`. CnDetailPage passes GETTER FUNCTIONS
250563
+ * (`() => props.objectId`) so the lock follows the route. `unref` returns a
250564
+ * function untouched, so the getter's SOURCE was interpolated into the URL:
250565
+ * every detail page sent `/api/objects/()=>pn/()=>Ct.schema||Bn/()=>Ct.objectId/lock`
250566
+ * and got a 404, and the cache lookup used the function as its key, so the
250567
+ * banner never saw a lock either. `toValue` reads a plain value, a ref and a
250568
+ * getter alike.
250569
+ */
250290
250570
  function readType() {
250291
- return vue$1.unref(schema)
250571
+ return vue$1.toValue(schema)
250292
250572
  }
250293
250573
  function readId() {
250294
- return vue$1.unref(id)
250574
+ return vue$1.toValue(id)
250295
250575
  }
250296
250576
  function readRegister() {
250297
- return vue$1.unref(register)
250577
+ return vue$1.toValue(register)
250298
250578
  }
250299
250579
 
250300
250580
  function readSelfLock() {
@@ -250340,7 +250620,22 @@ function useObjectLock(objectStore, register, schema, id, options = {}) {
250340
250620
  });
250341
250621
 
250342
250622
  function readSchemaSlug() {
250343
- return vue$1.unref(options.schemaSlug ?? schema)
250623
+ return vue$1.toValue(options.schemaSlug ?? schema)
250624
+ }
250625
+
250626
+ /**
250627
+ * Whether register, schema slug and object id are all known.
250628
+ *
250629
+ * A detail page mounts before its route params or object have resolved.
250630
+ * Without this a lock call would go out with `undefined` in the path, a
250631
+ * request OpenRegister can only answer with a 404.
250632
+ *
250633
+ * @spec openspec/changes/r4-object-lock-url-and-credentials-copy/specs/object-lock/spec.md
250634
+ * @return {boolean} True when a lock URL can be built.
250635
+ */
250636
+ function hasTarget() {
250637
+ return [readRegister(), readSchemaSlug(), readId()]
250638
+ .every((part) => typeof part === 'string' ? part !== '' : typeof part === 'number')
250344
250639
  }
250345
250640
 
250346
250641
  /**
@@ -250389,6 +250684,9 @@ function useObjectLock(objectStore, register, schema, id, options = {}) {
250389
250684
  }
250390
250685
 
250391
250686
  async function acquire() {
250687
+ if (!hasTarget()) {
250688
+ return
250689
+ }
250392
250690
  try {
250393
250691
  await axios$1.post(endpoint(), { duration: lockDurationSec });
250394
250692
  } catch (e) {
@@ -250421,6 +250719,9 @@ function useObjectLock(objectStore, register, schema, id, options = {}) {
250421
250719
 
250422
250720
  async function release() {
250423
250721
  stopRenewTimer();
250722
+ if (!hasTarget()) {
250723
+ return
250724
+ }
250424
250725
  try {
250425
250726
  await axios$1.post(unlockEndpoint());
250426
250727
  } catch (e) {
@@ -250464,7 +250765,7 @@ function useObjectLock(objectStore, register, schema, id, options = {}) {
250464
250765
  }
250465
250766
 
250466
250767
  function beaconRelease() {
250467
- if (!lockedByMe.value) {
250768
+ if (!lockedByMe.value || !hasTarget()) {
250468
250769
  return
250469
250770
  }
250470
250771
  try {
@@ -265899,6 +266200,58 @@ function resolveNameField(ctx) {
265899
266200
 
265900
266201
  function findSource(ctx, id) {
265901
266202
  return ctx.effectiveObjects().find((o) => o.id === id || o['@self']?.id === id)
266203
+ || (typeof ctx.knownRow === 'function' ? ctx.knownRow(id) : undefined)
266204
+ }
266205
+
266206
+ /**
266207
+ * The register/schema of a row that belongs to another pair than the page's,
266208
+ * in a list fetched from a `collectionUrl`. Registers a store type for that
266209
+ * pair on first use. Returns null for rows of the page's own pair, and always
266210
+ * without a `collectionUrl`.
266211
+ *
266212
+ * @param {object} opts Page context.
266213
+ * @param {string} opts.collectionUrl The page's collection endpoint, or ''.
266214
+ * @param {string} opts.register The page's register.
266215
+ * @param {string} opts.schema The page's schema.
266216
+ * @param {object|null} opts.primarySchema The page's resolved schema.
266217
+ * @param {object|null} [opts.primaryRegister] The page's resolved register, which matches a slug `register` to `@self.register`.
266218
+ * @param {object|null} opts.store The object store.
266219
+ * @param {object} row The row.
266220
+ * @return {{register: string, schema: string, type: string}|null} The row's own pair.
266221
+ */
266222
+ function resolveRowTarget({ collectionUrl, register, schema, primarySchema, primaryRegister, store }, row) {
266223
+ if (!collectionUrl || !row || !store) {
266224
+ return null
266225
+ }
266226
+ const self = row['@self'] || {};
266227
+ const reg = self.register !== undefined && self.register !== null ? String(self.register) : '';
266228
+ const sch = self.schema !== undefined && self.schema !== null ? String(self.schema) : '';
266229
+ if (!reg || !sch) {
266230
+ return null
266231
+ }
266232
+ const idsOf = (...values) => values.filter((v) => v !== undefined && v !== null && v !== '').map(String);
266233
+ const schemaIds = idsOf(schema, primarySchema && primarySchema.id, primarySchema && primarySchema.slug);
266234
+ const registerIds = idsOf(register, primaryRegister && primaryRegister.id, primaryRegister && primaryRegister.slug);
266235
+ if (schemaIds.includes(sch) && registerIds.includes(reg)) {
266236
+ return null
266237
+ }
266238
+ const type = `${reg}-${sch}`;
266239
+ if (!store.objectTypeRegistry?.[type]) {
266240
+ store.registerObjectType(type, sch, reg, { registerSlug: reg, schemaSlug: sch });
266241
+ }
266242
+ return { register: reg, schema: sch, type }
266243
+ }
266244
+
266245
+ /**
266246
+ * The store type a row is written through: its own pair's, or the page's.
266247
+ *
266248
+ * @param {object} ctx Accessor closures.
266249
+ * @param {object} [row] The row.
266250
+ * @return {string} The type slug.
266251
+ */
266252
+ function typeFor(ctx, row) {
266253
+ const target = row && typeof ctx.rowTarget === 'function' ? ctx.rowTarget(row) : null;
266254
+ return target ? target.type : ctx.selfObjectType()
265902
266255
  }
265903
266256
 
265904
266257
  /**
@@ -265911,6 +266264,10 @@ function findSource(ctx, id) {
265911
266264
  */
265912
266265
  function copyAddress(ctx, source) {
265913
266266
  const self = source['@self'] || {};
266267
+ const target = typeof ctx.rowTarget === 'function' ? ctx.rowTarget(source) : null;
266268
+ if (target) {
266269
+ return { register: target.register, schema: target.schema, id: String(source.id || self.id) }
266270
+ }
265914
266271
  const reg = ctx.register();
265915
266272
  const sch = ctx.schema();
265916
266273
  const register = (typeof reg === 'string' && reg) || self.register;
@@ -265940,12 +266297,12 @@ function refreshList(ctx) {
265940
266297
  }
265941
266298
  }
265942
266299
 
265943
- function storeError(ctx) {
265944
- return ctx.selfObjectStore()?.getError?.(ctx.selfObjectType())
266300
+ function storeError(ctx, type = ctx.selfObjectType()) {
266301
+ return ctx.selfObjectStore()?.getError?.(type)
265945
266302
  }
265946
266303
 
265947
- function storeErrorMessage(ctx, fallback) {
265948
- const err = storeError(ctx);
266304
+ function storeErrorMessage(ctx, fallback, type) {
266305
+ const err = storeError(ctx, type);
265949
266306
  return (err && err.message) || fallback
265950
266307
  }
265951
266308
 
@@ -265962,13 +266319,14 @@ function createSelfModeActions(ctx) {
265962
266319
  return false
265963
266320
  }
265964
266321
  try {
265965
- const ok = await ctx.selfObjectStore().deleteObject(ctx.selfObjectType(), id);
266322
+ const type = typeFor(ctx, findSource(ctx, id));
266323
+ const ok = await ctx.selfObjectStore().deleteObject(type, id);
265966
266324
  if (ok) {
265967
266325
  ctx.setResults.singleDelete({ success: true });
265968
266326
  ctx.emit('delete', id);
265969
266327
  refreshList(ctx);
265970
266328
  } else {
265971
- ctx.setResults.singleDelete({ error: storeErrorMessage(ctx, 'Delete failed') });
266329
+ ctx.setResults.singleDelete({ error: storeErrorMessage(ctx, 'Delete failed', type) });
265972
266330
  }
265973
266331
  } catch (err) {
265974
266332
  ctx.setResults.singleDelete({ error: (err && err.message) || 'Delete failed' });
@@ -265981,12 +266339,28 @@ function createSelfModeActions(ctx) {
265981
266339
  return false
265982
266340
  }
265983
266341
  try {
265984
- const { successfulIds, failedIds } = await ctx.selfObjectStore().deleteObjects(ctx.selfObjectType(), ids);
266342
+ // One request per pair: a mixed list holds rows of several types.
266343
+ const idsByType = new Map();
266344
+ for (const id of ids) {
266345
+ const type = typeFor(ctx, findSource(ctx, id));
266346
+ idsByType.set(type, [...(idsByType.get(type) || []), id]);
266347
+ }
266348
+ const successfulIds = [];
266349
+ const failedIds = [];
266350
+ let failedType = null;
266351
+ for (const [type, typeIds] of idsByType) {
266352
+ const outcome = await ctx.selfObjectStore().deleteObjects(type, typeIds);
266353
+ successfulIds.push(...outcome.successfulIds);
266354
+ failedIds.push(...outcome.failedIds);
266355
+ if (outcome.failedIds.length > 0 && failedType === null) {
266356
+ failedType = type;
266357
+ }
266358
+ }
265985
266359
  if (failedIds.length === 0) {
265986
266360
  ctx.setResults.massDelete({ success: true, successfulIds });
265987
266361
  } else {
265988
266362
  ctx.setResults.massDelete({
265989
- error: storeErrorMessage(ctx, `Failed to delete ${failedIds.length} item(s)`),
266363
+ error: storeErrorMessage(ctx, `Failed to delete ${failedIds.length} item(s)`, failedType),
265990
266364
  successfulIds,
265991
266365
  failedIds,
265992
266366
  });
@@ -266028,13 +266402,14 @@ function createSelfModeActions(ctx) {
266028
266402
  }
266029
266403
  }
266030
266404
  const clone = cloneObjectForCopy(source, newName, resolveNameField(ctx));
266031
- const saved = await ctx.selfObjectStore().saveObject(ctx.selfObjectType(), clone);
266405
+ const type = typeFor(ctx, source);
266406
+ const saved = await ctx.selfObjectStore().saveObject(type, clone);
266032
266407
  if (saved) {
266033
266408
  ctx.setResults.singleCopy({ success: true });
266034
266409
  ctx.emit('copy', payload);
266035
266410
  refreshList(ctx);
266036
266411
  } else {
266037
- ctx.setResults.singleCopy({ error: storeErrorMessage(ctx, 'Copy failed') });
266412
+ ctx.setResults.singleCopy({ error: storeErrorMessage(ctx, 'Copy failed', type) });
266038
266413
  }
266039
266414
  } catch (err) {
266040
266415
  ctx.setResults.singleCopy({ error: (err && err.message) || 'Copy failed' });
@@ -266077,7 +266452,7 @@ function createSelfModeActions(ctx) {
266077
266452
  }
266078
266453
  const clone = cloneObjectForCopy(source, getName(source), nameField);
266079
266454
  try {
266080
- const saved = await ctx.selfObjectStore().saveObject(ctx.selfObjectType(), clone);
266455
+ const saved = await ctx.selfObjectStore().saveObject(typeFor(ctx, source), clone);
266081
266456
  if (saved) {
266082
266457
  successfulIds.push(id);
266083
266458
  } else {
@@ -266147,7 +266522,9 @@ function createSelfModeActions(ctx) {
266147
266522
  return false
266148
266523
  }
266149
266524
  try {
266150
- const saved = await ctx.selfObjectStore().saveObject(ctx.selfObjectType(), formData);
266525
+ const item = ctx.editItem();
266526
+ const type = item ? typeFor(ctx, item) : ctx.selfObjectType();
266527
+ const saved = await ctx.selfObjectStore().saveObject(type, formData);
266151
266528
  if (saved) {
266152
266529
  ctx.setResults.form({ success: true });
266153
266530
  const isCreate = !ctx.editItem();
@@ -266163,7 +266540,7 @@ function createSelfModeActions(ctx) {
266163
266540
  ctx.afterCreateSuccess(saved);
266164
266541
  }
266165
266542
  } else {
266166
- const err = storeError(ctx);
266543
+ const err = storeError(ctx, type);
266167
266544
  if (err && err.isValidation) {
266168
266545
  // Keep the form visible so the user can fix the invalid data.
266169
266546
  ctx.setResults.formValidation(err.fields, err.message || 'Validation failed');
@@ -266630,7 +267007,11 @@ function useSelfFetchList(props, instance, inject, extras = {}) {
266630
267007
  const register = folder.register || props.register;
266631
267008
  return { register, schema: folder.schema, type: `${register}-${folder.schema}` }
266632
267009
  }
266633
- return { register: props.register, schema: props.schema, type: `${props.register}-${props.schema}` }
267010
+ // A collection endpoint gets its own type key, so a plain registration of
267011
+ // the same pair elsewhere never resets it.
267012
+ const collectionUrl = props.collectionUrl || '';
267013
+ const type = `${props.register}-${props.schema}` + (collectionUrl ? `@${collectionUrl}` : '');
267014
+ return { register: props.register, schema: props.schema, type, collectionUrl }
266634
267015
  });
266635
267016
  const objectType = vue$1.computed(() => resolvedTarget.value.type);
266636
267017
  const sidebarState = inject('sidebarState', null) ?? inject('objectSidebarState', null);
@@ -266679,9 +267060,17 @@ function useSelfFetchList(props, instance, inject, extras = {}) {
266679
267060
  // second arg) — that previously made fetch URLs go to `/api/objects/undefined/[object Object]`.
266680
267061
  // Runs (sync, ahead of the list's own watcher) again whenever the type switches.
266681
267062
  function registerTarget() {
266682
- const { register, schema, type } = resolvedTarget.value;
267063
+ const { register, schema, type, collectionUrl } = resolvedTarget.value;
266683
267064
  if (typeof objectStore.registerObjectType === 'function') {
266684
- objectStore.registerObjectType(type, schema, register, { registerSlug: register, schemaSlug: schema });
267065
+ objectStore.registerObjectType(type, schema, register, {
267066
+ registerSlug: register,
267067
+ schemaSlug: schema,
267068
+ ...(collectionUrl ? { collectionUrl } : {}),
267069
+ });
267070
+ }
267071
+ // A mixed list tells its own rows apart by `@self.register`, an id, so a slug register needs resolving.
267072
+ if (collectionUrl && !/^\d+$/.test(String(register)) && typeof objectStore.fetchRegister === 'function') {
267073
+ objectStore.fetchRegister(type);
266685
267074
  }
266686
267075
  }
266687
267076
  registerTarget();
@@ -267261,6 +267650,17 @@ var script$1M = {
267261
267650
  default: null,
267262
267651
  },
267263
267652
 
267653
+ /**
267654
+ * Gives each card in the card view a status accent: a colored start
267655
+ * border and icon. See CnObjectCard `accent`.
267656
+ *
267657
+ * @type {((object: object) => ({variant: string, icon: string, label: string}|null))|null}
267658
+ */
267659
+ cardAccent: {
267660
+ type: Function,
267661
+ default: null,
267662
+ },
267663
+
267264
267664
  /**
267265
267665
  * Board look: free text after the footer's count ("8 of 48 · click a
267266
267666
  * column header to sort"). Manifest key `config.footerNote`.
@@ -267432,6 +267832,21 @@ var script$1M = {
267432
267832
  default: () => [],
267433
267833
  },
267434
267834
 
267835
+ /**
267836
+ * Self-fetch only: list from this endpoint instead of
267837
+ * `/api/objects/{register}/{schema}`, e.g. an app endpoint that searches
267838
+ * several register/schema pairs at once. `register` and `schema` stay the
267839
+ * page's own pair (columns, create, export, import). Rows of another pair,
267840
+ * read from their `@self.register` / `@self.schema`, are edited, copied and
267841
+ * deleted against that pair, with its own form. The endpoint takes
267842
+ * `_page`, `_limit`, `_search` and `_order[key]=dir` and answers
267843
+ * `{ results, total, page, pages }`.
267844
+ */
267845
+ collectionUrl: {
267846
+ type: String,
267847
+ default: '',
267848
+ },
267849
+
267435
267850
  /**
267436
267851
  * Offer an "Also search inside files" switch beside the search box. On,
267437
267852
  * a search also matches words inside attached files (OpenRegister
@@ -268939,6 +269354,8 @@ var script$1M = {
268939
269354
  */
268940
269355
  persistedFilterKeys: [...(this.initialQueryFilterKeys || [])],
268941
269356
  internalSelectedIds: [...this.selectedIds],
269357
+ // Rows seen in a collectionUrl list, so a selection kept across pages still resolves its own pair.
269358
+ collectionRowsById: vue$1.markRaw(new Map()),
268942
269359
  // Folder-sidebar state: selected folder id + the register-fetched list.
268943
269360
  selectedFolderId: null,
268944
269361
  /**
@@ -268976,6 +269393,9 @@ var script$1M = {
268976
269393
  // Dialog targets
268977
269394
  actionTargetItem: null,
268978
269395
  editItem: null,
269396
+ // The pair and schema of a row edited outside the page's own pair (collectionUrl).
269397
+ rowFormTarget: null,
269398
+ rowFormSchema: null,
268979
269399
  // Drives the Actions-menu Refresh spinner during a self-fetch
268980
269400
  // refresh, where the host has no promise to bind `:refreshing` to.
268981
269401
  internalRefreshing: false,
@@ -270257,6 +270677,16 @@ var script$1M = {
270257
270677
  return (this.schema && typeof this.schema === 'object') ? this.schema : null
270258
270678
  },
270259
270679
 
270680
+ /** The form dialog's schema: the edited row's own when it is of another pair. */
270681
+ formSchema() {
270682
+ return this.rowFormTarget ? this.rowFormSchema : this.effectiveSchema
270683
+ },
270684
+
270685
+ /** The form dialog's register, following `formSchema`. */
270686
+ formRegister() {
270687
+ return this.rowFormTarget ? this.rowFormTarget.register : this.register
270688
+ },
270689
+
270260
270690
  /**
270261
270691
  * Schema slug for the export-leaf URL — the `schema` prop directly
270262
270692
  * when it's a string (self-fetch mode's precondition), else the
@@ -270643,8 +271073,7 @@ var script$1M = {
270643
271073
  this.$emit('edit-open', row);
270644
271074
  return
270645
271075
  }
270646
- this.editItem = row;
270647
- this.showFormDialogVisible = true;
271076
+ this.openFormFor(row);
270648
271077
  },
270649
271078
  onCopy: (row) => {
270650
271079
  this.actionTargetItem = row;
@@ -271153,6 +271582,21 @@ var script$1M = {
271153
271582
  },
271154
271583
 
271155
271584
  watch: {
271585
+ effectiveObjects: {
271586
+ immediate: true,
271587
+ handler(rows) {
271588
+ if (!this.collectionUrl || !this.isSelfFetchMode || !Array.isArray(rows)) {
271589
+ return
271590
+ }
271591
+ for (const row of rows) {
271592
+ const id = row?.id ?? row?.['@self']?.id;
271593
+ if (id !== undefined && id !== null) {
271594
+ this.collectionRowsById.set(id, row);
271595
+ }
271596
+ }
271597
+ },
271598
+ },
271599
+
271156
271600
  // A column or form field bound to a property the schema lacks is told to the host once.
271157
271601
  effectiveSchema: {
271158
271602
  immediate: true,
@@ -271345,6 +271789,9 @@ var script$1M = {
271345
271789
  if (this.splitViewEnabled && typeof window !== 'undefined') {
271346
271790
  window.addEventListener('resize', this.measureSplitViewport);
271347
271791
  }
271792
+ if (typeof window !== 'undefined') {
271793
+ window.addEventListener(OBJECTS_CHANGED_EVENT, this.onObjectsChanged);
271794
+ }
271348
271795
  this.loadManualOrder();
271349
271796
  this.loadPersonalColumns();
271350
271797
  this.publishHoistedSidebar();
@@ -271369,6 +271816,8 @@ var script$1M = {
271369
271816
  this.selfActions = createSelfModeActions({
271370
271817
  isSelfFetchMode: () => this.isSelfFetchMode,
271371
271818
  selfObjectStore: () => this.selfObjectStore,
271819
+ rowTarget: (row) => this.rowTypeTarget(row),
271820
+ knownRow: (id) => this.collectionRowsById.get(id),
271372
271821
  selfObjectType: () => this.selfObjectType,
271373
271822
  list: () => this.list,
271374
271823
  selectedIds: () => this.internalSelectedIds,
@@ -271394,13 +271843,14 @@ var script$1M = {
271394
271843
  },
271395
271844
 
271396
271845
  /**
271397
- * Drop the resize listener and the hoisted sidebar.
271846
+ * Drop the window listeners and the hoisted sidebar.
271398
271847
  *
271399
271848
  * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md
271400
271849
  */
271401
271850
  beforeUnmount() {
271402
271851
  if (typeof window !== 'undefined') {
271403
271852
  window.removeEventListener('resize', this.measureSplitViewport);
271853
+ window.removeEventListener(OBJECTS_CHANGED_EVENT, this.onObjectsChanged);
271404
271854
  }
271405
271855
  // Clear the holder so the hoisted sidebar disappears when
271406
271856
  // the user navigates away from the index page.
@@ -272862,6 +273312,33 @@ var script$1M = {
272862
273312
  }
272863
273313
  },
272864
273314
 
273315
+ /**
273316
+ * Refresh the list when `dispatchObjectsChanged` names this page's
273317
+ * register and schema, by slug or id. A part missing on either side matches.
273318
+ *
273319
+ * @param {CustomEvent} event The objects-changed event.
273320
+ * @return {void}
273321
+ */
273322
+ onObjectsChanged(event) {
273323
+ // A collection list can hold rows of any pair, so any change may show in it.
273324
+ if (this.isSelfFetchMode && this.collectionUrl) {
273325
+ this.onRefreshEvent();
273326
+ return
273327
+ }
273328
+ const detail = (event && event.detail) || {};
273329
+ const schema = this.effectiveSchema;
273330
+ const schemaIds = [this.schema, schema && schema.id, schema && schema.slug]
273331
+ .filter((v) => v !== undefined && v !== null && v !== '' && typeof v !== 'object')
273332
+ .map(String);
273333
+ if (detail.register && this.register && detail.register !== String(this.register)) {
273334
+ return
273335
+ }
273336
+ if (detail.schema && schemaIds.length > 0 && !schemaIds.includes(detail.schema)) {
273337
+ return
273338
+ }
273339
+ this.onRefreshEvent();
273340
+ },
273341
+
272865
273342
  /** @return {Promise<void>} */
272866
273343
  async onRefreshEvent() {
272867
273344
  this.$emit('refresh');
@@ -274004,6 +274481,8 @@ var script$1M = {
274004
274481
  closeFormDialog() {
274005
274482
  this.showFormDialogVisible = false;
274006
274483
  this.editItem = null;
274484
+ this.rowFormTarget = null;
274485
+ this.rowFormSchema = null;
274007
274486
  },
274008
274487
 
274009
274488
  /**
@@ -274064,8 +274543,55 @@ var script$1M = {
274064
274543
  * @public
274065
274544
  */
274066
274545
  openFormDialog(item = null) {
274067
- this.editItem = item;
274068
- this.showFormDialogVisible = true;
274546
+ return this.openFormFor(item)
274547
+ },
274548
+
274549
+ /**
274550
+ * Open the form dialog for an item. A row of another pair (collectionUrl)
274551
+ * opens with its own schema; everything else opens at once, as before.
274552
+ *
274553
+ * @param {object|null} item The row to edit, or null to create.
274554
+ * @return {Promise<void>|void}
274555
+ */
274556
+ openFormFor(item) {
274557
+ const target = item ? this.rowTypeTarget(item) : null;
274558
+ if (!target) {
274559
+ this.rowFormTarget = null;
274560
+ this.rowFormSchema = null;
274561
+ this.editItem = item;
274562
+ this.showFormDialogVisible = true;
274563
+ return
274564
+ }
274565
+ const store = this.selfObjectStore;
274566
+ return Promise.resolve(store.getSchema?.(target.type) || store.fetchSchema?.(target.type))
274567
+ .catch(() => null)
274568
+ .then((schema) => {
274569
+ if (!schema) {
274570
+ this.toastSavedView('error', l10n.translate('nextcloud-vue', 'Could not load the form for this item.'));
274571
+ return
274572
+ }
274573
+ this.rowFormTarget = target;
274574
+ this.rowFormSchema = schema;
274575
+ this.editItem = item;
274576
+ this.showFormDialogVisible = true;
274577
+ })
274578
+ },
274579
+
274580
+ /**
274581
+ * The row's own pair when it differs from the page's in a collectionUrl list.
274582
+ *
274583
+ * @param {object} row The row.
274584
+ * @return {{register: string, schema: string, type: string}|null} The pair, or null.
274585
+ */
274586
+ rowTypeTarget(row) {
274587
+ return resolveRowTarget({
274588
+ collectionUrl: this.isSelfFetchMode ? this.collectionUrl : '',
274589
+ register: this.register,
274590
+ schema: this.schema,
274591
+ primarySchema: this.effectiveSchema,
274592
+ primaryRegister: this.selfObjectStore?.getRegister?.(this.selfObjectType) || null,
274593
+ store: this.selfObjectStore,
274594
+ }, row)
274069
274595
  },
274070
274596
 
274071
274597
  /**
@@ -274715,7 +275241,7 @@ function render$1M(_ctx, _cache, $props, $setup, $data, $options) {
274715
275241
  vue$1.renderSlot(_ctx.$slots, "form-dialog", {
274716
275242
  show: $data.showFormDialogVisible,
274717
275243
  item: $data.editItem,
274718
- schema: $options.effectiveSchema,
275244
+ schema: $options.formSchema,
274719
275245
  confirm: $options.onFormConfirm,
274720
275246
  close: $options.closeFormDialog,
274721
275247
  refresh: $options.onRefreshEvent
@@ -274724,12 +275250,12 @@ function render$1M(_ctx, _cache, $props, $setup, $data, $options) {
274724
275250
  ? (vue$1.openBlock(), vue$1.createBlock(_component_CnFormDialog, {
274725
275251
  key: 0,
274726
275252
  ref: "formDialog",
274727
- schema: $options.effectiveSchema,
275253
+ schema: $options.formSchema,
274728
275254
  item: $data.editItem,
274729
- register: $props.register,
274730
- excludeFields: $props.excludeFields,
274731
- includeFields: $props.includeFields,
274732
- fieldOverrides: $props.fieldOverrides,
275255
+ register: $options.formRegister,
275256
+ excludeFields: $data.rowFormTarget ? [] : $props.excludeFields,
275257
+ includeFields: $data.rowFormTarget ? null : $props.includeFields,
275258
+ fieldOverrides: $data.rowFormTarget ? {} : $props.fieldOverrides,
274733
275259
  nameField: $props.massActionNameField,
274734
275260
  size: $props.formSize,
274735
275261
  columns: $props.formColumns,
@@ -274752,11 +275278,11 @@ function render$1M(_ctx, _cache, $props, $setup, $data, $options) {
274752
275278
  ? (vue$1.openBlock(), vue$1.createBlock(_component_CnAdvancedFormDialog, {
274753
275279
  key: 1,
274754
275280
  ref: "formDialog",
274755
- schema: $options.effectiveSchema,
275281
+ schema: $options.formSchema,
274756
275282
  item: $data.editItem,
274757
- excludeFields: $props.excludeFields,
274758
- includeFields: $props.includeFields,
274759
- fieldOverrides: $props.fieldOverrides,
275283
+ excludeFields: $data.rowFormTarget ? [] : $props.excludeFields,
275284
+ includeFields: $data.rowFormTarget ? null : $props.includeFields,
275285
+ fieldOverrides: $data.rowFormTarget ? {} : $props.fieldOverrides,
274760
275286
  nameField: $props.massActionNameField,
274761
275287
  initialValues: $options.resolvedCreateDefaults,
274762
275288
  onConfirm: $options.onFormConfirm,
@@ -275135,6 +275661,7 @@ function render$1M(_ctx, _cache, $props, $setup, $data, $options) {
275135
275661
  selectable: $props.selectable,
275136
275662
  clickToView: $options.rowClickOpens,
275137
275663
  cardFields: $options.resolvedCardFields,
275664
+ accentOf: $props.cardAccent,
275138
275665
  selectedIds: $data.internalSelectedIds,
275139
275666
  rowKey: $props.rowKey,
275140
275667
  emptyText: $props.emptyText,
@@ -275189,7 +275716,7 @@ function render$1M(_ctx, _cache, $props, $setup, $data, $options) {
275189
275716
  key: "2"
275190
275717
  }
275191
275718
  : undefined
275192
- ]), 1032 /* PROPS, DYNAMIC_SLOTS */, ["objects", "schema", "selectable", "clickToView", "cardFields", "selectedIds", "rowKey", "emptyText", "onClick", "onAuxClick", "onSelect"])),
275719
+ ]), 1032 /* PROPS, DYNAMIC_SLOTS */, ["objects", "schema", "selectable", "clickToView", "cardFields", "accentOf", "selectedIds", "rowKey", "emptyText", "onClick", "onAuxClick", "onSelect"])),
275193
275720
  vue$1.createVNode(_component_CnContextMenu, {
275194
275721
  open: $setup.contextMenuOpen,
275195
275722
  "onUpdate:open": _cache[23] || (_cache[23] = $event => (($setup.contextMenuOpen) = $event)),
@@ -290018,18 +290545,21 @@ var script$1l = {
290018
290545
  () => props.objectId,
290019
290546
  { enabled: () => Boolean(resolveType() && props.objectId) },
290020
290547
  );
290021
- const sidebarReg = props.sidebarProps?.register || props.resolvedSidebar?.register || props.register || '';
290022
- const sidebarSchema = props.sidebarProps?.schema || props.resolvedSidebar?.schema || props.schema || '';
290548
+ // Getters, read at call time: a register or schema that arrives after
290549
+ // mount (route params, a resolved sidebar) must reach the lock URL. They
290550
+ // used to be consts captured once at setup.
290551
+ const sidebarReg = () => props.sidebarProps?.register || props.resolvedSidebar?.register || props.register || '';
290552
+ const sidebarSchema = () => props.sidebarProps?.schema || props.resolvedSidebar?.schema || props.schema || '';
290023
290553
  const lock = useObjectLock(
290024
290554
  subscriptionStore,
290025
- () => sidebarReg,
290026
- () => resolveType() || sidebarSchema,
290555
+ sidebarReg,
290556
+ () => resolveType() || sidebarSchema(),
290027
290557
  () => props.objectId,
290028
290558
  // The third argument is the OBJECT CACHE KEY (`<register>-<schema>`)
290029
290559
  // and the lock URL needs the schema SLUG. They were one string, and
290030
290560
  // the acquire went to `/api/objects/<register>/<register>-<schema>/`,
290031
290561
  // which no register answers.
290032
- { schemaSlug: () => props.schema || sidebarSchema },
290562
+ { schemaSlug: () => props.schema || sidebarSchema() },
290033
290563
  );
290034
290564
  return {
290035
290565
  ...registryExposed,
@@ -341896,6 +342426,11 @@ var el = {
341896
342426
  };
341897
342427
 
341898
342428
  var translations$s = {
342429
+ "Linked items": "Linked items",
342430
+ "Still loading: {sections}": "Still loading: {sections}",
342431
+ "Could not load {section}.": "Could not load {section}.",
342432
+ "Organisation credentials let apps act for your organisation. Keepiq, the credential vault of Nextcloud, keeps the secret. The app never holds it. You choose which apps may use each credential.": "Organisation credentials let apps act for your organisation. Keepiq, the credential vault of Nextcloud, keeps the secret. The app never holds it. You choose which apps may use each credential.",
342433
+ "Apps sometimes act for you on an external service. You give the secret to Nextcloud once, and Keepiq keeps it in an encrypted vault. Apps make the call through Keepiq and never see the secret. You choose which apps may use each credential. Share one across apps, or keep one per app.": "Apps sometimes act for you on an external service. You give the secret to Nextcloud once, and Keepiq keeps it in an encrypted vault. Apps make the call through Keepiq and never see the secret. You choose which apps may use each credential. Share one across apps, or keep one per app.",
341899
342434
  "Show as": "Show as",
341900
342435
  Board: "Board",
341901
342436
  Calendar: "Calendar",
@@ -343180,7 +343715,8 @@ var translations$s = {
343180
343715
  "Development environment": "Development environment",
343181
343716
  "Test environment": "Test environment",
343182
343717
  "Acceptance environment": "Acceptance environment",
343183
- "About {label}": "About {label}"
343718
+ "About {label}": "About {label}",
343719
+ "Could not load the form for this item.": "Could not load the form for this item."
343184
343720
  };
343185
343721
  var plurals$1 = {
343186
343722
  "%n year": [
@@ -343407,6 +343943,11 @@ var nb = {
343407
343943
  };
343408
343944
 
343409
343945
  var translations$c = {
343946
+ "Linked items": "Gekoppelde items",
343947
+ "Still loading: {sections}": "Nog aan het laden: {sections}",
343948
+ "Could not load {section}.": "{section} kon niet worden geladen.",
343949
+ "Organisation credentials let apps act for your organisation. Keepiq, the credential vault of Nextcloud, keeps the secret. The app never holds it. You choose which apps may use each credential.": "Met inloggegevens van de organisatie handelen apps namens je organisatie. Keepiq, de kluis voor inloggegevens van Nextcloud, bewaart het geheim. De app krijgt het nooit in handen. Je kiest welke apps elk inloggegeven mogen gebruiken.",
343950
+ "Apps sometimes act for you on an external service. You give the secret to Nextcloud once, and Keepiq keeps it in an encrypted vault. Apps make the call through Keepiq and never see the secret. You choose which apps may use each credential. Share one across apps, or keep one per app.": "Apps handelen soms namens jou bij een externe dienst. Je geeft het geheim één keer aan Nextcloud, en Keepiq bewaart het in een versleutelde kluis. Apps doen de aanvraag via Keepiq en zien het geheim nooit. Je kiest welke apps elk inloggegeven mogen gebruiken. Deel er één tussen apps, of houd er één per app.",
343410
343951
  "Show as": "Toon als",
343411
343952
  Board: "Bord",
343412
343953
  Calendar: "Kalender",
@@ -343578,7 +344119,7 @@ var translations$c = {
343578
344119
  "This integration is not set up yet. Configure a connection to start using it.": "Deze integratie is nog niet ingesteld. Configureer een verbinding om hem te gebruiken.",
343579
344120
  "This integration is not set up yet. Install and enable the {app} app to start using it.": "Deze integratie is nog niet ingesteld. Installeer en activeer de app {app} om hem te gebruiken.",
343580
344121
  "Set up {app}": "{app} instellen",
343581
- "Add {type}": "Nieuwe {type}",
344122
+ "Add {type}": "{type} toevoegen",
343582
344123
  "Add new contact": "Nieuw contact toevoegen",
343583
344124
  "Link contact": "Contact koppelen",
343584
344125
  "Search contacts": "Contacten zoeken",
@@ -344742,7 +345283,8 @@ var translations$c = {
344742
345283
  "Development environment": "Ontwikkelomgeving",
344743
345284
  "Test environment": "Testomgeving",
344744
345285
  "Acceptance environment": "Acceptatieomgeving",
344745
- "About {label}": "Over {label}"
345286
+ "About {label}": "Over {label}",
345287
+ "Could not load the form for this item.": "Kon het formulier voor dit item niet laden."
344746
345288
  };
344747
345289
  var plurals = {
344748
345290
  "%n year": [
@@ -376548,6 +377090,7 @@ exports.deleteSchema = deleteSchema;
376548
377090
  exports.describeSchemaChange = describeSchemaChange;
376549
377091
  exports.diffManifest = diffManifest;
376550
377092
  exports.dispatchAction = dispatchAction$1;
377093
+ exports.dispatchObjectsChanged = dispatchObjectsChanged;
376551
377094
  exports.emailIntegration = emailIntegration;
376552
377095
  exports.emptyPaginated = emptyPaginated;
376553
377096
  exports.expandPageTemplates = expandPageTemplates;