@conduction/nextcloud-vue 2.98.0 → 2.100.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 (141) hide show
  1. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js +12 -0
  2. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +11 -2
  4. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
  5. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
  6. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js +6 -1
  7. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
  8. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +2 -1
  9. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
  10. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue.js +1 -1
  11. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue2.js.map +1 -1
  12. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue3.js +1 -1
  13. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue3.js.map +1 -1
  14. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +25 -8
  15. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  16. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +7 -4
  17. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  18. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
  19. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +11 -8
  20. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  21. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +13 -4
  22. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  23. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
  24. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +54 -3
  25. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
  26. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +16 -2
  27. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
  28. package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue.js +1 -1
  29. package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue2.js +42 -7
  30. package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue2.js.map +1 -1
  31. package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue3.js +121 -57
  32. package/dist/esm/components/CnFlowsPage/CnFlowBoard.vue3.js.map +1 -1
  33. package/dist/esm/components/CnFlowsPage/CnFlowEditorPage.vue2.js +10 -0
  34. package/dist/esm/components/CnFlowsPage/CnFlowEditorPage.vue2.js.map +1 -1
  35. package/dist/esm/components/CnFlowsPage/CnFlowEditorPage.vue3.js +2 -1
  36. package/dist/esm/components/CnFlowsPage/CnFlowEditorPage.vue3.js.map +1 -1
  37. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +136 -7
  38. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  39. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  40. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue.js +1 -1
  41. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js +26 -7
  42. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js.map +1 -1
  43. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js +78 -17
  44. package/dist/esm/components/CnOrderedListField/CnOrderedListField.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 +68 -7
  47. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  48. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +256 -240
  49. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  50. package/dist/esm/components/CnSettingsField/CnSettingsField.vue.js +9 -0
  51. package/dist/esm/components/CnSettingsField/CnSettingsField.vue.js.map +1 -0
  52. package/dist/esm/components/CnSettingsField/CnSettingsField.vue2.js +265 -0
  53. package/dist/esm/components/CnSettingsField/CnSettingsField.vue2.js.map +1 -0
  54. package/dist/esm/components/CnSettingsField/CnSettingsField.vue3.js +191 -0
  55. package/dist/esm/components/CnSettingsField/CnSettingsField.vue3.js.map +1 -0
  56. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue.js +9 -0
  57. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue.js.map +1 -0
  58. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue2.js +537 -0
  59. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue2.js.map +1 -0
  60. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue3.js +99 -0
  61. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue3.js.map +1 -0
  62. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue.js +1 -1
  63. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js +18 -70
  64. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js.map +1 -1
  65. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js +6 -44
  66. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js.map +1 -1
  67. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue.js +1 -1
  68. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +16 -2
  69. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
  70. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +40 -25
  71. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
  72. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  73. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  74. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue.js +1 -1
  75. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js +7 -7
  76. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js.map +1 -1
  77. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js.map +1 -1
  78. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue.js +9 -0
  79. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue.js.map +1 -0
  80. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue2.js +472 -0
  81. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue2.js.map +1 -0
  82. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue3.js +231 -0
  83. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue3.js.map +1 -0
  84. package/dist/esm/components/CnWorkingCalendarWidget/index.js +27 -0
  85. package/dist/esm/components/CnWorkingCalendarWidget/index.js.map +1 -0
  86. package/dist/esm/composables/useFlowStore.js +2 -1
  87. package/dist/esm/composables/useFlowStore.js.map +1 -1
  88. package/dist/esm/index.js +3 -0
  89. package/dist/esm/index.js.map +1 -1
  90. package/dist/esm/l10n/en.json.js +101 -1
  91. package/dist/esm/l10n/en.json.js.map +1 -1
  92. package/dist/esm/l10n/nl.json.js +115 -1
  93. package/dist/esm/l10n/nl.json.js.map +1 -1
  94. package/dist/esm/library-style.js +1 -1
  95. package/dist/esm/nextcloud-vue.css +999 -233
  96. package/dist/esm/utils/libraryWidgetKeys.js +1 -0
  97. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  98. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  99. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  100. package/dist/esm/utils/workingCalendarMonth.js +85 -0
  101. package/dist/esm/utils/workingCalendarMonth.js.map +1 -0
  102. package/dist/nextcloud-vue.cjs.js +10314 -7778
  103. package/dist/nextcloud-vue.cjs.js.map +2 -2
  104. package/dist/nextcloud-vue.css +999 -233
  105. package/l10n/en.json +101 -1
  106. package/l10n/nl.json +115 -1
  107. package/package.json +1 -1
  108. package/src/components/CnActionsMenu/CnActionsMenu.vue +14 -1
  109. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +7 -1
  110. package/src/components/CnBreadcrumbs/CnBreadcrumbs.vue +1 -0
  111. package/src/components/CnDetailPage/CnDetailPage.vue +29 -9
  112. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +13 -4
  113. package/src/components/CnFactsWidget/CnFactsWidget.vue +65 -3
  114. package/src/components/CnFlowsPage/CnFlowBoard.vue +77 -2
  115. package/src/components/CnFlowsPage/CnFlowEditorPage.vue +11 -0
  116. package/src/components/CnIndexPage/CnIndexPage.vue +136 -7
  117. package/src/components/CnOrderedListField/CnOrderedListField.vue +81 -9
  118. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +114 -7
  119. package/src/components/CnSettingsField/CnSettingsField.vue +449 -0
  120. package/src/components/CnSettingsField/index.js +4 -0
  121. package/src/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue +642 -0
  122. package/src/components/CnSettingsFieldsSection/index.js +4 -0
  123. package/src/components/CnSettingsPage/CnSettingsPage.vue +6 -86
  124. package/src/components/CnSetupWizard/CnSetupWizard.vue +37 -3
  125. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  126. package/src/components/CnWizardDialog/CnWizardDialog.vue +7 -7
  127. package/src/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue +725 -0
  128. package/src/components/CnWorkingCalendarWidget/index.js +26 -0
  129. package/src/components/index.js +3 -0
  130. package/src/composables/useFlowStore.js +2 -1
  131. package/src/css/badge.css +32 -16
  132. package/src/css/detail-page.css +15 -0
  133. package/src/css/dialog.css +48 -0
  134. package/src/css/look-board-detail.css +80 -8
  135. package/src/css/look-board-index.css +52 -8
  136. package/src/css/look-board.css +301 -1
  137. package/src/index.js +3 -0
  138. package/src/schemas/app-manifest-v2.schema.json +25 -1
  139. package/src/utils/libraryWidgetKeys.js +1 -0
  140. package/src/utils/validateManifestV2.compiled.js +3 -3
  141. package/src/utils/workingCalendarMonth.js +82 -0
