@conduction/nextcloud-vue 2.135.0 → 2.137.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 (123) hide show
  1. package/dist/esm/components/CnActionDialog/CnActionDialog.vue.js +1 -1
  2. package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js +2 -1
  3. package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js.map +1 -1
  4. package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js +65 -50
  5. package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js.map +1 -1
  6. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
  7. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js +9 -0
  8. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
  9. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +4 -3
  10. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
  11. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +4 -1
  12. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  13. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +61 -28
  14. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  15. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue.js +1 -1
  16. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +6 -0
  17. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
  18. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js +9 -1
  19. package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
  20. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue.js +1 -1
  21. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js.map +1 -1
  22. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js +4 -11
  23. package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js.map +1 -1
  24. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +32 -0
  25. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  26. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +34 -26
  27. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  28. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +24 -0
  29. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  30. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +2 -2
  31. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  32. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
  33. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  34. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +2 -1
  35. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  36. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +39 -2
  37. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  38. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +6 -5
  39. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  40. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue.js +1 -1
  41. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +11 -0
  42. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
  43. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js +10 -2
  44. package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
  45. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  46. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +18 -0
  47. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  48. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +38 -23
  49. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  50. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue.js +1 -1
  51. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue2.js.map +1 -1
  52. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue3.js +1 -0
  53. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue3.js.map +1 -1
  54. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue.js +1 -1
  55. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue2.js.map +1 -1
  56. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue3.js.map +1 -1
  57. package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue.js +1 -1
  58. package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue2.js +14 -4
  59. package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue2.js.map +1 -1
  60. package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue3.js.map +1 -1
  61. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue.js +1 -1
  62. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js +10 -0
  63. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js.map +1 -1
  64. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js +29 -13
  65. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js.map +1 -1
  66. package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js +3 -1
  67. package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js.map +1 -1
  68. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue.js +1 -1
  69. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue2.js.map +1 -1
  70. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue3.js.map +1 -1
  71. package/dist/esm/composables/indexSources.js +69 -3
  72. package/dist/esm/composables/indexSources.js.map +1 -1
  73. package/dist/esm/l10n/en.json.js +20 -20
  74. package/dist/esm/l10n/nl.json.js +21 -21
  75. package/dist/esm/library-style.js +1 -1
  76. package/dist/esm/nextcloud-vue.css +580 -324
  77. package/dist/esm/utils/contentHeaderLink.js +7 -1
  78. package/dist/esm/utils/contentHeaderLink.js.map +1 -1
  79. package/dist/esm/utils/savedViewMenu.js +4 -1
  80. package/dist/esm/utils/savedViewMenu.js.map +1 -1
  81. package/dist/esm/utils/savedViewSummary.js +11 -4
  82. package/dist/esm/utils/savedViewSummary.js.map +1 -1
  83. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  84. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  85. package/dist/esm/utils/widgetDispatch.js +3 -1
  86. package/dist/esm/utils/widgetDispatch.js.map +1 -1
  87. package/dist/nextcloud-vue.cjs.js +1159 -812
  88. package/dist/nextcloud-vue.cjs.js.map +2 -2
  89. package/dist/nextcloud-vue.css +580 -324
  90. package/l10n/en.json +20 -20
  91. package/l10n/nl.json +21 -21
  92. package/package.json +1 -1
  93. package/src/components/CnActionDialog/CnActionDialog.vue +45 -4
  94. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +13 -1
  95. package/src/components/CnAppNav/CnAppNav.vue +28 -3
  96. package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +15 -0
  97. package/src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue +2 -10
  98. package/src/components/CnDataTable/CnDataTable.md +1 -0
  99. package/src/components/CnDataTable/CnDataTable.vue +38 -1
  100. package/src/components/CnDetailPage/CnDetailPage.md +1 -0
  101. package/src/components/CnDetailPage/CnDetailPage.vue +26 -2
  102. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +1 -0
  103. package/src/components/CnIndexPage/CnIndexPage.vue +44 -6
  104. package/src/components/CnObjectDataWidget/CnObjectDataWidget.md +1 -0
  105. package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +21 -0
  106. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +38 -2
  107. package/src/components/CnRegisterMapping/CnRegisterMapping.vue +7 -0
  108. package/src/components/CnRetentionWidget/CnRetentionWidget.vue +13 -0
  109. package/src/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue +14 -4
  110. package/src/components/CnTimelineWidget/CnTimelineManage.vue +23 -0
  111. package/src/components/CnTimelineWidget/dashboardRegistration.js +3 -1
  112. package/src/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue +7 -0
  113. package/src/composables/indexSources.js +69 -3
  114. package/src/css/look-board-detail.css +57 -1
  115. package/src/css/look-board-index.css +76 -1
  116. package/src/css/look-board.css +51 -4
  117. package/src/css/table.css +5 -0
  118. package/src/schemas/app-manifest-v2.schema.json +4 -2
  119. package/src/utils/contentHeaderLink.js +7 -1
  120. package/src/utils/savedViewMenu.js +4 -1
  121. package/src/utils/savedViewSummary.js +11 -4
  122. package/src/utils/validateManifestV2.compiled.js +2 -2
  123. package/src/utils/widgetDispatch.js +3 -1
