@conduction/nextcloud-vue 2.129.0 → 2.130.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +23 -1
  2. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +87 -4
  4. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
  5. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
  6. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +29 -3
  7. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  8. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +68 -14
  9. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  10. package/dist/esm/components/CnEventsCard/CnEventsCard.vue.js +1 -1
  11. package/dist/esm/components/CnEventsCard/CnEventsCard.vue2.js +16 -5
  12. package/dist/esm/components/CnEventsCard/CnEventsCard.vue2.js.map +1 -1
  13. package/dist/esm/components/CnEventsCard/CnEventsCard.vue3.js.map +1 -1
  14. package/dist/esm/components/CnFilesCard/CnFilesCard.vue.js +1 -1
  15. package/dist/esm/components/CnFilesCard/CnFilesCard.vue2.js.map +1 -1
  16. package/dist/esm/components/CnFilesCard/CnFilesCard.vue3.js +11 -2
  17. package/dist/esm/components/CnFilesCard/CnFilesCard.vue3.js.map +1 -1
  18. package/dist/esm/components/CnIcon/semanticIcons.js +2 -0
  19. package/dist/esm/components/CnIcon/semanticIcons.js.map +1 -1
  20. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +32 -2
  21. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  22. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +3 -1
  23. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  24. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue.js +1 -1
  25. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  26. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -1
  27. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  28. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  29. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +62 -2
  30. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  31. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +515 -356
  32. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  33. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue.js +1 -1
  34. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js +6 -1
  35. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js.map +1 -1
  36. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue3.js +17 -9
  37. package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue3.js.map +1 -1
  38. package/dist/esm/library-style.js +1 -1
  39. package/dist/esm/nextcloud-vue.css +323 -165
  40. package/dist/esm/utils/boardReferenceColumns.js +38 -1
  41. package/dist/esm/utils/boardReferenceColumns.js.map +1 -1
  42. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  43. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  44. package/dist/nextcloud-vue.cjs.js +989 -479
  45. package/dist/nextcloud-vue.cjs.js.map +2 -2
  46. package/dist/nextcloud-vue.css +323 -165
  47. package/package.json +1 -1
  48. package/src/components/CnActionsBar/CnActionsBar.vue +67 -3
  49. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +59 -8
  50. package/src/components/CnEventsCard/CnEventsCard.vue +16 -5
  51. package/src/components/CnFilesCard/CnFilesCard.vue +7 -0
  52. package/src/components/CnIcon/semanticIcons.js +2 -0
  53. package/src/components/CnIndexPage/CnIndexPage.vue +34 -1
  54. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +1 -1
  55. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +186 -8
  56. package/src/css/look-board-detail.css +27 -2
  57. package/src/css/look-board-index.css +50 -2
  58. package/src/css/look-board.css +52 -2
  59. package/src/integrations/builtin/calendar/CnCalendarCard.vue +12 -3
  60. package/src/integrations/builtin/calendar/__tests__/CnCalendarCardHeaderActions.spec.js +12 -1
  61. package/src/schemas/app-manifest-v2.schema.json +27 -3
  62. package/src/utils/boardReferenceColumns.js +37 -0
  63. package/src/utils/validateManifestV2.compiled.js +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@conduction/nextcloud-vue",
3
- "version": "2.129.0",
3
+ "version": "2.130.0",
4
4
  "description": "Shared Vue component library for Conduction Nextcloud apps — complements @nextcloud/vue with higher-level components, OpenRegister integration, and NL Design System support",
5
5
  "homepage": "https://github.com/ConductionNL/nextcloud-vue#readme",