@@ -1 +1 @@
1
- {"version":3,"file":"CnWizardDialog.vue2.js","sources":["../../../../src/components/CnWizardDialog/CnWizardDialog.vue"],"sourcesContent":["<template>\n\t<CnDialog\n\t\t:look=\"look\"\n\t\t:width=\"width\"\n\t\tdefaultWidth=\"wizard\"\n\t\t:eyebrow=\"boardEyebrow\"\n\t\t:subtitle=\"subtitle\"\n\t\t:name=\"dialogTitle\"\n\t\tsize=\"large\"\n\t\t:open=\"dialogOpen\"\n\t\t:noClose=\"loading || !cancellable\"\n\t\tdata-testid=\"cn-modal\"\n\t\tdata-testid-modal=\"cn-wizard-dialog\"\n\t\t@update:open=\"dialogOpen = $event\"\n\t\t@closing=\"onClose\">\n\t\t<!-- Result phase: rendered after a successful `submit()`. -->\n\t\t<div v-if=\"result !== null\"\n\t\t\tclass=\"cn-wizard-dialog__result\"\n\t\t\tdata-testid-phase=\"result\">\n\t\t\t<NcNoteCard v-if=\"result.success\" type=\"success\">\n\t\t\t\t{{ result.message || successText }}\n\t\t\t</NcNoteCard>\n\t\t\t<NcNoteCard v-else-if=\"result.error\" type=\"error\">\n\t\t\t\t{{ result.error }}\n\t\t\t</NcNoteCard>\n\t\t\t<!-- @slot result-extra Optional extra content (e.g. batch\n\t\t\t progress poller, summary table) rendered below the\n\t\t\t success/error banner. Scope: { result }. -->\n\t\t\t<slot name=\"result-extra\" :result=\"result\" />\n\t\t</div>\n\n\t\t<!-- Wizard phase: progress bar + current step body. -->\n\t\t<div v-else\n\t\t\tclass=\"cn-wizard-dialog__wizard\"\n\t\t\tdata-testid-phase=\"form\">\n\t\t\t<!-- Progress indicator: an ordered list with the current step marked.\n\t\t\t A finished step is a button when allowJumpBack is true. -->\n\t\t\t<CnStepper\n\t\t\t\t:steps=\"steps\"\n\t\t\t\t:currentIndex=\"currentIndex\"\n\t\t\t\t:allowJumpBack=\"allowJumpBack\"\n\t\t\t\t:look=\"look\"\n\t\t\t\t@jump=\"jumpTo\" />\n\n\t\t\t<!-- Validation error from the current step's validate() result. -->\n\t\t\t<NcNoteCard v-if=\"validationError\" type=\"error\">\n\t\t\t\t{{ validationError }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<!-- Current step body — a dynamic slot named by step id. -->\n\t\t\t<div class=\"cn-wizard-dialog__step-body\" :data-step-id=\"currentStep.id\">\n\t\t\t\t<!-- @slot step-{id} Per-step body. Scope: { next,\n\t\t\t\t back, jumpTo, submit, currentStep, stepIndex,\n\t\t\t\t totalSteps, stepData, setStepData, isFirst,\n\t\t\t\t isLast }. -->\n\t\t\t\t<slot\n\t\t\t\t\t:name=\"'step-' + currentStep.id\"\n\t\t\t\t\t:next=\"next\"\n\t\t\t\t\t:back=\"back\"\n\t\t\t\t\t:jumpTo=\"jumpTo\"\n\t\t\t\t\t:submit=\"submit\"\n\t\t\t\t\t:currentStep=\"currentStep\"\n\t\t\t\t\t:stepIndex=\"currentIndex\"\n\t\t\t\t\t:totalSteps=\"steps.length\"\n\t\t\t\t\t:stepData=\"stepData\"\n\t\t\t\t\t:setStepData=\"setStepData\"\n\t\t\t\t\t:isFirst=\"isFirst\"\n\t\t\t\t\t:isLast=\"isLast\" />\n\t\t\t</div>\n\t\t</div>\n\n\t\t<template #actions>\n\t\t\t<!-- Result phase actions: just Close. -->\n\t\t\t<NcButton v-if=\"result !== null\" @click=\"onClose\">\n\t\t\t\t{{ closeLabel }}\n\t\t\t</NcButton>\n\n\t\t\t<!-- Wizard phase actions: Cancel + Back + Next/Submit.\n\t\t\t The testids exist because these buttons are the only way\n\t\t\t through a wizard and their LABELS are translated: an e2e that\n\t\t\t clicks \"Next\" passes on an English instance and times out on a\n\t\t\t Dutch one, reporting a broken dialog rather than a missing\n\t\t\t string. -->\n\t\t\t<template v-else>\n\t\t\t\t<NcButton v-if=\"cancellable\" data-testid=\"cn-wizard-cancel\" @click=\"onClose\">\n\t\t\t\t\t{{ cancelLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton v-if=\"!isFirst\"\n\t\t\t\t\tdata-testid=\"cn-wizard-back\"\n\t\t\t\t\t:disabled=\"loading\"\n\t\t\t\t\t@click=\"back\">\n\t\t\t\t\t<template v-if=\"isBoardLook\" #icon>\n\t\t\t\t\t\t<ChevronLeft :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ backLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton variant=\"primary\"\n\t\t\t\t\tdata-testid=\"cn-wizard-next\"\n\t\t\t\t\t:alignment=\"isBoardLook && !isLast ? 'center-reverse' : 'center'\"\n\t\t\t\t\t:disabled=\"loading || nextDisabled\"\n\t\t\t\t\t@click=\"isLast ? submit() : next()\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<NcLoadingIcon v-if=\"loading\" :size=\"20\" />\n\t\t\t\t\t\t<template v-else-if=\"isBoardLook\">\n\t\t\t\t\t\t\t<ChevronRight v-if=\"!isLast\" :size=\"20\" />\n\t\t\t\t\t\t\t<component :is=\"submitIcon || Check\" v-else :size=\"20\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ isLast ? submitLabel : nextLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport Check from 'vue-material-design-icons/Check.vue'\nimport ChevronLeft from 'vue-material-design-icons/ChevronLeft.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport CnDialog from '../CnDialog/CnDialog.vue'\nimport CnStepper from '../CnStepper/CnStepper.vue'\nimport { dialogBoardMixin } from '../../mixins/dialogBoard.js'\n\n/**\n * CnWizardDialog — Multi-step modal with per-step slots,\n * back/next navigation, optional per-step validation, and a single\n * result phase.\n *\n * Each step is declared in the `steps[]` prop (`{ id, label,\n * optional?, icon? }`) and rendered via a `#step-{id}` named slot\n * with the navigation API exposed through the slot scope. The\n * wizard owns the progress indicator, the back/next chrome, the\n * loading lifecycle, and the result-phase banner — the consumer\n * owns the per-step body + the data collection logic.\n *\n * Per-step validation is opt-in via the `validate` prop:\n *\n * ```js\n * async function validate(stepId, stepData) {\n * if (stepId === 'audience' && !stepData.cohort) {\n * return 'Pick a cohort first.'\n * }\n * return true\n * }\n * ```\n *\n * Returning `true` (or any truthy non-string) advances; returning a\n * string surfaces it as an error banner above the step body and\n * blocks the navigation.\n *\n * The result phase is entered by the consumer calling\n * `setResult({ success?, message?, error? })` after `@submit` fires.\n *\n * Use [`CnFormDialog`](../CnFormDialog/) for single-step forms.\n * Use [`CnExportWizard`](../CnExportWizard/) for the specific\n * scope+format+delivery export-trigger shape.\n *\n * ```vue\n * <CnWizardDialog\n * ref=\"wizard\"\n * dialog-title=\"Bulk enrol\"\n * :steps=\"[\n * { id: 'audience', label: 'Audience' },\n * { id: 'course', label: 'Course' },\n * { id: 'confirm', label: 'Confirm' },\n * ]\"\n * :validate=\"validateStep\"\n * @submit=\"onSubmit\"\n * @close=\"show = false\">\n * <template #step-audience=\"{ next, stepData, setStepData }\">\n * <CohortPicker :value=\"stepData.cohort\" @input=\"v => setStepData({ cohort: v })\" />\n * </template>\n * <template #step-course=\"{ next, back, stepData, setStepData }\">\n * <CoursePicker :value=\"stepData.course\" @input=\"v => setStepData({ course: v })\" />\n * </template>\n * <template #step-confirm=\"{ back, submit, stepData }\">\n * <p>Enrol {{ stepData.audience.cohort.size }} learners into {{ stepData.course.course.name }}?</p>\n * </template>\n * </CnWizardDialog>\n * ```\n */\nexport default {\n\tname: 'CnWizardDialog',\n\tcomponents: { CnDialog, CnStepper, ChevronLeft, ChevronRight, NcButton, NcNoteCard, NcLoadingIcon },\n\n\tmixins: [dialogBoardMixin],\n\tprops: {\n\t\t/**\n\t\t * Step declarations. Order is significant — the wizard\n\t\t * navigates linearly between adjacent steps unless the\n\t\t * consumer calls `jumpTo()` from a slot scope.\n\t\t *\n\t\t * @type {Array<{ id: string, label: string, optional?: boolean, icon?: string }>}\n\t\t */\n\t\tsteps: {\n\t\t\ttype: Array,\n\t\t\trequired: true,\n\t\t\tvalidator: (v) => Array.isArray(v) && v.length > 0\n\t\t\t\t&& v.every((s) => s && typeof s.id === 'string' && typeof s.label === 'string'),\n\t\t},\n\n\t\t/**\n\t\t * Dialog title shown in the NcDialog header.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: 'Wizard',\n\t\t},\n\n\t\t/**\n\t\t * Step id to start on. Defaults to the first step in `steps[]`.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tinitialStep: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Per-step validator. Async function returning `true` to\n\t\t * advance, a string to surface as an error banner + block\n\t\t * navigation, or `false` to block silently. Called from\n\t\t * `next()` and `submit()`. When omitted, navigation always\n\t\t * proceeds.\n\t\t *\n\t\t * @type {(stepId: string, stepData: object) => Promise<boolean|string>}\n\t\t */\n\t\tvalidate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Whether the progress indicator allows jumping back to a\n\t\t * completed step via click. Forward jumps are NEVER allowed\n\t\t * via the progress indicator (consumer-side `jumpTo` is\n\t\t * unrestricted).\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tallowJumpBack: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Seed values for `stepData` (the cross-step object passed\n\t\t * to every slot scope). Useful for prefilling on edit-style\n\t\t * wizards.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tdefaults: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * The context in the board look's eyebrow (\"<context>, step N of M\").\n\t\t * Empty uses the dialog title.\n\t\t */\n\t\teyebrowContext: { type: String, default: '' },\n\t\t/**\n\t\t * The eyebrow sentence, with `{context}`, `{step}` and `{total}`\n\t\t * placeholders, so it can be translated.\n\t\t */\n\t\tstepEyebrow: { type: String, default: () => t('nextcloud-vue', '{context}, step {step} of {total}') },\n\t\t/**\n\t\t * Icon component on the finishing button of the last step (board look).\n\t\t * Empty draws a check.\n\t\t *\n\t\t * @type {object|Function|null}\n\t\t */\n\t\tsubmitIcon: { type: [Object, Function], default: null },\n\n\t\t/** Cancel-button label (wizard phase). */\n\t\tcancelLabel: { type: String, default: 'Cancel' },\n\t\t/** Back-button label. */\n\t\tbackLabel: { type: String, default: 'Back' },\n\t\t/** Next-button label (intermediate steps). */\n\t\tnextLabel: { type: String, default: 'Next' },\n\t\t/** Submit-button label (last step). */\n\t\tsubmitLabel: { type: String, default: 'Submit' },\n\t\t/** Close-button label (result phase). */\n\t\tcloseLabel: { type: String, default: 'Close' },\n\t\t/** Success banner default text when result.message is empty. */\n\t\tsuccessText: { type: String, default: 'Done.' },\n\t\t/**\n\t\t * Whether the dialog can be dismissed (Cancel button, ESC, backdrop\n\t\t * click) before reaching the result phase. `false` hides Cancel and\n\t\t * disables all other close affordances — use for a step that must\n\t\t * be completed, not merely skipped. The result-phase Close button is\n\t\t * unaffected (a completed wizard is always dismissible).\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tcancellable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Disable the Next / Submit button, whatever the step's `validate`\n\t\t * would say. For a host that knows the wizard cannot go on yet, such as\n\t\t * `CnSetupWizard` while a required app is missing.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @spec openspec/changes/setup-wizard-card-load-and-dependency-gate/specs/cn-setup-wizard/spec.md#requirement-the-wizard-checks-dependencies-before-any-step\n\t\t */\n\t\tnextDisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: ['close', 'step-change', 'submit'],\n\tdata() {\n\t\tconst initialIndex = this.resolveInitialIndex()\n\t\treturn {\n\t\t\tcurrentIndex: initialIndex,\n\t\t\tstepData: { ...this.defaults },\n\t\t\tloading: false,\n\t\t\tresult: null,\n\t\t\tvalidationError: '',\n\t\t\t/**\n\t\t\t * Drives NcDialog's `open` prop directly. NcDialog's own `open`\n\t\t\t * prop defaults to `true` and is NOT self-managing on close — its\n\t\t\t * internal `showModal` flag resets back to `true` ~300ms after\n\t\t\t * any close (animation bookkeeping for next time it's reopened\n\t\t\t * via the prop), so without an explicit `false` here the dialog\n\t\t\t * reopens itself right after Cancel/ESC/backdrop-click.\n\t\t\t */\n\t\t\tdialogOpen: true,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The board look's eyebrow, \"<context>, step N of M\", updated on every step\n\t\t * change. Empty in the Nextcloud look and in the result phase.\n\t\t *\n\t\t * @return {string} The eyebrow.\n\t\t */\n\t\tboardEyebrow() {\n\t\t\tif (!this.isBoardLook || this.result !== null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn this.stepEyebrow\n\t\t\t\t.replace('{context}', this.eyebrowContext || this.eyebrow || this.dialogTitle)\n\t\t\t\t.replace('{step}', String(this.currentIndex + 1))\n\t\t\t\t.replace('{total}', String(this.steps.length))\n\t\t},\n\n\t\t/** @return {object} The check icon, the default finishing icon. */\n\t\tCheck() {\n\t\t\treturn Check\n\t\t},\n\n\t\t/**\n\t\t * The currently-active step object from `steps[]`.\n\t\t *\n\t\t * @return {object} The current step definition.\n\t\t */\n\t\tcurrentStep() {\n\t\t\treturn this.steps[this.currentIndex] || this.steps[0]\n\t\t},\n\n\t\t/**\n\t\t * Whether the current step is the first one.\n\t\t *\n\t\t * @return {boolean} True when on the first step.\n\t\t */\n\t\tisFirst() {\n\t\t\treturn this.currentIndex === 0\n\t\t},\n\n\t\t/**\n\t\t * Whether the current step is the last one (drives the\n\t\t * Next → Submit label flip).\n\t\t *\n\t\t * @return {boolean} True when on the last step.\n\t\t */\n\t\tisLast() {\n\t\t\treturn this.currentIndex === this.steps.length - 1\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Resolve the index of `initialStep` (falling back to 0 when\n\t\t * unset / not found).\n\t\t *\n\t\t * @return {number} Step index in the range [0, steps.length).\n\t\t */\n\t\tresolveInitialIndex() {\n\t\t\tif (!this.initialStep) {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tconst idx = this.steps.findIndex((s) => s.id === this.initialStep)\n\t\t\treturn idx >= 0 ? idx : 0\n\t\t},\n\n\t\t/**\n\t\t * Merge a partial step-data object onto the shared state.\n\t\t * Each slot scope receives this so consumers can write their\n\t\t * step's data without owning a `data()` block in their slot\n\t\t * component.\n\t\t *\n\t\t * @param {object} partial Fields to merge.\n\t\t * @return {void}\n\t\t */\n\t\tsetStepData(partial) {\n\t\t\tthis.stepData = { ...this.stepData, ...partial }\n\t\t},\n\n\t\t/**\n\t\t * Run the consumer's `validate` prop (if provided) for the\n\t\t * current step. Returns true on pass; sets `validationError`\n\t\t * and returns false on fail.\n\t\t *\n\t\t * @return {Promise<boolean>} Whether validation passed.\n\t\t */\n\t\tasync runValidation() {\n\t\t\tthis.validationError = ''\n\t\t\tif (typeof this.validate !== 'function') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst outcome = await this.validate(this.currentStep.id, this.stepData)\n\t\t\t\tif (outcome === true) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tif (typeof outcome === 'string') {\n\t\t\t\t\tthis.validationError = outcome\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\treturn Boolean(outcome)\n\t\t\t} catch (e) {\n\t\t\t\tthis.validationError = e && e.message ? e.message : 'Validation failed.'\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Advance to the next step after validation. Emits\n\t\t * `@step-change` with the new step id.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync next() {\n\t\t\tif (this.nextDisabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.isLast) {\n\t\t\t\treturn this.submit()\n\t\t\t}\n\t\t\tconst ok = await this.runValidation()\n\t\t\tif (!ok) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.currentIndex += 1\n\t\t\t/**\n\t\t\t * @event step-change Emitted on every step navigation\n\t\t\t * (next / back / jumpTo / submit).\n\t\t\t * @type {{ stepId: string, stepIndex: number, direction: 'next'|'back'|'jump' }}\n\t\t\t */\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'next',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Step back to the previous step. No validation runs on\n\t\t * back navigation — consumers can reach back without\n\t\t * losing the current step's draft.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tback() {\n\t\t\tif (this.isFirst) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex -= 1\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'back',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Jump to an arbitrary step by id. Validation is skipped\n\t\t * (the consumer is responsible for re-running it before\n\t\t * `submit()` if it matters).\n\t\t *\n\t\t * @param {string} stepId Target step id.\n\t\t * @return {void}\n\t\t */\n\t\tjumpTo(stepId) {\n\t\t\tconst idx = this.steps.findIndex((s) => s.id === stepId)\n\t\t\tif (idx < 0) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex = idx\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'jump',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Submit the wizard. Runs the current step's validation;\n\t\t * on pass flips `loading` on and emits `@submit` with the\n\t\t * accumulated `stepData`. The parent is responsible for\n\t\t * calling `setResult()` to flip into the result phase.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync submit() {\n\t\t\tif (this.nextDisabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst ok = await this.runValidation()\n\t\t\tif (!ok) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\t/**\n\t\t\t * @event submit Emitted when the user reaches the final\n\t\t\t * step and clicks Submit (or `submit()` is called\n\t\t\t * programmatically from a slot scope). Payload is the\n\t\t\t * accumulated `stepData`.\n\t\t\t * @type {object}\n\t\t\t */\n\t\t\tthis.$emit('submit', { ...this.stepData })\n\t\t},\n\n\t\t/**\n\t\t * Public method called by the parent to switch the wizard\n\t\t * into the result phase.\n\t\t *\n\t\t * @param {object} result `{ success?, message?, error? }`.\n\t\t * @return {void}\n\t\t */\n\t\tsetResult(result) {\n\t\t\tthis.result = result || { success: true }\n\t\t\tthis.loading = false\n\t\t},\n\n\t\t/**\n\t\t * Public method for a NON-terminal submit failure: stops the\n\t\t * loading spinner and surfaces `message` as the error banner above\n\t\t * the (still-editable) current step, WITHOUT entering the result\n\t\t * phase — so the user can correct the input and resubmit. Use this\n\t\t * instead of `setResult({ error })` when the failure is recoverable\n\t\t * (e.g. a taken slug, a validation conflict).\n\t\t *\n\t\t * @param {string} message The error to show above the step body.\n\t\t * @return {void}\n\t\t */\n\t\tsetError(message) {\n\t\t\tthis.loading = false\n\t\t\tthis.validationError = message || ''\n\t\t},\n\n\t\t/**\n\t\t * Close-button handler. Resets local state so the next open\n\t\t * starts fresh and emits `@close`.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonClose() {\n\t\t\tthis.result = null\n\t\t\tthis.loading = false\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex = this.resolveInitialIndex()\n\t\t\tthis.stepData = { ...this.defaults }\n\t\t\tthis.dialogOpen = false\n\t\t\t/**\n\t\t\t * @event close Emitted when the dialog should close.\n\t\t\t */\n\t\t\tthis.$emit('close')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-wizard-dialog__step-body {\n\tmin-height: 200px;\n}\n\n.cn-wizard-dialog__result {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n</style>\n"],"names":["CnDialog","CnStepper","t"],"mappings":"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"}
1
+ {"version":3,"file":"CnWizardDialog.vue2.js","sources":["../../../../src/components/CnWizardDialog/CnWizardDialog.vue"],"sourcesContent":["<template>\n\t<CnDialog\n\t\t:look=\"look\"\n\t\t:width=\"width\"\n\t\tdefaultWidth=\"wizard\"\n\t\t:eyebrow=\"boardEyebrow\"\n\t\t:subtitle=\"subtitle\"\n\t\t:name=\"dialogTitle\"\n\t\tsize=\"large\"\n\t\t:open=\"dialogOpen\"\n\t\t:noClose=\"loading || !cancellable\"\n\t\tdata-testid=\"cn-modal\"\n\t\tdata-testid-modal=\"cn-wizard-dialog\"\n\t\t@update:open=\"dialogOpen = $event\"\n\t\t@closing=\"onClose\">\n\t\t<!-- Result phase: rendered after a successful `submit()`. -->\n\t\t<div v-if=\"result !== null\"\n\t\t\tclass=\"cn-wizard-dialog__result\"\n\t\t\tdata-testid-phase=\"result\">\n\t\t\t<NcNoteCard v-if=\"result.success\" type=\"success\">\n\t\t\t\t{{ result.message || successText }}\n\t\t\t</NcNoteCard>\n\t\t\t<NcNoteCard v-else-if=\"result.error\" type=\"error\">\n\t\t\t\t{{ result.error }}\n\t\t\t</NcNoteCard>\n\t\t\t<!-- @slot result-extra Optional extra content (e.g. batch\n\t\t\t progress poller, summary table) rendered below the\n\t\t\t success/error banner. Scope: { result }. -->\n\t\t\t<slot name=\"result-extra\" :result=\"result\" />\n\t\t</div>\n\n\t\t<!-- Wizard phase: progress bar + current step body. -->\n\t\t<div v-else\n\t\t\tclass=\"cn-wizard-dialog__wizard\"\n\t\t\tdata-testid-phase=\"form\">\n\t\t\t<!-- Progress indicator: an ordered list with the current step marked.\n\t\t\t A finished step is a button when allowJumpBack is true. -->\n\t\t\t<CnStepper\n\t\t\t\t:steps=\"steps\"\n\t\t\t\t:currentIndex=\"currentIndex\"\n\t\t\t\t:allowJumpBack=\"allowJumpBack\"\n\t\t\t\t:look=\"look\"\n\t\t\t\t@jump=\"jumpTo\" />\n\n\t\t\t<!-- Validation error from the current step's validate() result. -->\n\t\t\t<NcNoteCard v-if=\"validationError\" type=\"error\">\n\t\t\t\t{{ validationError }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<!-- Current step body — a dynamic slot named by step id. -->\n\t\t\t<div class=\"cn-wizard-dialog__step-body\" :data-step-id=\"currentStep.id\">\n\t\t\t\t<!-- @slot step-{id} Per-step body. Scope: { next,\n\t\t\t\t back, jumpTo, submit, currentStep, stepIndex,\n\t\t\t\t totalSteps, stepData, setStepData, isFirst,\n\t\t\t\t isLast }. -->\n\t\t\t\t<slot\n\t\t\t\t\t:name=\"'step-' + currentStep.id\"\n\t\t\t\t\t:next=\"next\"\n\t\t\t\t\t:back=\"back\"\n\t\t\t\t\t:jumpTo=\"jumpTo\"\n\t\t\t\t\t:submit=\"submit\"\n\t\t\t\t\t:currentStep=\"currentStep\"\n\t\t\t\t\t:stepIndex=\"currentIndex\"\n\t\t\t\t\t:totalSteps=\"steps.length\"\n\t\t\t\t\t:stepData=\"stepData\"\n\t\t\t\t\t:setStepData=\"setStepData\"\n\t\t\t\t\t:isFirst=\"isFirst\"\n\t\t\t\t\t:isLast=\"isLast\" />\n\t\t\t</div>\n\t\t</div>\n\n\t\t<template #actions>\n\t\t\t<!-- Result phase actions: just Close. -->\n\t\t\t<NcButton v-if=\"result !== null\" @click=\"onClose\">\n\t\t\t\t{{ closeLabel }}\n\t\t\t</NcButton>\n\n\t\t\t<!-- Wizard phase actions: Cancel + Back + Next/Submit.\n\t\t\t The testids exist because these buttons are the only way\n\t\t\t through a wizard and their LABELS are translated: an e2e that\n\t\t\t clicks \"Next\" passes on an English instance and times out on a\n\t\t\t Dutch one, reporting a broken dialog rather than a missing\n\t\t\t string. -->\n\t\t\t<template v-else>\n\t\t\t\t<NcButton v-if=\"cancellable\" data-testid=\"cn-wizard-cancel\" @click=\"onClose\">\n\t\t\t\t\t{{ cancelLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton v-if=\"!isFirst\"\n\t\t\t\t\tdata-testid=\"cn-wizard-back\"\n\t\t\t\t\t:disabled=\"loading\"\n\t\t\t\t\t@click=\"back\">\n\t\t\t\t\t<template v-if=\"isBoardLook\" #icon>\n\t\t\t\t\t\t<ChevronLeft :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ backLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton variant=\"primary\"\n\t\t\t\t\tdata-testid=\"cn-wizard-next\"\n\t\t\t\t\t:alignment=\"isBoardLook && !isLast ? 'center-reverse' : 'center'\"\n\t\t\t\t\t:disabled=\"loading || nextDisabled\"\n\t\t\t\t\t@click=\"isLast ? submit() : next()\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<NcLoadingIcon v-if=\"loading\" :size=\"20\" />\n\t\t\t\t\t\t<template v-else-if=\"isBoardLook\">\n\t\t\t\t\t\t\t<ChevronRight v-if=\"!isLast\" :size=\"20\" />\n\t\t\t\t\t\t\t<component :is=\"submitIcon || Check\" v-else :size=\"20\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ isLast ? submitLabel : nextLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport Check from 'vue-material-design-icons/Check.vue'\nimport ChevronLeft from 'vue-material-design-icons/ChevronLeft.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport CnDialog from '../CnDialog/CnDialog.vue'\nimport CnStepper from '../CnStepper/CnStepper.vue'\nimport { dialogBoardMixin } from '../../mixins/dialogBoard.js'\n\n/**\n * CnWizardDialog — Multi-step modal with per-step slots,\n * back/next navigation, optional per-step validation, and a single\n * result phase.\n *\n * Each step is declared in the `steps[]` prop (`{ id, label,\n * optional?, icon? }`) and rendered via a `#step-{id}` named slot\n * with the navigation API exposed through the slot scope. The\n * wizard owns the progress indicator, the back/next chrome, the\n * loading lifecycle, and the result-phase banner — the consumer\n * owns the per-step body + the data collection logic.\n *\n * Per-step validation is opt-in via the `validate` prop:\n *\n * ```js\n * async function validate(stepId, stepData) {\n * if (stepId === 'audience' && !stepData.cohort) {\n * return 'Pick a cohort first.'\n * }\n * return true\n * }\n * ```\n *\n * Returning `true` (or any truthy non-string) advances; returning a\n * string surfaces it as an error banner above the step body and\n * blocks the navigation.\n *\n * The result phase is entered by the consumer calling\n * `setResult({ success?, message?, error? })` after `@submit` fires.\n *\n * Use [`CnFormDialog`](../CnFormDialog/) for single-step forms.\n * Use [`CnExportWizard`](../CnExportWizard/) for the specific\n * scope+format+delivery export-trigger shape.\n *\n * ```vue\n * <CnWizardDialog\n * ref=\"wizard\"\n * dialog-title=\"Bulk enrol\"\n * :steps=\"[\n * { id: 'audience', label: 'Audience' },\n * { id: 'course', label: 'Course' },\n * { id: 'confirm', label: 'Confirm' },\n * ]\"\n * :validate=\"validateStep\"\n * @submit=\"onSubmit\"\n * @close=\"show = false\">\n * <template #step-audience=\"{ next, stepData, setStepData }\">\n * <CohortPicker :value=\"stepData.cohort\" @input=\"v => setStepData({ cohort: v })\" />\n * </template>\n * <template #step-course=\"{ next, back, stepData, setStepData }\">\n * <CoursePicker :value=\"stepData.course\" @input=\"v => setStepData({ course: v })\" />\n * </template>\n * <template #step-confirm=\"{ back, submit, stepData }\">\n * <p>Enrol {{ stepData.audience.cohort.size }} learners into {{ stepData.course.course.name }}?</p>\n * </template>\n * </CnWizardDialog>\n * ```\n */\nexport default {\n\tname: 'CnWizardDialog',\n\tcomponents: { CnDialog, CnStepper, ChevronLeft, ChevronRight, NcButton, NcNoteCard, NcLoadingIcon },\n\n\tmixins: [dialogBoardMixin],\n\tprops: {\n\t\t/**\n\t\t * Step declarations. Order is significant — the wizard\n\t\t * navigates linearly between adjacent steps unless the\n\t\t * consumer calls `jumpTo()` from a slot scope.\n\t\t *\n\t\t * @type {Array<{ id: string, label: string, optional?: boolean, icon?: string }>}\n\t\t */\n\t\tsteps: {\n\t\t\ttype: Array,\n\t\t\trequired: true,\n\t\t\tvalidator: (v) => Array.isArray(v) && v.length > 0\n\t\t\t\t&& v.every((s) => s && typeof s.id === 'string' && typeof s.label === 'string'),\n\t\t},\n\n\t\t/**\n\t\t * Dialog title shown in the NcDialog header.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Wizard'),\n\t\t},\n\n\t\t/**\n\t\t * Step id to start on. Defaults to the first step in `steps[]`.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tinitialStep: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Per-step validator. Async function returning `true` to\n\t\t * advance, a string to surface as an error banner + block\n\t\t * navigation, or `false` to block silently. Called from\n\t\t * `next()` and `submit()`. When omitted, navigation always\n\t\t * proceeds.\n\t\t *\n\t\t * @type {(stepId: string, stepData: object) => Promise<boolean|string>}\n\t\t */\n\t\tvalidate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Whether the progress indicator allows jumping back to a\n\t\t * completed step via click. Forward jumps are NEVER allowed\n\t\t * via the progress indicator (consumer-side `jumpTo` is\n\t\t * unrestricted).\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tallowJumpBack: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Seed values for `stepData` (the cross-step object passed\n\t\t * to every slot scope). Useful for prefilling on edit-style\n\t\t * wizards.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tdefaults: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * The context in the board look's eyebrow (\"<context>, step N of M\").\n\t\t * Empty uses the dialog title.\n\t\t */\n\t\teyebrowContext: { type: String, default: '' },\n\t\t/**\n\t\t * The eyebrow sentence, with `{context}`, `{step}` and `{total}`\n\t\t * placeholders, so it can be translated.\n\t\t */\n\t\tstepEyebrow: { type: String, default: () => t('nextcloud-vue', '{context}, step {step} of {total}') },\n\t\t/**\n\t\t * Icon component on the finishing button of the last step (board look).\n\t\t * Empty draws a check.\n\t\t *\n\t\t * @type {object|Function|null}\n\t\t */\n\t\tsubmitIcon: { type: [Object, Function], default: null },\n\n\t\t/** Cancel-button label (wizard phase). */\n\t\tcancelLabel: { type: String, default: () => t('nextcloud-vue', 'Cancel') },\n\t\t/** Back-button label. */\n\t\tbackLabel: { type: String, default: () => t('nextcloud-vue', 'Back') },\n\t\t/** Next-button label (intermediate steps). */\n\t\tnextLabel: { type: String, default: () => t('nextcloud-vue', 'Next') },\n\t\t/** Submit-button label (last step). */\n\t\tsubmitLabel: { type: String, default: () => t('nextcloud-vue', 'Submit') },\n\t\t/** Close-button label (result phase). */\n\t\tcloseLabel: { type: String, default: () => t('nextcloud-vue', 'Close') },\n\t\t/** Success banner default text when result.message is empty. */\n\t\tsuccessText: { type: String, default: () => t('nextcloud-vue', 'Done.') },\n\t\t/**\n\t\t * Whether the dialog can be dismissed (Cancel button, ESC, backdrop\n\t\t * click) before reaching the result phase. `false` hides Cancel and\n\t\t * disables all other close affordances — use for a step that must\n\t\t * be completed, not merely skipped. The result-phase Close button is\n\t\t * unaffected (a completed wizard is always dismissible).\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tcancellable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Disable the Next / Submit button, whatever the step's `validate`\n\t\t * would say. For a host that knows the wizard cannot go on yet, such as\n\t\t * `CnSetupWizard` while a required app is missing.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @spec openspec/changes/setup-wizard-card-load-and-dependency-gate/specs/cn-setup-wizard/spec.md#requirement-the-wizard-checks-dependencies-before-any-step\n\t\t */\n\t\tnextDisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: ['close', 'step-change', 'submit'],\n\tdata() {\n\t\tconst initialIndex = this.resolveInitialIndex()\n\t\treturn {\n\t\t\tcurrentIndex: initialIndex,\n\t\t\tstepData: { ...this.defaults },\n\t\t\tloading: false,\n\t\t\tresult: null,\n\t\t\tvalidationError: '',\n\t\t\t/**\n\t\t\t * Drives NcDialog's `open` prop directly. NcDialog's own `open`\n\t\t\t * prop defaults to `true` and is NOT self-managing on close — its\n\t\t\t * internal `showModal` flag resets back to `true` ~300ms after\n\t\t\t * any close (animation bookkeeping for next time it's reopened\n\t\t\t * via the prop), so without an explicit `false` here the dialog\n\t\t\t * reopens itself right after Cancel/ESC/backdrop-click.\n\t\t\t */\n\t\t\tdialogOpen: true,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The board look's eyebrow, \"<context>, step N of M\", updated on every step\n\t\t * change. Empty in the Nextcloud look and in the result phase.\n\t\t *\n\t\t * @return {string} The eyebrow.\n\t\t */\n\t\tboardEyebrow() {\n\t\t\tif (!this.isBoardLook || this.result !== null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn this.stepEyebrow\n\t\t\t\t.replace('{context}', this.eyebrowContext || this.eyebrow || this.dialogTitle)\n\t\t\t\t.replace('{step}', String(this.currentIndex + 1))\n\t\t\t\t.replace('{total}', String(this.steps.length))\n\t\t},\n\n\t\t/** @return {object} The check icon, the default finishing icon. */\n\t\tCheck() {\n\t\t\treturn Check\n\t\t},\n\n\t\t/**\n\t\t * The currently-active step object from `steps[]`.\n\t\t *\n\t\t * @return {object} The current step definition.\n\t\t */\n\t\tcurrentStep() {\n\t\t\treturn this.steps[this.currentIndex] || this.steps[0]\n\t\t},\n\n\t\t/**\n\t\t * Whether the current step is the first one.\n\t\t *\n\t\t * @return {boolean} True when on the first step.\n\t\t */\n\t\tisFirst() {\n\t\t\treturn this.currentIndex === 0\n\t\t},\n\n\t\t/**\n\t\t * Whether the current step is the last one (drives the\n\t\t * Next → Submit label flip).\n\t\t *\n\t\t * @return {boolean} True when on the last step.\n\t\t */\n\t\tisLast() {\n\t\t\treturn this.currentIndex === this.steps.length - 1\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Resolve the index of `initialStep` (falling back to 0 when\n\t\t * unset / not found).\n\t\t *\n\t\t * @return {number} Step index in the range [0, steps.length).\n\t\t */\n\t\tresolveInitialIndex() {\n\t\t\tif (!this.initialStep) {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tconst idx = this.steps.findIndex((s) => s.id === this.initialStep)\n\t\t\treturn idx >= 0 ? idx : 0\n\t\t},\n\n\t\t/**\n\t\t * Merge a partial step-data object onto the shared state.\n\t\t * Each slot scope receives this so consumers can write their\n\t\t * step's data without owning a `data()` block in their slot\n\t\t * component.\n\t\t *\n\t\t * @param {object} partial Fields to merge.\n\t\t * @return {void}\n\t\t */\n\t\tsetStepData(partial) {\n\t\t\tthis.stepData = { ...this.stepData, ...partial }\n\t\t},\n\n\t\t/**\n\t\t * Run the consumer's `validate` prop (if provided) for the\n\t\t * current step. Returns true on pass; sets `validationError`\n\t\t * and returns false on fail.\n\t\t *\n\t\t * @return {Promise<boolean>} Whether validation passed.\n\t\t */\n\t\tasync runValidation() {\n\t\t\tthis.validationError = ''\n\t\t\tif (typeof this.validate !== 'function') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst outcome = await this.validate(this.currentStep.id, this.stepData)\n\t\t\t\tif (outcome === true) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tif (typeof outcome === 'string') {\n\t\t\t\t\tthis.validationError = outcome\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\treturn Boolean(outcome)\n\t\t\t} catch (e) {\n\t\t\t\tthis.validationError = e && e.message ? e.message : 'Validation failed.'\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Advance to the next step after validation. Emits\n\t\t * `@step-change` with the new step id.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync next() {\n\t\t\tif (this.nextDisabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.isLast) {\n\t\t\t\treturn this.submit()\n\t\t\t}\n\t\t\tconst ok = await this.runValidation()\n\t\t\tif (!ok) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.currentIndex += 1\n\t\t\t/**\n\t\t\t * @event step-change Emitted on every step navigation\n\t\t\t * (next / back / jumpTo / submit).\n\t\t\t * @type {{ stepId: string, stepIndex: number, direction: 'next'|'back'|'jump' }}\n\t\t\t */\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'next',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Step back to the previous step. No validation runs on\n\t\t * back navigation — consumers can reach back without\n\t\t * losing the current step's draft.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tback() {\n\t\t\tif (this.isFirst) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex -= 1\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'back',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Jump to an arbitrary step by id. Validation is skipped\n\t\t * (the consumer is responsible for re-running it before\n\t\t * `submit()` if it matters).\n\t\t *\n\t\t * @param {string} stepId Target step id.\n\t\t * @return {void}\n\t\t */\n\t\tjumpTo(stepId) {\n\t\t\tconst idx = this.steps.findIndex((s) => s.id === stepId)\n\t\t\tif (idx < 0) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex = idx\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'jump',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Submit the wizard. Runs the current step's validation;\n\t\t * on pass flips `loading` on and emits `@submit` with the\n\t\t * accumulated `stepData`. The parent is responsible for\n\t\t * calling `setResult()` to flip into the result phase.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync submit() {\n\t\t\tif (this.nextDisabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst ok = await this.runValidation()\n\t\t\tif (!ok) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\t/**\n\t\t\t * @event submit Emitted when the user reaches the final\n\t\t\t * step and clicks Submit (or `submit()` is called\n\t\t\t * programmatically from a slot scope). Payload is the\n\t\t\t * accumulated `stepData`.\n\t\t\t * @type {object}\n\t\t\t */\n\t\t\tthis.$emit('submit', { ...this.stepData })\n\t\t},\n\n\t\t/**\n\t\t * Public method called by the parent to switch the wizard\n\t\t * into the result phase.\n\t\t *\n\t\t * @param {object} result `{ success?, message?, error? }`.\n\t\t * @return {void}\n\t\t */\n\t\tsetResult(result) {\n\t\t\tthis.result = result || { success: true }\n\t\t\tthis.loading = false\n\t\t},\n\n\t\t/**\n\t\t * Public method for a NON-terminal submit failure: stops the\n\t\t * loading spinner and surfaces `message` as the error banner above\n\t\t * the (still-editable) current step, WITHOUT entering the result\n\t\t * phase — so the user can correct the input and resubmit. Use this\n\t\t * instead of `setResult({ error })` when the failure is recoverable\n\t\t * (e.g. a taken slug, a validation conflict).\n\t\t *\n\t\t * @param {string} message The error to show above the step body.\n\t\t * @return {void}\n\t\t */\n\t\tsetError(message) {\n\t\t\tthis.loading = false\n\t\t\tthis.validationError = message || ''\n\t\t},\n\n\t\t/**\n\t\t * Close-button handler. Resets local state so the next open\n\t\t * starts fresh and emits `@close`.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonClose() {\n\t\t\tthis.result = null\n\t\t\tthis.loading = false\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex = this.resolveInitialIndex()\n\t\t\tthis.stepData = { ...this.defaults }\n\t\t\tthis.dialogOpen = false\n\t\t\t/**\n\t\t\t * @event close Emitted when the dialog should close.\n\t\t\t */\n\t\t\tthis.$emit('close')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-wizard-dialog__step-body {\n\tmin-height: 200px;\n}\n\n.cn-wizard-dialog__result {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n</style>\n"],"names":["CnDialog","CnStepper","t"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CnWizardDialog.vue3.js","sources":["../../../../src/components/CnWizardDialog/CnWizardDialog.vue?vue&type=template&id=4a9bf6d1&lang.js"],"sourcesContent":["<template>\n\t<CnDialog\n\t\t:look=\"look\"\n\t\t:width=\"width\"\n\t\tdefaultWidth=\"wizard\"\n\t\t:eyebrow=\"boardEyebrow\"\n\t\t:subtitle=\"subtitle\"\n\t\t:name=\"dialogTitle\"\n\t\tsize=\"large\"\n\t\t:open=\"dialogOpen\"\n\t\t:noClose=\"loading || !cancellable\"\n\t\tdata-testid=\"cn-modal\"\n\t\tdata-testid-modal=\"cn-wizard-dialog\"\n\t\t@update:open=\"dialogOpen = $event\"\n\t\t@closing=\"onClose\">\n\t\t<!-- Result phase: rendered after a successful `submit()`. -->\n\t\t<div v-if=\"result !== null\"\n\t\t\tclass=\"cn-wizard-dialog__result\"\n\t\t\tdata-testid-phase=\"result\">\n\t\t\t<NcNoteCard v-if=\"result.success\" type=\"success\">\n\t\t\t\t{{ result.message || successText }}\n\t\t\t</NcNoteCard>\n\t\t\t<NcNoteCard v-else-if=\"result.error\" type=\"error\">\n\t\t\t\t{{ result.error }}\n\t\t\t</NcNoteCard>\n\t\t\t<!-- @slot result-extra Optional extra content (e.g. batch\n\t\t\t progress poller, summary table) rendered below the\n\t\t\t success/error banner. Scope: { result }. -->\n\t\t\t<slot name=\"result-extra\" :result=\"result\" />\n\t\t</div>\n\n\t\t<!-- Wizard phase: progress bar + current step body. -->\n\t\t<div v-else\n\t\t\tclass=\"cn-wizard-dialog__wizard\"\n\t\t\tdata-testid-phase=\"form\">\n\t\t\t<!-- Progress indicator: an ordered list with the current step marked.\n\t\t\t A finished step is a button when allowJumpBack is true. -->\n\t\t\t<CnStepper\n\t\t\t\t:steps=\"steps\"\n\t\t\t\t:currentIndex=\"currentIndex\"\n\t\t\t\t:allowJumpBack=\"allowJumpBack\"\n\t\t\t\t:look=\"look\"\n\t\t\t\t@jump=\"jumpTo\" />\n\n\t\t\t<!-- Validation error from the current step's validate() result. -->\n\t\t\t<NcNoteCard v-if=\"validationError\" type=\"error\">\n\t\t\t\t{{ validationError }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<!-- Current step body — a dynamic slot named by step id. -->\n\t\t\t<div class=\"cn-wizard-dialog__step-body\" :data-step-id=\"currentStep.id\">\n\t\t\t\t<!-- @slot step-{id} Per-step body. Scope: { next,\n\t\t\t\t back, jumpTo, submit, currentStep, stepIndex,\n\t\t\t\t totalSteps, stepData, setStepData, isFirst,\n\t\t\t\t isLast }. -->\n\t\t\t\t<slot\n\t\t\t\t\t:name=\"'step-' + currentStep.id\"\n\t\t\t\t\t:next=\"next\"\n\t\t\t\t\t:back=\"back\"\n\t\t\t\t\t:jumpTo=\"jumpTo\"\n\t\t\t\t\t:submit=\"submit\"\n\t\t\t\t\t:currentStep=\"currentStep\"\n\t\t\t\t\t:stepIndex=\"currentIndex\"\n\t\t\t\t\t:totalSteps=\"steps.length\"\n\t\t\t\t\t:stepData=\"stepData\"\n\t\t\t\t\t:setStepData=\"setStepData\"\n\t\t\t\t\t:isFirst=\"isFirst\"\n\t\t\t\t\t:isLast=\"isLast\" />\n\t\t\t</div>\n\t\t</div>\n\n\t\t<template #actions>\n\t\t\t<!-- Result phase actions: just Close. -->\n\t\t\t<NcButton v-if=\"result !== null\" @click=\"onClose\">\n\t\t\t\t{{ closeLabel }}\n\t\t\t</NcButton>\n\n\t\t\t<!-- Wizard phase actions: Cancel + Back + Next/Submit.\n\t\t\t The testids exist because these buttons are the only way\n\t\t\t through a wizard and their LABELS are translated: an e2e that\n\t\t\t clicks \"Next\" passes on an English instance and times out on a\n\t\t\t Dutch one, reporting a broken dialog rather than a missing\n\t\t\t string. -->\n\t\t\t<template v-else>\n\t\t\t\t<NcButton v-if=\"cancellable\" data-testid=\"cn-wizard-cancel\" @click=\"onClose\">\n\t\t\t\t\t{{ cancelLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton v-if=\"!isFirst\"\n\t\t\t\t\tdata-testid=\"cn-wizard-back\"\n\t\t\t\t\t:disabled=\"loading\"\n\t\t\t\t\t@click=\"back\">\n\t\t\t\t\t<template v-if=\"isBoardLook\" #icon>\n\t\t\t\t\t\t<ChevronLeft :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ backLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton variant=\"primary\"\n\t\t\t\t\tdata-testid=\"cn-wizard-next\"\n\t\t\t\t\t:alignment=\"isBoardLook && !isLast ? 'center-reverse' : 'center'\"\n\t\t\t\t\t:disabled=\"loading || nextDisabled\"\n\t\t\t\t\t@click=\"isLast ? submit() : next()\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<NcLoadingIcon v-if=\"loading\" :size=\"20\" />\n\t\t\t\t\t\t<template v-else-if=\"isBoardLook\">\n\t\t\t\t\t\t\t<ChevronRight v-if=\"!isLast\" :size=\"20\" />\n\t\t\t\t\t\t\t<component :is=\"submitIcon || Check\" v-else :size=\"20\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ isLast ? submitLabel : nextLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport Check from 'vue-material-design-icons/Check.vue'\nimport ChevronLeft from 'vue-material-design-icons/ChevronLeft.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport CnDialog from '../CnDialog/CnDialog.vue'\nimport CnStepper from '../CnStepper/CnStepper.vue'\nimport { dialogBoardMixin } from '../../mixins/dialogBoard.js'\n\n/**\n * CnWizardDialog — Multi-step modal with per-step slots,\n * back/next navigation, optional per-step validation, and a single\n * result phase.\n *\n * Each step is declared in the `steps[]` prop (`{ id, label,\n * optional?, icon? }`) and rendered via a `#step-{id}` named slot\n * with the navigation API exposed through the slot scope. The\n * wizard owns the progress indicator, the back/next chrome, the\n * loading lifecycle, and the result-phase banner — the consumer\n * owns the per-step body + the data collection logic.\n *\n * Per-step validation is opt-in via the `validate` prop:\n *\n * ```js\n * async function validate(stepId, stepData) {\n * if (stepId === 'audience' && !stepData.cohort) {\n * return 'Pick a cohort first.'\n * }\n * return true\n * }\n * ```\n *\n * Returning `true` (or any truthy non-string) advances; returning a\n * string surfaces it as an error banner above the step body and\n * blocks the navigation.\n *\n * The result phase is entered by the consumer calling\n * `setResult({ success?, message?, error? })` after `@submit` fires.\n *\n * Use [`CnFormDialog`](../CnFormDialog/) for single-step forms.\n * Use [`CnExportWizard`](../CnExportWizard/) for the specific\n * scope+format+delivery export-trigger shape.\n *\n * ```vue\n * <CnWizardDialog\n * ref=\"wizard\"\n * dialog-title=\"Bulk enrol\"\n * :steps=\"[\n * { id: 'audience', label: 'Audience' },\n * { id: 'course', label: 'Course' },\n * { id: 'confirm', label: 'Confirm' },\n * ]\"\n * :validate=\"validateStep\"\n * @submit=\"onSubmit\"\n * @close=\"show = false\">\n * <template #step-audience=\"{ next, stepData, setStepData }\">\n * <CohortPicker :value=\"stepData.cohort\" @input=\"v => setStepData({ cohort: v })\" />\n * </template>\n * <template #step-course=\"{ next, back, stepData, setStepData }\">\n * <CoursePicker :value=\"stepData.course\" @input=\"v => setStepData({ course: v })\" />\n * </template>\n * <template #step-confirm=\"{ back, submit, stepData }\">\n * <p>Enrol {{ stepData.audience.cohort.size }} learners into {{ stepData.course.course.name }}?</p>\n * </template>\n * </CnWizardDialog>\n * ```\n */\nexport default {\n\tname: 'CnWizardDialog',\n\tcomponents: { CnDialog, CnStepper, ChevronLeft, ChevronRight, NcButton, NcNoteCard, NcLoadingIcon },\n\n\tmixins: [dialogBoardMixin],\n\tprops: {\n\t\t/**\n\t\t * Step declarations. Order is significant — the wizard\n\t\t * navigates linearly between adjacent steps unless the\n\t\t * consumer calls `jumpTo()` from a slot scope.\n\t\t *\n\t\t * @type {Array<{ id: string, label: string, optional?: boolean, icon?: string }>}\n\t\t */\n\t\tsteps: {\n\t\t\ttype: Array,\n\t\t\trequired: true,\n\t\t\tvalidator: (v) => Array.isArray(v) && v.length > 0\n\t\t\t\t&& v.every((s) => s && typeof s.id === 'string' && typeof s.label === 'string'),\n\t\t},\n\n\t\t/**\n\t\t * Dialog title shown in the NcDialog header.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: 'Wizard',\n\t\t},\n\n\t\t/**\n\t\t * Step id to start on. Defaults to the first step in `steps[]`.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tinitialStep: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Per-step validator. Async function returning `true` to\n\t\t * advance, a string to surface as an error banner + block\n\t\t * navigation, or `false` to block silently. Called from\n\t\t * `next()` and `submit()`. When omitted, navigation always\n\t\t * proceeds.\n\t\t *\n\t\t * @type {(stepId: string, stepData: object) => Promise<boolean|string>}\n\t\t */\n\t\tvalidate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Whether the progress indicator allows jumping back to a\n\t\t * completed step via click. Forward jumps are NEVER allowed\n\t\t * via the progress indicator (consumer-side `jumpTo` is\n\t\t * unrestricted).\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tallowJumpBack: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Seed values for `stepData` (the cross-step object passed\n\t\t * to every slot scope). Useful for prefilling on edit-style\n\t\t * wizards.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tdefaults: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * The context in the board look's eyebrow (\"<context>, step N of M\").\n\t\t * Empty uses the dialog title.\n\t\t */\n\t\teyebrowContext: { type: String, default: '' },\n\t\t/**\n\t\t * The eyebrow sentence, with `{context}`, `{step}` and `{total}`\n\t\t * placeholders, so it can be translated.\n\t\t */\n\t\tstepEyebrow: { type: String, default: () => t('nextcloud-vue', '{context}, step {step} of {total}') },\n\t\t/**\n\t\t * Icon component on the finishing button of the last step (board look).\n\t\t * Empty draws a check.\n\t\t *\n\t\t * @type {object|Function|null}\n\t\t */\n\t\tsubmitIcon: { type: [Object, Function], default: null },\n\n\t\t/** Cancel-button label (wizard phase). */\n\t\tcancelLabel: { type: String, default: 'Cancel' },\n\t\t/** Back-button label. */\n\t\tbackLabel: { type: String, default: 'Back' },\n\t\t/** Next-button label (intermediate steps). */\n\t\tnextLabel: { type: String, default: 'Next' },\n\t\t/** Submit-button label (last step). */\n\t\tsubmitLabel: { type: String, default: 'Submit' },\n\t\t/** Close-button label (result phase). */\n\t\tcloseLabel: { type: String, default: 'Close' },\n\t\t/** Success banner default text when result.message is empty. */\n\t\tsuccessText: { type: String, default: 'Done.' },\n\t\t/**\n\t\t * Whether the dialog can be dismissed (Cancel button, ESC, backdrop\n\t\t * click) before reaching the result phase. `false` hides Cancel and\n\t\t * disables all other close affordances — use for a step that must\n\t\t * be completed, not merely skipped. The result-phase Close button is\n\t\t * unaffected (a completed wizard is always dismissible).\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tcancellable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Disable the Next / Submit button, whatever the step's `validate`\n\t\t * would say. For a host that knows the wizard cannot go on yet, such as\n\t\t * `CnSetupWizard` while a required app is missing.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @spec openspec/changes/setup-wizard-card-load-and-dependency-gate/specs/cn-setup-wizard/spec.md#requirement-the-wizard-checks-dependencies-before-any-step\n\t\t */\n\t\tnextDisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: ['close', 'step-change', 'submit'],\n\tdata() {\n\t\tconst initialIndex = this.resolveInitialIndex()\n\t\treturn {\n\t\t\tcurrentIndex: initialIndex,\n\t\t\tstepData: { ...this.defaults },\n\t\t\tloading: false,\n\t\t\tresult: null,\n\t\t\tvalidationError: '',\n\t\t\t/**\n\t\t\t * Drives NcDialog's `open` prop directly. NcDialog's own `open`\n\t\t\t * prop defaults to `true` and is NOT self-managing on close — its\n\t\t\t * internal `showModal` flag resets back to `true` ~300ms after\n\t\t\t * any close (animation bookkeeping for next time it's reopened\n\t\t\t * via the prop), so without an explicit `false` here the dialog\n\t\t\t * reopens itself right after Cancel/ESC/backdrop-click.\n\t\t\t */\n\t\t\tdialogOpen: true,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The board look's eyebrow, \"<context>, step N of M\", updated on every step\n\t\t * change. Empty in the Nextcloud look and in the result phase.\n\t\t *\n\t\t * @return {string} The eyebrow.\n\t\t */\n\t\tboardEyebrow() {\n\t\t\tif (!this.isBoardLook || this.result !== null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn this.stepEyebrow\n\t\t\t\t.replace('{context}', this.eyebrowContext || this.eyebrow || this.dialogTitle)\n\t\t\t\t.replace('{step}', String(this.currentIndex + 1))\n\t\t\t\t.replace('{total}', String(this.steps.length))\n\t\t},\n\n\t\t/** @return {object} The check icon, the default finishing icon. */\n\t\tCheck() {\n\t\t\treturn Check\n\t\t},\n\n\t\t/**\n\t\t * The currently-active step object from `steps[]`.\n\t\t *\n\t\t * @return {object} The current step definition.\n\t\t */\n\t\tcurrentStep() {\n\t\t\treturn this.steps[this.currentIndex] || this.steps[0]\n\t\t},\n\n\t\t/**\n\t\t * Whether the current step is the first one.\n\t\t *\n\t\t * @return {boolean} True when on the first step.\n\t\t */\n\t\tisFirst() {\n\t\t\treturn this.currentIndex === 0\n\t\t},\n\n\t\t/**\n\t\t * Whether the current step is the last one (drives the\n\t\t * Next → Submit label flip).\n\t\t *\n\t\t * @return {boolean} True when on the last step.\n\t\t */\n\t\tisLast() {\n\t\t\treturn this.currentIndex === this.steps.length - 1\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Resolve the index of `initialStep` (falling back to 0 when\n\t\t * unset / not found).\n\t\t *\n\t\t * @return {number} Step index in the range [0, steps.length).\n\t\t */\n\t\tresolveInitialIndex() {\n\t\t\tif (!this.initialStep) {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tconst idx = this.steps.findIndex((s) => s.id === this.initialStep)\n\t\t\treturn idx >= 0 ? idx : 0\n\t\t},\n\n\t\t/**\n\t\t * Merge a partial step-data object onto the shared state.\n\t\t * Each slot scope receives this so consumers can write their\n\t\t * step's data without owning a `data()` block in their slot\n\t\t * component.\n\t\t *\n\t\t * @param {object} partial Fields to merge.\n\t\t * @return {void}\n\t\t */\n\t\tsetStepData(partial) {\n\t\t\tthis.stepData = { ...this.stepData, ...partial }\n\t\t},\n\n\t\t/**\n\t\t * Run the consumer's `validate` prop (if provided) for the\n\t\t * current step. Returns true on pass; sets `validationError`\n\t\t * and returns false on fail.\n\t\t *\n\t\t * @return {Promise<boolean>} Whether validation passed.\n\t\t */\n\t\tasync runValidation() {\n\t\t\tthis.validationError = ''\n\t\t\tif (typeof this.validate !== 'function') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst outcome = await this.validate(this.currentStep.id, this.stepData)\n\t\t\t\tif (outcome === true) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tif (typeof outcome === 'string') {\n\t\t\t\t\tthis.validationError = outcome\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\treturn Boolean(outcome)\n\t\t\t} catch (e) {\n\t\t\t\tthis.validationError = e && e.message ? e.message : 'Validation failed.'\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Advance to the next step after validation. Emits\n\t\t * `@step-change` with the new step id.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync next() {\n\t\t\tif (this.nextDisabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.isLast) {\n\t\t\t\treturn this.submit()\n\t\t\t}\n\t\t\tconst ok = await this.runValidation()\n\t\t\tif (!ok) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.currentIndex += 1\n\t\t\t/**\n\t\t\t * @event step-change Emitted on every step navigation\n\t\t\t * (next / back / jumpTo / submit).\n\t\t\t * @type {{ stepId: string, stepIndex: number, direction: 'next'|'back'|'jump' }}\n\t\t\t */\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'next',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Step back to the previous step. No validation runs on\n\t\t * back navigation — consumers can reach back without\n\t\t * losing the current step's draft.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tback() {\n\t\t\tif (this.isFirst) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex -= 1\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'back',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Jump to an arbitrary step by id. Validation is skipped\n\t\t * (the consumer is responsible for re-running it before\n\t\t * `submit()` if it matters).\n\t\t *\n\t\t * @param {string} stepId Target step id.\n\t\t * @return {void}\n\t\t */\n\t\tjumpTo(stepId) {\n\t\t\tconst idx = this.steps.findIndex((s) => s.id === stepId)\n\t\t\tif (idx < 0) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex = idx\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'jump',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Submit the wizard. Runs the current step's validation;\n\t\t * on pass flips `loading` on and emits `@submit` with the\n\t\t * accumulated `stepData`. The parent is responsible for\n\t\t * calling `setResult()` to flip into the result phase.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync submit() {\n\t\t\tif (this.nextDisabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst ok = await this.runValidation()\n\t\t\tif (!ok) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\t/**\n\t\t\t * @event submit Emitted when the user reaches the final\n\t\t\t * step and clicks Submit (or `submit()` is called\n\t\t\t * programmatically from a slot scope). Payload is the\n\t\t\t * accumulated `stepData`.\n\t\t\t * @type {object}\n\t\t\t */\n\t\t\tthis.$emit('submit', { ...this.stepData })\n\t\t},\n\n\t\t/**\n\t\t * Public method called by the parent to switch the wizard\n\t\t * into the result phase.\n\t\t *\n\t\t * @param {object} result `{ success?, message?, error? }`.\n\t\t * @return {void}\n\t\t */\n\t\tsetResult(result) {\n\t\t\tthis.result = result || { success: true }\n\t\t\tthis.loading = false\n\t\t},\n\n\t\t/**\n\t\t * Public method for a NON-terminal submit failure: stops the\n\t\t * loading spinner and surfaces `message` as the error banner above\n\t\t * the (still-editable) current step, WITHOUT entering the result\n\t\t * phase — so the user can correct the input and resubmit. Use this\n\t\t * instead of `setResult({ error })` when the failure is recoverable\n\t\t * (e.g. a taken slug, a validation conflict).\n\t\t *\n\t\t * @param {string} message The error to show above the step body.\n\t\t * @return {void}\n\t\t */\n\t\tsetError(message) {\n\t\t\tthis.loading = false\n\t\t\tthis.validationError = message || ''\n\t\t},\n\n\t\t/**\n\t\t * Close-button handler. Resets local state so the next open\n\t\t * starts fresh and emits `@close`.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonClose() {\n\t\t\tthis.result = null\n\t\t\tthis.loading = false\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex = this.resolveInitialIndex()\n\t\t\tthis.stepData = { ...this.defaults }\n\t\t\tthis.dialogOpen = false\n\t\t\t/**\n\t\t\t * @event close Emitted when the dialog should close.\n\t\t\t */\n\t\t\tthis.$emit('close')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-wizard-dialog__step-body {\n\tmin-height: 200px;\n}\n\n.cn-wizard-dialog__result {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n</style>\n"],"names":["_createBlock","_createElementBlock","_Fragment","_createTextVNode","_createVNode","_resolveDynamicComponent","_toDisplayString","_openBlock","_renderSlot","_createElementVNode"],"mappings":"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"}
1
+ {"version":3,"file":"CnWizardDialog.vue3.js","sources":["../../../../src/components/CnWizardDialog/CnWizardDialog.vue?vue&type=template&id=547e7819&lang.js"],"sourcesContent":["<template>\n\t<CnDialog\n\t\t:look=\"look\"\n\t\t:width=\"width\"\n\t\tdefaultWidth=\"wizard\"\n\t\t:eyebrow=\"boardEyebrow\"\n\t\t:subtitle=\"subtitle\"\n\t\t:name=\"dialogTitle\"\n\t\tsize=\"large\"\n\t\t:open=\"dialogOpen\"\n\t\t:noClose=\"loading || !cancellable\"\n\t\tdata-testid=\"cn-modal\"\n\t\tdata-testid-modal=\"cn-wizard-dialog\"\n\t\t@update:open=\"dialogOpen = $event\"\n\t\t@closing=\"onClose\">\n\t\t<!-- Result phase: rendered after a successful `submit()`. -->\n\t\t<div v-if=\"result !== null\"\n\t\t\tclass=\"cn-wizard-dialog__result\"\n\t\t\tdata-testid-phase=\"result\">\n\t\t\t<NcNoteCard v-if=\"result.success\" type=\"success\">\n\t\t\t\t{{ result.message || successText }}\n\t\t\t</NcNoteCard>\n\t\t\t<NcNoteCard v-else-if=\"result.error\" type=\"error\">\n\t\t\t\t{{ result.error }}\n\t\t\t</NcNoteCard>\n\t\t\t<!-- @slot result-extra Optional extra content (e.g. batch\n\t\t\t progress poller, summary table) rendered below the\n\t\t\t success/error banner. Scope: { result }. -->\n\t\t\t<slot name=\"result-extra\" :result=\"result\" />\n\t\t</div>\n\n\t\t<!-- Wizard phase: progress bar + current step body. -->\n\t\t<div v-else\n\t\t\tclass=\"cn-wizard-dialog__wizard\"\n\t\t\tdata-testid-phase=\"form\">\n\t\t\t<!-- Progress indicator: an ordered list with the current step marked.\n\t\t\t A finished step is a button when allowJumpBack is true. -->\n\t\t\t<CnStepper\n\t\t\t\t:steps=\"steps\"\n\t\t\t\t:currentIndex=\"currentIndex\"\n\t\t\t\t:allowJumpBack=\"allowJumpBack\"\n\t\t\t\t:look=\"look\"\n\t\t\t\t@jump=\"jumpTo\" />\n\n\t\t\t<!-- Validation error from the current step's validate() result. -->\n\t\t\t<NcNoteCard v-if=\"validationError\" type=\"error\">\n\t\t\t\t{{ validationError }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<!-- Current step body — a dynamic slot named by step id. -->\n\t\t\t<div class=\"cn-wizard-dialog__step-body\" :data-step-id=\"currentStep.id\">\n\t\t\t\t<!-- @slot step-{id} Per-step body. Scope: { next,\n\t\t\t\t back, jumpTo, submit, currentStep, stepIndex,\n\t\t\t\t totalSteps, stepData, setStepData, isFirst,\n\t\t\t\t isLast }. -->\n\t\t\t\t<slot\n\t\t\t\t\t:name=\"'step-' + currentStep.id\"\n\t\t\t\t\t:next=\"next\"\n\t\t\t\t\t:back=\"back\"\n\t\t\t\t\t:jumpTo=\"jumpTo\"\n\t\t\t\t\t:submit=\"submit\"\n\t\t\t\t\t:currentStep=\"currentStep\"\n\t\t\t\t\t:stepIndex=\"currentIndex\"\n\t\t\t\t\t:totalSteps=\"steps.length\"\n\t\t\t\t\t:stepData=\"stepData\"\n\t\t\t\t\t:setStepData=\"setStepData\"\n\t\t\t\t\t:isFirst=\"isFirst\"\n\t\t\t\t\t:isLast=\"isLast\" />\n\t\t\t</div>\n\t\t</div>\n\n\t\t<template #actions>\n\t\t\t<!-- Result phase actions: just Close. -->\n\t\t\t<NcButton v-if=\"result !== null\" @click=\"onClose\">\n\t\t\t\t{{ closeLabel }}\n\t\t\t</NcButton>\n\n\t\t\t<!-- Wizard phase actions: Cancel + Back + Next/Submit.\n\t\t\t The testids exist because these buttons are the only way\n\t\t\t through a wizard and their LABELS are translated: an e2e that\n\t\t\t clicks \"Next\" passes on an English instance and times out on a\n\t\t\t Dutch one, reporting a broken dialog rather than a missing\n\t\t\t string. -->\n\t\t\t<template v-else>\n\t\t\t\t<NcButton v-if=\"cancellable\" data-testid=\"cn-wizard-cancel\" @click=\"onClose\">\n\t\t\t\t\t{{ cancelLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton v-if=\"!isFirst\"\n\t\t\t\t\tdata-testid=\"cn-wizard-back\"\n\t\t\t\t\t:disabled=\"loading\"\n\t\t\t\t\t@click=\"back\">\n\t\t\t\t\t<template v-if=\"isBoardLook\" #icon>\n\t\t\t\t\t\t<ChevronLeft :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ backLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton variant=\"primary\"\n\t\t\t\t\tdata-testid=\"cn-wizard-next\"\n\t\t\t\t\t:alignment=\"isBoardLook && !isLast ? 'center-reverse' : 'center'\"\n\t\t\t\t\t:disabled=\"loading || nextDisabled\"\n\t\t\t\t\t@click=\"isLast ? submit() : next()\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<NcLoadingIcon v-if=\"loading\" :size=\"20\" />\n\t\t\t\t\t\t<template v-else-if=\"isBoardLook\">\n\t\t\t\t\t\t\t<ChevronRight v-if=\"!isLast\" :size=\"20\" />\n\t\t\t\t\t\t\t<component :is=\"submitIcon || Check\" v-else :size=\"20\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ isLast ? submitLabel : nextLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport Check from 'vue-material-design-icons/Check.vue'\nimport ChevronLeft from 'vue-material-design-icons/ChevronLeft.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport CnDialog from '../CnDialog/CnDialog.vue'\nimport CnStepper from '../CnStepper/CnStepper.vue'\nimport { dialogBoardMixin } from '../../mixins/dialogBoard.js'\n\n/**\n * CnWizardDialog — Multi-step modal with per-step slots,\n * back/next navigation, optional per-step validation, and a single\n * result phase.\n *\n * Each step is declared in the `steps[]` prop (`{ id, label,\n * optional?, icon? }`) and rendered via a `#step-{id}` named slot\n * with the navigation API exposed through the slot scope. The\n * wizard owns the progress indicator, the back/next chrome, the\n * loading lifecycle, and the result-phase banner — the consumer\n * owns the per-step body + the data collection logic.\n *\n * Per-step validation is opt-in via the `validate` prop:\n *\n * ```js\n * async function validate(stepId, stepData) {\n * if (stepId === 'audience' && !stepData.cohort) {\n * return 'Pick a cohort first.'\n * }\n * return true\n * }\n * ```\n *\n * Returning `true` (or any truthy non-string) advances; returning a\n * string surfaces it as an error banner above the step body and\n * blocks the navigation.\n *\n * The result phase is entered by the consumer calling\n * `setResult({ success?, message?, error? })` after `@submit` fires.\n *\n * Use [`CnFormDialog`](../CnFormDialog/) for single-step forms.\n * Use [`CnExportWizard`](../CnExportWizard/) for the specific\n * scope+format+delivery export-trigger shape.\n *\n * ```vue\n * <CnWizardDialog\n * ref=\"wizard\"\n * dialog-title=\"Bulk enrol\"\n * :steps=\"[\n * { id: 'audience', label: 'Audience' },\n * { id: 'course', label: 'Course' },\n * { id: 'confirm', label: 'Confirm' },\n * ]\"\n * :validate=\"validateStep\"\n * @submit=\"onSubmit\"\n * @close=\"show = false\">\n * <template #step-audience=\"{ next, stepData, setStepData }\">\n * <CohortPicker :value=\"stepData.cohort\" @input=\"v => setStepData({ cohort: v })\" />\n * </template>\n * <template #step-course=\"{ next, back, stepData, setStepData }\">\n * <CoursePicker :value=\"stepData.course\" @input=\"v => setStepData({ course: v })\" />\n * </template>\n * <template #step-confirm=\"{ back, submit, stepData }\">\n * <p>Enrol {{ stepData.audience.cohort.size }} learners into {{ stepData.course.course.name }}?</p>\n * </template>\n * </CnWizardDialog>\n * ```\n */\nexport default {\n\tname: 'CnWizardDialog',\n\tcomponents: { CnDialog, CnStepper, ChevronLeft, ChevronRight, NcButton, NcNoteCard, NcLoadingIcon },\n\n\tmixins: [dialogBoardMixin],\n\tprops: {\n\t\t/**\n\t\t * Step declarations. Order is significant — the wizard\n\t\t * navigates linearly between adjacent steps unless the\n\t\t * consumer calls `jumpTo()` from a slot scope.\n\t\t *\n\t\t * @type {Array<{ id: string, label: string, optional?: boolean, icon?: string }>}\n\t\t */\n\t\tsteps: {\n\t\t\ttype: Array,\n\t\t\trequired: true,\n\t\t\tvalidator: (v) => Array.isArray(v) && v.length > 0\n\t\t\t\t&& v.every((s) => s && typeof s.id === 'string' && typeof s.label === 'string'),\n\t\t},\n\n\t\t/**\n\t\t * Dialog title shown in the NcDialog header.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Wizard'),\n\t\t},\n\n\t\t/**\n\t\t * Step id to start on. Defaults to the first step in `steps[]`.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tinitialStep: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Per-step validator. Async function returning `true` to\n\t\t * advance, a string to surface as an error banner + block\n\t\t * navigation, or `false` to block silently. Called from\n\t\t * `next()` and `submit()`. When omitted, navigation always\n\t\t * proceeds.\n\t\t *\n\t\t * @type {(stepId: string, stepData: object) => Promise<boolean|string>}\n\t\t */\n\t\tvalidate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Whether the progress indicator allows jumping back to a\n\t\t * completed step via click. Forward jumps are NEVER allowed\n\t\t * via the progress indicator (consumer-side `jumpTo` is\n\t\t * unrestricted).\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tallowJumpBack: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Seed values for `stepData` (the cross-step object passed\n\t\t * to every slot scope). Useful for prefilling on edit-style\n\t\t * wizards.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tdefaults: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * The context in the board look's eyebrow (\"<context>, step N of M\").\n\t\t * Empty uses the dialog title.\n\t\t */\n\t\teyebrowContext: { type: String, default: '' },\n\t\t/**\n\t\t * The eyebrow sentence, with `{context}`, `{step}` and `{total}`\n\t\t * placeholders, so it can be translated.\n\t\t */\n\t\tstepEyebrow: { type: String, default: () => t('nextcloud-vue', '{context}, step {step} of {total}') },\n\t\t/**\n\t\t * Icon component on the finishing button of the last step (board look).\n\t\t * Empty draws a check.\n\t\t *\n\t\t * @type {object|Function|null}\n\t\t */\n\t\tsubmitIcon: { type: [Object, Function], default: null },\n\n\t\t/** Cancel-button label (wizard phase). */\n\t\tcancelLabel: { type: String, default: () => t('nextcloud-vue', 'Cancel') },\n\t\t/** Back-button label. */\n\t\tbackLabel: { type: String, default: () => t('nextcloud-vue', 'Back') },\n\t\t/** Next-button label (intermediate steps). */\n\t\tnextLabel: { type: String, default: () => t('nextcloud-vue', 'Next') },\n\t\t/** Submit-button label (last step). */\n\t\tsubmitLabel: { type: String, default: () => t('nextcloud-vue', 'Submit') },\n\t\t/** Close-button label (result phase). */\n\t\tcloseLabel: { type: String, default: () => t('nextcloud-vue', 'Close') },\n\t\t/** Success banner default text when result.message is empty. */\n\t\tsuccessText: { type: String, default: () => t('nextcloud-vue', 'Done.') },\n\t\t/**\n\t\t * Whether the dialog can be dismissed (Cancel button, ESC, backdrop\n\t\t * click) before reaching the result phase. `false` hides Cancel and\n\t\t * disables all other close affordances — use for a step that must\n\t\t * be completed, not merely skipped. The result-phase Close button is\n\t\t * unaffected (a completed wizard is always dismissible).\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tcancellable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Disable the Next / Submit button, whatever the step's `validate`\n\t\t * would say. For a host that knows the wizard cannot go on yet, such as\n\t\t * `CnSetupWizard` while a required app is missing.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @spec openspec/changes/setup-wizard-card-load-and-dependency-gate/specs/cn-setup-wizard/spec.md#requirement-the-wizard-checks-dependencies-before-any-step\n\t\t */\n\t\tnextDisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: ['close', 'step-change', 'submit'],\n\tdata() {\n\t\tconst initialIndex = this.resolveInitialIndex()\n\t\treturn {\n\t\t\tcurrentIndex: initialIndex,\n\t\t\tstepData: { ...this.defaults },\n\t\t\tloading: false,\n\t\t\tresult: null,\n\t\t\tvalidationError: '',\n\t\t\t/**\n\t\t\t * Drives NcDialog's `open` prop directly. NcDialog's own `open`\n\t\t\t * prop defaults to `true` and is NOT self-managing on close — its\n\t\t\t * internal `showModal` flag resets back to `true` ~300ms after\n\t\t\t * any close (animation bookkeeping for next time it's reopened\n\t\t\t * via the prop), so without an explicit `false` here the dialog\n\t\t\t * reopens itself right after Cancel/ESC/backdrop-click.\n\t\t\t */\n\t\t\tdialogOpen: true,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The board look's eyebrow, \"<context>, step N of M\", updated on every step\n\t\t * change. Empty in the Nextcloud look and in the result phase.\n\t\t *\n\t\t * @return {string} The eyebrow.\n\t\t */\n\t\tboardEyebrow() {\n\t\t\tif (!this.isBoardLook || this.result !== null) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn this.stepEyebrow\n\t\t\t\t.replace('{context}', this.eyebrowContext || this.eyebrow || this.dialogTitle)\n\t\t\t\t.replace('{step}', String(this.currentIndex + 1))\n\t\t\t\t.replace('{total}', String(this.steps.length))\n\t\t},\n\n\t\t/** @return {object} The check icon, the default finishing icon. */\n\t\tCheck() {\n\t\t\treturn Check\n\t\t},\n\n\t\t/**\n\t\t * The currently-active step object from `steps[]`.\n\t\t *\n\t\t * @return {object} The current step definition.\n\t\t */\n\t\tcurrentStep() {\n\t\t\treturn this.steps[this.currentIndex] || this.steps[0]\n\t\t},\n\n\t\t/**\n\t\t * Whether the current step is the first one.\n\t\t *\n\t\t * @return {boolean} True when on the first step.\n\t\t */\n\t\tisFirst() {\n\t\t\treturn this.currentIndex === 0\n\t\t},\n\n\t\t/**\n\t\t * Whether the current step is the last one (drives the\n\t\t * Next → Submit label flip).\n\t\t *\n\t\t * @return {boolean} True when on the last step.\n\t\t */\n\t\tisLast() {\n\t\t\treturn this.currentIndex === this.steps.length - 1\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Resolve the index of `initialStep` (falling back to 0 when\n\t\t * unset / not found).\n\t\t *\n\t\t * @return {number} Step index in the range [0, steps.length).\n\t\t */\n\t\tresolveInitialIndex() {\n\t\t\tif (!this.initialStep) {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tconst idx = this.steps.findIndex((s) => s.id === this.initialStep)\n\t\t\treturn idx >= 0 ? idx : 0\n\t\t},\n\n\t\t/**\n\t\t * Merge a partial step-data object onto the shared state.\n\t\t * Each slot scope receives this so consumers can write their\n\t\t * step's data without owning a `data()` block in their slot\n\t\t * component.\n\t\t *\n\t\t * @param {object} partial Fields to merge.\n\t\t * @return {void}\n\t\t */\n\t\tsetStepData(partial) {\n\t\t\tthis.stepData = { ...this.stepData, ...partial }\n\t\t},\n\n\t\t/**\n\t\t * Run the consumer's `validate` prop (if provided) for the\n\t\t * current step. Returns true on pass; sets `validationError`\n\t\t * and returns false on fail.\n\t\t *\n\t\t * @return {Promise<boolean>} Whether validation passed.\n\t\t */\n\t\tasync runValidation() {\n\t\t\tthis.validationError = ''\n\t\t\tif (typeof this.validate !== 'function') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst outcome = await this.validate(this.currentStep.id, this.stepData)\n\t\t\t\tif (outcome === true) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tif (typeof outcome === 'string') {\n\t\t\t\t\tthis.validationError = outcome\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\treturn Boolean(outcome)\n\t\t\t} catch (e) {\n\t\t\t\tthis.validationError = e && e.message ? e.message : 'Validation failed.'\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Advance to the next step after validation. Emits\n\t\t * `@step-change` with the new step id.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync next() {\n\t\t\tif (this.nextDisabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.isLast) {\n\t\t\t\treturn this.submit()\n\t\t\t}\n\t\t\tconst ok = await this.runValidation()\n\t\t\tif (!ok) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.currentIndex += 1\n\t\t\t/**\n\t\t\t * @event step-change Emitted on every step navigation\n\t\t\t * (next / back / jumpTo / submit).\n\t\t\t * @type {{ stepId: string, stepIndex: number, direction: 'next'|'back'|'jump' }}\n\t\t\t */\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'next',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Step back to the previous step. No validation runs on\n\t\t * back navigation — consumers can reach back without\n\t\t * losing the current step's draft.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tback() {\n\t\t\tif (this.isFirst) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex -= 1\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'back',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Jump to an arbitrary step by id. Validation is skipped\n\t\t * (the consumer is responsible for re-running it before\n\t\t * `submit()` if it matters).\n\t\t *\n\t\t * @param {string} stepId Target step id.\n\t\t * @return {void}\n\t\t */\n\t\tjumpTo(stepId) {\n\t\t\tconst idx = this.steps.findIndex((s) => s.id === stepId)\n\t\t\tif (idx < 0) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex = idx\n\t\t\tthis.$emit('step-change', {\n\t\t\t\tstepId: this.currentStep.id,\n\t\t\t\tstepIndex: this.currentIndex,\n\t\t\t\tdirection: 'jump',\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Submit the wizard. Runs the current step's validation;\n\t\t * on pass flips `loading` on and emits `@submit` with the\n\t\t * accumulated `stepData`. The parent is responsible for\n\t\t * calling `setResult()` to flip into the result phase.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync submit() {\n\t\t\tif (this.nextDisabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst ok = await this.runValidation()\n\t\t\tif (!ok) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\t/**\n\t\t\t * @event submit Emitted when the user reaches the final\n\t\t\t * step and clicks Submit (or `submit()` is called\n\t\t\t * programmatically from a slot scope). Payload is the\n\t\t\t * accumulated `stepData`.\n\t\t\t * @type {object}\n\t\t\t */\n\t\t\tthis.$emit('submit', { ...this.stepData })\n\t\t},\n\n\t\t/**\n\t\t * Public method called by the parent to switch the wizard\n\t\t * into the result phase.\n\t\t *\n\t\t * @param {object} result `{ success?, message?, error? }`.\n\t\t * @return {void}\n\t\t */\n\t\tsetResult(result) {\n\t\t\tthis.result = result || { success: true }\n\t\t\tthis.loading = false\n\t\t},\n\n\t\t/**\n\t\t * Public method for a NON-terminal submit failure: stops the\n\t\t * loading spinner and surfaces `message` as the error banner above\n\t\t * the (still-editable) current step, WITHOUT entering the result\n\t\t * phase — so the user can correct the input and resubmit. Use this\n\t\t * instead of `setResult({ error })` when the failure is recoverable\n\t\t * (e.g. a taken slug, a validation conflict).\n\t\t *\n\t\t * @param {string} message The error to show above the step body.\n\t\t * @return {void}\n\t\t */\n\t\tsetError(message) {\n\t\t\tthis.loading = false\n\t\t\tthis.validationError = message || ''\n\t\t},\n\n\t\t/**\n\t\t * Close-button handler. Resets local state so the next open\n\t\t * starts fresh and emits `@close`.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonClose() {\n\t\t\tthis.result = null\n\t\t\tthis.loading = false\n\t\t\tthis.validationError = ''\n\t\t\tthis.currentIndex = this.resolveInitialIndex()\n\t\t\tthis.stepData = { ...this.defaults }\n\t\t\tthis.dialogOpen = false\n\t\t\t/**\n\t\t\t * @event close Emitted when the dialog should close.\n\t\t\t */\n\t\t\tthis.$emit('close')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-wizard-dialog__step-body {\n\tmin-height: 200px;\n}\n\n.cn-wizard-dialog__result {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n</style>\n"],"names":["_createBlock","_createElementBlock","_Fragment","_createTextVNode","_createVNode","_resolveDynamicComponent","_toDisplayString","_openBlock","_renderSlot","_createElementVNode"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import script from './CnWorkingCalendarWidget.vue2.js';
2
+ import { render } from './CnWorkingCalendarWidget.vue3.js';
3
+
4
+ script.render = render;
5
+ script.__scopeId = "data-v-03ee459c";
6
+ const __sfc_main = script;
7
+
8
+ export { __sfc_main as default };
9
+ //# sourceMappingURL=CnWorkingCalendarWidget.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnWorkingCalendarWidget.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}