package/l10n/en.json CHANGED
@@ -1484,18 +1484,6 @@
1484
1484
  "Pages": "Pages",
1485
1485
  "Open {module}": "Open {module}",
1486
1486
  "{list} and {last}": "{list} and {last}",
1487
- "%n page: {pages}": [
1488
- "%n page: {pages}",
1489
- "%n pages: {pages}"
1490
- ],
1491
- "%n page, including {pages}": [
1492
- "%n page, including {pages}",
1493
- "%n pages, including {pages}"
1494
- ],
1495
- "{on} of %n is in the menu": [
1496
- "{on} of %n is in the menu",
1497
- "{on} of %n are in the menu"
1498
- ],
1499
1487
  "Put it in the menu:": "Put it in the menu:",
1500
1488
  "Admin settings": "Admin settings",
1501
1489
  "Support this app": "Support this app",
@@ -1513,10 +1501,6 @@
1513
1501
  "{status}, {expected}": "{status}, {expected}",
1514
1502
  "Build on this app": "Build on this app",
1515
1503
  "AI skills": "AI skills",
1516
- "%n feature": [
1517
- "%n feature",
1518
- "%n features"
1519
- ],
1520
1504
  "Your account": "Your account",
1521
1505
  "Only for you. Colleagues keep their own settings.": "Only for you. Colleagues keep their own settings.",
1522
1506
  "Sections of the settings": "Sections of the settings",
@@ -2254,10 +2238,6 @@
2254
2238
  "from {from}": "from {from}",
2255
2239
  "up to {to}": "up to {to}",
2256
2240
  "this week": "this week",
2257
- "within %n day": [
2258
- "within %n day",
2259
- "within %n days"
2260
- ],
2261
2241
  "Search term: {term}": "Search term: {term}",
2262
2242
  "New contact": "New contact",
2263
2243
  "Template": "Template",
@@ -2578,6 +2558,26 @@
2578
2558
  "%n minute": [
2579
2559
  "%n minute",
2580
2560
  "%n minutes"
2561
+ ],
2562
+ "%n page: {pages}": [
2563
+ "%n page: {pages}",
2564
+ "%n pages: {pages}"
2565
+ ],
2566
+ "%n page, including {pages}": [
2567
+ "%n page, including {pages}",
2568
+ "%n pages, including {pages}"
2569
+ ],
2570
+ "{on} of %n is in the menu": [
2571
+ "{on} of %n is in the menu",
2572
+ "{on} of %n are in the menu"
2573
+ ],
2574
+ "%n feature": [
2575
+ "%n feature",
2576
+ "%n features"
2577
+ ],
2578
+ "within %n day": [
2579
+ "within %n day",
2580
+ "within %n days"
2581
2581
  ]
2582
2582
  }
2583
2583
  }
package/l10n/nl.json CHANGED
@@ -56,7 +56,7 @@
56
56
  "Save sharing": "Delen opslaan",
57
57
  "Failed to save sharing": "Delen opslaan is mislukt",
58
58
  "My views": "Mijn weergaven",
59
- "Shared with me": "Met mij gedeeld",
59
+ "Shared with me": "Gedeeld met mij",
60
60
  "Share \"{name}\"": "\"{name}\" delen",
61
61
  "Save the current view to \"{name}\"": "Huidige weergave opslaan in \"{name}\"",
