@conduction/nextcloud-vue 2.61.0 → 2.63.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 (186) hide show
  1. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue.js +10 -0
  2. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue.js.map +1 -0
  3. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js +189 -0
  4. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js.map +1 -0
  5. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js +72 -0
  6. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js.map +1 -0
  7. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +394 -27
  8. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  9. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  10. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +99 -9
  11. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  12. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +39 -18
  13. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  14. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +79 -2
  15. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
  16. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js +38 -25
  17. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
  18. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js +21 -1
  19. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js.map +1 -1
  20. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js +4 -1
  21. package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js.map +1 -1
  22. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
  23. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +53 -37
  24. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
  25. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +30 -6
  26. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  27. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +2 -2
  28. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  29. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js +10 -0
  30. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js.map +1 -0
  31. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js +293 -0
  32. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js.map +1 -0
  33. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js +189 -0
  34. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js.map +1 -0
  35. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +256 -23
  36. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  37. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +119 -51
  38. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  39. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  40. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +2 -1
  41. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  42. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js +3 -1
  43. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js.map +1 -1
  44. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js +1 -1
  45. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js.map +1 -1
  46. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +234 -9
  47. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  48. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +96 -57
  49. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  50. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +51 -2
  51. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  52. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +5 -1
  53. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  54. package/dist/esm/components/CnIndexPage/selfModeActions.js +3 -3
  55. package/dist/esm/components/CnIndexPage/selfModeActions.js.map +1 -1
  56. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue2.js.map +1 -1
  57. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue3.js.map +1 -1
  58. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +36 -1
  59. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  60. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -1
  61. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  62. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +53 -0
  63. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  64. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +22 -5
  65. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  66. package/dist/esm/components/CnReportsPage/CnReportsPage.vue2.js.map +1 -1
  67. package/dist/esm/components/CnReportsPage/CnReportsPage.vue3.js.map +1 -1
  68. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js +121 -12
  69. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js.map +1 -1
  70. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js +3 -1
  71. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js.map +1 -1
  72. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +326 -1
  73. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
  74. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +112 -26
  75. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
  76. package/dist/esm/components/CnStorePage/CnStorePage.vue2.js.map +1 -1
  77. package/dist/esm/components/CnStorePage/CnStorePage.vue3.js.map +1 -1
  78. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +10 -0
  79. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js.map +1 -0
  80. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +337 -0
  81. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -0
  82. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js +102 -0
  83. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -0
  84. package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js +34 -0
  85. package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js.map +1 -0
  86. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js +131 -8
  87. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js.map +1 -1
  88. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js +40 -38
  89. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js.map +1 -1
  90. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +8 -6
  91. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
  92. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  93. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  94. package/dist/esm/components/CnWikiPage/CnWikiPage.vue2.js.map +1 -1
  95. package/dist/esm/components/CnWikiPage/CnWikiPage.vue3.js.map +1 -1
  96. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js +19 -0
  97. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js.map +1 -1
  98. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js +1 -1
  99. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js.map +1 -1
  100. package/dist/esm/composables/useDependencyCheck.js +65 -0
  101. package/dist/esm/composables/useDependencyCheck.js.map +1 -0
  102. package/dist/esm/composables/useWalkthrough.js +218 -6
  103. package/dist/esm/composables/useWalkthrough.js.map +1 -1
  104. package/dist/esm/index.js +2 -0
  105. package/dist/esm/index.js.map +1 -1
  106. package/dist/esm/l10n/en.json.js +48 -0
  107. package/dist/esm/l10n/en.json.js.map +1 -1
  108. package/dist/esm/l10n/nl.json.js +48 -0
  109. package/dist/esm/l10n/nl.json.js.map +1 -1
  110. package/dist/esm/nextcloud-vue.css +557 -9
  111. package/dist/esm/store/useObjectStore.js +8 -0
  112. package/dist/esm/store/useObjectStore.js.map +1 -1
  113. package/dist/esm/utils/columnFilters.js +311 -0
  114. package/dist/esm/utils/columnFilters.js.map +1 -0
  115. package/dist/esm/utils/groupAutocomplete.js +123 -0
  116. package/dist/esm/utils/groupAutocomplete.js.map +1 -0
  117. package/dist/esm/utils/libraryWidgetKeys.js +2 -0
  118. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  119. package/dist/esm/utils/pickerOptions.js +198 -0
  120. package/dist/esm/utils/pickerOptions.js.map +1 -0
  121. package/dist/esm/utils/schema.js +83 -7
  122. package/dist/esm/utils/schema.js.map +1 -1
  123. package/dist/esm/utils/timelineEvents.js +174 -0
  124. package/dist/esm/utils/timelineEvents.js.map +1 -0
  125. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  126. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  127. package/dist/esm/utils/walkthroughSignals.js +88 -0
  128. package/dist/esm/utils/walkthroughSignals.js.map +1 -0
  129. package/dist/nextcloud-vue.cjs.js +9779 -5236
  130. package/dist/nextcloud-vue.cjs.js.map +2 -2
  131. package/dist/nextcloud-vue.css +557 -9
  132. package/l10n/en.json +48 -0
  133. package/l10n/nl.json +48 -0
  134. package/package.json +3 -2
  135. package/scripts/manifest-schema-hash.js +41 -0
  136. package/scripts/record-manifest-schema-hash.js +52 -0
  137. package/src/components/CnAdminActionCard/CnAdminActionCard.vue +234 -0
  138. package/src/components/CnAdminActionCard/index.js +4 -0
  139. package/src/components/CnAppNav/CnAppNav.vue +394 -27
  140. package/src/components/CnAppRoot/CnAppRoot.vue +129 -15
  141. package/src/components/CnBannerWidget/CnBannerWidget.vue +113 -2
  142. package/src/components/CnBrandStripe/CnBrandStripe.md +16 -0
  143. package/src/components/CnBrandStripe/CnBrandStripe.vue +58 -5
  144. package/src/components/CnChoiceCards/CnChoiceCards.vue +56 -31
  145. package/src/components/CnDashboardPage/CnDashboardPage.vue +32 -8
  146. package/src/components/CnDataTable/CnColumnFilterPopover.vue +524 -0
  147. package/src/components/CnDataTable/CnDataTable.md +4 -1
  148. package/src/components/CnDataTable/CnDataTable.vue +302 -21
  149. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +2 -2
  150. package/src/components/CnFieldHelper/CnFieldHelper.vue +4 -2
  151. package/src/components/CnFormDialog/CnFormDialog.vue +290 -31
  152. package/src/components/CnIndexPage/CnIndexPage.vue +55 -2
  153. package/src/components/CnIndexPage/selfModeActions.js +3 -3
  154. package/src/components/CnLinkCardsPage/CnLinkCardsPage.vue +35 -2
  155. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +39 -1
  156. package/src/components/CnObjectSidebar/CnFilesTab.vue +65 -0
  157. package/src/components/CnReportsPage/CnReportsPage.vue +7 -0
  158. package/src/components/CnResourceSelect/CnResourceSelect.vue +123 -12
  159. package/src/components/CnSetupWizard/CnSetupWizard.vue +392 -3
  160. package/src/components/CnStorePage/CnStorePage.vue +7 -0
  161. package/src/components/CnTimelineWidget/CnTimelineWidget.vue +477 -0
  162. package/src/components/CnTimelineWidget/dashboardRegistration.js +32 -0
  163. package/src/components/CnTimelineWidget/index.js +4 -0
  164. package/src/components/CnWalkthrough/CnWalkthrough.vue +143 -10
  165. package/src/components/CnWidgetGrid/builtInWidgets.js +2 -0
  166. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  167. package/src/components/CnWikiPage/CnWikiPage.vue +7 -0
  168. package/src/components/CnWizardDialog/CnWizardDialog.vue +20 -1
  169. package/src/components/index.js +2 -0
  170. package/src/composables/useDependencyCheck.js +61 -0
  171. package/src/composables/useWalkthrough.js +217 -5
  172. package/src/css/dashboard.css +49 -0
  173. package/src/css/detail-page.css +19 -0
  174. package/src/css/table.css +82 -2
  175. package/src/index.js +2 -0
  176. package/src/public/index.js +5 -0
  177. package/src/schemas/app-manifest-v2.schema.json +23 -1
  178. package/src/store/useObjectStore.js +8 -0
  179. package/src/utils/columnFilters.js +324 -0
  180. package/src/utils/groupAutocomplete.js +119 -0
  181. package/src/utils/libraryWidgetKeys.js +2 -0
  182. package/src/utils/pickerOptions.js +194 -0
  183. package/src/utils/schema.js +83 -7
  184. package/src/utils/timelineEvents.js +171 -0
  185. package/src/utils/validateManifestV2.compiled.js +2 -2
  186. package/src/utils/walkthroughSignals.js +94 -0
