@conduction/nextcloud-vue 2.56.0-beta.35 → 2.56.0-beta.36

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 (37) hide show
  1. package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue.js +1 -1
  2. package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js +114 -0
  3. package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js.map +1 -1
  4. package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue3.js +2 -2
  5. package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue3.js.map +1 -1
  6. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue.js +1 -1
  7. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +95 -0
  8. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
  9. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js +24 -2
  10. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
  11. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js +1 -1
  12. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js +2 -1
  13. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js.map +1 -1
  14. package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js.map +1 -1
  15. package/dist/esm/index.js +1 -0
  16. package/dist/esm/index.js.map +1 -1
  17. package/dist/esm/library-style.js +1 -1
  18. package/dist/esm/nextcloud-vue.css +120 -65
  19. package/dist/esm/utils/gridStack.js +40 -1
  20. package/dist/esm/utils/gridStack.js.map +1 -1
  21. package/dist/esm/utils/humaniseKey.js +41 -0
  22. package/dist/esm/utils/humaniseKey.js.map +1 -0
  23. package/dist/esm/utils/notificationRuleLabel.js +6 -23
  24. package/dist/esm/utils/notificationRuleLabel.js.map +1 -1
  25. package/dist/nextcloud-vue.cjs.js +546 -256
  26. package/dist/nextcloud-vue.cjs.js.map +2 -2
  27. package/dist/nextcloud-vue.css +120 -65
  28. package/package.json +1 -1
  29. package/src/components/CnDashboardGrid/CnDashboardGrid.vue +116 -2
  30. package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +123 -3
  31. package/src/components/CnWeekStripWidget/CnWeekStripWidget.vue +2 -1
  32. package/src/css/kpi-card.css +13 -0
  33. package/src/css/look-board.css +19 -0
  34. package/src/index.js +2 -0
  35. package/src/utils/gridStack.js +39 -0
  36. package/src/utils/humaniseKey.js +38 -0
  37. package/src/utils/notificationRuleLabel.js +5 -23
@@ -18436,9 +18436,9 @@ const _hoisted_14$1S = {
18436
18436
  };
18437
18437
  const _hoisted_15$1G = { class: "cn-column-filter__field" };
18438
18438
  const _hoisted_16$1u = { class: "cn-column-filter__label" };
18439
- const _hoisted_17$1d = ["type"];
18440
- const _hoisted_18$14 = { class: "cn-column-filter__field" };
18441
- const _hoisted_19$Y = { class: "cn-column-filter__label" };
18439
+ const _hoisted_17$1e = ["type"];
18440
+ const _hoisted_18$15 = { class: "cn-column-filter__field" };
18441
+ const _hoisted_19$Z = { class: "cn-column-filter__label" };
18442
18442
  const _hoisted_20$Q = ["type"];
18443
18443
  const _hoisted_21$O = {
18444
18444
  key: 3,
@@ -18540,12 +18540,12 @@ function render$74(_ctx, _cache, $props, $setup, $data, $options) {
18540
18540
  class: "cn-column-filter__input",
18541
18541
  type: $props.def.kind === 'date' ? 'date' : 'number',
18542
18542
  "data-testid": "cn-column-filter-from"
18543
- }, null, 8 /* PROPS */, _hoisted_17$1d), [
18543
+ }, null, 8 /* PROPS */, _hoisted_17$1e), [
18544
18544
  [vue$1.vModelDynamic, $data.draft.from]
18545
18545
  ])
18546
18546
  ]),
18547
- vue$1.createElementVNode("label", _hoisted_18$14, [
18548
- vue$1.createElementVNode("span", _hoisted_19$Y, vue$1.toDisplayString($options.toLabel), 1 /* TEXT */),
18547
+ vue$1.createElementVNode("label", _hoisted_18$15, [
18548
+ vue$1.createElementVNode("span", _hoisted_19$Z, vue$1.toDisplayString($options.toLabel), 1 /* TEXT */),
18549
18549
  vue$1.withDirectives(vue$1.createElementVNode("input", {
18550
18550
  "onUpdate:modelValue": _cache[3] || (_cache[3] = $event => (($data.draft.to) = $event)),
18551
18551
  class: "cn-column-filter__input",
@@ -22280,13 +22280,13 @@ const _hoisted_16$1t = {
22280
22280
  key: 0,
22281
22281
  class: "cn-cell-renderer__avatar"
22282
22282
  };
22283
- const _hoisted_17$1c = {
22283
+ const _hoisted_17$1d = {
22284
22284
  key: 0,
22285
22285
  class: "cn-cell-renderer__avatar-picture",
22286
22286
  "aria-hidden": "true"
22287
22287
  };
22288
- const _hoisted_18$13 = { class: "cn-cell-renderer__avatar-text" };
22289
- const _hoisted_19$X = ["title"];
22288
+ const _hoisted_18$14 = { class: "cn-cell-renderer__avatar-text" };
22289
+ const _hoisted_19$Y = ["title"];
22290
22290
  const _hoisted_20$P = {
22291
22291
  key: 0,
22292
22292
  class: "cn-cell-renderer__avatar-secondary",
@@ -22520,7 +22520,7 @@ function render$71(_ctx, _cache, $props, $setup, $data, $options) {
22520
22520
  ($options.avatarName || $options.avatarUserId)
22521
22521
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_16$1t, [
22522
22522
  ($options.avatarUserId)
22523
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$1c, [
22523
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$1d, [
22524
22524
  vue$1.createVNode(_component_NcAvatar, {
22525
22525
  user: $options.avatarUserId,
22526
22526
  displayName: $options.avatarName || $options.avatarUserId,
@@ -22535,11 +22535,11 @@ function render$71(_ctx, _cache, $props, $setup, $data, $options) {
22535
22535
  style: vue$1.normalizeStyle({ width: $options.avatarSize + 'px', height: $options.avatarSize + 'px' }),
22536
22536
  "aria-hidden": "true"
22537
22537
  }, vue$1.toDisplayString($options.avatarInitials), 5 /* TEXT, STYLE */)),
22538
- vue$1.createElementVNode("span", _hoisted_18$13, [
22538
+ vue$1.createElementVNode("span", _hoisted_18$14, [
22539
22539
  vue$1.createElementVNode("span", {
22540
22540
  class: "cn-cell-renderer__avatar-name",
22541
22541
  title: $options.avatarName || $options.avatarUserId
22542
- }, vue$1.toDisplayString($options.avatarName || $options.avatarUserId), 9 /* TEXT, PROPS */, _hoisted_19$X),
22542
+ }, vue$1.toDisplayString($options.avatarName || $options.avatarUserId), 9 /* TEXT, PROPS */, _hoisted_19$Y),
22543
22543
  ($props.secondary)
22544
22544
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_20$P, vue$1.toDisplayString($props.secondary), 1 /* TEXT */))
22545
22545
  : vue$1.createCommentVNode("v-if", true)
@@ -24998,16 +24998,16 @@ const _hoisted_16$1s = {
24998
24998
  key: 2,
24999
24999
  class: "cn-table-col--actions"
25000
25000
  };
25001
- const _hoisted_17$1b = {
25001
+ const _hoisted_17$1c = {
25002
25002
  key: 0,
25003
25003
  class: "hidden-visually"
25004
25004
  };
25005
- const _hoisted_18$12 = {
25005
+ const _hoisted_18$13 = {
25006
25006
  key: 0,
25007
25007
  class: "cn-table-empty",
25008
25008
  "data-testid": "cn-object-list-empty"
25009
25009
  };
25010
- const _hoisted_19$W = ["colspan"];
25010
+ const _hoisted_19$X = ["colspan"];
25011
25011
  const _hoisted_20$O = {
25012
25012
  key: 0,
25013
25013
  class: "cn-table-empty__lens-reason",
@@ -25222,7 +25222,7 @@ function render$6_(_ctx, _cache, $props, $setup, $data, $options) {
25222
25222
  (_ctx.$slots['row-actions'])
25223
25223
  ? (vue$1.openBlock(), vue$1.createElementBlock("th", _hoisted_16$1s, [
25224
25224
  ($options.isBoardLook)
25225
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$1b, vue$1.toDisplayString($options.actionsColumnLabel), 1 /* TEXT */))
25225
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$1c, vue$1.toDisplayString($options.actionsColumnLabel), 1 /* TEXT */))
25226
25226
  : vue$1.createCommentVNode("v-if", true),
25227
25227
  vue$1.renderSlot(_ctx.$slots, "actions-header")
25228
25228
  ]))
@@ -25232,7 +25232,7 @@ function render$6_(_ctx, _cache, $props, $setup, $data, $options) {
25232
25232
  : vue$1.createCommentVNode("v-if", true),
25233
25233
  vue$1.createElementVNode("tbody", null, [
25234
25234
  ($options.effectiveRows.length === 0)
25235
- ? (vue$1.openBlock(), vue$1.createElementBlock("tr", _hoisted_18$12, [
25235
+ ? (vue$1.openBlock(), vue$1.createElementBlock("tr", _hoisted_18$13, [
25236
25236
  vue$1.createElementVNode("td", { colspan: $options.totalColumns }, [
25237
25237
  vue$1.renderSlot(_ctx.$slots, "empty", {}, () => [
25238
25238
  ($options.lensReasonText)
@@ -25241,7 +25241,7 @@ function render$6_(_ctx, _cache, $props, $setup, $data, $options) {
25241
25241
  vue$1.createTextVNode(vue$1.toDisplayString($options.translateLabel($props.emptyText)), 1 /* TEXT */)
25242
25242
  ], 64 /* STABLE_FRAGMENT */))
25243
25243
  ])
25244
- ], 8 /* PROPS */, _hoisted_19$W)
25244
+ ], 8 /* PROPS */, _hoisted_19$X)
25245
25245
  ]))
25246
25246
  : (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, { key: 1 }, vue$1.renderList($options.effectiveRows, (row) => {
25247
25247
  return (vue$1.openBlock(), vue$1.createElementBlock("tr", {
@@ -61034,12 +61034,12 @@ const _hoisted_13$1$ = {
61034
61034
  const _hoisted_14$1P = ["title", "aria-label", "tabindex", "onClick", "onKeydown"];
61035
61035
  const _hoisted_15$1D = ["viewBox"];
61036
61036
  const _hoisted_16$1r = ["d"];
61037
- const _hoisted_17$1a = {
61037
+ const _hoisted_17$1b = {
61038
61038
  key: 2,
61039
61039
  class: "cn-icon-browser-panel__cell-label"
61040
61040
  };
61041
- const _hoisted_18$11 = { class: "cn-icon-browser-panel__empty" };
61042
- const _hoisted_19$V = {
61041
+ const _hoisted_18$12 = { class: "cn-icon-browser-panel__empty" };
61042
+ const _hoisted_19$W = {
61043
61043
  key: 2,
61044
61044
  class: "cn-icon-browser-panel__hint"
61045
61045
  };
@@ -61209,16 +61209,16 @@ function render$6P(_ctx, _cache, $props, $setup, $data, $options) {
61209
61209
  }, null, 8 /* PROPS */, _hoisted_16$1r)
61210
61210
  ], 8 /* PROPS */, _hoisted_15$1D)),
61211
61211
  ($props.showLabels)
61212
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$1a, vue$1.toDisplayString(icon.label), 1 /* TEXT */))
61212
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$1b, vue$1.toDisplayString(icon.label), 1 /* TEXT */))
61213
61213
  : vue$1.createCommentVNode("v-if", true)
61214
61214
  ], 42 /* CLASS, PROPS, NEED_HYDRATION */, _hoisted_14$1P))
61215
61215
  }), 128 /* KEYED_FRAGMENT */))
61216
61216
  ]))
61217
61217
  : vue$1.renderSlot(_ctx.$slots, "empty", {}, () => [
61218
- vue$1.createElementVNode("p", _hoisted_18$11, vue$1.toDisplayString($options.emptyMessage), 1 /* TEXT */)
61218
+ vue$1.createElementVNode("p", _hoisted_18$12, vue$1.toDisplayString($options.emptyMessage), 1 /* TEXT */)
61219
61219
  ], undefined, 1),
61220
61220
  ($options.truncated)
61221
- ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_19$V, vue$1.toDisplayString($options.t('nextcloud-vue', 'Showing {shown} of {total} — refine your search to narrow results.', { shown: $options.visibleIcons.length, total: $options.matchCount })), 1 /* TEXT */))
61221
+ ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_19$W, vue$1.toDisplayString($options.t('nextcloud-vue', 'Showing {shown} of {total} — refine your search to narrow results.', { shown: $options.visibleIcons.length, total: $options.matchCount })), 1 /* TEXT */))
61222
61222
  : vue$1.createCommentVNode("v-if", true)
61223
61223
  ], 64 /* STABLE_FRAGMENT */))
61224
61224
  : vue$1.createCommentVNode("v-if", true)
@@ -72008,9 +72008,9 @@ const _hoisted_16$1q = {
72008
72008
  key: 2,
72009
72009
  class: "cn-activity-card__timeline"
72010
72010
  };
72011
- const _hoisted_17$19 = { class: "cn-activity-card__day-header" };
72012
- const _hoisted_18$10 = { class: "cn-activity-card__day-count" };
72013
- const _hoisted_19$U = { class: "cn-activity-card__list" };
72011
+ const _hoisted_17$1a = { class: "cn-activity-card__day-header" };
72012
+ const _hoisted_18$11 = { class: "cn-activity-card__day-count" };
72013
+ const _hoisted_19$V = { class: "cn-activity-card__list" };
72014
72014
  const _hoisted_20$M = { class: "cn-activity-card__row-main" };