62
62
  "Save \"{name}\" as my view": "\"{name}\" opslaan als mijn weergave",
@@ -1671,18 +1671,6 @@
1671
1671
  "Pages": "Pagina's",
1672
1672
  "Open {module}": "{module} openen",
1673
1673
  "{list} and {last}": "{list} en {last}",
1674
- "%n page: {pages}": [
1675
- "%n pagina: {pages}",
1676
- "%n pagina's: {pages}"
1677
- ],
1678
- "%n page, including {pages}": [
1679
- "%n pagina, waaronder {pages}",
1680
- "%n pagina's, waaronder {pages}"
1681
- ],
1682
- "{on} of %n is in the menu": [
1683
- "{on} van %n staat in het menu",
1684
- "{on} van %n staan in het menu"
1685
- ],
1686
1674
  "Put it in the menu:": "In het menu zetten:",
1687
1675
  "Support this app": "Steun deze app",
1688
1676
  "No features with this status": "Geen functies met deze status",
@@ -1699,10 +1687,6 @@
1699
1687
  "{status}, {expected}": "{status}, {expected}",
1700
1688
  "Build on this app": "Bouw verder op deze app",
1701
1689
  "AI skills": "AI-vaardigheden",
1702
- "%n feature": [
1703
- "%n functie",
1704
- "%n functies"
1705
- ],
1706
1690
  "Your account": "Uw account",
1707
1691
  "Only for you. Colleagues keep their own settings.": "Alleen voor jou. Collega's houden hun eigen instellingen.",
1708
1692
  "Sections of the settings": "Onderdelen van de instellingen",
@@ -2504,10 +2488,6 @@
2504
2488
  "from {from}": "vanaf {from}",
2505
2489
  "up to {to}": "tot en met {to}",
2506
2490
  "this week": "deze week",
2507
- "within %n day": [
2508
- "binnen %n dag",
2509
- "binnen %n dagen"
2510
- ],
2511
2491
  "Search term: {term}": "Zoekterm: {term}",
2512
2492
  "New contact": "Nieuw contact",
2513
2493
  "Template": "Sjabloon",
@@ -2845,6 +2825,26 @@
2845
2825
  "%n minute": [
2846
2826
  "%n minuut",
2847
2827
  "%n minuten"
2828
+ ],
2829
+ "%n page: {pages}": [
2830
+ "%n pagina: {pages}",
2831
+ "%n pagina's: {pages}"
2832
+ ],
2833
+ "%n page, including {pages}": [
2834
+ "%n pagina, waaronder {pages}",
2835
+ "%n pagina's, waaronder {pages}"
2836
+ ],
2837
+ "{on} of %n is in the menu": [
2838
+ "{on} van %n staat in het menu",
2839
+ "{on} van %n staan in het menu"
2840
+ ],
2841
+ "%n feature": [
2842
+ "%n functie",
2843
+ "%n functies"
2844
+ ],
2845
+ "within %n day": [
2846
+ "binnen %n dag",
2847
+ "binnen %n dagen"
2848
2848
  ]
2849
2849
  }