package/l10n/en.json CHANGED
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "translations": {
3
+ "The item could not be created.": "The item could not be created.",
4
+ "Start over": "Start over",
5
+ "Continue where you left off": "Continue where you left off",
3
6
  "Active": "Active",
4
7
  "Appraisal": "Appraisal",
5
8
  "Archiving": "Archiving",
@@ -295,6 +298,10 @@
295
298
  "Last": "Last",
296
299
  "Load more": "Load more",
297
300
  "Nothing to open here.": "Nothing to open here.",
301
+ "Could not check": "Could not check",
302
+ "Could not check: {subject}": "Could not check: {subject}",
303
+ "The check failed.": "The check failed.",
304
+ "The check failed: {reason}": "The check failed: {reason}",
298
305
  "To do": "To do",
299
306
  "Next step": "Next step",
300
307
  "Review": "Review",
@@ -375,6 +382,46 @@
375
382
  "Not configured": "Not configured",
376
383
  "Not set": "Not set",
377
384
  "Not run": "Not run",
385
+ "Load": "Load",
386
+ "Load again": "Load again",
387
+ "Load {name}": "Load {name}",
388
+ "Loaded.": "Loaded.",
389
+ "Apps this app needs": "Apps this app needs",
390
+ "Required apps": "Required apps",
391
+ "Setup can start once these apps are installed and enabled: {apps}.": "Setup can start once these apps are installed and enabled: {apps}.",
392
+ "Optional, not installed: {apps}. You can add them later.": "Optional, not installed: {apps}. You can add them later.",
393
+ "Skipped, needs {apps}": "Skipped, needs {apps}",
394
+ "Running\u2026": "Running…",
395
+ "This action is not configured.": "This action is not configured.",
396
+ "Done.": "Done.",
397
+ "Something went wrong.": "Something went wrong.",
398
+ "Filter {column}": "Filter {column}",
399
+ "Filter {column}, active": "Filter {column}, active",
400
+ "{column}: {value}": "{column}: {value}",
401
+ "Remove filter {column}": "Remove filter {column}",
402
+ "Active filters": "Active filters",
403
+ "{from} to {to}": "{from} to {to}",
404
+ "from {value}": "from {value}",
405
+ "up to {value}": "up to {value}",
406
+ "Any": "Any",
407
+ "To": "To",
408
+ "Equals": "Equals",
409
+ "Clear": "Clear",
410
+ "Apply": "Apply",
411
+ "This column cannot list its objects.": "This column cannot list its objects.",
412
+ "The list could not load.": "The list could not load.",
413
+ "Nothing to choose from here.": "Nothing to choose from here.",
414
+ "Part of the timeline could not load: {parts}.": "Part of the timeline could not load: {parts}.",
415
+ "Nothing has happened yet.": "Nothing has happened yet.",
416
+ "Upcoming": "Upcoming",
417
+ "changes": "changes",
418
+ "notes and messages": "notes and messages",
419
+ "dates": "dates",
420
+ "related items": "related items",
421
+ "Deleted": "Deleted",
422
+ "Changed": "Changed",
423
+ "{action} by {actor}": "{action} by {actor}",
424
+ "Note": "Note",
378
425
  "Notes": "Notes",
379
426
  "Number": "Number",
380
427
  "Number configuration": "Number configuration",
@@ -622,6 +669,7 @@
622
669
  "No linked emails yet": "No linked emails yet",
623
670
  "Could not load emails": "Could not load emails",
624
671
  "Open in Mail": "Open in Mail",
672
+ "Open in Office": "Open in Office",
625
673
  "(no subject)": "(no subject)",
626
674
  "Unknown sender": "Unknown sender",
627
675
  "No conversations linked yet": "No conversations linked yet",
package/l10n/nl.json CHANGED
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "translations": {
3
+ "The item could not be created.": "Het item kon niet worden aangemaakt.",
4
+ "Start over": "Opnieuw beginnen",
5
+ "Continue where you left off": "Ga verder waar je was",
3
6
  "Active": "Actief",
4
7
  "Appraisal": "Waardering",
5
8
  "Archiving": "Archivering",
@@ -295,6 +298,10 @@
295
298
  "Last": "Laatste",
296
299
  "Load more": "Meer laden",
297
300
  "Nothing to open here.": "Hier is niets te openen.",
301
+ "Could not check": "Kon niet controleren",
302
+ "Could not check: {subject}": "Kon niet controleren: {subject}",
303
+ "The check failed.": "De controle is mislukt.",
304
+ "The check failed: {reason}": "De controle is mislukt: {reason}",
298
305
  "To do": "Nog doen",
299
306
  "Next step": "Volgende stap",
300
307
  "Review": "Beoordelen",
@@ -375,6 +382,46 @@
375
382
  "Not configured": "Niet geconfigureerd",
376
383
  "Not set": "Niet ingesteld",
377
384
  "Not run": "Niet uitgevoerd",
385
+ "Load": "Laden",
386
+ "Load again": "Opnieuw laden",
387
+ "Load {name}": "{name} laden",
388
+ "Loaded.": "Geladen.",
389
+ "Apps this app needs": "Apps die deze app nodig heeft",
390
+ "Required apps": "Vereiste apps",
391
+ "Setup can start once these apps are installed and enabled: {apps}.": "De installatie kan beginnen zodra deze apps geïnstalleerd en ingeschakeld zijn: {apps}.",
392
+ "Optional, not installed: {apps}. You can add them later.": "Optioneel, niet geïnstalleerd: {apps}. Je kunt ze later toevoegen.",
393
+ "Skipped, needs {apps}": "Overgeslagen, vereist {apps}",
394
+ "Running\u2026": "Bezig…",
395
+ "This action is not configured.": "Deze actie is niet ingesteld.",
396
+ "Done.": "Klaar.",
397
+ "Something went wrong.": "Er ging iets mis.",
398
+ "Filter {column}": "{column} filteren",
399
+ "Filter {column}, active": "{column} filteren, actief",
400
+ "{column}: {value}": "{column}: {value}",
401
+ "Remove filter {column}": "Filter {column} verwijderen",
402
+ "Active filters": "Actieve filters",
403
+ "{from} to {to}": "{from} tot {to}",
404
+ "from {value}": "vanaf {value}",
405
+ "up to {value}": "tot en met {value}",
406
+ "Any": "Alle",
407
+ "To": "Tot",
408
+ "Equals": "Is gelijk aan",
409
+ "Clear": "Wissen",
410
+ "Apply": "Toepassen",
411
+ "This column cannot list its objects.": "Deze kolom kan zijn objecten niet tonen.",
412
+ "The list could not load.": "De lijst kon niet laden.",
413
+ "Nothing to choose from here.": "Er valt hier niets te kiezen.",
414
+ "Part of the timeline could not load: {parts}.": "Een deel van de tijdlijn kon niet laden: {parts}.",
415
+ "Nothing has happened yet.": "Er is nog niets gebeurd.",
416
+ "Upcoming": "Gepland",
417
+ "changes": "wijzigingen",
418
+ "notes and messages": "notities en berichten",
419
+ "dates": "datums",
420
+ "related items": "gekoppelde items",
421
+ "Deleted": "Verwijderd",
422
+ "Changed": "Gewijzigd",
423
+ "{action} by {actor}": "{action} door {actor}",
424
+ "Note": "Notitie",
378
425
  "Notes": "Notities",
379
426
  "Number": "Getal",
380
427
  "Number configuration": "Nummerconfiguratie",
@@ -614,6 +661,7 @@
614
661
  "No linked emails yet": "Nog geen gekoppelde e-mails",
615
662
  "Could not load emails": "Kon e-mails niet laden",
616
663
  "Open in Mail": "Openen in Mail",
664
+ "Open in Office": "Openen in Office",
617
665
  "(no subject)": "(geen onderwerp)",
618
666
  "Unknown sender": "Onbekende afzender",
619
667
  "No conversations linked yet": "Nog geen gesprekken gekoppeld",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@conduction/nextcloud-vue",
3
- "version": "2.61.0",
3
+ "version": "2.63.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": {
@@ -94,7 +94,8 @@
94
94
  "test": "jest",
95
95
  "test:e2e": "playwright test",
96
96
  "test:types": "tsd",
97
- "update:manifest-fixtures": "node scripts/update-fleet-manifest-fixtures.js"
97
+ "update:manifest-fixtures": "node scripts/update-fleet-manifest-fixtures.js",
98
+ "update:manifest-schema-hash": "node scripts/record-manifest-schema-hash.js"
98
99
  },
99
100
  "overrides": {
100
101
  "@vue/vue3-jest": {
@@ -0,0 +1,41 @@
1
+ /**
2
+ * SPDX-License-Identifier: EUPL-1.2
3
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
4
+ *
5
+ * The content hash of the v2 manifest schema, shared by the recording script
6
+ * (`record-manifest-schema-hash.js`) and the test that checks it
7
+ * (`tests/schemas/app-manifest-v2.schema-version.spec.js`).
8
+ */
9
+
10
+ const crypto = require('crypto')
11
+ const fs = require('fs')
12
+ const path = require('path')
13
+
14
+ const ROOT = path.resolve(__dirname, '..')
15
+ const SCHEMA_PATH = path.join(ROOT, 'src/schemas/app-manifest-v2.schema.json')
16
+ const LEDGER_PATH = path.join(ROOT, 'tests/schemas/app-manifest-v2.schema.hashes.json')
17
+
18
+ /**
19
+ * Hash a parsed schema. The hash is over the parsed document written back
20
+ * without whitespace, so reformatting the file is not a content change while
21
+ * any key, value or ordering change is. `version` is part of the content.
22
+ *
23
+ * @param {object} schema The parsed schema.
24
+ * @return {string} `sha256:<hex>`.
25
+ * @spec openspec/changes/live-check-follow-ups/specs/live-check-follow-ups/spec.md#requirement-the-manifest-schema-version-moves-with-its-content
26
+ */
27
+ function hashSchema(schema) {
28
+ return 'sha256:' + crypto.createHash('sha256').update(JSON.stringify(schema)).digest('hex')
29
+ }
30
+
31
+ /**
32
+ * Read the ledger of recorded versions.
33
+ *
34
+ * @return {{versions: Record<string, string>}} The ledger.
35
+ * @spec openspec/changes/live-check-follow-ups/specs/live-check-follow-ups/spec.md#requirement-the-manifest-schema-version-moves-with-its-content
36
+ */
37
+ function readLedger() {
38
+ return JSON.parse(fs.readFileSync(LEDGER_PATH, 'utf8'))
39
+ }
40
+
41
+ module.exports = { SCHEMA_PATH, LEDGER_PATH, hashSchema, readLedger }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * SPDX-License-Identifier: EUPL-1.2
3
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
4
+ *
5
+ * Records the content hash of `src/schemas/app-manifest-v2.schema.json` under
6
+ * its current `version` in `tests/schemas/app-manifest-v2.schema.hashes.json`
7
+ * (`npm run update:manifest-schema-hash`).
8
+ *
9
+ * Why a ledger. The schema's `version` is the only machine-readable signal a
10
+ * consumer gets that the vocabulary moved: ConductionNL/.github vendors this
11
+ * file into the gate tooling and compares versions to decide whether its copy
12
+ * is stale. 2.61.0 shipped a new page type under an unchanged 2.42.0, so that
13
+ * comparison read "already current" against a schema that had moved. The
14
+ * ledger makes that state fail a test here instead: a version has one content
15
+ * hash, so changing the content means taking a new version.
16
+ *
17
+ * This script therefore REFUSES to replace the hash of a version that is
18
+ * already recorded. Bump `version` in the schema first, then run it.
19
+ *
20
+ * The hash and the ledger shape live in `manifest-schema-hash.js`, which the
21
+ * test requires too, so the two cannot disagree about what "content" means.
22
+ */
23
+
24
+ const fs = require('fs')
25
+ const { SCHEMA_PATH, LEDGER_PATH, hashSchema, readLedger } = require('./manifest-schema-hash.js')
26
+
27
+ const schema = JSON.parse(fs.readFileSync(SCHEMA_PATH, 'utf8'))
28
+ const version = schema.version
29
+ if (typeof version !== 'string' || version === '') {
30
+ console.error(`${SCHEMA_PATH} has no "version". Nothing to record.`)
31
+ process.exit(1)
32
+ }
33
+
34
+ const ledger = readLedger()
35
+ const hash = hashSchema(schema)
36
+ const recorded = ledger.versions[version]
37
+
38
+ if (recorded === hash) {
39
+ console.log(`Version ${version} is already recorded with this content. Nothing to do.`)
40
+ process.exit(0)
41
+ }
42
+ if (recorded !== undefined) {
43
+ const message = `Version ${version} is already recorded with different content.\n`
44
+ + 'A version has one content. Bump "version" in the schema (minor for an\n'
45
+ + 'additive change), then run this script again.'
46
+ console.error(message)
47
+ process.exit(1)
48
+ }
49
+
50
+ ledger.versions[version] = hash
51
+ fs.writeFileSync(LEDGER_PATH, JSON.stringify(ledger, null, '\t') + '\n')
52
+ console.log(`Recorded ${version} = ${hash}`)
@@ -0,0 +1,234 @@
1
+ <!-- SPDX-License-Identifier: EUPL-1.2 -->
2
+ <!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->
3
+ <template>
4
+ <CnConfigurationCard class="cn-admin-action-card" :title="title" data-testid="cn-admin-action-card">
5
+ <p v-if="description" class="cn-admin-action-card__description">
6
+ {{ description }}
7
+ </p>
8
+ <!-- @slot default Extra content between the explanation and the button. -->
9
+ <slot />
10
+ <div class="cn-admin-action-card__footer">
11
+ <NcButton
12
+ :variant="buttonVariant"
13
+ :disabled="running || disabled"
14
+ data-testid="cn-admin-action-card-run"
15
+ @click="run">
16
+ <template v-if="running" #icon>
17
+ <NcLoadingIcon :size="20" />
18
+ </template>
19
+ {{ running ? runningLabel : resolvedButtonLabel }}
20
+ </NcButton>
21
+ </div>
22
+ <!-- role=status so a screen reader hears the outcome without moving focus. -->
23
+ <div role="status" aria-live="polite">
24
+ <NcNoteCard
25
+ v-if="result"
26
+ :type="result.success ? 'success' : 'error'"
27
+ data-testid="cn-admin-action-card-result">
28
+ {{ result.message }}
29
+ </NcNoteCard>
30
+ </div>
31
+ </CnConfigurationCard>
32
+ </template>
33
+
34
+ <script>
35
+ import { translate as t } from '@nextcloud/l10n'
36
+ import { NcButton, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'
37
+ import CnConfigurationCard from '../CnConfigurationCard/CnConfigurationCard.vue'
38
+
39
+ /**
40
+ * CnAdminActionCard — one maintenance action on an admin settings page.
41
+ *
42
+ * A card with a title, a short explanation and one button. The click POSTs
43
+ * an app action, the button spins while it runs, and the server's message
44
+ * shows below it as success or error. Use it for work an admin starts by
45
+ * hand, such as repairing the register or re-importing schemas. That work
46
+ * never belongs in the setup wizard.
47
+ *
48
+ * By default it posts to the app's setup action contract,
49
+ * `/apps/{appId}/api/setup/action/{action}`, the same endpoint the setup
50
+ * wizard uses. Pass `url` to post somewhere else.
51
+ *
52
+ * ```vue
53
+ * <CnAdminActionCard
54
+ * app-id="pipelinq"
55
+ * action="provision"
56
+ * :title="t('pipelinq', 'Repair the register')"
57
+ * :description="t('pipelinq', 'Creates missing schemas again. Your data stays as it is.')"
58
+ * :button-label="t('pipelinq', 'Repair')" />
59
+ * ```
60
+ *
61
+ * @spec openspec/changes/setup-wizard-card-load-and-dependency-gate/specs/cn-setup-wizard/spec.md#requirement-an-admin-action-card-runs-one-server-action
62
+ */
63
+ export default {
64
+ name: 'CnAdminActionCard',
65
+
66
+ components: {
67
+ CnConfigurationCard,
68
+ NcButton,
69
+ NcLoadingIcon,
70
+ NcNoteCard,
71
+ },
72
+
73
+ props: {
74
+ /** Card heading. Pass it translated. */
75
+ title: {
76
+ type: String,
77
+ required: true,
78
+ },
79
+
80
+ /** What the action does, in one or two short sentences. Pass it translated. */
81
+ description: {
82
+ type: String,
83
+ default: '',
84
+ },
85
+
86
+ /** The Nextcloud app id; builds the default action URL. */
87
+ appId: {
88
+ type: String,
89
+ default: '',
90
+ },
91
+
92
+ /** The action id, posted to `/apps/{appId}/api/setup/action/{action}`. */
93
+ action: {
94
+ type: String,
95
+ default: '',
96
+ },
97
+
98
+ /**
99
+ * An app path to POST to instead of the setup action contract, e.g.
100
+ * `/apps/pipelinq/api/settings/repair`. Passed through `generateUrl`.
101
+ */
102
+ url: {
103
+ type: String,
104
+ default: '',
105
+ },
106
+
107
+ /** Request body to send with the POST. */
108
+ payload: {
109
+ type: Object,
110
+ default: () => ({}),
111
+ },
112
+
113
+ /** Button label. Defaults to "Run". */
114
+ buttonLabel: {
115
+ type: String,
116
+ default: '',
117
+ },
118
+
119
+ /** Label next to the spinner while the action runs. */
120
+ runningLabel: {
121
+ type: String,
122
+ default: () => t('nextcloud-vue', 'Running…'),
123
+ },
124
+
125
+ /** NcButton variant for the action button. */
126
+ buttonVariant: {
127
+ type: String,
128
+ default: 'secondary',
129
+ },
130
+
131
+ /** Disable the button, e.g. while a precondition is not met. */
132
+ disabled: {
133
+ type: Boolean,
134
+ default: false,
135
+ },
136
+ },
137
+
138
+ emits: ['result'],
139
+
140
+ data() {
141
+ return {
142
+ running: false,
143
+ /** @type {{ success: boolean, message: string }|null} */
144
+ result: null,
145
+ }
146
+ },
147
+
148
+ computed: {
149
+ resolvedButtonLabel() {
150
+ return this.buttonLabel || t('nextcloud-vue', 'Run')
151
+ },
152
+
153
+ /**
154
+ * The app path the button posts to: `url` when set, else the setup
155
+ * action contract. Empty when neither is configured.
156
+ *
157
+ * @return {string}
158
+ */
159
+ actionPath() {
160
+ if (this.url) {
161
+ return this.url
162
+ }
163
+ if (this.appId && this.action) {
164
+ return `/apps/${this.appId}/api/setup/action/${this.action}`
165
+ }
166
+ return ''
167
+ },
168
+ },
169
+
170
+ methods: {
171
+ /**
172
+ * Run the action: POST, spin while it runs, show the result.
173
+ *
174
+ * @return {Promise<void>}
175
+ * @spec openspec/changes/setup-wizard-card-load-and-dependency-gate/specs/cn-setup-wizard/spec.md#requirement-an-admin-action-card-runs-one-server-action
176
+ */
177
+ async run() {
178
+ if (this.running) {
179
+ return
180
+ }
181
+ if (!this.actionPath) {
182
+ this.result = { success: false, message: t('nextcloud-vue', 'This action is not configured.') }
183
+ return
184
+ }
185
+ this.running = true
186
+ this.result = null
187
+ let data
188
+ try {
189
+ const [{ default: axios }, { generateUrl }] = await Promise.all([
190
+ import('@nextcloud/axios'),
191
+ import('@nextcloud/router'),
192
+ ])
193
+ const response = await axios.post(generateUrl(this.actionPath), this.payload)
194
+ data = response && response.data
195
+ this.result = {
196
+ success: !!data && data.success !== false,
197
+ message: (data && data.message) || t('nextcloud-vue', 'Done.'),
198
+ }
199
+ } catch (err) {
200
+ data = err && err.response ? err.response.data : null
201
+ this.result = { success: false, message: this.errorMessage(err) }
202
+ } finally {
203
+ this.running = false
204
+ }
205
+ /**
206
+ * @event result The action finished.
207
+ * @type {{ success: boolean, message: string, data: object|null }}
208
+ */
209
+ this.$emit('result', { ...this.result, data })
210
+ },
211
+
212
+ errorMessage(err) {
213
+ const data = err && err.response && err.response.data
214
+ if (data && (data.message || data.error)) {
215
+ return data.message || data.error
216
+ }
217
+ return (err && err.message) || t('nextcloud-vue', 'Something went wrong.')
218
+ },
219
+ },
220
+ }
221
+ </script>
222
+
223
+ <style scoped>
224
+ .cn-admin-action-card__description {
225
+ margin: 0 0 12px;
226
+ color: var(--color-text-maxcontrast);
227
+ }
228
+
229
+ .cn-admin-action-card__footer {
230
+ display: flex;
231
+ gap: 8px;
232
+ margin-block: 8px;
233
+ }
234
+ </style>
@@ -0,0 +1,4 @@
1
+ import CnAdminActionCard from './CnAdminActionCard.vue'
2
+
3
+ export default CnAdminActionCard
4
+ export { CnAdminActionCard }