72015
72015
  const _hoisted_21$K = { class: "cn-activity-card__row-subject" };
72016
72016
  const _hoisted_22$J = { class: "cn-activity-card__row-meta" };
@@ -72079,12 +72079,12 @@ function render$6I(_ctx, _cache, $props, $setup, $data, $options) {
72079
72079
  key: day.key,
72080
72080
  class: "cn-activity-card__day"
72081
72081
  }, [
72082
- vue$1.createElementVNode("header", _hoisted_17$19, [
72082
+ vue$1.createElementVNode("header", _hoisted_17$1a, [
72083
72083
  vue$1.createVNode(_component_CalendarOutline, { size: 14 }),
72084
72084
  vue$1.createElementVNode("span", null, vue$1.toDisplayString(day.label), 1 /* TEXT */),
72085
- vue$1.createElementVNode("span", _hoisted_18$10, vue$1.toDisplayString(day.rows.length), 1 /* TEXT */)
72085
+ vue$1.createElementVNode("span", _hoisted_18$11, vue$1.toDisplayString(day.rows.length), 1 /* TEXT */)
72086
72086
  ]),
72087
- vue$1.createElementVNode("ul", _hoisted_19$U, [
72087
+ vue$1.createElementVNode("ul", _hoisted_19$V, [
72088
72088
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList(day.rows.slice(0, $data.COMPACT_LIMIT), (entry) => {
72089
72089
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
72090
72090
  key: $options.entryKey(entry),
@@ -72989,9 +72989,9 @@ const _hoisted_13$1Z = { class: "cn-activity-tab__filter-label" };
72989
72989
  const _hoisted_14$1N = { value: "" };
72990
72990
  const _hoisted_15$1B = ["value"];
72991
72991
  const _hoisted_16$1p = { class: "cn-activity-tab__filter" };
72992
- const _hoisted_17$18 = { class: "cn-activity-tab__filter-label" };
72993
- const _hoisted_18$$ = { value: "" };
72994
- const _hoisted_19$T = ["value"];
72992
+ const _hoisted_17$19 = { class: "cn-activity-tab__filter-label" };
72993
+ const _hoisted_18$10 = { value: "" };
72994
+ const _hoisted_19$U = ["value"];
72995
72995
  const _hoisted_20$L = {
72996
72996
  key: 1,
72997
72997
  class: "cn-activity-tab__visibility",
@@ -73180,18 +73180,18 @@ function render$6H(_ctx, _cache, $props, $setup, $data, $options) {
73180
73180
  ]))
73181
73181
  : vue$1.createCommentVNode("v-if", true),
73182
73182
  vue$1.createElementVNode("label", _hoisted_16$1p, [
73183
- vue$1.createElementVNode("span", _hoisted_17$18, vue$1.toDisplayString($data.actorLabel), 1 /* TEXT */),
73183
+ vue$1.createElementVNode("span", _hoisted_17$19, vue$1.toDisplayString($data.actorLabel), 1 /* TEXT */),
73184
73184
  vue$1.withDirectives(vue$1.createElementVNode("select", {
73185
73185
  "onUpdate:modelValue": _cache[3] || (_cache[3] = $event => (($data.selectedActor) = $event)),
73186
73186
  class: "cn-activity-tab__select",
73187
73187
  onChange: _cache[4] || (_cache[4] = (...args) => ($options.resetAndFetch && $options.resetAndFetch(...args)))
73188
73188
  }, [
73189
- vue$1.createElementVNode("option", _hoisted_18$$, vue$1.toDisplayString($data.allActorsLabel), 1 /* TEXT */),
73189
+ vue$1.createElementVNode("option", _hoisted_18$10, vue$1.toDisplayString($data.allActorsLabel), 1 /* TEXT */),
73190
73190
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($data.actors, (ac) => {
73191
73191
  return (vue$1.openBlock(), vue$1.createElementBlock("option", {
73192
73192
  key: ac,
73193
73193
  value: ac
73194
- }, vue$1.toDisplayString(ac), 9 /* TEXT, PROPS */, _hoisted_19$T))
73194
+ }, vue$1.toDisplayString(ac), 9 /* TEXT, PROPS */, _hoisted_19$U))
73195
73195
  }), 128 /* KEYED_FRAGMENT */))
73196
73196
  ], 544 /* NEED_HYDRATION, NEED_PATCH */), [
73197
73197
  [vue$1.vModelSelect, $data.selectedActor]
@@ -73796,12 +73796,12 @@ const _hoisted_14$1M = {
73796
73796
  };
73797
73797
  const _hoisted_15$1A = { class: "cn-analytics-card__row-icon" };
73798
73798
  const _hoisted_16$1o = { class: "cn-analytics-card__row-main" };
73799
- const _hoisted_17$17 = ["href"];
73800
- const _hoisted_18$_ = {
73799
+ const _hoisted_17$18 = ["href"];
73800
+ const _hoisted_18$$ = {
73801
73801
  key: 3,
73802
73802
  class: "cn-analytics-card__view-all"
73803
73803
  };
73804
- const _hoisted_19$S = ["href"];
73804
+ const _hoisted_19$T = ["href"];
73805
73805
 
73806
73806
  function render$6G(_ctx, _cache, $props, $setup, $data, $options) {
73807
73807
  const _component_NcLoadingIcon = vue$1.resolveComponent("NcLoadingIcon");
@@ -73887,7 +73887,7 @@ function render$6G(_ctx, _cache, $props, $setup, $data, $options) {
73887
73887
  target: "_blank",
73888
73888
  rel: "noopener noreferrer",
73889
73889
  class: "cn-analytics-card__title"
73890
- }, vue$1.toDisplayString($options.reportTitle(report)), 9 /* TEXT, PROPS */, _hoisted_17$17),
73890
+ }, vue$1.toDisplayString($options.reportTitle(report)), 9 /* TEXT, PROPS */, _hoisted_17$18),
73891
73891
  vue$1.createElementVNode("span", {
73892
73892
  class: vue$1.normalizeClass(["cn-analytics-card__badge", $options.badgeClass(report)])
73893
73893
  }, vue$1.toDisplayString($options.reportTypeLabel(report)), 3 /* TEXT, CLASS */)
@@ -73896,12 +73896,12 @@ function render$6G(_ctx, _cache, $props, $setup, $data, $options) {
73896
73896
  }), 128 /* KEYED_FRAGMENT */))
73897
73897
  ])),
73898
73898
  ($data.reports.length > $data.COMPACT_LIMIT)
73899
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$_, [
73899
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$$, [
73900
73900
  vue$1.createElementVNode("a", {
73901
73901
  href: $props.analyticsAppUrl,
73902
73902
  target: "_blank",
73903
73903
  rel: "noopener noreferrer"
73904
- }, vue$1.toDisplayString($props.viewAllLabel), 9 /* TEXT, PROPS */, _hoisted_19$S)
73904
+ }, vue$1.toDisplayString($props.viewAllLabel), 9 /* TEXT, PROPS */, _hoisted_19$T)
73905
73905
  ]))
73906
73906
  : vue$1.createCommentVNode("v-if", true)
73907
73907
  ], 64 /* STABLE_FRAGMENT */))
@@ -76136,15 +76136,15 @@ const _hoisted_16$1n = {
76136
76136
  key: 0,
76137
76137
  class: "cn-audit-details__old"
76138
76138
  };
76139
- const _hoisted_17$16 = {
76139
+ const _hoisted_17$17 = {
76140
76140
  key: 1,
76141
76141
  class: "cn-audit-details__arrow"
76142
76142
  };
76143
- const _hoisted_18$Z = {
76143
+ const _hoisted_18$_ = {
76144
76144
  key: 2,
76145
76145
  class: "cn-audit-details__new"
76146
76146
  };
76147
- const _hoisted_19$R = {
76147
+ const _hoisted_19$S = {
76148
76148
  key: 3,
76149
76149
  class: "cn-audit-details__null"
76150
76150
  };
@@ -76290,13 +76290,13 @@ function render$6z(_ctx, _cache, $props, $setup, $data, $options) {
76290
76290
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_16$1n, vue$1.toDisplayString($options.formatValue(change.old)), 1 /* TEXT */))
76291
76291
  : vue$1.createCommentVNode("v-if", true),
76292
76292
  (change.old !== null && change.new !== null)
76293
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$16, "→"))
76293
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$17, "→"))
76294
76294
  : vue$1.createCommentVNode("v-if", true),
76295
76295
  (change.new !== null && change.new !== undefined)
76296
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_18$Z, vue$1.toDisplayString($options.formatValue(change.new)), 1 /* TEXT */))
76296
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_18$_, vue$1.toDisplayString($options.formatValue(change.new)), 1 /* TEXT */))
76297
76297
  : vue$1.createCommentVNode("v-if", true),
76298
76298
  (change.old === null && change.new === null)
76299
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_19$R, "null"))
76299
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_19$S, "null"))
76300
76300
  : vue$1.createCommentVNode("v-if", true)
76301
76301
  ]))
76302
76302
  : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_20$K, [
@@ -76634,15 +76634,15 @@ const _hoisted_16$1m = {
76634
76634
  key: 0,
76635
76635
  class: "cn-bookmarks-card__empty"
76636
76636
  };
76637
- const _hoisted_17$15 = {
76637
+ const _hoisted_17$16 = {
76638
76638
  key: 1,
76639
76639
  class: "cn-bookmarks-card__empty"
76640
76640
  };
76641
- const _hoisted_18$Y = {
76641
+ const _hoisted_18$Z = {
76642
76642
  key: 2,
76643
76643
  class: "cn-bookmarks-card__list"
76644
76644
  };
76645
- const _hoisted_19$Q = { class: "cn-bookmarks-card__row-icon" };
76645
+ const _hoisted_19$R = { class: "cn-bookmarks-card__row-icon" };
76646
76646
  const _hoisted_20$J = ["src", "onError"];
76647
76647
  const _hoisted_21$H = { class: "cn-bookmarks-card__row-main" };
76648
76648
  const _hoisted_22$G = ["href"];
@@ -76749,14 +76749,14 @@ function render$6y(_ctx, _cache, $props, $setup, $data, $options) {
76749
76749
  ($data.degraded)
76750
76750
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_16$1m, vue$1.toDisplayString($data.degraded), 1 /* TEXT */))
76751
76751
  : ($data.bookmarks.length === 0)
76752
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$15, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
76753
- : (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_18$Y, [
76752
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$16, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
76753
+ : (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_18$Z, [
76754
76754
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.displayedBookmarks, (bookmark) => {
76755
76755
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
76756
76756
  key: $options.bookmarkKey(bookmark),
76757
76757
  class: "cn-bookmarks-card__row"
76758
76758
  }, [
76759
- vue$1.createElementVNode("div", _hoisted_19$Q, [
76759
+ vue$1.createElementVNode("div", _hoisted_19$R, [
76760
76760
  ($options.faviconUrl(bookmark))
76761
76761
  ? (vue$1.openBlock(), vue$1.createElementBlock("img", {
76762
76762
  key: 0,
@@ -78718,12 +78718,12 @@ const _hoisted_13$1T = {
78718
78718
  const _hoisted_14$1I = ["onClick", "onKeyup"];
78719
78719
  const _hoisted_15$1x = { class: "cn-calendar-event-picker__event-summary" };
78720
78720
  const _hoisted_16$1l = { class: "cn-calendar-event-picker__event-meta" };
78721
- const _hoisted_17$14 = { class: "cn-calendar-event-picker__event-when" };
78722
- const _hoisted_18$X = {
78721
+ const _hoisted_17$15 = { class: "cn-calendar-event-picker__event-when" };
78722
+ const _hoisted_18$Y = {
78723
78723
  key: 0,
78724
78724
  class: "cn-calendar-event-picker__event-location"
78725
78725
  };
78726
- const _hoisted_19$P = {
78726
+ const _hoisted_19$Q = {
78727
78727
  key: 3,
78728
78728
  class: "cn-calendar-event-picker__empty"
78729
78729
  };
@@ -78840,15 +78840,15 @@ function render$6s(_ctx, _cache, $props, $setup, $data, $options) {
78840
78840
  }, [
78841
78841
  vue$1.createElementVNode("div", _hoisted_15$1x, vue$1.toDisplayString(ev.summary || $props.untitledLabel), 1 /* TEXT */),
78842
78842
  vue$1.createElementVNode("div", _hoisted_16$1l, [
78843
- vue$1.createElementVNode("span", _hoisted_17$14, vue$1.toDisplayString($options.formatWhen(ev)), 1 /* TEXT */),
78843
+ vue$1.createElementVNode("span", _hoisted_17$15, vue$1.toDisplayString($options.formatWhen(ev)), 1 /* TEXT */),
78844
78844
  (ev.location)
78845
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_18$X, vue$1.toDisplayString(ev.location), 1 /* TEXT */))
78845
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_18$Y, vue$1.toDisplayString(ev.location), 1 /* TEXT */))
78846
78846
  : vue$1.createCommentVNode("v-if", true)
78847
78847
  ])
78848
78848
  ], 42 /* CLASS, PROPS, NEED_HYDRATION */, _hoisted_14$1I))
78849
78849
  }), 128 /* KEYED_FRAGMENT */))
78850
78850
  ]))
78851
- : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_19$P, vue$1.toDisplayString($props.noEventsLabel), 1 /* TEXT */))
78851
+ : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_19$Q, vue$1.toDisplayString($props.noEventsLabel), 1 /* TEXT */))
78852
78852
  ]))