6
6
  "bugs": {
@@ -483,7 +483,7 @@
483
483
  @description User clicked a declarative bulk action. Payload carries the action id AND the selection, because a bulk action without its selection is not a bulk action.
484
484
  -->
485
485
  <NcButton
486
- v-for="entry in bulkActions"
486
+ v-for="entry in inlineBulkActions"
487
487
  :key="entry.id"
488
488
  variant="secondary"
489
489
  :disabled="entry.disabled === true"
@@ -492,6 +492,27 @@
492
492
  @click="$emit('bulk-action', { id: entry.id, action: entry.id, selectedIds, count: selectedIds.length })">
493
493
  {{ entry.label ? effectiveTranslate(entry.label) : entry.label }}
494
494
  </NcButton>
495
+ <!-- Bulk actions declared with `menu: true` gather under More. -->
496
+ <NcActions
497
+ v-if="menuBulkActions.length > 0"
498
+ :menuName="t('nextcloud-vue', 'More')"
499
+ variant="secondary"
500
+ :forceMenu="true"
501
+ data-testid="cn-bulk-more">
502
+ <NcActionButton
503
+ v-for="entry in menuBulkActions"
504
+ :key="entry.id"
505
+ :closeAfterClick="true"
506
+ :disabled="entry.disabled === true"
507
+ :data-testid="`cn-bulk-action-${entry.id}`"
508
+ :lang="bulkLang(entry)"
509
+ @click="$emit('bulk-action', { id: entry.id, action: entry.id, selectedIds, count: selectedIds.length })">
510
+ <template v-if="entry.icon" #icon>
511
+ <CnIcon :name="entry.icon" :size="20" />
512
+ </template>
513
+ {{ entry.label ? effectiveTranslate(entry.label) : entry.label }}
514
+ </NcActionButton>
515
+ </NcActions>
495
516
  <!--
496
517
  @slot selection-actions The host app's bulk-action buttons (NcButton family), rendered inside the contextual selection strip that appears while a selection is active. This strip is the primary bulk-actions surface; #mass-actions remains available for hosts that ALSO want the actions listed in the overflow menu (optional — strip-only is fine).
497
518
  @binding {number} count Length of the current selection.
@@ -549,7 +570,7 @@
549
570
  {{ t('nextcloud-vue', 'Delete selected') }}
550
571
  </NcButton>
551
572
  <NcButton
552
- v-for="entry in bulkActions"
573
+ v-for="entry in inlineBulkActions"
553
574
  :key="entry.id"
554
575
  variant="secondary"
555
576
  :disabled="entry.disabled === true || selectedIds.length === 0"
@@ -561,6 +582,27 @@
561
582
  </template>
562
583
  {{ entry.label ? effectiveTranslate(entry.label) : entry.label }}
563
584
  </NcButton>
585
+ <NcActions
586
+ v-if="menuBulkActions.length > 0"
587
+ :menuName="t('nextcloud-vue', 'More')"
588
+ variant="secondary"
589
+ :forceMenu="true"
590
+ :disabled="selectedIds.length === 0"
591
+ data-testid="cn-bulk-band-more">
592
+ <NcActionButton
593
+ v-for="entry in menuBulkActions"
594
+ :key="entry.id"
595
+ :closeAfterClick="true"
596
+ :disabled="entry.disabled === true"
597
+ :data-testid="`cn-bulk-action-${entry.id}`"
598
+ :lang="bulkLang(entry)"
599
+ @click="$emit('bulk-action', { id: entry.id, action: entry.id, selectedIds, count: selectedIds.length })">
600
+ <template v-if="entry.icon" #icon>
601
+ <CnIcon :name="entry.icon" :size="20" />
602
+ </template>
603
+ {{ entry.label ? effectiveTranslate(entry.label) : entry.label }}
604
+ </NcActionButton>
605
+ </NcActions>
564
606
  <slot
565
607
  name="selection-actions"
566
608
  :count="selectedIds.length"
@@ -1106,8 +1148,10 @@ export default {
1106
1148
  * render side by side in one row.
1107
1149
  *
1108
1150
  * Clicking emits `bulk-action` with the id AND the current selection.
1151
+ * An entry with `menu: true` is listed under a More menu after the
1152
+ * buttons instead of as a button of its own.
1109
1153
  *
1110
- * @type {Array<{ id: string, label: string, icon?: string, disabled?: boolean }>}
1154
+ * @type {Array<{ id: string, label: string, icon?: string, disabled?: boolean, menu?: boolean }>}
1111
1155
  */
1112
1156
  bulkActions: {
1113
1157
  type: Array,
@@ -1197,6 +1241,26 @@ export default {
1197
1241
  *
1198
1242
  * @return {boolean}
1199
1243
  */
1244
+ /**
1245
+ * The bulk actions drawn as buttons: every one without `menu: true`.
1246
+ *
1247
+ * @spec openspec/changes/bulk-actions-more-menu/specs/bulk-actions-more-menu/spec.md#requirement-a-bulk-action-can-sit-under-more
1248
+ * @return {Array<object>}
1249
+ */
1250
+ inlineBulkActions() {
1251
+ return (this.bulkActions || []).filter((entry) => entry && entry.menu !== true)
1252
+ },
1253
+
1254
+ /**
1255
+ * The bulk actions gathered under the selection's More menu (`menu: true`).
1256
+ *
1257
+ * @spec openspec/changes/bulk-actions-more-menu/specs/bulk-actions-more-menu/spec.md#requirement-a-bulk-action-can-sit-under-more
1258
+ * @return {Array<object>}
1259
+ */
1260
+ menuBulkActions() {
1261
+ return (this.bulkActions || []).filter((entry) => entry && entry.menu === true)
1262
+ },
1263
+
1200
1264
  bulkBandHasActions() {
1201
1265
  return this.showMassCopy || this.showMassDelete
1202
1266
  || (Array.isArray(this.bulkActions) && this.bulkActions.length > 0)
@@ -254,7 +254,7 @@
254
254
  :subtitle="rendererHeader.subtitle || widgetSubtitle"
255
255
  titleIconPosition="left"
256
256
  :titleTone="widgetTitleTone"
257
- :showActions="actionsShown || catalogAddEnabled"
257
+ :showActions="actionsShown || catalogAddInMenu || rendererHeader.menuActions.length > 0"
258
258
  :showRefresh="false"
259
259
  :showRequestFeature="false"
260
260
  :headerLink="cardHeaderLink"
@@ -265,16 +265,41 @@
265
265
  <!-- A renderer that reports its own header (`header` event:
266
266
  `{ link, note, action, actions, pill }`, e.g. record-list's "3 in
267
267
  totaal", a facts card's status pill). -->
268
- <template v-if="hasRendererHeaderItems" #actions>
269
- <CnDetailWidgetHeaderItems :header="rendererHeader" />
268
+ <template v-if="hasRendererHeaderItems || catalogAddInHeader" #actions>
269
+ <CnDetailWidgetHeaderItems v-if="hasRendererHeaderItems" :header="rendererHeader" />
270
+ <!-- The board look draws the catalog Add as a button in the title
271
+ row; the list's footer Add is hidden there (look-board-detail.css). -->
272
+ <NcButton
273
+ v-if="catalogAddInHeader"
274
+ variant="secondary"
275
+ class="cn-detail-page__catalog-add"
276
+ data-testid="cn-detail-widget-catalog-add"
277
+ @click="invokeCatalogAdd">
278
+ <template #icon>
279
+ <Plus :size="20" />
280
+ </template>
281
+ {{ addLabel }}
282
+ </NcButton>
270
283
  </template>
271
- <template v-if="catalogAddEnabled" #action-items>
272
- <NcActionButton @click="invokeCatalogAdd">
284
+ <template v-if="catalogAddInMenu || rendererHeader.menuActions.length > 0" #action-items>
285
+ <NcActionButton v-if="catalogAddInMenu" @click="invokeCatalogAdd">
273
286
  <template #icon>
274
287
  <Plus :size="20" />
275
288
  </template>
276
289
  {{ addLabel }}
277
290
  </NcActionButton>
291
+ <!-- `menuActions` a renderer reports: items in the card's Actions menu. -->
292
+ <NcActionButton
293
+ v-for="(action, index) in rendererHeader.menuActions"
294
+ :key="`menu-${index}-${action.label}`"
295
+ :closeAfterClick="true"
296
+ data-testid="cn-detail-widget-menu-action"
297
+ @click="action.run()">
298
+ <template v-if="action.icon" #icon>
299
+ <CnIcon :name="action.icon" :size="20" />
300
+ </template>
301
+ {{ action.label }}
302
+ </NcActionButton>
278
303
  </template>
279
304
  <component
280
305
  :is="renderer"
@@ -394,7 +419,7 @@
394
419
 
395
420
  <script>
396
421
  import { translate as t } from '@nextcloud/l10n'
397
- import { NcActionButton } from '@nextcloud/vue'
422
+ import { NcActionButton, NcButton } from '@nextcloud/vue'
398
423
  import { computed } from 'vue'
399
424
  import Plus from 'vue-material-design-icons/Plus.vue'
400
425
  import CnEmptyContent from '../CnEmptyContent/CnEmptyContent.vue'
@@ -496,6 +521,7 @@ export default {
496
521
  CnWidgetEmptyState,
497
522
  CnWidgetWrapper,
498
523
  NcActionButton,
524
+ NcButton,
499
525
  CnEmptyContent,
500
526
  Plus,
501
527
  },
@@ -764,7 +790,7 @@ export default {
764
790
  * `header` event (screens-relation-pages): a link and a note,
765
791
  * with the list's total already filled in.
766
792
  */
767
- rendererHeader: { link: null, note: '', subtitle: '', actions: [], pill: null, count: null, empty: null },
793
+ rendererHeader: { link: null, note: '', subtitle: '', actions: [], pill: null, count: null, empty: null, menuActions: [] },
768
794
  }
769
795
  },
770
796
 
@@ -1505,6 +1531,29 @@ export default {
1505
1531
  return createActionState(this.content, this.object).visible
1506
1532
  },
1507
1533
 
1534
+ /**
1535
+ * Whether the catalog Add is a button in the card's title row: the board
1536
+ * look draws it there, right-aligned, instead of in the Actions menu and
1537
+ * the list's footer bar.
1538
+ *
1539
+ * @spec openspec/changes/board-object-list-add-button/specs/board-object-list-add-button/spec.md#requirement-the-board-look-draws-a-cards-add-as-a-title-row-button
1540
+ * @return {boolean} true when the header button renders.
1541
+ */
1542
+ catalogAddInHeader() {
1543
+ return this.catalogAddEnabled && !this.isBare && normalizeLook(this.cnLook) === 'board'
1544
+ },
1545
+
1546
+ /**
1547
+ * Whether the catalog Add is an item of the card's Actions menu, as
1548
+ * ADR-062 places it in the Nextcloud look.
1549
+ *
1550
+ * @spec openspec/changes/board-object-list-add-button/specs/board-object-list-add-button/spec.md#requirement-the-board-look-draws-a-cards-add-as-a-title-row-button
1551
+ * @return {boolean} true when the menu item renders.
1552
+ */
1553
+ catalogAddInMenu() {
1554
+ return this.catalogAddEnabled && !this.catalogAddInHeader
1555
+ },
1556
+
1508
1557
  /**
1509
1558
  * Whether the widget's overflow Actions menu renders: the definition's
1510
1559
  * own `showActions` when it is a boolean, else the surface's
@@ -1610,7 +1659,9 @@ export default {
1610
1659
  : null
1611
1660
  // `subtitle`: a muted line under the card title (a task table's "1 open, 3 done").
1612
1661
  const subtitle = header && typeof header.subtitle === 'string' ? header.subtitle : ''
1613
- this.rendererHeader = { link, note, subtitle, actions, pill, count, empty }
1662
+ // `menuActions`: items for the card's Actions menu instead of the title row.
1663
+ const menuActions = (header && Array.isArray(header.menuActions) ? header.menuActions : []).filter(usable)
1664
+ this.rendererHeader = { link, note, subtitle, actions, pill, count, empty, menuActions }
1614
1665
  },
1615
1666
 
1616
1667
  /**
@@ -118,7 +118,11 @@ export default {
118
118
  * (translated through the host) and `headerActions` (`link`, `create`):
119
119
  * the buttons it reports for its card's title row.
120
120
  *
121
- * @type {{source?: object, endpoint?: string, emptyText?: string, headerActions?: Array<string>}}
121
+ * `createVariant: "secondary"` and `createIcon` draw the create action
122
+ * as the quiet header action with its own icon. `menuActions` (`link`,
123
+ * `create`) puts those flows in the card's Actions menu instead.
124
+ *
125
+ * @type {{source?: object, endpoint?: string, emptyText?: string, headerActions?: Array<string>, menuActions?: Array<string>, createVariant?: string, createIcon?: string}}
122
126
  */
123
127
  content: { type: Object, default: () => ({}) },
124
128
 
@@ -195,13 +199,20 @@ export default {
195
199
  const asked = Array.isArray(this.content?.headerActions) ? this.content.headerActions : []
196
200
  const known = {
197
201
  link: { label: t('nextcloud-vue', 'Link an existing one'), icon: 'LinkVariant', run: () => { this.showPicker = true } },
198
- create: { label: t('nextcloud-vue', 'Make an appointment'), icon: 'Plus', variant: 'primary', run: () => { this.showCreate = true } },
202
+ create: {
203
+ label: t('nextcloud-vue', 'Make an appointment'),
204
+ icon: typeof this.content?.createIcon === 'string' && this.content.createIcon !== '' ? this.content.createIcon : 'Plus',
205
+ ...(this.content?.createVariant === 'secondary' ? {} : { variant: 'primary' }),
206
+ run: () => { this.showCreate = true },
207
+ },
199
208
  }
200
- const actions = this.url === '' ? [] : asked.filter((key, index) => known[key] && asked.indexOf(key) === index).map((key) => known[key])
209
+ const pick = (keys) => (this.url === '' ? [] : keys.filter((key, index) => known[key] && keys.indexOf(key) === index).map((key) => known[key]))
210
+ const actions = pick(asked)
211
+ const inMenu = Array.isArray(this.content?.menuActions) ? this.content.menuActions.filter((key) => !asked.includes(key)) : []
201
212
  /**
202
- * @event header The card's title-row actions, `{ actions }`, for the host to draw.
213
+ * @event header The card's title-row actions and Actions-menu items, `{ actions, menuActions }`, for the host to draw.
203
214
  */
204
- this.$emit('header', { actions })
215
+ this.$emit('header', { actions, menuActions: pick(inMenu) })
205
216
  },
206
217
 
207
218
  /**
@@ -14,6 +14,13 @@
14
14
  -->
15
15
  <template>
16
16
  <CnDetailCard :title="resolvedTitle" :icon="Paperclip" :collapsible="collapsible">
17
+ <template v-if="$slots.actions" #actions>
18
+ <!--
19
+ @slot actions Header actions of the card, e.g. an Add button. Scope:
20
+ `{ refresh }`, which reads the files again after the host added one.
21
+ -->
22
+ <slot name="actions" :refresh="fetchFiles" />
23
+ </template>
17
24
  <NcLoadingIcon v-if="loading" />
18
25
  <div v-else-if="files.length === 0" class="cn-files-card__empty">
19
26
  {{ noFilesLabel }}
@@ -60,6 +60,7 @@ import CalculatorVariantOutlineIcon from 'vue-material-design-icons/CalculatorVa
60
60
  import CalendarAccountOutlineIcon from 'vue-material-design-icons/CalendarAccountOutline.vue'
61
61
  import CalendarClockOutlineIcon from 'vue-material-design-icons/CalendarClockOutline.vue'
62
62
  import CalendarOutlineIcon from 'vue-material-design-icons/CalendarOutline.vue'
63
+ import CalendarPlusOutlineIcon from 'vue-material-design-icons/CalendarPlusOutline.vue'
63
64
  import CalendarRemoveOutlineIcon from 'vue-material-design-icons/CalendarRemoveOutline.vue'
64
65
  import CalendarTextOutlineIcon from 'vue-material-design-icons/CalendarTextOutline.vue'
65
66
  import CalendarWeekendOutlineIcon from 'vue-material-design-icons/CalendarWeekendOutline.vue'
@@ -425,6 +426,7 @@ export const SEMANTIC_ICON_COMPONENTS = Object.freeze({
425
426
  CalendarAccountOutline: CalendarAccountOutlineIcon,
426
427
  CalendarClockOutline: CalendarClockOutlineIcon,
427
428
  CalendarOutline: CalendarOutlineIcon,
429
+ CalendarPlusOutline: CalendarPlusOutlineIcon,
428
430
  CalendarRemoveOutline: CalendarRemoveOutlineIcon,
429
431
  CalendarTextOutline: CalendarTextOutlineIcon,
430
432
  CalendarWeekendOutline: CalendarWeekendOutlineIcon,
@@ -613,6 +613,8 @@
613
613
  ref="deleteViewConfirmDialog"
614
614
  variant="error"
615
615
  :dialogTitle="t('nextcloud-vue', 'Delete view?')"
616
+ :eyebrow="deleteViewEyebrow"
617
+ :subtitle="deleteViewSubtitle"
616
618
  :message="deleteViewMessage"
617
619
  :confirmLabel="t('nextcloud-vue', 'Delete view')"
618
620
  confirmIcon="DeleteOutline"
@@ -1436,6 +1438,7 @@ import {
1436
1438
  buildValueStages,
1437
1439
  columnFieldsOf,
1438
1440
  columnKeyOfRow,
1441
+ declaredStatesOf,
1439
1442
  fetchReferenceObjects,
1440
1443
  flattenItemRefs,
1441
1444
  fullTargetOf,
@@ -5463,7 +5466,15 @@ export default {
5463
5466
  return { states: this.boardStages.states }
5464
5467
  }
5465
5468
  const field = this.boardColumnField
5466
- return this.effectiveSchema?.properties?.[field] || null
5469
+ const property = this.effectiveSchema?.properties?.[field] || null
5470
+ const declared = declaredStatesOf(this.board, this.boardActiveColumnField, field)
5471
+ if (declared !== null) {
5472
+ return {
5473
+ ...(property || {}),
5474
+ states: declared.map((state) => ({ ...state, label: this.cnTranslate(state.label) })),
5475
+ }
5476
+ }
5477
+ return property
5467
5478
  },
5468
5479
 
5469
5480
  /**
@@ -7357,6 +7368,28 @@ export default {
7357
7368
  return (user && user.uid) || ''
7358
7369
  },
7359
7370
 
7371
+ /**
7372
+ * The line above the delete-saved-view confirm's title: "Saved view"
7373
+ * in the board look, as on the view's edit and share dialogs.
7374
+ *
7375
+ * @return {string}
7376
+ * @spec openspec/changes/board-delete-view-confirm-header/specs/board-delete-view-confirm-header/spec.md#requirement-the-board-delete-view-confirm-names-the-saved-view
7377
+ */
7378
+ deleteViewEyebrow() {
7379
+ return this.isBoardLook ? t('nextcloud-vue', 'Saved view') : ''
7380
+ },
7381
+
7382
+ /**
7383
+ * The line under the delete-saved-view confirm's title: the view's
7384
+ * name, in the board look.
7385
+ *
7386
+ * @return {string}
7387
+ * @spec openspec/changes/board-delete-view-confirm-header/specs/board-delete-view-confirm-header/spec.md#requirement-the-board-delete-view-confirm-names-the-saved-view
7388
+ */
7389
+ deleteViewSubtitle() {
7390
+ return this.isBoardLook && this.viewPendingDelete ? String(this.viewPendingDelete.name || '') : ''
7391
+ },
7392
+
7360
7393
  /**
7361
7394
  * Confirmation message for the delete-saved-view dialog.
7362
7395
  *
@@ -40,7 +40,7 @@
40
40
  :compact="fitRows !== null && fitRows < 3"
41
41
  class="cn-object-list-widget__empty">
42
42
  <template v-if="allowCreate && !waitingForContext" #action>
43
- <NcButton @click="openCreate">
43
+ <NcButton class="cn-object-list-widget__empty-add" @click="openCreate">
44
44
  <template #icon>
45
45
  <Plus :size="20" />
46
46
  </template>