2850
2850
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@conduction/nextcloud-vue",
3
- "version": "2.135.0",
3
+ "version": "2.137.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": {
@@ -14,7 +14,9 @@
14
14
  <div v-if="!done" class="cn-action-dialog">
15
15
  <!-- The record the action is about: its title, a meta line, a badge. -->
16
16
  <div v-if="summary" class="cn-action-dialog__summary" data-testid="cn-action-dialog-summary">
17
- <CnIcon :name="config.summary.icon || 'FolderOutline'" :size="20" class="cn-action-dialog__summary-icon" />
17
+ <span class="cn-action-dialog__summary-icon">
18
+ <CnIcon :name="config.summary.icon || 'FolderOutline'" :size="20" />
19
+ </span>
18
20
  <span class="cn-action-dialog__summary-text">
19
21
  <strong>{{ summary.title }}</strong>
20
22
  <span v-if="summary.meta" class="cn-action-dialog__muted">{{ summary.meta }}</span>
@@ -142,6 +144,9 @@
142
144
  :type="noteType"
143
145
  :heading="text(config.note.title)"
144
146
  data-testid="cn-action-dialog-note">
147
+ <template v-if="config.note.icon" #icon>
148
+ <CnIcon :name="config.note.icon" :size="20" />
149
+ </template>
145
150
  {{ text(config.note.text) }}
146
151
  </NcNoteCard>
147
152
 
@@ -239,7 +244,8 @@ let reasonSeq = 0
239
244
  * - `reason`: `{ label?, hint?, required?, field?, rows? }`: a text area; required by
240
245
  * default; sent as `field` (default `reason`). `rows` is its height in lines
241
246
  * (default 2; board DqBesluit draws 4).
242
- * - `note`: `{ variant?, title?, text }`: a read-only note.
247
+ * - `note`: `{ variant?, title?, text, icon? }`: a read-only note; `icon` an
248
+ * icon name in place of the variant's own ("LockOutline").
243
249
  * - `confirm`: `{ label, icon?, request?: { method?, url, body? }, action? }`.
244
250
  * `request` posts itself (`body` templates filled with the record and
245
251
  * `{reason}`); `action` dispatches a manifest action through the page.
@@ -808,10 +814,32 @@ export default {
808
814
  .cn-action-dialog__summary {
809
815
  display: flex;
810
816
  align-items: center;
811
- gap: 10px;
817
+ gap: 12px;
812
818
  padding: 12px 14px;
813
819
  border: 1px solid var(--color-border);
814
- border-radius: var(--border-radius-large, 8px);
820
+ border-radius: var(--border-radius-large, 10px);
821
+ }
822
+
823
+ /* The record's icon on a tinted tile (DqArchiveren). */
824
+ .cn-action-dialog__summary-icon {
825
+ display: flex;
826
+ flex: none;
827
+ align-items: center;
828
+ justify-content: center;
829
+ width: 36px;
830
+ height: 36px;
831
+ border-radius: 8px;
832
+ background: var(--color-primary-element-light);
833
+ color: var(--color-primary-element-light-text);
834
+ }
835
+
836
+ .cn-action-dialog__summary-text strong {
837
+ font-size: 15px;
838
+ font-weight: 600;
839
+ }
840
+
841
+ .cn-action-dialog__summary-text .cn-action-dialog__muted {
842
+ font-size: 13px;
815
843
  }
816
844
 
817
845
  .cn-action-dialog__summary-text {
@@ -853,13 +881,26 @@ export default {
853
881
  border-bottom: 1px solid var(--color-border);
854
882
  }
855
883
 
884
+ /* The server draws every dt as a 130px right-aligned inline block and pads
885
+ dt and dd 12px; a fact is a label over its value. */
886
+ .cn-action-dialog__facts dt,
887
+ .cn-action-dialog__facts dd {
888
+ display: block;
889
+ width: auto;
890
+ white-space: normal;
891
+ text-align: start;
892
+ }
893
+
856
894
  .cn-action-dialog__facts dt {
895
+ margin: 0;
896
+ padding: 0;
857
897
  color: var(--color-text-maxcontrast);
858
898
  font-size: 13px;
859
899
  }
860
900
 
861
901
  .cn-action-dialog__facts dd {
862
902
  margin: 0;
903
+ padding: 0;
863
904
  font-size: 15px;
864
905
  font-weight: 500;
865
906
  }
@@ -1,5 +1,8 @@
1
1
  <template>
2
- <div class="cn-admin-settings-shell" :class="[ownLookClass, sectionColumns ? `cn-admin-settings-shell--columns-${sectionColumns}` : '']">
2
+ <div
3
+ class="cn-admin-settings-shell"
4
+ :class="[ownLookClass, sectionColumns ? `cn-admin-settings-shell--columns-${sectionColumns}` : '']"
5
+ :style="versionTitleSize ? { '--cn-board-version-title-size': `${versionTitleSize}px` } : null">
3
6
  <!-- Names a development, test or acceptance environment; cannot be dismissed. Production shows nothing. -->
4
7
  <CnEnvironmentBanner v-if="environmentName" :environment="environmentName" />
5
8
 
@@ -768,6 +771,15 @@ export default {
768
771
  type: Object,
769
772
  default: () => ({}),
770
773
  },
774
+
775
+ /**
776
+ * The board look's version card title size in px, when the app's board
777
+ * draws it other than 17px (PqBeheer 19, OcInstellingen 18).
778
+ */
779
+ versionTitleSize: {
780
+ type: Number,
781
+ default: 0,
782
+ },
771
783
  },
772
784
 
773
785
  emits: ['update', 'reimported', 'reimport-error', 'tab-change'],
@@ -184,8 +184,9 @@
184
184
  :key="item.id"
185
185
  :name="resolveLabel(item)"
186
186
  :data-testid="`cn-nav-caption-${item.id}`">
187
- <template v-if="item.href" #actions>
187
+ <template v-if="item.href || item.action === 'user-settings'" #actions>
188
188
  <NcActionLink
189
+ v-if="item.href"
189
190
  :href="item.href"
190
191
  :aria-label="captionEditLabel(item)"
191
192
  :data-testid="`cn-nav-caption-edit-${item.id}`">
@@ -194,6 +195,16 @@
194
195
  </template>
195
196
  {{ captionEditLabel(item) }}
196
197
  </NcActionLink>
198
+ <NcActionButton
199
+ v-else
200
+ :aria-label="captionEditLabel(item)"
201
+ :data-testid="`cn-nav-caption-edit-${item.id}`"
202
+ @click="cnOpenUserSettings()">
203
+ <template #icon>
204
+ <Pencil :size="20" />
205
+ </template>
206
+ {{ captionEditLabel(item) }}
207
+ </NcActionButton>
197
208
  </template>
198
209
  </NcAppNavigationCaption>
199
210
  <!-- `type: "hint"`: a muted line, no link, as the empty "My
@@ -447,8 +458,9 @@
447
458
  :key="item.id"
448
459
  :name="resolveLabel(item)"
449
460
  :data-testid="`cn-nav-caption-${item.id}`">
450
- <template v-if="item.href" #actions>
461
+ <template v-if="item.href || item.action === 'user-settings'" #actions>
451
462
  <NcActionLink
463
+ v-if="item.href"
452
464
  :href="item.href"
453
465
  :aria-label="captionEditLabel(item)"
454
466
  :data-testid="`cn-nav-caption-edit-${item.id}`">
@@ -457,6 +469,16 @@
457
469
  </template>
458
470
  {{ captionEditLabel(item) }}
459
471
  </NcActionLink>
472
+ <NcActionButton
473
+ v-else
474
+ :aria-label="captionEditLabel(item)"
475
+ :data-testid="`cn-nav-caption-edit-${item.id}`"
476
+ @click="cnOpenUserSettings()">
477
+ <template #icon>
478
+ <Pencil :size="20" />
479
+ </template>
480
+ {{ captionEditLabel(item) }}
481
+ </NcActionButton>
460
482
  </template>
461
483
  </NcAppNavigationCaption>
462
484
  <NcAppNavigationItem
@@ -500,7 +522,7 @@
500
522
  <script>
501
523
  import { translate as t } from '@nextcloud/l10n'
502
524
  import { generateUrl } from '@nextcloud/router'
503
- import { NcActionLink, NcAppNavigation, NcAppNavigationCaption, NcAppNavigationItem, NcAppNavigationList, NcAppNavigationNew, NcAppNavigationSettings, NcButton, NcCounterBubble } from '@nextcloud/vue'
525
+ import { NcActionButton, NcActionLink, NcAppNavigation, NcAppNavigationCaption, NcAppNavigationItem, NcAppNavigationList, NcAppNavigationNew, NcAppNavigationSettings, NcButton, NcCounterBubble } from '@nextcloud/vue'
504
526
  import { toRaw } from 'vue'
505
527
  import BookOpenVariant from 'vue-material-design-icons/BookOpenVariant.vue'
506
528
  import Cog from 'vue-material-design-icons/Cog.vue'
@@ -595,6 +617,7 @@ export default {
595
617
  name: 'CnAppNav',
596
618
 
597
619
  components: {
620
+ NcActionButton,
598
621
  NcActionLink,
599
622
  Pencil,
600
623
  NcAppNavigation,
@@ -1974,6 +1997,8 @@ export default {
1974
1997
  * `icon`, `count`, `children`, and `pinned`. A caption's `href` is
1975
1998
  * drawn as a pencil link beside the heading: the place where what
1976
1999
  * stands under it is changed (a user's own choice of entries, say).
2000
+ * `action: "user-settings"` draws the same pencil as a button that
2001
+ * opens the user settings dialog.
1977
2002
  *
1978
2003
  * @param {{ type?: string }} item Menu entry descriptor.
1979
2004
  * @return {boolean}
@@ -47,6 +47,9 @@
47
47
  </p>
48
48
  </li>
49
49
  </ul>
50
+ <p v-if="footnote" class="cn-audit-card__footnote" data-testid="cn-audit-trail-widget-footnote">
51
+ {{ footnote }}
52
+ </p>
50
53
  <template v-if="shownEntries.length > maxDisplay" #footer>
51
54
  <button class="cn-audit-card__show-all" @click="$emit('show-all')">
52
55
  {{ showAllLabel }} ({{ shownEntries.length }})
@@ -93,6 +96,12 @@ export default {
93
96
  components: { CnDetailCard, NcLoadingIcon },
94
97
 
95
98
  props: {
99
+ /**
100
+ * A muted line under the trail, inside the card ("Kenmerk ZT-OMV-REG").
101
+ *
102
+ * @spec openspec/changes/audit-trail-footnote/specs/audit-trail/spec.md#requirement-a-history-card-can-end-in-a-line-about-the-record
103
+ */
104
+ footnote: { type: String, default: '' },
96
105
  /** OpenRegister register id (slug or uuid). Optional for `scope: "app"`. */
97
106
  register: { type: String, default: '' },
98
107
  /** OpenRegister schema id (slug or uuid). Optional for `scope: "app"`. */
@@ -523,6 +532,12 @@ export default {
523
532
  padding: 12px 0;
524
533
  }
525
534
 
535
+ .cn-audit-card__footnote {
536
+ margin: 12px 0 0;
537
+ color: var(--color-text-maxcontrast);
538
+ font-size: 13px;
539
+ }
540
+
526
541
  .cn-audit-card__show-all {
527
542
  background: none;
528
543
  border: none;
@@ -20,10 +20,8 @@
20
20
  :actionLabels="actionLabels"
21
21
  :valueLabels="valueLabels"
22
22
  :relatedSources="relatedSources"
23
+ :footnote="footnote"
23
24
  v-bind="emptyText ? { noEntriesLabel: emptyText } : {}" />
24
- <p v-if="footnote" class="cn-audit-trail-widget__footnote" data-testid="cn-audit-trail-widget-footnote">
25
- {{ footnote }}
26
- </p>
27
25
  </div>
28
26
  </template>
29
27
 
@@ -283,14 +281,8 @@ export default {
283
281
  </script>
284
282
 
285
283
  <style scoped>
286
- /* The card keeps its own box; the wrapper only adds the line under it. */
284
+ /* The card keeps its own box, footnote included. */
287
285
  .cn-audit-trail-widget {
288
286
  display: contents;
289
287
  }
290
-
291
- .cn-audit-trail-widget__footnote {
292
- margin: 0;
293
- font-size: 13px;
294
- color: var(--color-text-maxcontrast);
295
- }
296
288
  </style>
@@ -209,6 +209,7 @@ export default {
209
209
  | `filterable` | Boolean | `false` | Show a filter button in every header whose column can filter: enum, boolean, text, number, date and reference columns backed by a schema property. A column opts out with `filterable: false`. Applying a filter emits `column-filter`; the host owns the state and passes it back as `activeFilters`. `CnIndexPage` turns it on by default. |
210
210
  | `activeFilters` | Object | `{}` | The active filter map, `{ paramKey: values[] }`: the same map the facet sidebar writes, so a header filter and a sidebar filter on one field show the same state. |
211
211
  | `filterSchema` | Object | `null` | The schema the header filters read instead of `schema`, for a page that filters through other fields than the rows' own (a named source's search fields). Null: the header filters read `schema`. |
212
+ | `filterChips` | Boolean | `true` | Draw the active header filters as removable chips above the table. A host that lists them itself (the index page's board Active line) turns this off, so a filter is not shown twice. |
212
213
  | `filterRegister` | String | `''` | Register slug a reference column's filter searches in when the column names none. |
213
214
  | `lensReasonTexts` | Object \| null | `null` | App wording for an unavailable personal lens in self-fetch mode, keyed `<lens>.<reason>` or `<reason>`. Without it the library's text is used (see below). |
214
215
 
@@ -24,7 +24,7 @@
24
24
 
25
25
  <!-- Active header filters, one removable chip each. -->
26
26
  <ul
27
- v-if="!isLoading && activeColumnFilterChips.length > 0"
27
+ v-if="filterChips && !isLoading && activeColumnFilterChips.length > 0"
28
28
  class="cn-data-table__filter-chips"
29
29
  :aria-label="activeFiltersLabel"
30
30
  data-testid="cn-table-filter-chips">
@@ -346,7 +346,12 @@
346
346
  falls back to formatValue(). Columns with `aggregate` get a
347
347
  count of related objects (see cellValue/loadAggregates). The
348
348
  #column-{key} slot still wins. -->
349
+ <span
350
+ v-if="isTextZero(row, col)"
351
+ class="cn-table-cell__zero"
352
+ data-testid="cn-cell-zero">{{ cellValue(row, col) }}</span>
349
353
  <CnCellRenderer
354
+ v-else
350
355
  :value="cellValue(row, col)"
351
356
  :property="columnProperty(col)"
352
357
  :formatter="col.formatter || null"
@@ -1081,6 +1086,18 @@ export default {
1081
1086
  default: null,
1082
1087
  },
1083
1088
 
1089
+ /**
1090
+ * Draw the active header filters as removable chips above the table.
1091
+ * A host that lists them itself (the index page's board Active line)
1092
+ * turns this off, so a filter is not shown twice.
1093
+ *
1094
+ * @spec openspec/changes/index-table-filter-chips-once/specs/cn-data-table/spec.md#requirement-a-host-that-lists-the-active-filters-itself-turns-the-table-chips-off
1095
+ */
1096
+ filterChips: {
1097
+ type: Boolean,
1098
+ default: true,
1099
+ },
1100
+
1084
1101
  /**
1085
1102
  * The active filter map, `{ paramKey: values[] }`: the same map the
1086
1103
  * facet sidebar writes, so a header filter and a sidebar filter on one
@@ -2187,6 +2204,26 @@ export default {
2187
2204
  return this.getCellValue(row, this.columnValueField(col))
2188
2205
  },
2189
2206
 
2207
+ /**
2208
+ * Whether an aggregate cell shows its `zeroLabel` as muted text instead
2209
+ * of through the column's widget (`aggregate.zeroAs: "text"`): a count
2210
+ * of zero, or a max with nothing to read.
2211
+ *
2212
+ * @param {object} row The row data.
2213
+ * @param {object} col The column definition.
2214
+ * @return {boolean}
2215
+ * @spec openspec/changes/aggregate-zero-as-text/specs/index-page/spec.md#requirement-a-count-column-can-show-its-zero-label-as-text
2216
+ */
2217
+ isTextZero(row, col) {
2218
+ const aggregate = col && col.aggregate
2219
+ if (!aggregate || aggregate.zeroAs !== 'text' || typeof aggregate.zeroLabel !== 'string' || aggregate.zeroLabel === '') {
2220
+ return false
2221
+ }
2222
+ const cached = this.aggregateValues[String(row[this.rowKey])]
2223
+ const v = cached ? cached[col.key] : undefined
2224
+ return v === 0 || v === '0' || v === null
2225
+ },
2226
+
2190
2227
  /**
2191
2228
  * The row field a column's cell shows: `col.valueField` when set, else
2192
2229
  * `col.key`. The key stays what the header sorts and filters on, so a
@@ -372,6 +372,7 @@ The header carries the shared [CnActionsMenu](./cn-actions-menu.md) overflow (Re
372
372
  | `formSize` (`form-size`) | String | `'normal'` | NcDialog size for this page's create and edit form dialogs (`'small'`, `'normal'`, `'large'`). Set from the manifest as `config.formSize`. Before 2.44.0 the page passed no size, so both forms sat at `normal` however many properties the schema declared, while a manifest `open-form` header action could already ask for `large`. |
373
373
  | `formColumns` (`form-columns`) | Number | `1` | How many columns the create and edit forms flow their fields into (`1` or `2`). Pair `2` with `formSize: 'large'`, or the two columns are merely two narrow ones. Textareas and JSON editors still span both, and the layout collapses back to one column below 700px. Set from the manifest as `config.formColumns`. |
374
374
  | `editLabel` | String | `''` | Label for the header Edit button. Defaults to a translated "Edit". |
375
+ | `editTitle` | String | `''` | Title of the record edit form, run through the host translate. Empty uses the Edit button's label. |
375
376
  | `editSubtitle` | String | `''` | One line under the edit form's title, run through the host translate. Empty shows none. |
376
377
  | `showRequestFeature` | Boolean | `true` | Show the Request-a-feature item. Emits `@request-feature`; the default opens the forge's feature-request issue form (repo and forge injected by CnAppRoot) in a new tab, pre-filled with the page title and `surface: "detail:<id>"`. |
377
378
  | `documentationUrl` | String | `''` | When set, adds a **Documentation** entry opening the link in a new tab. Empty hides it. |
@@ -253,7 +253,7 @@
253
253
  card, next to the checklist that explains it, and not here
254
254
  as well: one primary button per page. -->
255
255
  <NcButton
256
- v-if="effectivePrimaryLabel && !showsNextStepCard"
256
+ v-if="effectivePrimaryLabel && !showsNextStepCard && stagePrimaryOnTab"
257
257
  :id="primaryActionAnchorId"
258
258
  ref="primaryActionButton"
259
259
  variant="primary"
@@ -1324,7 +1324,7 @@
1324
1324
  :schema="currentSchema"
1325
1325
  :item="currentObject"
1326
1326
  :register="register"
1327
- :dialogTitle="editActionLabel"
1327
+ :dialogTitle="editFormTitle"
1328
1328
  :subtitle="editFormSubtitle"
1329
1329
  :excludeFields="excludeFields"
1330
1330
  :includeFields="includeFields"
@@ -2454,6 +2454,12 @@ export default {
2454
2454
  default: '',
2455
2455
  },
2456
2456
 
2457
+ /** Title of the record edit form, run through the host translate. Empty uses the Edit button's label. */
2458
+ editTitle: {
2459
+ type: String,
2460
+ default: '',
2461
+ },
2462
+
2457
2463
  /** One line under the edit form's title, run through the host translate. Empty shows none. */
2458
2464
  editSubtitle: {
2459
2465
  type: String,
@@ -3826,6 +3832,19 @@ export default {
3826
3832
  .slice(0, MAX_QUICK_ACTIONS)
3827
3833
  },
3828
3834
 
3835
+ /**
3836
+ * Whether the stage's primary button belongs beside the open body tab:
3837
+ * an inline stage action with `tabs`/`notTabs` follows the tab like a
3838
+ * quick action (DqZaakAssistent: no "Next step" beside AI oversight).
3839
+ * It stays in the Actions menu either way.
3840
+ *
3841
+ * @return {boolean} true when the button may show.
3842
+ * @spec openspec/changes/stage-primary-follows-tab/specs/detail-page/spec.md#requirement-a-stage-action-can-follow-the-open-tab
3843
+ */
3844
+ stagePrimaryOnTab() {
3845
+ return !this.stagePrimaryEntry || onTab(this.stagePrimary, this.activeBodyTab)
3846
+ },
3847
+
3829
3848
  /**
3830
3849
  * The stage's primary action in dispatchable form: the menu entry
3831
3850
  * CnActionButtons built for it, with its `run()`. Null while the
@@ -4790,6 +4809,11 @@ export default {
4790
4809
  return this.editLabel ? this.effectiveTranslate(this.editLabel) : t('nextcloud-vue', 'Edit')
4791
4810
  },
4792
4811
 
4812
+ /** @return {string} The edit form's title, translated; the Edit button's label when none is configured. */
4813
+ editFormTitle() {
4814
+ return this.editTitle ? this.effectiveTranslate(this.editTitle) : this.editActionLabel
4815
+ },
4816
+
4793
4817
  /** @return {string} The edit form's subtitle, translated; empty when none is configured. */
4794
4818
  editFormSubtitle() {
4795
4819
  return this.editSubtitle ? this.effectiveTranslate(this.editSubtitle) : ''
@@ -99,6 +99,7 @@
99
99
  :hideEmpty="content.hideEmpty === true || hideEmpty"
100
100
  :columns="content.columns || 3"
101
101
  :collapsedFields="content.collapsedFields ?? null"
102
+ :footnote="content.footnote || ''"
102
103
  :editable="content.editable !== false" />
103
104
 
104
105
  <!-- `type: 'related'` — resolves this object's relations and links into