78853
78853
  : vue$1.createCommentVNode("v-if", true)
78854
78854
  ])
@@ -79289,12 +79289,12 @@ const _hoisted_16$1k = {
79289
79289
  key: 0,
79290
79290
  class: "cn-calendar-tab__location"
79291
79291
  };
79292
- const _hoisted_17$13 = { class: "cn-calendar-tab__location-text" };
79293
- const _hoisted_18$W = {
79292
+ const _hoisted_17$14 = { class: "cn-calendar-tab__location-text" };
79293
+ const _hoisted_18$X = {
79294
79294
  key: 1,
79295
79295
  class: "cn-calendar-tab__attendees"
79296
79296
  };
79297
- const _hoisted_19$O = ["title"];
79297
+ const _hoisted_19$P = ["title"];
79298
79298
  const _hoisted_20$I = ["title"];
79299
79299
  const _hoisted_21$G = {
79300
79300
  key: 1,
@@ -79420,17 +79420,17 @@ function render$6r(_ctx, _cache, $props, $setup, $data, $options) {
79420
79420
  size: 14,
79421
79421
  class: "cn-calendar-tab__meta-icon"
79422
79422
  }),
79423
- vue$1.createElementVNode("span", _hoisted_17$13, vue$1.toDisplayString(ev.location), 1 /* TEXT */)
79423
+ vue$1.createElementVNode("span", _hoisted_17$14, vue$1.toDisplayString(ev.location), 1 /* TEXT */)
79424
79424
  ]))
79425
79425
  : vue$1.createCommentVNode("v-if", true),
79426
79426
  ($options.attendeeList(ev).length > 0)
79427
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$W, [
79427
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$X, [
79428
79428
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.visibleAttendees(ev), (att, idx) => {
79429
79429
  return (vue$1.openBlock(), vue$1.createElementBlock("span", {
79430
79430
  key: idx,
79431
79431
  class: "cn-calendar-tab__avatar",
79432
79432
  title: att.name
79433
- }, vue$1.toDisplayString(att.initials), 9 /* TEXT, PROPS */, _hoisted_19$O))
79433
+ }, vue$1.toDisplayString(att.initials), 9 /* TEXT, PROPS */, _hoisted_19$P))
79434
79434
  }), 128 /* KEYED_FRAGMENT */)),
79435
79435
  ($options.extraAttendees(ev) > 0)
79436
79436
  ? (vue$1.openBlock(), vue$1.createElementBlock("span", {
@@ -79984,15 +79984,15 @@ const _hoisted_15$1v = {
79984
79984
  class: "cn-collectives-card__view-all"
79985
79985
  };
79986
79986
  const _hoisted_16$1j = ["href"];
79987
- const _hoisted_17$12 = {
79987
+ const _hoisted_17$13 = {
79988
79988
  key: 0,
79989
79989
  class: "cn-collectives-card__empty"
79990
79990
  };
79991
- const _hoisted_18$V = {
79991
+ const _hoisted_18$W = {
79992
79992
  key: 1,
79993
79993
  class: "cn-collectives-card__empty"
79994
79994
  };
79995
- const _hoisted_19$N = {
79995
+ const _hoisted_19$O = {
79996
79996
  key: 2,
79997
79997
  class: "cn-collectives-card__list"
79998
79998
  };
@@ -80104,10 +80104,10 @@ function render$6q(_ctx, _cache, $props, $setup, $data, $options) {
80104
80104
  ], 64 /* STABLE_FRAGMENT */))
80105
80105
  : (vue$1.openBlock(), vue$1.createElementBlock(vue$1.Fragment, { key: 3 }, [
80106
80106
  ($data.degraded)
80107
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$12, vue$1.toDisplayString($data.degraded), 1 /* TEXT */))
80107
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$13, vue$1.toDisplayString($data.degraded), 1 /* TEXT */))
80108
80108
  : ($data.pages.length === 0)
80109
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$V, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
80110
- : (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_19$N, [
80109
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$W, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
80110
+ : (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_19$O, [
80111
80111
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.displayedPages, (page) => {
80112
80112
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
80113
80113
  key: $options.pageKey(page),
@@ -83190,13 +83190,13 @@ const _hoisted_16$1i = {
83190
83190
  key: 2,
83191
83191
  class: "cn-contacts-tab__sub"
83192
83192
  };
83193
- const _hoisted_17$11 = { class: "cn-contacts-tab__sub-text" };
83194
- const _hoisted_18$U = {
83193
+ const _hoisted_17$12 = { class: "cn-contacts-tab__sub-text" };
83194
+ const _hoisted_18$V = {
83195
83195
  key: 3,
83196
83196
  class: "cn-contacts-tab__sub",
83197
83197
  "data-testid": "cn-contacts-tab-period"
83198
83198
  };
83199
- const _hoisted_19$M = { class: "cn-contacts-tab__sub-text" };
83199
+ const _hoisted_19$N = { class: "cn-contacts-tab__sub-text" };
83200
83200
  const _hoisted_20$G = {
83201
83201
  key: 4,
83202
83202
  class: "cn-contacts-tab__sub"
@@ -83349,16 +83349,16 @@ function render$6h(_ctx, _cache, $props, $setup, $data, $options) {
83349
83349
  size: 14,
83350
83350
  class: "cn-contacts-tab__sub-icon"
83351
83351
  }),
83352
- vue$1.createElementVNode("span", _hoisted_17$11, vue$1.toDisplayString(contact.org), 1 /* TEXT */)
83352
+ vue$1.createElementVNode("span", _hoisted_17$12, vue$1.toDisplayString(contact.org), 1 /* TEXT */)
83353
83353
  ]))
83354
83354
  : vue$1.createCommentVNode("v-if", true),
83355
83355
  ($options.periodOf(contact))
83356
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$U, [
83356
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$V, [
83357
83357
  vue$1.createVNode(_component_CalendarRange, {
83358
83358
  size: 14,
83359
83359
  class: "cn-contacts-tab__sub-icon"
83360
83360
  }),
83361
- vue$1.createElementVNode("span", _hoisted_19$M, vue$1.toDisplayString($options.periodOf(contact)), 1 /* TEXT */)
83361
+ vue$1.createElementVNode("span", _hoisted_19$N, vue$1.toDisplayString($options.periodOf(contact)), 1 /* TEXT */)
83362
83362
  ]))
83363
83363
  : vue$1.createCommentVNode("v-if", true),
83364
83364
  (contact.note)
@@ -83764,7 +83764,7 @@ const _hoisted_15$1s = {
83764
83764
  class: "cn-cospend-card__rows"
83765
83765
  };
83766
83766
  const _hoisted_16$1h = ["href"];
83767
- const _hoisted_17$10 = {
83767
+ const _hoisted_17$11 = {
83768
83768
  key: 0,
83769
83769
  class: "cn-cospend-card__amount"
83770
83770
  };
@@ -83861,7 +83861,7 @@ function render$6g(_ctx, _cache, $props, $setup, $data, $options) {
83861
83861
  class: vue$1.normalizeClass(["cn-cospend-card__chip-pill", $options.typeChipClass(row)])
83862
83862
  }, vue$1.toDisplayString($options.typeLabel(row)), 3 /* TEXT, CLASS */),
83863
83863
  ($options.amountLabel(row))
83864
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$10, vue$1.toDisplayString($options.amountLabel(row)), 1 /* TEXT */))
83864
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$11, vue$1.toDisplayString($options.amountLabel(row)), 1 /* TEXT */))
83865
83865
  : vue$1.createCommentVNode("v-if", true)
83866
83866
  ], 2 /* CLASS */))
83867
83867
  }), 128 /* KEYED_FRAGMENT */))
@@ -85206,9 +85206,9 @@ const _hoisted_16$1g = {
85206
85206
  key: 2,
85207
85207
  class: "cn-deck-card__kanban"
85208
85208
  };
85209
- const _hoisted_17$$ = { class: "cn-deck-card__column-header" };
85210
- const _hoisted_18$T = { class: "cn-deck-card__column-title" };
85211
- const _hoisted_19$L = { class: "cn-deck-card__column-count" };
85209
+ const _hoisted_17$10 = { class: "cn-deck-card__column-header" };
85210
+ const _hoisted_18$U = { class: "cn-deck-card__column-title" };
85211
+ const _hoisted_19$M = { class: "cn-deck-card__column-count" };
85212
85212
  const _hoisted_20$F = { class: "cn-deck-card__column-list" };
85213
85213
  const _hoisted_21$D = ["href"];
85214
85214
 
@@ -85291,9 +85291,9 @@ function render$6c(_ctx, _cache, $props, $setup, $data, $options) {
85291
85291
  key: stack.key,
85292
85292
  class: "cn-deck-card__column"
85293
85293
  }, [
85294
- vue$1.createElementVNode("header", _hoisted_17$$, [
85295
- vue$1.createElementVNode("span", _hoisted_18$T, vue$1.toDisplayString(stack.label), 1 /* TEXT */),
85296
- vue$1.createElementVNode("span", _hoisted_19$L, vue$1.toDisplayString(stack.cards.length), 1 /* TEXT */)
85294
+ vue$1.createElementVNode("header", _hoisted_17$10, [
85295
+ vue$1.createElementVNode("span", _hoisted_18$U, vue$1.toDisplayString(stack.label), 1 /* TEXT */),
85296
+ vue$1.createElementVNode("span", _hoisted_19$M, vue$1.toDisplayString(stack.cards.length), 1 /* TEXT */)
85297
85297
  ]),
85298
85298
  vue$1.createElementVNode("ul", _hoisted_20$F, [
85299
85299
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList(stack.cards, (card) => {
@@ -86389,7 +86389,7 @@ const _hoisted_16$1f = {
86389
86389
  key: 1,
86390
86390
  class: "cn-deck-tab__avatars"
86391
86391
  };
86392
- const _hoisted_17$_ = ["title"];
86392
+ const _hoisted_17$$ = ["title"];
86393
86393
 
86394
86394
  function render$69(_ctx, _cache, $props, $setup, $data, $options) {
86395
86395
  const _component_AlertCircleOutline = vue$1.resolveComponent("AlertCircleOutline");
@@ -86540,7 +86540,7 @@ function render$69(_ctx, _cache, $props, $setup, $data, $options) {
86540
86540
  key: 0,
86541
86541
  class: "cn-deck-tab__avatar-overflow",
86542
86542
  title: $options.overflowTitle(card)
86543
- }, "+" + vue$1.toDisplayString($options.assigneeOverflow(card)), 9 /* TEXT, PROPS */, _hoisted_17$_))
86543
+ }, "+" + vue$1.toDisplayString($options.assigneeOverflow(card)), 9 /* TEXT, PROPS */, _hoisted_17$$))
86544
86544
  : vue$1.createCommentVNode("v-if", true)
86545
86545
  ]))
86546
86546
  : vue$1.createCommentVNode("v-if", true)
@@ -87224,9 +87224,9 @@ const _hoisted_16$1e = {
87224
87224
  key: 2,
87225
87225
  class: "cn-email-picker__list cn-email-picker__list--messages"
87226
87226
  };
87227
- const _hoisted_17$Z = ["onClick"];
87228
- const _hoisted_18$S = { class: "cn-email-picker__message" };
87229
- const _hoisted_19$K = { class: "cn-email-picker__message-subject" };
87227
+ const _hoisted_17$_ = ["onClick"];
87228
+ const _hoisted_18$T = { class: "cn-email-picker__message" };
87229
+ const _hoisted_19$L = { class: "cn-email-picker__message-subject" };
87230
87230
  const _hoisted_20$E = { class: "cn-email-picker__message-meta" };
87231
87231
  const _hoisted_21$C = { class: "cn-email-picker__message-sender" };
87232
87232
  const _hoisted_22$C = {
@@ -87401,8 +87401,8 @@ function render$67(_ctx, _cache, $props, $setup, $data, $options) {
87401
87401
  onClick: $event => ($options.pickMessage(msg))
87402
87402
  }, [
87403
87403
  vue$1.createVNode(_component_EmailOutline, { size: 18 }),
87404
- vue$1.createElementVNode("span", _hoisted_18$S, [
87405
- vue$1.createElementVNode("span", _hoisted_19$K, vue$1.toDisplayString(msg.subject || $options.t('nextcloud-vue', '(no subject)')), 1 /* TEXT */),
87404
+ vue$1.createElementVNode("span", _hoisted_18$T, [
87405
+ vue$1.createElementVNode("span", _hoisted_19$L, vue$1.toDisplayString(msg.subject || $options.t('nextcloud-vue', '(no subject)')), 1 /* TEXT */),
87406
87406
  vue$1.createElementVNode("span", _hoisted_20$E, [
87407
87407
  vue$1.createElementVNode("span", _hoisted_21$C, vue$1.toDisplayString(msg.sender || $options.t('nextcloud-vue', 'Unknown sender')), 1 /* TEXT */),
87408
87408
  (msg.date)
@@ -87410,7 +87410,7 @@ function render$67(_ctx, _cache, $props, $setup, $data, $options) {
87410
87410
  : vue$1.createCommentVNode("v-if", true)
87411
87411
  ])
87412
87412
  ])
87413
- ], 8 /* PROPS */, _hoisted_17$Z)
87413
+ ], 8 /* PROPS */, _hoisted_17$_)
87414
87414
  ], 2 /* CLASS */))
87415
87415
  }), 128 /* KEYED_FRAGMENT */))
87416
87416
  ])),
@@ -89252,11 +89252,11 @@ const _hoisted_13$1G = {
89252
89252
  const _hoisted_14$1w = ["data-testid"];
89253
89253
  const _hoisted_15$1o = ["onUpdate:modelValue", "name", "data-testid"];
89254
89254
  const _hoisted_16$1d = ["onUpdate:modelValue", "name", "data-testid"];
89255
- const _hoisted_17$Y = {
89255
+ const _hoisted_17$Z = {
89256
89256
  key: 5,
89257
89257
  class: "cn-offline-queue__row-actions"
89258
89258
  };
89259
- const _hoisted_18$R = ["data-testid"];
89259
+ const _hoisted_18$S = ["data-testid"];
89260
89260
 
89261
89261
  function render$65(_ctx, _cache, $props, $setup, $data, $options) {
89262
89262
  const _component_NcLoadingIcon = vue$1.resolveComponent("NcLoadingIcon");
@@ -89404,7 +89404,7 @@ function render$65(_ctx, _cache, $props, $setup, $data, $options) {
89404
89404
  ], 8 /* PROPS */, _hoisted_14$1w))
89405
89405
  : vue$1.createCommentVNode("v-if", true),
89406
89406
  (operation.status === 'failed')
89407
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$Y, [
89407
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$Z, [
89408
89408
  ($options.isPermissionLost(operation) === false)
89409
89409
  ? (vue$1.openBlock(), vue$1.createBlock(_component_NcButton, {
89410
89410
  key: 0,
@@ -89434,7 +89434,7 @@ function render$65(_ctx, _cache, $props, $setup, $data, $options) {
89434
89434
  class: "cn-offline-queue__meta",
89435
89435
  "data-testid": `cn-offline-queue-copied-${operation.id}`,
89436
89436
  role: "status"
89437
- }, vue$1.toDisplayString($data.copyMessage), 9 /* TEXT, PROPS */, _hoisted_18$R))
89437
+ }, vue$1.toDisplayString($data.copyMessage), 9 /* TEXT, PROPS */, _hoisted_18$S))
89438
89438
  : vue$1.createCommentVNode("v-if", true)
89439
89439
  ], 8 /* PROPS */, _hoisted_5$3V))
89440
89440
  }), 128 /* KEYED_FRAGMENT */))
@@ -90516,9 +90516,9 @@ const _hoisted_13$1F = { value: "" };
90516
90516
  const _hoisted_14$1v = { value: "yes" };
90517
90517
  const _hoisted_15$1n = { value: "no" };
90518
90518
  const _hoisted_16$1c = { value: "na" };
90519
- const _hoisted_17$X = ["onUpdate:modelValue", "data-testid"];
90520
- const _hoisted_18$Q = ["data-testid"];
90521
- const _hoisted_19$J = {
90519
+ const _hoisted_17$Y = ["onUpdate:modelValue", "data-testid"];
90520
+ const _hoisted_18$R = ["data-testid"];
90521
+ const _hoisted_19$K = {
90522
90522
  key: 0,
90523
90523
  class: "cn-field-inspection__error",
90524
90524
  role: "alert",
@@ -90685,7 +90685,7 @@ function render$64(_ctx, _cache, $props, $setup, $data, $options) {
90685
90685
  "data-testid": `cn-fi-answer-${q.questionId}`,
90686
90686
  class: "cn-field-inspection__input",
90687
90687
  rows: "2"
90688
- }, null, 8 /* PROPS */, _hoisted_17$X)), [
90688
+ }, null, 8 /* PROPS */, _hoisted_17$Y)), [
90689
90689
  [vue$1.vModelText, $data.answers[q.questionId].answer]
90690
90690
  ]),
90691
90691
  ($options.errorFor(q.questionId))
@@ -90693,12 +90693,12 @@ function render$64(_ctx, _cache, $props, $setup, $data, $options) {
90693
90693
  key: 2,
90694
90694
  class: "cn-field-inspection__error",
90695
90695
  "data-testid": `cn-fi-error-${q.questionId}`
90696
- }, vue$1.toDisplayString($options.errorFor(q.questionId)), 9 /* TEXT, PROPS */, _hoisted_18$Q))
90696
+ }, vue$1.toDisplayString($options.errorFor(q.questionId)), 9 /* TEXT, PROPS */, _hoisted_18$R))
90697
90697
  : vue$1.createCommentVNode("v-if", true)
90698
90698
  ]))
90699
90699
  }), 128 /* KEYED_FRAGMENT */)),
90700
90700
  ($data.saveError)
90701
- ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_19$J, vue$1.toDisplayString($data.saveError), 1 /* TEXT */))
90701
+ ? (vue$1.openBlock(), vue$1.createElementBlock("p", _hoisted_19$K, vue$1.toDisplayString($data.saveError), 1 /* TEXT */))
90702
90702
  : vue$1.createCommentVNode("v-if", true),
90703
90703
  vue$1.createVNode(_component_NcButton, {
90704
90704
  type: "submit",
@@ -94767,13 +94767,13 @@ const _hoisted_16$1b = {
94767
94767
  class: "cn-files-browser__table",
94768
94768
  "data-testid": "cn-files-browser-table"
94769
94769
  };
94770
- const _hoisted_17$W = {
94770
+ const _hoisted_17$X = {
94771
94771
  key: 0,
94772
94772
  class: "cn-files-browser__col-select",
94773
94773
  scope: "col"
94774
94774
  };
94775
- const _hoisted_18$P = ["checked", ".indeterminate", "disabled", "aria-label"];
94776
- const _hoisted_19$I = {
94775
+ const _hoisted_18$Q = ["checked", ".indeterminate", "disabled", "aria-label"];
94776
+ const _hoisted_19$J = {
94777
94777
  class: "cn-files-browser__col-icon",
94778
94778
  scope: "col"
94779
94779
  };
@@ -95166,7 +95166,7 @@ function render$5_(_ctx, _cache, $props, $setup, $data, $options) {
95166
95166
  vue$1.createElementVNode("thead", null, [
95167
95167
  vue$1.createElementVNode("tr", null, [
95168
95168
  ($options.bulkEnabled)
95169
- ? (vue$1.openBlock(), vue$1.createElementBlock("th", _hoisted_17$W, [
95169
+ ? (vue$1.openBlock(), vue$1.createElementBlock("th", _hoisted_17$X, [
95170
95170
  vue$1.createElementVNode("input", {
95171
95171
  type: "checkbox",
95172
95172
  class: "cn-files-browser__select",
@@ -95176,10 +95176,10 @@ function render$5_(_ctx, _cache, $props, $setup, $data, $options) {
95176
95176
  "aria-label": $options.t('nextcloud-vue', 'Select all files'),
95177
95177
  "data-testid": "cn-files-browser-select-all",
95178
95178
  onChange: _cache[1] || (_cache[1] = $event => ($options.toggleAll($event.target.checked)))
95179
- }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_18$P)
95179
+ }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_18$Q)
95180
95180
  ]))
95181
95181
  : vue$1.createCommentVNode("v-if", true),
95182
- vue$1.createElementVNode("th", _hoisted_19$I, [
95182
+ vue$1.createElementVNode("th", _hoisted_19$J, [
95183
95183
  vue$1.createElementVNode("span", _hoisted_20$D, vue$1.toDisplayString($options.t('nextcloud-vue', 'Type')), 1 /* TEXT */)
95184
95184
  ]),
95185
95185
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.renderedColumns, (column) => {
@@ -97402,7 +97402,7 @@ const _hoisted_13$1D = {
97402
97402
  const _hoisted_14$1t = { class: "cn-flow-card__row-header" };
97403
97403
  const _hoisted_15$1l = ["href"];
97404
97404
  const _hoisted_16$1a = ["aria-label"];
97405
- const _hoisted_17$V = {
97405
+ const _hoisted_17$W = {
97406
97406
  key: 0,
97407
97407
  class: "cn-flow-card__subtitle"
97408
97408
  };
@@ -97493,7 +97493,7 @@ function render$5Y(_ctx, _cache, $props, $setup, $data, $options) {
97493
97493
  }, null, 10 /* CLASS, PROPS */, _hoisted_16$1a)
97494
97494
  ]),
97495
97495
  ($options.rowMeta(op))
97496
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$V, vue$1.toDisplayString($options.rowMeta(op)), 1 /* TEXT */))
97496
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_17$W, vue$1.toDisplayString($options.rowMeta(op)), 1 /* TEXT */))
97497
97497
  : vue$1.createCommentVNode("v-if", true)
97498
97498
  ], 2 /* CLASS */))
97499
97499
  }), 128 /* KEYED_FRAGMENT */))
@@ -100363,15 +100363,15 @@ const _hoisted_16$17 = {
100363
100363
  key: 0,
100364
100364
  class: "cn-maps-card__empty"
100365
100365
  };
100366
- const _hoisted_17$U = {
100366
+ const _hoisted_17$V = {
100367
100367
  key: 1,
100368
100368
  class: "cn-maps-card__empty"
100369
100369
  };
100370
- const _hoisted_18$O = {
100370
+ const _hoisted_18$P = {
100371
100371
  key: 2,
100372
100372
  class: "cn-maps-card__list"
100373
100373
  };
100374
- const _hoisted_19$H = { class: "cn-maps-card__row-main" };
100374
+ const _hoisted_19$I = { class: "cn-maps-card__row-main" };
100375
100375
  const _hoisted_20$C = { class: "cn-maps-card__row-header" };
100376
100376
  const _hoisted_21$A = ["href"];
100377
100377
  const _hoisted_22$A = {
@@ -100470,8 +100470,8 @@ function render$5R(_ctx, _cache, $props, $setup, $data, $options) {
100470
100470
  ($data.degraded)
100471
100471
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_16$17, vue$1.toDisplayString($data.degraded), 1 /* TEXT */))
100472
100472
  : ($data.points.length === 0)
100473
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$U, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
100474
- : (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_18$O, [
100473
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$V, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
100474
+ : (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_18$P, [
100475
100475
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.displayedPoints, (point) => {
100476
100476
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
100477
100477
  key: $options.pointKey(point),
@@ -100481,7 +100481,7 @@ function render$5R(_ctx, _cache, $props, $setup, $data, $options) {
100481
100481
  size: 14,
100482
100482
  class: "cn-maps-card__row-icon"
100483
100483
  }),
100484
- vue$1.createElementVNode("div", _hoisted_19$H, [
100484
+ vue$1.createElementVNode("div", _hoisted_19$I, [
100485
100485
  vue$1.createElementVNode("div", _hoisted_20$C, [
100486
100486
  vue$1.createElementVNode("a", {
100487
100487
  href: $options.pointUrl(point),
@@ -105085,15 +105085,15 @@ const _hoisted_16$15 = {
105085
105085
  key: 0,
105086
105086
  class: "cn-openproject-card__auth-badge cn-openproject-card__auth-badge--error"
105087
105087
  };
105088
- const _hoisted_17$T = {
105088
+ const _hoisted_17$U = {
105089
105089
  key: 1,
105090
105090
  class: "cn-openproject-card__auth-badge cn-openproject-card__auth-badge--warn"
105091
105091
  };
105092
- const _hoisted_18$N = {
105092
+ const _hoisted_18$O = {
105093
105093
  key: 2,
105094
105094
  class: "cn-openproject-card__empty"
105095
105095
  };
105096
- const _hoisted_19$G = {
105096
+ const _hoisted_19$H = {
105097
105097
  key: 3,
105098
105098
  class: "cn-openproject-card__empty"
105099
105099
  };
@@ -105208,14 +105208,14 @@ function render$5H(_ctx, _cache, $props, $setup, $data, $options) {
105208
105208
  vue$1.createElementVNode("span", null, vue$1.toDisplayString($data.authBanner), 1 /* TEXT */)
105209
105209
  ]))
105210
105210
  : ($data.unconfigured)
105211
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$T, [
105211
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$U, [
105212
105212
  vue$1.createVNode(_component_AlertCircleOutline, { size: 14 }),
105213
105213
  vue$1.createElementVNode("span", null, vue$1.toDisplayString($props.unconfiguredLabel), 1 /* TEXT */)
105214
105214
  ]))
105215
105215
  : ($data.degraded)
105216
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$N, vue$1.toDisplayString($data.degraded), 1 /* TEXT */))
105216
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$O, vue$1.toDisplayString($data.degraded), 1 /* TEXT */))
105217
105217
  : ($data.workPackages.length === 0)
105218
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_19$G, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
105218
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_19$H, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
105219
105219
  : (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_20$B, [
105220
105220
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($data.workPackages, (wp) => {
105221
105221
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
@@ -106925,15 +106925,15 @@ const _hoisted_16$13 = {
106925
106925
  key: 0,
106926
106926
  class: "cn-photos-card__empty"
106927
106927
  };
106928
- const _hoisted_17$S = {
106928
+ const _hoisted_17$T = {
106929
106929
  key: 1,
106930
106930
  class: "cn-photos-card__empty"
106931
106931
  };
106932
- const _hoisted_18$M = {
106932
+ const _hoisted_18$N = {
106933
106933
  key: 2,
106934
106934
  class: "cn-photos-card__grid"
106935
106935
  };
106936
- const _hoisted_19$F = ["href", "title"];
106936
+ const _hoisted_19$G = ["href", "title"];
106937
106937
  const _hoisted_20$A = { class: "cn-photos-card__tile-cover" };
106938
106938
  const _hoisted_21$y = ["src", "onError"];
106939
106939
  const _hoisted_22$y = { class: "cn-photos-card__tile-name" };
@@ -107037,8 +107037,8 @@ function render$5D(_ctx, _cache, $props, $setup, $data, $options) {
107037
107037
  ($data.degraded)
107038
107038
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_16$13, vue$1.toDisplayString($data.degraded), 1 /* TEXT */))
107039
107039
  : ($data.albums.length === 0)
107040
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$S, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
107041
- : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$M, [
107040
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_17$T, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
107041
+ : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$N, [
107042
107042
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.displayedAlbums, (album) => {
107043
107043
  return (vue$1.openBlock(), vue$1.createElementBlock("a", {
107044
107044
  key: $options.albumKey(album),
@@ -107065,7 +107065,7 @@ function render$5D(_ctx, _cache, $props, $setup, $data, $options) {
107065
107065
  }))
107066
107066
  ]),
107067
107067
  vue$1.createElementVNode("span", _hoisted_22$y, vue$1.toDisplayString($options.albumName(album)), 1 /* TEXT */)
107068
- ], 8 /* PROPS */, _hoisted_19$F))
107068
+ ], 8 /* PROPS */, _hoisted_19$G))
107069
107069
  }), 128 /* KEYED_FRAGMENT */))
107070
107070
  ])),
107071
107071
  ($data.albums.length > $data.COMPACT_LIMIT)
@@ -108348,12 +108348,12 @@ const _hoisted_14$1j = {
108348
108348
  };
108349
108349
  const _hoisted_15$1c = { class: "cn-polls-card__row-header" };
108350
108350
  const _hoisted_16$12 = ["title", "aria-label"];
108351
- const _hoisted_17$R = ["href"];
108352
- const _hoisted_18$L = {
108351
+ const _hoisted_17$S = ["href"];
108352
+ const _hoisted_18$M = {
108353
108353
  key: 0,
108354
108354
  class: "cn-polls-card__subtitle"
108355
108355
  };
108356
- const _hoisted_19$E = {
108356
+ const _hoisted_19$F = {
108357
108357
  key: 1,
108358
108358
  class: "cn-polls-card__options"
108359
108359
  };
@@ -108455,7 +108455,7 @@ function render$5z(_ctx, _cache, $props, $setup, $data, $options) {
108455
108455
  target: "_blank",
108456
108456
  rel: "noopener",
108457
108457
  class: "cn-polls-card__title"
108458
- }, vue$1.toDisplayString($options.pollTitle(poll)), 9 /* TEXT, PROPS */, _hoisted_17$R),
108458
+ }, vue$1.toDisplayString($options.pollTitle(poll)), 9 /* TEXT, PROPS */, _hoisted_17$S),
108459
108459
  vue$1.createVNode(_component_CnStatusBadge, {
108460
108460
  label: $options.statusLabel(poll),
108461
108461
  variant: $options.statusVariant(poll),
@@ -108464,10 +108464,10 @@ function render$5z(_ctx, _cache, $props, $setup, $data, $options) {
108464
108464
  }, null, 8 /* PROPS */, ["label", "variant"])
108465
108465
  ]),
108466
108466
  ($options.rowMeta(poll))
108467
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_18$L, vue$1.toDisplayString($options.rowMeta(poll)), 1 /* TEXT */))
108467
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_18$M, vue$1.toDisplayString($options.rowMeta(poll)), 1 /* TEXT */))
108468
108468
  : vue$1.createCommentVNode("v-if", true),
108469
108469
  ($options.pollOptions(poll).length > 0)
108470
- ? (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_19$E, [
108470
+ ? (vue$1.openBlock(), vue$1.createElementBlock("ul", _hoisted_19$F, [
108471
108471
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.pollOptions(poll), (opt) => {
108472
108472
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
108473
108473
  key: $options.optionKey(opt),
@@ -109354,9 +109354,9 @@ const _hoisted_14$1i = {
109354
109354
  };
109355
109355
  const _hoisted_15$1b = { class: "cn-polls-tab__option-label" };
109356
109356
  const _hoisted_16$11 = { class: "cn-polls-tab__option-text" };
109357
- const _hoisted_17$Q = { class: "cn-polls-tab__option-count" };
109358
- const _hoisted_18$K = ["aria-valuenow"];
109359
- const _hoisted_19$D = {
109357
+ const _hoisted_17$R = { class: "cn-polls-tab__option-count" };
109358
+ const _hoisted_18$L = ["aria-valuenow"];
109359
+ const _hoisted_19$E = {
109360
109360
  key: 1,
109361
109361
  class: "cn-polls-tab__description"
109362
109362
  };
@@ -109523,7 +109523,7 @@ function render$5w(_ctx, _cache, $props, $setup, $data, $options) {
109523
109523
  }, [
109524
109524
  vue$1.createElementVNode("div", _hoisted_15$1b, [
109525
109525
  vue$1.createElementVNode("span", _hoisted_16$11, vue$1.toDisplayString($options.optionLabel(opt)), 1 /* TEXT */),
109526
- vue$1.createElementVNode("span", _hoisted_17$Q, vue$1.toDisplayString($options.optionCount(opt)) + " (" + vue$1.toDisplayString($options.optionPercent(poll, opt)) + "%) ", 1 /* TEXT */)
109526
+ vue$1.createElementVNode("span", _hoisted_17$R, vue$1.toDisplayString($options.optionCount(opt)) + " (" + vue$1.toDisplayString($options.optionPercent(poll, opt)) + "%) ", 1 /* TEXT */)
109527
109527
  ]),
109528
109528
  vue$1.createElementVNode("div", {
109529
109529
  class: "cn-polls-tab__option-bar",
@@ -109536,13 +109536,13 @@ function render$5w(_ctx, _cache, $props, $setup, $data, $options) {
109536
109536
  class: "cn-polls-tab__option-bar-fill",
109537
109537
  style: vue$1.normalizeStyle({ width: $options.optionPercent(poll, opt) + '%' })
109538
109538
  }, null, 4 /* STYLE */)
109539
- ], 8 /* PROPS */, _hoisted_18$K)
109539
+ ], 8 /* PROPS */, _hoisted_18$L)
109540
109540
  ]))
109541
109541
  }), 128 /* KEYED_FRAGMENT */))
109542
109542
  ]))
109543
109543
  : vue$1.createCommentVNode("v-if", true),
109544
109544
  ($options.pollDescription(poll))
109545
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_19$D, vue$1.toDisplayString($options.pollDescription(poll)), 1 /* TEXT */))
109545
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_19$E, vue$1.toDisplayString($options.pollDescription(poll)), 1 /* TEXT */))
109546
109546
  : vue$1.createCommentVNode("v-if", true)
109547
109547
  ], 2 /* CLASS */))
109548
109548
  }), 128 /* KEYED_FRAGMENT */))
@@ -109947,7 +109947,7 @@ const _hoisted_13$1r = { class: "cn-shares-card__group-count" };
109947
109947
  const _hoisted_14$1h = { class: "cn-shares-card__list" };
109948
109948
  const _hoisted_15$1a = { class: "cn-shares-card__row-main" };
109949
109949
  const _hoisted_16$10 = { class: "cn-shares-card__title" };
109950
- const _hoisted_17$P = { class: "cn-shares-card__subtitle" };
109950
+ const _hoisted_17$Q = { class: "cn-shares-card__subtitle" };
109951
109951
 
109952
109952
  function render$5v(_ctx, _cache, $props, $setup, $data, $options) {
109953
109953
  const _component_NcLoadingIcon = vue$1.resolveComponent("NcLoadingIcon");
@@ -110025,7 +110025,7 @@ function render$5v(_ctx, _cache, $props, $setup, $data, $options) {
110025
110025
  }, [
110026
110026
  vue$1.createElementVNode("div", _hoisted_15$1a, [
110027
110027
  vue$1.createElementVNode("span", _hoisted_16$10, vue$1.toDisplayString($options.chipLabel(share)), 1 /* TEXT */),
110028
- vue$1.createElementVNode("span", _hoisted_17$P, vue$1.toDisplayString($options.permissionLabel(share)), 1 /* TEXT */)
110028
+ vue$1.createElementVNode("span", _hoisted_17$Q, vue$1.toDisplayString($options.permissionLabel(share)), 1 /* TEXT */)
110029
110029
  ]),
110030
110030
  ($options.isPasswordProtected(share))
110031
110031
  ? (vue$1.openBlock(), vue$1.createBlock(_component_LockOutline, {
@@ -111775,8 +111775,8 @@ const _hoisted_14$1f = {
111775
111775
  };
111776
111776
  const _hoisted_15$19 = { class: "cn-talk-card__row-icon" };
111777
111777
  const _hoisted_16$$ = { class: "cn-talk-card__row-main" };
111778
- const _hoisted_17$O = ["href"];
111779
- const _hoisted_18$J = {
111778
+ const _hoisted_17$P = ["href"];
111779
+ const _hoisted_18$K = {
111780
111780
  key: 0,
111781
111781
  class: "cn-talk-card__subtitle"
111782
111782
  };
@@ -111883,9 +111883,9 @@ function render$5q(_ctx, _cache, $props, $setup, $data, $options) {
111883
111883
  target: "_blank",
111884
111884
  rel: "noopener",
111885
111885
  class: "cn-talk-card__title"
111886
- }, vue$1.toDisplayString($options.roomTitle(room)), 9 /* TEXT, PROPS */, _hoisted_17$O),
111886
+ }, vue$1.toDisplayString($options.roomTitle(room)), 9 /* TEXT, PROPS */, _hoisted_17$P),
111887
111887
  ($options.roomPreview(room))
111888
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_18$J, vue$1.toDisplayString($options.roomPreview(room)), 1 /* TEXT */))
111888
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_18$K, vue$1.toDisplayString($options.roomPreview(room)), 1 /* TEXT */))
111889
111889
  : vue$1.createCommentVNode("v-if", true)
111890
111890
  ])
111891
111891
  ], 2 /* CLASS */))
@@ -118258,8 +118258,8 @@ const _hoisted_16$_ = {
118258
118258
  key: 2,
118259
118259
  class: "cn-time-tracker-card__rows"
118260
118260
  };
118261
- const _hoisted_17$N = ["href"];
118262
- const _hoisted_18$I = {
118261
+ const _hoisted_17$O = ["href"];
118262
+ const _hoisted_18$J = {
118263
118263
  key: 0,
118264
118264
  class: "cn-time-tracker-card__duration"
118265
118265
  };
@@ -118360,12 +118360,12 @@ function render$5j(_ctx, _cache, $props, $setup, $data, $options) {
118360
118360
  target: "_blank",
118361
118361
  rel: "noopener",
118362
118362
  class: "cn-time-tracker-card__title"
118363
- }, vue$1.toDisplayString($options.rowTitle(row)), 9 /* TEXT, PROPS */, _hoisted_17$N),
118363
+ }, vue$1.toDisplayString($options.rowTitle(row)), 9 /* TEXT, PROPS */, _hoisted_17$O),
118364
118364
  vue$1.createElementVNode("span", {
118365
118365
  class: vue$1.normalizeClass(["cn-time-tracker-card__chip-pill", $options.kindChipClass(row)])
118366
118366
  }, vue$1.toDisplayString($options.kindLabel(row)), 3 /* TEXT, CLASS */),
118367
118367
  ($options.durationLabel(row))
118368
- ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_18$I, vue$1.toDisplayString($options.durationLabel(row)), 1 /* TEXT */))
118368
+ ? (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_18$J, vue$1.toDisplayString($options.durationLabel(row)), 1 /* TEXT */))
118369
118369
  : vue$1.createCommentVNode("v-if", true)
118370
118370
  ], 2 /* CLASS */))
118371
118371
  }), 128 /* KEYED_FRAGMENT */))
@@ -120431,9 +120431,9 @@ const _hoisted_16$Y = {
120431
120431
  key: 2,
120432
120432
  class: "cn-xwiki-card__detail"
120433
120433
  };
120434
- const _hoisted_17$M = { class: "cn-xwiki-card__list" };
120435
- const _hoisted_18$H = { class: "cn-xwiki-card__row-header" };
120436
- const _hoisted_19$C = ["href"];
120434
+ const _hoisted_17$N = { class: "cn-xwiki-card__list" };
120435
+ const _hoisted_18$I = { class: "cn-xwiki-card__row-header" };
120436
+ const _hoisted_19$D = ["href"];
120437
120437
  const _hoisted_20$y = {
120438
120438
  key: 0,
120439
120439
  class: "cn-xwiki-card__breadcrumb"
@@ -120518,13 +120518,13 @@ function render$5e(_ctx, _cache, $props, $setup, $data, $options) {
120518
120518
  : ($data.pages.length === 0)
120519
120519
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_15$16, vue$1.toDisplayString($props.emptyLabel), 1 /* TEXT */))
120520
120520
  : (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_16$Y, [
120521
- vue$1.createElementVNode("ul", _hoisted_17$M, [
120521
+ vue$1.createElementVNode("ul", _hoisted_17$N, [
120522
120522
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($data.pages, (page) => {
120523
120523
  return (vue$1.openBlock(), vue$1.createElementBlock("li", {
120524
120524
  key: $options.pageKey(page),
120525
120525
  class: "cn-xwiki-card__row"
120526
120526
  }, [
120527
- vue$1.createElementVNode("div", _hoisted_18$H, [
120527
+ vue$1.createElementVNode("div", _hoisted_18$I, [
120528
120528
  vue$1.createVNode(_component_FileDocumentMultiple, {
120529
120529
  size: 16,
120530
120530
  class: "cn-xwiki-card__row-icon"
@@ -120534,7 +120534,7 @@ function render$5e(_ctx, _cache, $props, $setup, $data, $options) {
120534
120534
  target: "_blank",
120535
120535
  rel: "noopener",
120536
120536
  class: "cn-xwiki-card__title"
120537
- }, vue$1.toDisplayString($options.pageTitle(page)), 9 /* TEXT, PROPS */, _hoisted_19$C)
120537
+ }, vue$1.toDisplayString($options.pageTitle(page)), 9 /* TEXT, PROPS */, _hoisted_19$D)
120538
120538
  ]),
120539
120539
  ($options.breadcrumbLabel(page))
120540
120540
  ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_20$y, vue$1.toDisplayString($options.breadcrumbLabel(page)), 1 /* TEXT */))
@@ -128200,12 +128200,12 @@ const _hoisted_15$15 = {
128200
128200
  class: "cn-form-dialog__select-wrapper"
128201
128201
  };
128202
128202
  const _hoisted_16$X = { class: "cn-form-dialog__option" };
128203
- const _hoisted_17$L = { class: "cn-form-dialog__option" };
128204
- const _hoisted_18$G = {
128203
+ const _hoisted_17$M = { class: "cn-form-dialog__option" };
128204
+ const _hoisted_18$H = {
128205
128205
  key: 7,
128206
128206
  class: "cn-form-dialog__select-wrapper"
128207
128207
  };
128208
- const _hoisted_19$B = { class: "cn-form-dialog__option" };
128208
+ const _hoisted_19$C = { class: "cn-form-dialog__option" };
128209
128209
  const _hoisted_20$x = { class: "cn-form-dialog__option" };
128210
128210
  const _hoisted_21$v = {
128211
128211
  key: 8,
@@ -128783,7 +128783,7 @@ function render$5a(_ctx, _cache, $props, $setup, $data, $options) {
128783
128783
  : {
128784
128784
  name: "selected-option",
128785
128785
  fn: vue$1.withCtx((optionProps) => [
128786
- vue$1.createElementVNode("span", _hoisted_17$L, vue$1.toDisplayString($options.optionText(optionProps)), 1 /* TEXT */)
128786
+ vue$1.createElementVNode("span", _hoisted_17$M, vue$1.toDisplayString($options.optionText(optionProps)), 1 /* TEXT */)
128787
128787
  ]),
128788
128788
  key: "3"
128789
128789
  }
@@ -128800,7 +128800,7 @@ function render$5a(_ctx, _cache, $props, $setup, $data, $options) {
128800
128800
  }, null, 8 /* PROPS */, ["id", "text", "more", "help", "label", "error"])
128801
128801
  ]))
128802
128802
  : (field.widget === 'tags')
128803
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$G, [
128803
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$H, [
128804
128804
  vue$1.withDirectives((vue$1.openBlock(), vue$1.createBlock(_component_NcSelect, {
128805
128805
  inputId: 'cn-form-' + field.key,
128806
128806
  inputLabel: $options.fieldLabelText(field),
@@ -128828,7 +128828,7 @@ function render$5a(_ctx, _cache, $props, $setup, $data, $options) {
128828
128828
  : {
128829
128829
  name: "option",
128830
128830
  fn: vue$1.withCtx((optionProps) => [
128831
- vue$1.createElementVNode("span", _hoisted_19$B, vue$1.toDisplayString($options.optionText(optionProps)), 1 /* TEXT */)
128831
+ vue$1.createElementVNode("span", _hoisted_19$C, vue$1.toDisplayString($options.optionText(optionProps)), 1 /* TEXT */)
128832
128832
  ]),
128833
128833
  key: "1"
128834
128834
  },
@@ -136334,12 +136334,12 @@ const _hoisted_16$V = {
136334
136334
  "data-testid": "cn-related-pending",
136335
136335
  role: "status"
136336
136336
  };
136337
- const _hoisted_17$K = ["data-section"];
136338
- const _hoisted_18$F = {
136337
+ const _hoisted_17$L = ["data-section"];
136338
+ const _hoisted_18$G = {
136339
136339
  key: 3,
136340
136340
  class: "cn-related-objects-widget__empty"
136341
136341
  };
136342
- const _hoisted_19$A = {
136342
+ const _hoisted_19$B = {
136343
136343
  key: 0,
136344
136344
  class: "cn-related-objects-widget__group"
136345
136345
  };
@@ -136502,10 +136502,10 @@ function render$53(_ctx, _cache, $props, $setup, $data, $options) {
136502
136502
  class: "cn-related-objects-widget__section-error",
136503
136503
  "data-testid": "cn-related-section-error",
136504
136504
  "data-section": failed.key
136505
- }, vue$1.toDisplayString($options.t('nextcloud-vue', 'Could not load {section}.', { section: failed.label })), 9 /* TEXT, PROPS */, _hoisted_17$K))
136505
+ }, vue$1.toDisplayString($options.t('nextcloud-vue', 'Could not load {section}.', { section: failed.label })), 9 /* TEXT, PROPS */, _hoisted_17$L))
136506
136506
  }), 128 /* KEYED_FRAGMENT */)),
136507
136507
  ($data.loading && !$options.visibleGroups.length)
136508
- ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$F, vue$1.toDisplayString($options.loadingLabel), 1 /* TEXT */))
136508
+ ? (vue$1.openBlock(), vue$1.createElementBlock("div", _hoisted_18$G, vue$1.toDisplayString($options.loadingLabel), 1 /* TEXT */))
136509
136509
  : ($data.hasLoaded && !$options.visibleGroups.length)
136510
136510
  ? (vue$1.openBlock(), vue$1.createBlock(_component_CnEmptyContent, {
136511
136511
  key: 4,
@@ -136524,7 +136524,7 @@ function render$53(_ctx, _cache, $props, $setup, $data, $options) {
136524
136524
  ], 64 /* STABLE_FRAGMENT */))
136525
136525
  : (vue$1.openBlock(), vue$1.createElementBlock(vue$1.Fragment, { key: 1 }, [
136526
136526
  ($props.showObjects && $data.objectItems.length)
136527
- ? (vue$1.openBlock(), vue$1.createElementBlock("section", _hoisted_19$A, [
136527
+ ? (vue$1.openBlock(), vue$1.createElementBlock("section", _hoisted_19$B, [
136528
136528
  vue$1.createElementVNode("h4", _hoisted_20$w, [
136529
136529
  vue$1.createTextVNode(vue$1.toDisplayString($props.objectsLabel) + " ", 1 /* TEXT */),
136530
136530
  vue$1.createElementVNode("span", _hoisted_21$u, vue$1.toDisplayString($data.objectItems.length), 1 /* TEXT */)
@@ -146858,6 +146858,45 @@ script$4R.render = render$4R;
146858
146858
  script$4R.__scopeId = "data-v-51cc4b46";
146859
146859
  const __sfc_main$4L = script$4R;
146860
146860
 
146861
+ /**
146862
+ * SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl>
146863
+ * SPDX-License-Identifier: EUPL-1.2
146864
+ *
146865
+ * Make an identifier-shaped key readable for a person. Pure: no Vue.
146866
+ */
146867
+
146868
+ /**
146869
+ * Split camelCase, snake_case and kebab-case into words, keep acronyms, and
146870
+ * capitalise only the first word.
146871
+ *
146872
+ * `caseAssigned` → "Case assigned", `object_created` → "Object created",
146873
+ * `newBRPRecord` → "New BRP record".
146874
+ *
146875
+ * @param {string} key The key.
146876
+ * @return {string} A readable sentence-case label, or the key when it has no words.
146877
+ * @spec openspec/changes/data-widget-nested-objects/specs/data-widget-nested-objects/spec.md#requirement-a-nested-object-reads-as-a-list-per-key
146878
+ */
146879
+ function humaniseKey(key) {
146880
+ const words = String(key || '')
146881
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
146882
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
146883
+ .split(/[\s_\-.]+/)
146884
+ .filter(Boolean);
146885
+ if (words.length === 0) {
146886
+ return String(key || '')
146887
+ }
146888
+ return words
146889
+ .map((word, index) => {
146890
+ const isAcronym = word.length > 1 && word === word.toUpperCase() && /[A-Z]/.test(word);
146891
+ if (isAcronym) {
146892
+ return word
146893
+ }
146894
+ const lower = word.toLowerCase();
146895
+ return index === 0 ? lower.charAt(0).toUpperCase() + lower.slice(1) : lower
146896
+ })
146897
+ .join(' ')
146898
+ }
146899
+
146861
146900
  /**
146862
146901
  * SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl>
146863
146902
  * SPDX-License-Identifier: EUPL-1.2
@@ -148293,6 +148332,9 @@ function render$4N(_ctx, _cache, $props, $setup, $data, $options) {
148293
148332
  script$4N.render = render$4N;
148294
148333
  const __sfc_main$4H = script$4N;
148295
148334
 
148335
+ // Widgets whose value the inline text fallback would corrupt.
148336
+ const STRUCTURED_WIDGETS = ['json', 'code', 'file', 'sub-objects', 'child-records'];
148337
+
148296
148338
  /**
148297
148339
  * CnObjectDataWidget — Schema-driven editable data grid widget.
148298
148340
  *
@@ -149233,6 +149275,59 @@ var script$4M = {
149233
149275
  return (raw && typeof raw === 'object') ? Object.entries(raw) : []
149234
149276
  },
149235
149277
 
149278
+ /**
149279
+ * Whether a value is a plain object (not an array, not null).
149280
+ *
149281
+ * @param {unknown} v The value.
149282
+ * @return {boolean} True for a plain object.
149283
+ */
149284
+ isPlainObject(v) {
149285
+ return v !== null && typeof v === 'object' && !Array.isArray(v)
149286
+ },
149287
+
149288
+ /**
149289
+ * Label for a key inside an object value: the sub-schema's `title`
149290
+ * (translated) when the schema describes it, else the key, made
149291
+ * readable when it is identifier-shaped (`shortDescription` → "Short
149292
+ * description"; `nl` stays `nl`).
149293
+ *
149294
+ * @param {object} field Resolved field definition.
149295
+ * @param {string[]} path Keys from the field's value down to this entry.
149296
+ * @return {string} The label.
149297
+ * @spec openspec/changes/data-widget-nested-objects/specs/data-widget-nested-objects/spec.md#requirement-a-nested-object-reads-as-a-list-per-key
149298
+ */
149299
+ nestedLabel(field, path) {
149300
+ let prop = ((this.schema && this.schema.properties) || {})[field.key];
149301
+ for (const key of path) {
149302
+ if (!this.isPlainObject(prop)) {
149303
+ prop = null;
149304
+ break
149305
+ }
149306
+ prop = (prop.properties && prop.properties[key])
149307
+ || (this.isPlainObject(prop.additionalProperties) ? prop.additionalProperties : null);
149308
+ }
149309
+ if (prop && typeof prop.title === 'string' && prop.title) {
149310
+ return this.cnTranslate(prop.title)
149311
+ }
149312
+ const key = String(path[path.length - 1]);
149313
+ return /[A-Z_-]/.test(key) ? humaniseKey(key) : key
149314
+ },
149315
+
149316
+ /**
149317
+ * Stringify a value inside a definition list: a list of scalars reads
149318
+ * as a comma-separated line, anything else as `stringifyCell`.
149319
+ *
149320
+ * @param {unknown} v The value.
149321
+ * @return {string} The display string.
149322
+ * @spec openspec/changes/data-widget-nested-objects/specs/data-widget-nested-objects/spec.md#requirement-a-nested-object-reads-as-a-list-per-key
149323
+ */
149324
+ stringifyNested(v) {
149325
+ if (Array.isArray(v) && v.length && v.every((item) => item === null || typeof item !== 'object')) {
149326
+ return v.map((item) => this.stringifyCell(item)).join(', ')
149327
+ }
149328
+ return this.stringifyCell(v)
149329
+ },
149330
+
149236
149331
  /**
149237
149332
  * Stringify a scalar cell value; a nested object/array collapses to
149238
149333
  * compact JSON (never "[object Object]").
@@ -149560,15 +149655,53 @@ var script$4M = {
149560
149655
  }));
149561
149656
  },
149562
149657
 
149658
+ /**
149659
+ * Whether a field's value cannot be edited inline: a structured widget
149660
+ * (json, code, file, sub-objects, child-records), or a plain-object /
149661
+ * list-of-objects value that is not a relation. Scalar widgets without
149662
+ * a dedicated editor (duration, language, …) keep the text fallback.
149663
+ *
149664
+ * @param {object} field Resolved field definition.
149665
+ * @return {boolean} True when only the form dialog can edit it.
149666
+ * @spec openspec/changes/data-widget-nested-objects/specs/data-widget-nested-objects/spec.md#requirement-a-structured-value-is-never-edited-inline
149667
+ */
149668
+ hasNoInlineEditor(field) {
149669
+ if (STRUCTURED_WIDGETS.includes(field.widget)) {
149670
+ return true
149671
+ }
149672
+ const prop = ((this.schema && this.schema.properties) || {})[field.key];
149673
+ if (this.isRelationField(prop)) {
149674
+ return false
149675
+ }
149676
+ // A list of objects by schema, also while empty (it resolves to `tags`).
149677
+ if (prop && prop.type === 'array' && prop.items && prop.items.type === 'object') {
149678
+ return true
149679
+ }
149680
+ // Classify the raw value itself: fieldValueKind reports a formatter
149681
+ // field as 'scalar' whatever it holds.
149682
+ const raw = this.rawOf(field);
149683
+ if (Array.isArray(raw)) {
149684
+ return raw.some((v) => this.isPlainObject(v))
149685
+ }
149686
+ return this.isPlainObject(raw)
149687
+ },
149688
+
149563
149689
  /**
149564
149690
  * Check if a field is editable.
149565
149691
  *
149566
149692
  * @param {object} field - Resolved field definition from resolvedFields
149693
+ * @spec openspec/changes/data-widget-nested-objects/specs/data-widget-nested-objects/spec.md#requirement-a-structured-value-is-never-edited-inline
149567
149694
  */
149568
149695
  isEditable(field) {
149569
149696
  if (!this.editable) {
149570
149697
  return false
149571
149698
  }
149699
+ // No inline editor exists for structured values: the text fallback
149700
+ // would commit "[object Object]". Those edit through the form dialog,
149701
+ // unless the consumer supplies its own `field-<key>` editor slot.
149702
+ if (!this.$slots['field-' + field.key] && this.hasNoInlineEditor(field)) {
149703
+ return false
149704
+ }
149572
149705
  // Per-field override takes priority
149573
149706
  const override = this.resolvedOverrides[field.key];
149574
149707
  if (override && typeof override.editable === 'boolean') {
@@ -150145,6 +150278,15 @@ const _hoisted_16$U = {
150145
150278
  key: 5,
150146
150279
  class: "cn-object-data-widget__deflist"
150147
150280
  };
150281
+ const _hoisted_17$K = {
150282
+ key: 0,
150283
+ class: "cn-object-data-widget__deflist cn-object-data-widget__deflist--nested"
150284
+ };
150285
+ const _hoisted_18$F = { class: "cn-object-data-widget__deflist-text" };
150286
+ const _hoisted_19$A = {
150287
+ key: 1,
150288
+ class: "cn-object-data-widget__deflist-text"
150289
+ };
150148
150290
 
150149
150291
  function render$4M(_ctx, _cache, $props, $setup, $data, $options) {
150150
150292
  const _component_CnIcon = vue$1.resolveComponent("CnIcon");
@@ -150529,8 +150671,21 @@ function render$4M(_ctx, _cache, $props, $setup, $data, $options) {
150529
150671
  ? (vue$1.openBlock(), vue$1.createElementBlock("dl", _hoisted_16$U, [
150530
150672
  (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.objectEntries($options.rawOf(field)), (pair, pi) => {
150531
150673
  return (vue$1.openBlock(), vue$1.createElementBlock(vue$1.Fragment, { key: pi }, [
150532
- vue$1.createElementVNode("dt", null, vue$1.toDisplayString(pair[0]), 1 /* TEXT */),
150533
- vue$1.createElementVNode("dd", null, vue$1.toDisplayString($options.stringifyCell(pair[1])), 1 /* TEXT */)
150674
+ vue$1.createElementVNode("dt", null, vue$1.toDisplayString($options.nestedLabel(field, [pair[0]])), 1 /* TEXT */),
150675
+ vue$1.createElementVNode("dd", null, [
150676
+ ($options.isPlainObject(pair[1]))
150677
+ ? (vue$1.openBlock(), vue$1.createElementBlock("dl", _hoisted_17$K, [
150678
+ (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.objectEntries(pair[1]), (sub, si) => {
150679
+ return (vue$1.openBlock(), vue$1.createElementBlock(vue$1.Fragment, { key: si }, [
150680
+ vue$1.createElementVNode("dt", null, vue$1.toDisplayString($options.nestedLabel(field, [pair[0], sub[0]])), 1 /* TEXT */),
150681
+ vue$1.createElementVNode("dd", null, [
150682
+ vue$1.createElementVNode("span", _hoisted_18$F, vue$1.toDisplayString($options.stringifyNested(sub[1])), 1 /* TEXT */)
150683
+ ])
150684
+ ], 64 /* STABLE_FRAGMENT */))
150685
+ }), 128 /* KEYED_FRAGMENT */))
150686
+ ]))
150687
+ : (vue$1.openBlock(), vue$1.createElementBlock("span", _hoisted_19$A, vue$1.toDisplayString($options.stringifyNested(pair[1])), 1 /* TEXT */))
150688
+ ])
150534
150689
  ], 64 /* STABLE_FRAGMENT */))
150535
150690
  }), 128 /* KEYED_FRAGMENT */))
150536
150691
  ]))
@@ -150614,7 +150769,7 @@ function render$4M(_ctx, _cache, $props, $setup, $data, $options) {
150614
150769
  }
150615
150770
 
150616
150771
  script$4M.render = render$4M;
150617
- script$4M.__scopeId = "data-v-76edf75d";
150772
+ script$4M.__scopeId = "data-v-324e1a00";
150618
150773
  const __sfc_main$4G = script$4M;
150619
150774
 
150620
150775
  /**
@@ -165626,7 +165781,8 @@ const DEFAULT_LIMIT = 100;
165626
165781
  *
165627
165782
  * It renders the five working days by default (`days: 7` adds the weekend),
165628
165783
  * highlights today, marks items that are late, and says so when a day has
165629
- * nothing. On a narrow screen the strip scrolls sideways.
165784
+ * nothing. On a narrow screen the strip scrolls sideways; under the board
165785
+ * look (`.cn-look-board`) the days wrap into rows instead.
165630
165786
  *
165631
165787
  * Items come from an OpenRegister source (one request for the whole week) or
165632
165788
  * from static `items`. Resolved by its registry type key `week-strip`.
@@ -166332,7 +166488,7 @@ function render$4k(_ctx, _cache, $props, $setup, $data, $options) {
166332
166488
  }
166333
166489
 
166334
166490
  script$4k.render = render$4k;
166335
- script$4k.__scopeId = "data-v-b6c5e274";
166491
+ script$4k.__scopeId = "data-v-27a717bd";
166336
166492
  const __sfc_main$4e = script$4k;
166337
166493
 
166338
166494
  /**
@@ -300159,6 +300315,100 @@ script$1u.render = render$1u;
300159
300315
  script$1u.__scopeId = "data-v-44324dca";
300160
300316
  const __sfc_main$1u = script$1u;
300161
300317
 
300318
+ /**
300319
+ * Thin GridStack bootstrap shared by the drag/resize grids (CnDashboardGrid and
300320
+ * CnWidgetGrid's editable body slot). Keeps the GridStack option shape in one
300321
+ * place so the two engines stay consistent.
300322
+ *
300323
+ * @module utils/gridStack
300324
+ */
300325
+
300326
+ // `gridstack` is a peerDependency, not bundled — see the matching comment in
300327
+ // CnDashboardGrid.vue. The consumer must install `gridstack` themselves and
300328
+ // import its stylesheet (`gridstack/dist/gridstack.min.css`) from that same
300329
+ // copy; nc-vue ships no GridStack CSS of its own so the JS driving the grid
300330
+ // and the CSS sizing it can never come from two different versions.
300331
+
300332
+ /**
300333
+ * Initialise a GridStack instance on a `.grid-stack` element.
300334
+ *
300335
+ * @param {HTMLElement} el The `.grid-stack` container element.
300336
+ * @param {object} opts Options.
300337
+ * @param {number} opts.columns Column count.
300338
+ * @param {boolean} opts.editable Whether drag + resize are enabled.
300339
+ * @param {number} [opts.cellHeight] Cell height in px (default 80).
300340
+ * @param {number} [opts.margin] Grid margin in px (default 12).
300341
+ * @return {import('gridstack').GridStack} The GridStack instance.
300342
+ */
300343
+ function initGridStack(el, opts) {
300344
+ const { columns, editable, cellHeight = 80, margin = 12 } = opts;
300345
+ return gridstack.GridStack.init({
300346
+ column: columns,
300347
+ cellHeight,
300348
+ margin,
300349
+ float: true,
300350
+ animate: true,
300351
+ disableDrag: !editable,
300352
+ disableResize: !editable,
300353
+ removable: false,
300354
+ }, el)
300355
+ }
300356
+
300357
+ /**
300358
+ * Read the geometry GridStack reports for a changed set of items into a plain
300359
+ * map keyed by node id.
300360
+ *
300361
+ * @param {Array<{id: (string|number), x: number, y: number, w: number, h: number}>} items
300362
+ * The items GridStack passes to its `change` handler.
300363
+ * @return {Map<string, {gridX: number, gridY: number, gridWidth: number, gridHeight: number}>}
300364
+ */
300365
+ function readGridGeometry(items) {
300366
+ const map = new Map();
300367
+ for (const it of items || []) {
300368
+ map.set(String(it.id), { gridX: it.x, gridY: it.y, gridWidth: it.w, gridHeight: it.h });
300369
+ }
300370
+ return map
300371
+ }
300372
+
300373
+ /**
300374
+ * Where the items under a growing cell go so they keep their order: every item
300375
+ * the growth would overlap moves down by the growth, and so does every item
300376
+ * that move would overlap in turn. Items beside the cell stay put.
300377
+ *
300378
+ * GridStack resolves the same collision itself, but not in order: when
300379
+ * pipelinq's size-to-content banner grew from two rows to three, the
300380
+ * full-width card under the stat tiles landed below the lists.
300381
+ *
300382
+ * @spec openspec/changes/dashboard-growth-keeps-order/specs/dashboard-grid/spec.md#requirement-a-growing-cell-keeps-the-order-of-the-cards-under-it
300383
+ * @param {Array<{x: number, y: number, w: number, h: number}>} nodes The grid's items (the growing one among them).
300384
+ * @param {{x: number, y: number, w: number, h: number}} node The growing item.
300385
+ * @param {number} h Its new height, in grid rows.
300386
+ * @return {Array<{node: object, y: number}>} The items to move and their new row, bottom-most first.
300387
+ */
300388
+ function planGrowth(nodes, node, h) {
300389
+ const delta = h - node.h;
300390
+ if (!(delta > 0)) {
300391
+ return []
300392
+ }
300393
+ const moved = new Map();
300394
+ const overlaps = (a, b) => a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h;
300395
+ const queue = [{ x: node.x, y: node.y, w: node.w, h }];
300396
+ while (queue.length > 0) {
300397
+ const rect = queue.shift();
300398
+ for (const other of nodes) {
300399
+ if (other === node || moved.has(other) || !overlaps(rect, other)) {
300400
+ continue
300401
+ }
300402
+ const next = { x: other.x, y: other.y + delta, w: other.w, h: other.h };
300403
+ moved.set(other, next.y);
300404
+ queue.push(next);
300405
+ }
300406
+ }
300407
+ return [...moved.entries()]
300408
+ .map(([item, y]) => ({ node: item, y }))
300409
+ .sort((a, b) => b.y - a.y)
300410
+ }
300411
+
300162
300412
  // `gridstack` is a peerDependency (see package.json), not bundled — this
300163
300413
  // component's JS and the consumer's GridStack stylesheet MUST come from the
300164
300414
  // exact same installed copy, because GridStack's JS writes layout state
@@ -300421,6 +300671,30 @@ var script$1t = {
300421
300671
  },
300422
300672
 
300423
300673
  computed: {
300674
+ /**
300675
+ * The layout's items top to bottom, then left to right: the order the
300676
+ * items are in the page, so GridStack places them in that order.
300677
+ *
300678
+ * GridStack sizes a size-to-content cell while it adds the items, one
300679
+ * at a time, and an item it adds onto a cell that has already grown
300680
+ * moves itself below whatever it then collides with. In the layout's
300681
+ * own order a card declared after the lists (pipelinq's full-width
300682
+ * "client in focus" card) was added last, so when the banner above
300683
+ * it grew it skipped past the stat tiles AND the lists and landed at
300684
+ * the bottom. Added top to bottom, every card lands under the one
300685
+ * above it. It is also the order a screen reader and the Tab key
300686
+ * follow. An item without a row or column sorts after the items
300687
+ * that have one, in the layout's order.
300688
+ *
300689
+ * @spec openspec/changes/dashboard-growth-keeps-order/specs/dashboard-grid/spec.md#requirement-a-growing-cell-keeps-the-order-of-the-cards-under-it
300690
+ * @return {Array<object>} The items in row order.
300691
+ */
300692
+ itemsInRowOrder() {
300693
+ const items = Array.isArray(this.layout) ? [...this.layout] : [];
300694
+ const at = (value) => (Number.isFinite(value) ? value : Number.MAX_SAFE_INTEGER);
300695
+ return items.sort((a, b) => (at(a.gridY) - at(b.gridY)) || (at(a.gridX) - at(b.gridX)))
300696
+ },
300697
+
300424
300698
  /**
300425
300699
  * Whether the grid draws each layout row as ROW_SPLIT finer rows. A
300426
300700
  * size-to-content cell can only be a whole number of rows tall, so on
@@ -300696,6 +300970,13 @@ var script$1t = {
300696
300970
  )
300697
300971
  },
300698
300972
 
300973
+ /**
300974
+ * Build the GridStack grid on the rendered items, install the growth
300975
+ * wrapper (`keepOrderOnGrowth`) and listen for its changes.
300976
+ *
300977
+ * @spec openspec/changes/dashboard-growth-keeps-order/specs/dashboard-grid/spec.md#requirement-a-growing-cell-keeps-the-order-of-the-cards-under-it
300978
+ * @return {void}
300979
+ */
300699
300980
  initGrid() {
300700
300981
  if (this.cellHeightCssVar && typeof document !== 'undefined' && document.documentElement) {
300701
300982
  document.documentElement.style.setProperty(this.cellHeightCssVar, `${this.cellHeight}px`);
@@ -300712,6 +300993,7 @@ var script$1t = {
300712
300993
  removable: false,
300713
300994
  ...(this.columnOpts ? { columnOpts: this.columnOpts } : {}),
300714
300995
  }, el);
300996
+ this.keepOrderOnGrowth();
300715
300997
 
300716
300998
  this.grid.on('change', (_event, items) => {
300717
300999
  this.handleGridChange(items);
@@ -300723,6 +301005,87 @@ var script$1t = {
300723
301005
  this.syncInteractivity();
300724
301006
  },
300725
301007
 
301008
+ /**
301009
+ * Let a size-to-content cell that grows push the cards under it down in
301010
+ * their order. GridStack resolves that collision itself, but not in
301011
+ * order: when pipelinq's banner grew from two rows to three, the
301012
+ * full-width card under the stat tiles landed below the lists, also
301013
+ * with `float: false`. Every grow after the grid is built, whether
301014
+ * GridStack measures it on resize or this grid's content observer asks
301015
+ * for it, now first moves the cards the growth reaches down by the
301016
+ * growth (`planGrowth`), bottom-most first, and only then grows the
301017
+ * cell, so GridStack has no collision left to resolve. The wrapper is
301018
+ * installed after `GridStack.init` has already measured the cells on
301019
+ * load; the order on load comes from adding the items in row order
301020
+ * (`itemsInRowOrder`). A cell that shrinks is left to GridStack as
301021
+ * before.
301022
+ *
301023
+ * @spec openspec/changes/dashboard-growth-keeps-order/specs/dashboard-grid/spec.md#requirement-a-growing-cell-keeps-the-order-of-the-cards-under-it
301024
+ * @return {void}
301025
+ */
301026
+ keepOrderOnGrowth() {
301027
+ const grid = this.grid;
301028
+ if (!grid || typeof grid.resizeToContent !== 'function' || typeof grid.update !== 'function') {
301029
+ return
301030
+ }
301031
+ const resize = grid.resizeToContent.bind(grid);
301032
+ grid.resizeToContent = (el) => {
301033
+ const node = el && el.gridstackNode;
301034
+ const nodes = grid.engine && Array.isArray(grid.engine.nodes) ? grid.engine.nodes : null;
301035
+ const rows = node && nodes ? this.contentRows(el, node) : null;
301036
+ const plan = rows ? planGrowth(nodes, node, rows) : [];
301037
+ if (plan.length === 0) {
301038
+ resize(el);
301039
+ return
301040
+ }
301041
+ // Inside a batch the moves are not packed until the cell has grown.
301042
+ const batching = Boolean(grid.engine.batchMode);
301043
+ if (!batching) {
301044
+ grid.batchUpdate();
301045
+ }
301046
+ for (const step of plan) {
301047
+ grid.update(step.node.el, { y: step.y });
301048
+ }
301049
+ resize(el);
301050
+ if (!batching) {
301051
+ grid.batchUpdate(false);
301052
+ }
301053
+ };
301054
+ },
301055
+
301056
+ /**
301057
+ * The rows a size-to-content cell needs for its content, measured the
301058
+ * way GridStack's `resizeToContent` measures it (the content's first
301059
+ * child, plus the cell's own padding), within its size-to-content row
301060
+ * maximum and its minimum and maximum height.
301061
+ *
301062
+ * @spec openspec/changes/dashboard-growth-keeps-order/specs/dashboard-grid/spec.md#requirement-a-growing-cell-keeps-the-order-of-the-cards-under-it
301063
+ * @param {HTMLElement} el The cell.
301064
+ * @param {object} node Its GridStack node.
301065
+ * @return {number|null} The rows, or null when it cannot be measured.
301066
+ */
301067
+ contentRows(el, node) {
301068
+ const cell = this.grid.getCellHeight(true);
301069
+ const item = el.querySelector('.grid-stack-item-content');
301070
+ const child = item && item.firstElementChild;
301071
+ if (!el.clientHeight || !cell || !child || !Number.isFinite(node.h)) {
301072
+ return null
301073
+ }
301074
+ const padding = el.clientHeight - item.clientHeight;
301075
+ const itemHeight = node.h * cell - padding;
301076
+ const wanted = child.getBoundingClientRect().height || itemHeight;
301077
+ let rows = Math.ceil((node.h * cell + wanted - itemHeight) / cell);
301078
+ if (Number.isInteger(node.sizeToContent) && rows > node.sizeToContent) {
301079
+ rows = node.sizeToContent;
301080
+ }
301081
+ if (node.minH && rows < node.minH) {
301082
+ rows = node.minH;
301083
+ } else if (node.maxH && rows > node.maxH) {
301084
+ rows = node.maxH;
301085
+ }
301086
+ return rows
301087
+ },
301088
+
300726
301089
  /**
300727
301090
  * Keep both editing lanes in step with whether an edit could actually be
300728
301091
  * kept: the pointer's handles, and — through `reflowed` feeding
@@ -301259,12 +301622,12 @@ function render$1t(_ctx, _cache, $props, $setup, $data, $options) {
301259
301622
  }, vue$1.toDisplayString($options.keyboardHelpText), 9 /* TEXT, PROPS */, _hoisted_2$1s))
301260
301623
  : vue$1.createCommentVNode("v-if", true),
301261
301624
  vue$1.createElementVNode("div", _hoisted_3$1h, [
301262
- (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($props.layout, (item, index) => {
301625
+ (vue$1.openBlock(true), vue$1.createElementBlock(vue$1.Fragment, null, vue$1.renderList($options.itemsInRowOrder, (item) => {
301263
301626
  return (vue$1.openBlock(), vue$1.createElementBlock("div", {
301264
301627
  key: $options.resolveItemKey(item),
301265
301628
  class: vue$1.normalizeClass(["grid-stack-item", { 'cn-dashboard-grid__item--fit': $options.sizeToContentAttr(item) !== undefined }]),
301266
301629
  role: "group",
301267
- "aria-label": $options.resolveItemLabel(item, index),
301630
+ "aria-label": $options.resolveItemLabel(item, $props.layout.indexOf(item)),
301268
301631
  "aria-describedby": $options.itemDescribedBy,
301269
301632
  tabindex: $options.itemTabindex,
301270
301633
  "gs-id": item.id,
@@ -301288,7 +301651,7 @@ function render$1t(_ctx, _cache, $props, $setup, $data, $options) {
301288
301651
  }
301289
301652
 
301290
301653
  script$1t.render = render$1t;
301291
- script$1t.__scopeId = "data-v-ca2ae49c";
301654
+ script$1t.__scopeId = "data-v-a91998fc";
301292
301655
  const __sfc_main$1t = script$1t;
301293
301656
 
301294
301657
  /**
@@ -336681,61 +337044,6 @@ script$w.render = render$w;
336681
337044
  script$w.__scopeId = "data-v-355b2c95";
336682
337045
  const __sfc_main$w = script$w;
336683
337046
 
336684
- /**
336685
- * Thin GridStack bootstrap shared by the drag/resize grids (CnDashboardGrid and
336686
- * CnWidgetGrid's editable body slot). Keeps the GridStack option shape in one
336687
- * place so the two engines stay consistent.
336688
- *
336689
- * @module utils/gridStack
336690
- */
336691
-
336692
- // `gridstack` is a peerDependency, not bundled — see the matching comment in
336693
- // CnDashboardGrid.vue. The consumer must install `gridstack` themselves and
336694
- // import its stylesheet (`gridstack/dist/gridstack.min.css`) from that same
336695
- // copy; nc-vue ships no GridStack CSS of its own so the JS driving the grid
336696
- // and the CSS sizing it can never come from two different versions.
336697
-
336698
- /**
336699
- * Initialise a GridStack instance on a `.grid-stack` element.
336700
- *
336701
- * @param {HTMLElement} el The `.grid-stack` container element.
336702
- * @param {object} opts Options.
336703
- * @param {number} opts.columns Column count.
336704
- * @param {boolean} opts.editable Whether drag + resize are enabled.
336705
- * @param {number} [opts.cellHeight] Cell height in px (default 80).
336706
- * @param {number} [opts.margin] Grid margin in px (default 12).
336707
- * @return {import('gridstack').GridStack} The GridStack instance.
336708
- */
336709
- function initGridStack(el, opts) {
336710
- const { columns, editable, cellHeight = 80, margin = 12 } = opts;
336711
- return gridstack.GridStack.init({
336712
- column: columns,
336713
- cellHeight,
336714
- margin,
336715
- float: true,
336716
- animate: true,
336717
- disableDrag: !editable,
336718
- disableResize: !editable,
336719
- removable: false,
336720
- }, el)
336721
- }
336722
-
336723
- /**
336724
- * Read the geometry GridStack reports for a changed set of items into a plain
336725
- * map keyed by node id.
336726
- *
336727
- * @param {Array<{id: (string|number), x: number, y: number, w: number, h: number}>} items
336728
- * The items GridStack passes to its `change` handler.
336729
- * @return {Map<string, {gridX: number, gridY: number, gridWidth: number, gridHeight: number}>}
336730
- */
336731
- function readGridGeometry(items) {
336732
- const map = new Map();
336733
- for (const it of items || []) {
336734
- map.set(String(it.id), { gridX: it.x, gridY: it.y, gridWidth: it.w, gridHeight: it.h });
336735
- }
336736
- return map
336737
- }
336738
-
336739
337047
  /**
336740
337048
  * Resolve the grid column count for a manifest slot.
336741
337049
  *
@@ -347116,6 +347424,7 @@ const __sfc_main$l = script$l;
347116
347424
  * @spec openspec/changes/notification-rule-labels-and-runtime-version/specs/notification-preferences/spec.md
347117
347425
  */
347118
347426
 
347427
+
347119
347428
  /**
347120
347429
  * Pick the string for the current language out of a string or per-locale map.
347121
347430
  *
@@ -347142,34 +347451,14 @@ function resolveLocalised(value, language = 'en') {
347142
347451
  }
347143
347452
 
347144
347453
  /**
347145
- * Make a rule key readable: split camelCase, snake_case and kebab-case into
347146
- * words, keep acronyms, and capitalise only the first word.
347147
- *
347148
- * `caseAssigned` → "Case assigned", `object_created` → "Object created",
347149
- * `newBRPRecord` → "New BRP record".
347454
+ * Make a rule key readable (`caseAssigned` → "Case assigned"); see `humaniseKey`.
347150
347455
  *
347151
347456
  * @param {string} key The rule key.
347152
347457
  * @return {string} A readable sentence-case label, or the key when it has no words.
347458
+ * @spec openspec/changes/notification-rule-labels-and-runtime-version/specs/notification-preferences/spec.md#requirement-a-notification-rule-reads-as-a-label
347153
347459
  */
347154
347460
  function humaniseRuleKey(key) {
347155
- const words = String(key || '')
347156
- .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
347157
- .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
347158
- .split(/[\s_\-.]+/)
347159
- .filter(Boolean);
347160
- if (words.length === 0) {
347161
- return String(key || '')
347162
- }
347163
- return words
347164
- .map((word, index) => {
347165
- const isAcronym = word.length > 1 && word === word.toUpperCase() && /[A-Z]/.test(word);
347166
- if (isAcronym) {
347167
- return word
347168
- }
347169
- const lower = word.toLowerCase();
347170
- return index === 0 ? lower.charAt(0).toUpperCase() + lower.slice(1) : lower
347171
- })
347172
- .join(' ')
347461
+ return humaniseKey(key)
347173
347462
  }
347174
347463
 
347175
347464
  /**
@@ -394411,6 +394700,7 @@ exports.getRegisterApiUrl = getRegisterApiUrl;
394411
394700
  exports.getSchemaApiUrl = getSchemaApiUrl;
394412
394701
  exports.getSharedRegistry = getSharedRegistry;
394413
394702
  exports.getWidgetTypeEntry = getWidgetTypeEntry;
394703
+ exports.humaniseKey = humaniseKey;
394414
394704
  exports.humaniseRuleKey = humaniseRuleKey;
394415
394705
  exports.installIntegrationRegistry = installIntegrationRegistry;
394416
394706
  exports.installModalStack = installModalStack;