@conduction/nextcloud-vue 2.56.0-beta.3 → 2.56.0-beta.4
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.
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +21 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +49 -5
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/l10n/en.json.js +1 -0
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +1 -0
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +7 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +76 -10
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +7 -0
- package/l10n/en.json +1 -0
- package/l10n/nl.json +1 -0
- package/package.json +1 -1
- package/src/components/CnAppRoot/CnAppRoot.vue +31 -2
- package/src/components/CnSetupWizard/CnSetupWizard.vue +57 -6
- package/src/schemas/app-manifest-v2.schema.json +2 -1
- package/src/utils/validateManifestV2.compiled.js +2 -2
|
@@ -231,7 +231,14 @@ var script = {
|
|
|
231
231
|
* a done marker (info steps always done; choice steps done when picked;
|
|
232
232
|
* run-action steps done when the action succeeded).
|
|
233
233
|
*
|
|
234
|
-
*
|
|
234
|
+
* An on-demand step (`onDemand: true`) is the exception: it is done
|
|
235
|
+
* only when its action succeeded in THIS session. Apps report such a
|
|
236
|
+
* step as `done` on purpose so it never auto-runs (learniq's "Remove
|
|
237
|
+
* the example data"), and reading that flag here ticked a removal
|
|
238
|
+
* nobody ran. When it did not run it gets `notRun: true` and the value
|
|
239
|
+
* "Not run" instead.
|
|
240
|
+
*
|
|
241
|
+
* @return {Array<{ id: string, title: string, value: string, done: boolean, notRun: boolean }>}
|
|
235
242
|
*/
|
|
236
243
|
summaryItems() {
|
|
237
244
|
return this.setupSteps
|
|
@@ -250,6 +257,16 @@ var script = {
|
|
|
250
257
|
.map((f) => `${f.label}: ${this.configModel[f.key] !== null && this.configModel[f.key] !== undefined ? this.configModel[f.key] : ''}`)
|
|
251
258
|
.join(', ');
|
|
252
259
|
}
|
|
260
|
+
if (this.isOnDemand(step)) {
|
|
261
|
+
const ran = this.ranThisSession(step.id);
|
|
262
|
+
return {
|
|
263
|
+
id: step.id,
|
|
264
|
+
title: this.stepTitle(step),
|
|
265
|
+
value: ran ? '' : translate('nextcloud-vue', 'Not run'),
|
|
266
|
+
done: ran,
|
|
267
|
+
notRun: !ran,
|
|
268
|
+
}
|
|
269
|
+
}
|
|
253
270
|
let done;
|
|
254
271
|
if (step.type === 'info') {
|
|
255
272
|
done = true;
|
|
@@ -258,7 +275,7 @@ var script = {
|
|
|
258
275
|
} else {
|
|
259
276
|
done = this.isStepDone(step.id);
|
|
260
277
|
}
|
|
261
|
-
return { id: step.id, title: this.stepTitle(step), value, done }
|
|
278
|
+
return { id: step.id, title: this.stepTitle(step), value, done, notRun: false }
|
|
262
279
|
})
|
|
263
280
|
},
|
|
264
281
|
|
|
@@ -278,7 +295,9 @@ var script = {
|
|
|
278
295
|
if (this.completedStepIds.length === 0) {
|
|
279
296
|
return ''
|
|
280
297
|
}
|
|
281
|
-
|
|
298
|
+
// An on-demand step is never outstanding work, so it is never the
|
|
299
|
+
// step to resume on.
|
|
300
|
+
const actionable = this.setupSteps.filter((s) => s.type !== 'info' && s.type !== 'summary' && !this.isOnDemand(s));
|
|
282
301
|
const firstUnmetIndex = actionable.findIndex((s) => {
|
|
283
302
|
if (s.type === 'choice') {
|
|
284
303
|
return !(this.hasChoice(s) || this.isServerDone(s.id))
|
|
@@ -310,14 +329,16 @@ var script = {
|
|
|
310
329
|
* the step has nothing else for the user to decide by then (the
|
|
311
330
|
* choice it acts on was already made on an earlier step), so
|
|
312
331
|
* requiring a click before showing progress just adds a stall.
|
|
313
|
-
* No-ops for any other step type, or one already run/running
|
|
332
|
+
* No-ops for any other step type, or one already run/running, and
|
|
333
|
+
* never fires an on-demand step (`onDemand: true`): those run only
|
|
334
|
+
* when the user clicks Run.
|
|
314
335
|
*
|
|
315
336
|
* @param {string} stepId The step id becoming current.
|
|
316
337
|
* @return {void}
|
|
317
338
|
*/
|
|
318
339
|
maybeAutoRunStep(stepId) {
|
|
319
340
|
const step = this.setupSteps.find((s) => s.id === stepId);
|
|
320
|
-
if (step && step.type === 'run-action' && !this.isStepDone(step.id) && !this.running[step.id]) {
|
|
341
|
+
if (step && step.type === 'run-action' && !this.isOnDemand(step) && !this.isStepDone(step.id) && !this.running[step.id]) {
|
|
321
342
|
this.runAction(step);
|
|
322
343
|
}
|
|
323
344
|
},
|
|
@@ -698,6 +719,29 @@ var script = {
|
|
|
698
719
|
}
|
|
699
720
|
},
|
|
700
721
|
|
|
722
|
+
/**
|
|
723
|
+
* Whether a step is marked on-demand (`onDemand: true`): it runs only
|
|
724
|
+
* when the user asks, never automatically, and the summary ticks it
|
|
725
|
+
* only when it ran in this session.
|
|
726
|
+
*
|
|
727
|
+
* @param {object} step The manifest step.
|
|
728
|
+
* @return {boolean}
|
|
729
|
+
*/
|
|
730
|
+
isOnDemand(step) {
|
|
731
|
+
return !!step && step.onDemand === true
|
|
732
|
+
},
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* Whether a step's action succeeded in the CURRENT session, ignoring
|
|
736
|
+
* whatever the server reports.
|
|
737
|
+
*
|
|
738
|
+
* @param {string} id Step id.
|
|
739
|
+
* @return {boolean}
|
|
740
|
+
*/
|
|
741
|
+
ranThisSession(id) {
|
|
742
|
+
return !!(this.actionResult[id] && this.actionResult[id].success)
|
|
743
|
+
},
|
|
744
|
+
|
|
701
745
|
isStepDone(id) {
|
|
702
746
|
return this.isServerDone(id) || this.localDone[id] === true || (this.actionResult[id] && this.actionResult[id].success)
|
|
703
747
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnSetupWizard.vue2.js","sources":["../../../../src/components/CnSetupWizard/CnSetupWizard.vue"],"sourcesContent":["<!-- SPDX-License-Identifier: EUPL-1.2 -->\n<!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->\n<template>\n\t<CnWizardDialog\n\t\tref=\"wizard\"\n\t\t:steps=\"wizardSteps\"\n\t\t:dialogTitle=\"resolvedDialogTitle\"\n\t\t:submitLabel=\"submitLabel\"\n\t\t:cancelLabel=\"cancelLabel\"\n\t\t:nextLabel=\"nextLabel\"\n\t\t:backLabel=\"backLabel\"\n\t\t:successText=\"successText\"\n\t\t:validate=\"validateStep\"\n\t\t:cancellable=\"cancellable\"\n\t\t:initialStep=\"initialStepId\"\n\t\t@stepChange=\"onStepChange\"\n\t\t@submit=\"onSubmit\"\n\t\t@close=\"onClose\">\n\t\t<!-- This `<template v-for>` defines dynamic SLOTS, not a rendered list.\n\t\t `@vue/compiler-sfc` DISCARDS a `:key` on a slot-defining\n\t\t `<template>` (verified against the generated `createSlots` call)\n\t\t and honours it only on the child, so the rule's advice is inverted\n\t\t here — moving the key up would throw it away. -->\n\t\t<!-- eslint-disable vue/no-v-for-template-key-on-child -->\n\t\t<template v-for=\"step in setupSteps\" #[stepSlot(step)]=\"scope\">\n\t\t\t<div :key=\"step.id\" class=\"cn-setup-step\" :data-step-type=\"step.type\">\n\t\t\t\t<!-- @slot step-{id} Override a step's body (for `component` steps or\n\t\t\t\t any bespoke step). Scope: the CnWizardDialog step scope plus\n\t\t\t\t `{ step, runAction, saveConfig }`. -->\n\t\t\t\t<slot\n\t\t\t\t\tv-if=\"hasCustomSlot(step.id)\"\n\t\t\t\t\t:name=\"stepSlot(step)\"\n\t\t\t\t\tv-bind=\"scope\"\n\t\t\t\t\t:step=\"step\"\n\t\t\t\t\t:runAction=\"() => runAction(step)\"\n\t\t\t\t\t:saveConfig=\"(patch) => saveConfig(patch)\" />\n\n\t\t\t\t<!-- info -->\n\t\t\t\t<template v-else-if=\"step.type === 'info'\">\n\t\t\t\t\t<NcNoteCard type=\"info\" :heading=\"stepTitle(step)\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- choice -->\n\t\t\t\t<template v-else-if=\"step.type === 'choice'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<CnChoiceCards\n\t\t\t\t\t\tv-if=\"isCardChoice(step)\"\n\t\t\t\t\t\t:label=\"stepTitle(step)\"\n\t\t\t\t\t\t:options=\"optionsFor(step)\"\n\t\t\t\t\t\t:multiple=\"step.multiple === true\"\n\t\t\t\t\t\t:disabled=\"isChoiceDisabled(step)\"\n\t\t\t\t\t\t:loading=\"isOptionsLoading(step)\"\n\t\t\t\t\t\t:modelValue=\"cardModel(step)\"\n\t\t\t\t\t\t@update:modelValue=\"(v) => onChoice(step, v)\" />\n\t\t\t\t\t<NcSelect\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:inputLabel=\"stepTitle(step)\"\n\t\t\t\t\t\t:options=\"optionsFor(step)\"\n\t\t\t\t\t\t:multiple=\"step.multiple === true\"\n\t\t\t\t\t\t:disabled=\"isChoiceDisabled(step)\"\n\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t:modelValue=\"choiceModel[step.id]\"\n\t\t\t\t\t\t@update:modelValue=\"(v) => onChoice(step, v)\" />\n\t\t\t\t\t<NcNoteCard v-if=\"isChoiceDisabled(step)\" type=\"warning\">\n\t\t\t\t\t\t{{ dependsOnHint(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- config-fields -->\n\t\t\t\t<template v-else-if=\"step.type === 'config-fields'\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-for=\"field in fieldsFor(step)\"\n\t\t\t\t\t\t:key=\"field.key\"\n\t\t\t\t\t\tclass=\"cn-setup-field\">\n\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\tv-if=\"field.widget === 'checkbox'\"\n\t\t\t\t\t\t\t:modelValue=\"!!configModel[field.key]\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\">\n\t\t\t\t\t\t\t{{ field.label }}\n\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\tv-else-if=\"field.widget === 'select'\"\n\t\t\t\t\t\t\t:inputLabel=\"field.label\"\n\t\t\t\t\t\t\t:options=\"field.enum || []\"\n\t\t\t\t\t\t\t:modelValue=\"configModel[field.key]\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\" />\n\t\t\t\t\t\t<NcTextField\n\t\t\t\t\t\t\tv-else\n\t\t\t\t\t\t\t:label=\"field.label\"\n\t\t\t\t\t\t\t:type=\"field.widget === 'number' ? 'number' : 'text'\"\n\t\t\t\t\t\t\t:modelValue=\"configModel[field.key] != null ? String(configModel[field.key]) : ''\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\" />\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- run-action -->\n\t\t\t\t<template v-else-if=\"step.type === 'run-action'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<!-- The action starts automatically on entering this step\n\t\t\t\t\t (see `maybeAutoRunStep`), so the default state is the\n\t\t\t\t\t spinner, not an idle button. -->\n\t\t\t\t\t<div v-if=\"running[step.id]\" class=\"cn-setup-step__running\">\n\t\t\t\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t\t\t\t<span>{{ runningLabel }}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<template v-else>\n\t\t\t\t\t\t<NcNoteCard\n\t\t\t\t\t\t\tv-if=\"actionResult[step.id]\"\n\t\t\t\t\t\t\t:type=\"actionResult[step.id].success ? 'success' : 'error'\">\n\t\t\t\t\t\t\t{{ actionResult[step.id].message }}\n\t\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t\t<div class=\"cn-setup-step__nav\">\n\t\t\t\t\t\t\t<NcButton :variant=\"actionResult[step.id] ? 'secondary' : 'primary'\" @click=\"runAction(step)\">\n\t\t\t\t\t\t\t\t{{ actionResult[step.id] ? rerunLabel : runLabel }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- summary -->\n\t\t\t\t<template v-else-if=\"step.type === 'summary'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<ul class=\"cn-setup-summary\">\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tv-for=\"item in summaryItems\"\n\t\t\t\t\t\t\t:key=\"item.id\"\n\t\t\t\t\t\t\tclass=\"cn-setup-summary__item\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-setup-summary__item--done': item.done }\">\n\t\t\t\t\t\t\t<span class=\"cn-setup-summary__mark\">{{ item.done ? '✓' : '○' }}</span>\n\t\t\t\t\t\t\t<span class=\"cn-setup-summary__label\">{{ item.title }}</span>\n\t\t\t\t\t\t\t<span v-if=\"item.value\" class=\"cn-setup-summary__value\">{{ item.value }}</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</template>\n\t\t<!-- eslint-enable vue/no-v-for-template-key-on-child -->\n\t</CnWizardDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcCheckboxRadioSwitch, NcLoadingIcon, NcNoteCard, NcSelect, NcTextField } from '@nextcloud/vue'\nimport CnChoiceCards from '../CnChoiceCards/CnChoiceCards.vue'\nimport CnWizardDialog from '../CnWizardDialog/CnWizardDialog.vue'\nimport { useSetupStatus } from '../../composables/useSetupStatus.js'\nimport { fieldsFromSchema } from '../../utils/schema.js'\n\n/**\n * CnSetupWizard — abstract, manifest-driven first-time setup wizard (ADR-042).\n *\n * Wraps {@link CnWizardDialog} and renders a `manifest.setup.steps[]` array by\n * each step's `type`: `info` (note), `config-fields` (fields from a JSON Schema\n * via `fieldsFromSchema`, the same field shapes the admin pages use), `choice`\n * (`NcSelect` persisting to an app-config key), `run-action` (POST a privileged\n * server action), `summary` (recap), and `component` (a parent-provided\n * `#step-<id>` slot). It NEVER writes OpenRegister objects from the browser —\n * all persistence goes through the per-app setup contract\n * (`POST /apps/{appId}/api/setup/config` and `/api/setup/action/{actionId}`).\n *\n * Mount it gated by `CnAppRoot`'s setup phase, or open it on demand from\n * `CnAdminSettingsShell`.\n *\n * ```vue\n * <CnSetupWizard\n * :app-id=\"'procest'\"\n * :steps=\"manifest.setup.steps\"\n * @complete=\"onSetupComplete\"\n * @close=\"showWizard = false\" />\n * ```\n */\nexport default {\n\tname: 'CnSetupWizard',\n\n\tcomponents: {\n\t\tCnWizardDialog,\n\t\tCnChoiceCards,\n\t\tNcButton,\n\t\tNcNoteCard,\n\t\tNcSelect,\n\t\tNcTextField,\n\t\tNcCheckboxRadioSwitch,\n\t\tNcLoadingIcon,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Consumer translation function, provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id). Step field\n\t\t * labels come from schema property titles, authored in English as the\n\t\t * canonical source; the visible label is resolved through this function\n\t\t * so it follows the user's language. Defaults to identity when used\n\t\t * standalone (no CnAppRoot ancestor).\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** The Nextcloud app id; used to build the `/apps/{appId}/api/setup/*` URLs. */\n\t\tappId: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** The `manifest.setup.steps` array to render. */\n\t\tsteps: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Dialog title. Overridden by `appName` when that prop is set. */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Set up this app'),\n\t\t},\n\n\t\t/**\n\t\t * The app's human-readable display name. When set, the dialog title\n\t\t * becomes \"Set up {appName}\" instead of the generic `dialogTitle`\n\t\t * default — pass the same display name CnAppRoot already resolves\n\t\t * (`appDisplayName || manifest.name || appId`).\n\t\t */\n\t\tappName: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Final-step submit button label. */\n\t\tsubmitLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Finish'),\n\t\t},\n\n\t\t/** Cancel button label. */\n\t\tcancelLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Cancel'),\n\t\t},\n\n\t\t/** Next button label. */\n\t\tnextLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Next'),\n\t\t},\n\n\t\t/** Back button label. */\n\t\tbackLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Back'),\n\t\t},\n\n\t\t/** Run-action button label (shown before the first automatic run). */\n\t\trunLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Run'),\n\t\t},\n\n\t\t/** Run-action button label offered after a run already finished. */\n\t\trerunLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Run again'),\n\t\t},\n\n\t\t/** Label shown next to the spinner while a run-action step is running. */\n\t\trunningLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Loading…'),\n\t\t},\n\n\t\t/** Result-phase success text. */\n\t\tsuccessText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Setup complete.'),\n\t\t},\n\n\t\t/**\n\t\t * Whether the wizard can be dismissed before finishing (Cancel\n\t\t * button, ESC, backdrop click). Pass `false` when a REQUIRED step\n\t\t * is unmet and the host is gating its shell behind this wizard\n\t\t * (ADR-042) — an offered-but-non-functional Cancel would be\n\t\t * misleading. Optional-only setup stays cancellable (default).\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 * Ids of steps the SERVER already reports as done (e.g.\n\t\t * `useSetupStatus(...).steps` filtered to `done === true`), passed by\n\t\t * the host so a freshly (re)mounted wizard doesn't re-ask something\n\t\t * already persisted in an earlier session — this component's own\n\t\t * `localDone`/`choiceModel` only track the CURRENT session and reset\n\t\t * blank on every mount. Drives both the initial step (`initialStepId`)\n\t\t * and the summary page's done markers.\n\t\t *\n\t\t * @type {Array<string>}\n\t\t */\n\t\tcompletedStepIds: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\t},\n\n\temits: ['complete', 'close', 'step-change', 'action-result'],\n\n\t/**\n\t * Live option lists come from the app's own setup status document, so a\n\t * step that offers a choice of things the SERVER ships never has to\n\t * restate them in the manifest. `useSetupStatus` caches per app id, so the\n\t * host's own status fetch (CnAppRoot's setup gate) is the one that runs —\n\t * this reads the same refs rather than asking again.\n\t *\n\t * Only called when a step actually declares `optionsSource`: a wizard with\n\t * none must not start making requests it never made before.\n\t *\n\t * @param {object} props The component props.\n\t * @return {object} `setupStatus` / `setupStatusLoading` for the option resolver.\n\t */\n\tsetup(props) {\n\t\tconst wantsSource = (props.steps || []).some((s) => s && s.optionsSource)\n\t\tif (!wantsSource) {\n\t\t\treturn {}\n\t\t}\n\t\tconst { status, loading } = useSetupStatus(props.appId, { setup: { steps: props.steps } })\n\t\treturn { setupStatus: status, setupStatusLoading: loading }\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tchoiceModel: {},\n\t\t\tchoiceValues: {},\n\t\t\tconfigModel: {},\n\t\t\trunning: {},\n\t\t\tactionResult: {},\n\t\t\tlocalDone: {},\n\t\t\tuserTouched: {},\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The title actually rendered by CnWizardDialog: \"Set up {appName}\"\n\t\t * when a display name was passed, otherwise whatever `dialogTitle`\n\t\t * resolves to (a caller override, or its own generic default).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedDialogTitle() {\n\t\t\treturn this.appName\n\t\t\t\t? t('nextcloud-vue', 'Set up {app}', { app: this.appName })\n\t\t\t\t: this.dialogTitle\n\t\t},\n\n\t\tsetupSteps() {\n\t\t\treturn (this.steps || []).filter((s) => s && s.id && s.type)\n\t\t},\n\n\t\twizardSteps() {\n\t\t\treturn this.setupSteps.map((s) => ({\n\t\t\t\tid: s.id,\n\t\t\t\tlabel: this.stepTitle(s),\n\t\t\t\toptional: s.required !== true,\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Recap rows for the `summary` step — one per non-summary step, with\n\t\t * the value the user selected (choice label / config field values) and\n\t\t * a done marker (info steps always done; choice steps done when picked;\n\t\t * run-action steps done when the action succeeded).\n\t\t *\n\t\t * @return {Array<{ id: string, title: string, value: string, done: boolean }>}\n\t\t */\n\t\tsummaryItems() {\n\t\t\treturn this.setupSteps\n\t\t\t\t.filter((s) => s.type !== 'summary')\n\t\t\t\t.map((step) => {\n\t\t\t\t\tlet value = ''\n\t\t\t\t\tif (step.type === 'choice') {\n\t\t\t\t\t\tconst raw = this.choiceModel[step.id]\n\t\t\t\t\t\tif (Array.isArray(raw)) {\n\t\t\t\t\t\t\tvalue = raw.map((o) => this.choiceLabel(step, o)).join(', ')\n\t\t\t\t\t\t} else if (raw !== null && raw !== undefined && raw !== '') {\n\t\t\t\t\t\t\tvalue = this.choiceLabel(step, raw)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (step.type === 'config-fields') {\n\t\t\t\t\t\tvalue = this.fieldsFor(step)\n\t\t\t\t\t\t\t.map((f) => `${f.label}: ${this.configModel[f.key] !== null && this.configModel[f.key] !== undefined ? this.configModel[f.key] : ''}`)\n\t\t\t\t\t\t\t.join(', ')\n\t\t\t\t\t}\n\t\t\t\t\tlet done\n\t\t\t\t\tif (step.type === 'info') {\n\t\t\t\t\t\tdone = true\n\t\t\t\t\t} else if (step.type === 'choice') {\n\t\t\t\t\t\tdone = this.hasChoice(step) || this.isServerDone(step.id)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdone = this.isStepDone(step.id)\n\t\t\t\t\t}\n\t\t\t\t\treturn { id: step.id, title: this.stepTitle(step), value, done }\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Id of the step the wizard should open on when RESUMING: the first\n\t\t * non-`info`/`summary` step not already done, per the CURRENT session's\n\t\t * local state OR the server-reported `completedStepIds` (a prior\n\t\t * session). Falls back to `''` (CnWizardDialog's own first-step default)\n\t\t * on a fresh setup and when every actionable step is already done.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tinitialStepId() {\n\t\t\t// Fresh setup — nothing done anywhere yet, so there is nothing to\n\t\t\t// resume past. Start at step one so a leading `info`/welcome step is\n\t\t\t// actually seen; resuming is only for returning sessions.\n\t\t\tif (this.completedStepIds.length === 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst actionable = this.setupSteps.filter((s) => s.type !== 'info' && s.type !== 'summary')\n\t\t\tconst firstUnmetIndex = actionable.findIndex((s) => {\n\t\t\t\tif (s.type === 'choice') {\n\t\t\t\t\treturn !(this.hasChoice(s) || this.isServerDone(s.id))\n\t\t\t\t}\n\t\t\t\treturn !this.isStepDone(s.id)\n\t\t\t})\n\t\t\t// Done is not the same as seen: an app that pre-satisfies a step at\n\t\t\t// install time (buildiq seeds templates from a repair step) reports it\n\t\t\t// done before anyone opens the wizard. Only finished work BEFORE the\n\t\t\t// outstanding step means there is something to resume past.\n\t\t\tif (firstUnmetIndex <= 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn actionable[firstUnmetIndex].id\n\t\t},\n\t},\n\n\tmounted() {\n\t\t// Covers a RESUMED wizard opening straight onto its run-action step\n\t\t// (`initialStepId`) — `onStepChange` only fires on later navigation,\n\t\t// so a step already active at mount time needs its own trigger.\n\t\tthis.maybeAutoRunStep(this.initialStepId || (this.setupSteps[0] && this.setupSteps[0].id))\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Start a `run-action` step's action automatically the moment it\n\t\t * becomes current, instead of waiting for a manual \"Run\" click —\n\t\t * the step has nothing else for the user to decide by then (the\n\t\t * choice it acts on was already made on an earlier step), so\n\t\t * requiring a click before showing progress just adds a stall.\n\t\t * No-ops for any other step type, or one already run/running.\n\t\t *\n\t\t * @param {string} stepId The step id becoming current.\n\t\t * @return {void}\n\t\t */\n\t\tmaybeAutoRunStep(stepId) {\n\t\t\tconst step = this.setupSteps.find((s) => s.id === stepId)\n\t\t\tif (step && step.type === 'run-action' && !this.isStepDone(step.id) && !this.running[step.id]) {\n\t\t\t\tthis.runAction(step)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The visible title for a step, resolved through the host app's\n\t\t * translation function.\n\t\t *\n\t\t * `manifest.setup.steps[].title` is authored in English as the\n\t\t * canonical source, exactly like the schema property titles this\n\t\t * component already routes through `cnTranslate` for field labels\n\t\t * (see `fieldsFromSchema` below). The step titles were the one\n\t\t * remaining place rendering the manifest string verbatim, so an\n\t\t * nl-locale user saw a wizard whose field labels were translated and\n\t\t * whose step headings were not.\n\t\t *\n\t\t * Falls back to the step id when a step declares no title, which is\n\t\t * the same fallback the raw bindings used.\n\t\t *\n\t\t * @param {object} step A `manifest.setup.steps[]` entry.\n\t\t * @return {string} The translated title, or the step id.\n\t\t */\n\t\tstepTitle(step) {\n\t\t\tconst raw = (step && step.title) || (step && step.id) || ''\n\t\t\treturn raw === '' ? '' : this.cnTranslate(raw)\n\t\t},\n\n\t\t/**\n\t\t * The visible body for a step, resolved through the host app's\n\t\t * translation function.\n\t\t *\n\t\t * 🔴 THIS USED TO RENDER THE MANIFEST STRING VERBATIM, IN FOUR PLACES.\n\t\t * `stepTitle()` was routed through `cnTranslate` and the body was not,\n\t\t * so a wizard on a Dutch instance showed a translated heading over an\n\t\t * English paragraph, with translated Cancel/Next buttons underneath.\n\t\t * That reads as a bug rather than as a missing string, and the app could\n\t\t * not fix it: decidiq shipped correct Dutch for its setup copy in\n\t\t * `l10n/nl.json`, and the component never asked for it.\n\t\t *\n\t\t * @param {object} step The step declaration.\n\t\t * @return {string} The translated body, or ''.\n\t\t */\n\t\tstepBody(step) {\n\t\t\tconst raw = (step && step.body) || ''\n\t\t\treturn raw === '' ? '' : this.cnTranslate(raw)\n\t\t},\n\n\t\tstepSlot(step) {\n\t\t\treturn 'step-' + step.id\n\t\t},\n\n\t\thasCustomSlot(id) {\n\t\t\treturn !!this.$slots['step-' + id] || !!this.$slots['step-' + id]\n\t\t},\n\n\t\tfieldsFor(step) {\n\t\t\tif (step.schema && typeof step.schema === 'object') {\n\t\t\t\treturn fieldsFromSchema(step.schema, { translate: this.cnTranslate })\n\t\t\t}\n\t\t\t// Fallback: a plain text field per declared config key.\n\t\t\treturn (step.configKeys || []).map((key) => ({ key, label: key, widget: 'text' }))\n\t\t},\n\n\t\t/**\n\t\t * Options for a `choice` step. When the step declares `dependsOn`\n\t\t * (a parent step's configKey) + `optionsByParent`, the option list\n\t\t * is the entry keyed by the parent's currently-selected value — this\n\t\t * is the country → organisation-type cascade. Otherwise the static\n\t\t * `options` array.\n\t\t *\n\t\t * @param {object} step The choice step definition.\n\t\t * @return {Array} The option list to render.\n\t\t */\n\t\toptionsFor(step) {\n\t\t\tlet options = step.options || []\n\t\t\tif (step.optionsSource) {\n\t\t\t\toptions = this.sourcedOptions(step)\n\t\t\t} else if (step.dependsOn && step.optionsByParent) {\n\t\t\t\tconst parentValue = this.choiceValues[step.dependsOn]\n\t\t\t\toptions = (parentValue === null || parentValue === undefined || parentValue === '')\n\t\t\t\t\t? []\n\t\t\t\t\t: (step.optionsByParent[parentValue] || [])\n\t\t\t}\n\t\t\t// The LABEL is translated, the VALUE never is. `scalarChoice()` reads\n\t\t\t// `.value` and that is what reaches `POST /api/setup/config`, so a\n\t\t\t// translated label cannot change what gets stored — while an\n\t\t\t// untranslated one leaves the choice itself in English on a\n\t\t\t// localised instance, which is the half-translated screen this fix\n\t\t\t// exists to remove.\n\t\t\treturn options.map((option) => {\n\t\t\t\tif (!option || typeof option !== 'object' || !option.label) {\n\t\t\t\t\treturn option\n\t\t\t\t}\n\t\t\t\tconst translated = { ...option, label: this.cnTranslate(option.label) }\n\t\t\t\tif (option.description) {\n\t\t\t\t\ttranslated.description = this.cnTranslate(option.description)\n\t\t\t\t}\n\t\t\t\treturn translated\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The option list a `choice` step declares `optionsSource` for, read\n\t\t * from the setup status document the app already serves.\n\t\t *\n\t\t * `optionsSource` names a key in that document (dots walk into nested\n\t\t * objects), and the entries are normalised to the option shape: `id` is\n\t\t * accepted for `value`, `name` for `label`, and a bare `objectCount`\n\t\t * becomes the one stat a card shows. A server that already sends\n\t\t * `stats` keeps them.\n\t\t *\n\t\t * @param {object} step The choice step declaring `optionsSource`.\n\t\t * @return {Array<object>} The options, or [] while the status is loading.\n\t\t */\n\t\tsourcedOptions(step) {\n\t\t\tlet node = this.setupStatus\n\t\t\tfor (const key of String(step.optionsSource).split('.')) {\n\t\t\t\tif (node === null || node === undefined || typeof node !== 'object') {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\tnode = node[key]\n\t\t\t}\n\t\t\tif (!Array.isArray(node)) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn node\n\t\t\t\t.filter((entry) => entry && typeof entry === 'object')\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tconst value = entry.value !== undefined ? entry.value : entry.id\n\t\t\t\t\tconst option = {\n\t\t\t\t\t\t...entry,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tlabel: entry.label || entry.name || String(value),\n\t\t\t\t\t}\n\t\t\t\t\tif (!option.stats && typeof entry.objectCount === 'number' && entry.objectCount > 0) {\n\t\t\t\t\t\toption.stats = [{ label: t('nextcloud-vue', 'Objects'), value: entry.objectCount }]\n\t\t\t\t\t}\n\t\t\t\t\treturn option\n\t\t\t\t})\n\t\t\t\t.filter((option) => option.value !== undefined)\n\t\t},\n\n\t\t/**\n\t\t * Whether a choice step renders as a card grid rather than a dropdown.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {boolean} True for `display: \"cards\"`.\n\t\t */\n\t\tisCardChoice(step) {\n\t\t\treturn step.display === 'cards'\n\t\t},\n\n\t\t/**\n\t\t * Whether this step is still waiting for its live option list.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {boolean} True while the status document is in flight.\n\t\t */\n\t\tisOptionsLoading(step) {\n\t\t\treturn !!step.optionsSource && this.setupStatusLoading === true\n\t\t},\n\n\t\t/**\n\t\t * The card grid's model: plain values, not the option objects NcSelect\n\t\t * binds. `scalarChoice` already reduces either shape to values, so both\n\t\t * renderers can share one `choiceModel` entry.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {unknown} The selected value, or [] / null when nothing is picked.\n\t\t */\n\t\tcardModel(step) {\n\t\t\tconst value = this.scalarChoice(step)\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn Array.isArray(value) ? value : []\n\t\t\t}\n\t\t\treturn value === undefined ? null : value\n\t\t},\n\n\t\tisChoiceDisabled(step) {\n\t\t\tif (!step.dependsOn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst parentValue = this.choiceValues[step.dependsOn]\n\t\t\treturn parentValue === null || parentValue === undefined || parentValue === ''\n\t\t},\n\n\t\tdependsOnHint(step) {\n\t\t\tconst parent = this.setupSteps.find((s) => s.configKey === step.dependsOn)\n\t\t\tconst label = parent ? (parent.title || parent.id) : step.dependsOn\n\t\t\treturn t('nextcloud-vue', 'Select \"{step}\" first.', { step: label })\n\t\t},\n\n\t\t/**\n\t\t * The visible label for one selected choice entry.\n\t\t *\n\t\t * A card grid stores plain VALUES where NcSelect stores option objects,\n\t\t * so the recap looked one up and printed the other: the summary read\n\t\t * \"municipality\" instead of \"Municipality\". Resolves a bare value back\n\t\t * to its option, and falls back to the value when the option list is\n\t\t * not (yet) available.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @param {unknown} entry One selected entry: an option object or a value.\n\t\t * @return {string} The label to show.\n\t\t */\n\t\tchoiceLabel(step, entry) {\n\t\t\tif (entry && typeof entry === 'object' && entry.label) {\n\t\t\t\treturn entry.label\n\t\t\t}\n\t\t\tconst match = this.optionsFor(step).find((o) => o && String(o.value) === String(entry))\n\t\t\treturn (match && match.label) ? match.label : String(entry)\n\t\t},\n\n\t\thasChoice(step) {\n\t\t\tconst v = this.choiceModel[step.id]\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn Array.isArray(v) && v.length > 0\n\t\t\t}\n\t\t\treturn v !== null && v !== undefined && v !== ''\n\t\t},\n\n\t\tscalarChoice(step) {\n\t\t\tconst raw = this.choiceModel[step.id]\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn (raw || []).map((o) => (o && o.value !== undefined ? o.value : o))\n\t\t\t}\n\t\t\treturn raw && raw.value !== undefined ? raw.value : raw\n\t\t},\n\n\t\tonChoice(step, value) {\n\t\t\tthis.userTouched[step.id] = true\n\t\t\tthis.choiceModel[step.id] = value\n\t\t\tif (step.configKey) {\n\t\t\t\tthis.choiceValues[step.configKey] = this.scalarChoice(step)\n\t\t\t}\n\t\t\t// Reset any dependent child choices when the parent changes.\n\t\t\tfor (const child of this.setupSteps) {\n\t\t\t\tif (child.dependsOn && child.dependsOn === step.configKey) {\n\t\t\t\t\tthis.choiceModel[child.id] = child.multiple === true ? [] : null\n\t\t\t\t\tthis.userTouched[child.id] = false\n\t\t\t\t\tif (child.configKey) {\n\t\t\t\t\t\tthis.choiceValues[child.configKey] = ''\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Re-apply auto-suggestions for steps that derive a default from this one.\n\t\t\tfor (const dep of this.setupSteps) {\n\t\t\t\tif (dep.suggestFrom && dep.suggestFrom === step.configKey) {\n\t\t\t\t\tthis.applySuggestion(dep)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Auto-fill a `choice` step's suggested default from an earlier choice\n\t\t * (its `suggestFrom` configKey → `suggestMap[parentValue]`). No-op once\n\t\t * the user has manually picked here, so a suggestion never clobbers an\n\t\t * explicit choice.\n\t\t *\n\t\t * @param {object} step The dependent choice step.\n\t\t * @return {void}\n\t\t */\n\t\tapplySuggestion(step) {\n\t\t\tif (this.userTouched[step.id] === true) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst parentValue = this.choiceValues[step.suggestFrom]\n\t\t\tif (parentValue === null || parentValue === undefined || parentValue === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst wanted = (step.suggestMap || {})[parentValue]\n\t\t\tif (wanted === null || wanted === undefined) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst opt = this.optionsFor(step).find((o) => o.value === wanted) || { value: wanted, label: String(wanted) }\n\t\t\tthis.choiceModel[step.id] = opt\n\t\t\tif (step.configKey) {\n\t\t\t\tthis.choiceValues[step.configKey] = wanted\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * CnWizardDialog `validate` hook — intercepts Next/Submit to persist\n\t\t * the active step before advancing. `choice`/`config-fields` steps\n\t\t * POST their value via the setup contract; required `choice` steps\n\t\t * block advance until a value is picked; required `run-action` steps\n\t\t * block until the action has succeeded. Returns `true` to advance or\n\t\t * an error string to surface above the step and block navigation.\n\t\t *\n\t\t * @param {string} stepId The active step id.\n\t\t * @return {Promise<boolean|string>} True to advance, or an error message.\n\t\t */\n\t\tasync validateStep(stepId) {\n\t\t\tconst step = this.setupSteps.find((s) => s.id === stepId)\n\t\t\tif (!step) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (step.type === 'choice') {\n\t\t\t\tif (!this.hasChoice(step)) {\n\t\t\t\t\t// Already persisted server-side and the user only back-navigated\n\t\t\t\t\t// onto it — `choiceModel` is blank because it's session-local, not\n\t\t\t\t\t// because nothing is set. Don't force a re-pick, and don't re-POST.\n\t\t\t\t\tif (this.isServerDone(step.id)) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t\treturn step.required === true\n\t\t\t\t\t\t? t('nextcloud-vue', 'Please make a selection to continue.')\n\t\t\t\t\t\t: true\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait this.saveConfig({ [step.configKey]: this.scalarChoice(step) })\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t\treturn true\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn this.errorMessage(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (step.type === 'config-fields') {\n\t\t\t\ttry {\n\t\t\t\t\tconst patch = {}\n\t\t\t\t\tfor (const field of this.fieldsFor(step)) {\n\t\t\t\t\t\tpatch[field.key] = this.configModel[field.key]\n\t\t\t\t\t}\n\t\t\t\t\tawait this.saveConfig(patch)\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t\treturn true\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn this.errorMessage(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (step.type === 'run-action' && step.required === true && !this.isStepDone(step.id)) {\n\t\t\t\treturn t('nextcloud-vue', 'Please run this step before continuing.')\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\n\t\t/**\n\t\t * Persist one or more app-config values via the setup contract.\n\t\t *\n\t\t * @param {object} patch `{ <configKey>: value }` to write.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync saveConfig(patch) {\n\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\timport('@nextcloud/router'),\n\t\t\t])\n\t\t\tawait axios.post(generateUrl(`/apps/${this.appId}/api/setup/config`), patch)\n\t\t},\n\n\t\tasync runAction(step) {\n\t\t\tthis.running[step.id] = true\n\t\t\tthis.actionResult[step.id] = null\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst { data } = await axios.post(generateUrl(`/apps/${this.appId}/api/setup/action/${step.action}`))\n\t\t\t\tconst result = {\n\t\t\t\t\tsuccess: data && data.success !== false,\n\t\t\t\t\tmessage: (data && data.message) || t('nextcloud-vue', 'Done.'),\n\t\t\t\t}\n\t\t\t\tthis.actionResult[step.id] = result\n\t\t\t\tif (result.success) {\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * @event action-result Emitted when a `run-action` step finishes.\n\t\t\t\t * @type {{ stepId: string, action: string, success: boolean, message: string }}\n\t\t\t\t */\n\t\t\t\tthis.$emit('action-result', { stepId: step.id, action: step.action, ...result })\n\t\t\t} catch (err) {\n\t\t\t\tthis.actionResult[step.id] = { success: false, message: this.errorMessage(err) }\n\t\t\t\tthis.$emit('action-result', { stepId: step.id, action: step.action, success: false, message: this.errorMessage(err) })\n\t\t\t} finally {\n\t\t\t\tthis.running[step.id] = false\n\t\t\t}\n\t\t},\n\n\t\tisStepDone(id) {\n\t\t\treturn this.isServerDone(id) || this.localDone[id] === true || (this.actionResult[id] && this.actionResult[id].success)\n\t\t},\n\n\t\t/**\n\t\t * Whether the server already reported this step done in a prior\n\t\t * session, via the `completedStepIds` prop.\n\t\t *\n\t\t * @param {string} id Step id.\n\t\t * @return {boolean}\n\t\t */\n\t\tisServerDone(id) {\n\t\t\treturn this.completedStepIds.includes(id)\n\t\t},\n\n\t\tonSubmit() {\n\t\t\tif (this.$refs.wizard && this.$refs.wizard.setResult) {\n\t\t\t\tthis.$refs.wizard.setResult({ success: true, message: this.successText })\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event complete Emitted when the last step is submitted (setup finished).\n\t\t\t */\n\t\t\tthis.$emit('complete')\n\t\t},\n\n\t\tonStepChange(payload) {\n\t\t\t// Pre-fill a suggested default when entering a step that derives one.\n\t\t\tconst step = this.setupSteps.find((s) => s.id === payload.stepId)\n\t\t\tif (step && step.suggestFrom) {\n\t\t\t\tthis.applySuggestion(step)\n\t\t\t}\n\t\t\tthis.maybeAutoRunStep(payload.stepId)\n\t\t\t/**\n\t\t\t * @event step-change Emitted when the active step changes.\n\t\t\t * @type {{ stepId: string, stepIndex: number, direction: string }}\n\t\t\t */\n\t\t\tthis.$emit('step-change', payload)\n\t\t},\n\n\t\tonClose() {\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\n\t\terrorMessage(err) {\n\t\t\tconst data = err && err.response && err.response.data\n\t\t\tif (data && (data.message || data.error)) {\n\t\t\t\treturn data.message || data.error\n\t\t\t}\n\t\t\treturn (err && err.message) || t('nextcloud-vue', 'Something went wrong.')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-setup-step {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n.cn-setup-step__nav {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tgap: 8px;\n\tmargin-top: 8px;\n}\n\n.cn-setup-step__running {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 8px;\n\tpadding: 24px 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-setup-field {\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.cn-setup-summary {\n\tlist-style: none;\n\tpadding: 0;\n\tmargin: 0;\n}\n\n.cn-setup-summary__item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 4px 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-setup-summary__item--done {\n\tcolor: var(--color-main-text);\n}\n\n.cn-setup-summary__mark {\n\tfont-weight: bold;\n\tcolor: var(--color-success);\n}\n\n.cn-setup-summary__label {\n\tflex: 0 0 auto;\n}\n\n.cn-setup-summary__value {\n\tmargin-inline-start: auto;\n\tfont-weight: 600;\n\tcolor: var(--color-main-text);\n}\n</style>\n"],"names":["CnWizardDialog","CnChoiceCards","t"],"mappings":";;;;;;;AA4JA;AACC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;;;AAIA;;AAED,aAAe;AACd,CAAA,IAAI,EAAE,eAAe;;CAErB,UAAU,EAAE;AACX,kBAAAA,UAAc;iBACdC,YAAa;AACb,EAAA,QAAQ;EACR,UAAU;AACV,EAAA,QAAQ;EACR,WAAW;AACX,EAAA,qBAAqB;EACrB,aAAa;EACb;;AAED,CAAA,MAAM,EAAE;AACP;;;;;;AAMC;;AAED,EAAA,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,KAAK,KAAK;EAC5C;;AAED,CAAA,KAAK,EAAE;AACN;AACA,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,MAAM;GACZ,QAAQ,EAAE,IAAI;GACd;;AAED;AACA,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,KAAK;AACX,GAAA,OAAO,EAAE,MAAM,EAAE;GACjB;;;EAGD,WAAW,EAAE;GACZ,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMC,SAAC,CAAC,eAAe,EAAE,iBAAiB,CAAC;GACpD;;AAED;;;;AAIC;;AAED,EAAA,OAAO,EAAE;GACR,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;EACA,WAAW,EAAE;GACZ,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,QAAQ,CAAC;GAC3C;;;EAGD,WAAW,EAAE;GACZ,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,QAAQ,CAAC;GAC3C;;AAED;EACA,SAAS,EAAE;GACV,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,MAAM,CAAC;GACzC;;AAED;EACA,SAAS,EAAE;GACV,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,MAAM,CAAC;GACzC;;;AAGD,EAAA,QAAQ,EAAE;GACT,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,KAAK,CAAC;GACxC;;;EAGD,UAAU,EAAE;GACX,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,WAAW,CAAC;GAC9C;;;EAGD,YAAY,EAAE;GACb,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,UAAU,CAAC;GAC7C;;;EAGD,WAAW,EAAE;GACZ,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,iBAAiB,CAAC;GACpD;;AAED;;;;;;AAMC;AACA;;EAED,WAAW,EAAE;GACZ,IAAI,EAAE,OAAO;GACb,OAAO,EAAE,IAAI;GACb;;AAED;AACC;;;;;;AAMA;AACA;AACA;;AAED,EAAA,gBAAgB,EAAE;GACjB,IAAI,EAAE,KAAK;AACX,GAAA,OAAO,EAAE,MAAM,EAAE;GACjB;EACD;;CAED,KAAK,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,CAAC;;AAE5D;;;;;AAKC;AACA;AACA;;AAEA;AACA;AACA;;CAED,KAAK,CAAC,KAAK,EAAE;AACZ,EAAA,MAAM,WAAY,GAAE,CAAC,KAAK,CAAC,KAAI,IAAK,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAE,IAAG,CAAC,CAAC,aAAa,EAAA;AACxE,EAAA,IAAI,CAAC,WAAW,EAAE;AACjB,GAAA,OAAO,EAAC;AACT,GAAA;AACA,EAAA,MAAM,EAAE,MAAM,EAAE,OAAM,KAAM,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAI,IAAK,EAAA;EACzF,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAQ,EAAA;EAC1D;;AAED,CAAA,IAAI,GAAG;AACN,EAAA,OAAO;AACN,GAAA,WAAW,EAAE,EAAE;AACf,GAAA,YAAY,EAAE,EAAE;AAChB,GAAA,WAAW,EAAE,EAAE;GACf,OAAO,EAAE,EAAE;AACX,GAAA,YAAY,EAAE,EAAE;GAChB,SAAS,EAAE,EAAE;AACb,GAAA,WAAW,EAAE,EAAE;AAChB,GAAA;EACA;;AAED,CAAA,QAAQ,EAAE;AACT;;;;AAIC;AACA;;AAED,EAAA,mBAAmB,GAAG;AACrB,GAAA,OAAO,IAAI,CAAC,OAAM;MACfA,SAAC,CAAC,eAAe,EAAE,cAAc,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,OAAM,EAAG,CAAA;AAC1D,MAAE,IAAI,CAAC,WAAU;GAClB;;EAED,UAAU,GAAG;GACZ,OAAO,CAAC,IAAI,CAAC,KAAM,IAAG,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAA,IAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAA;GAC3D;;EAED,WAAW,GAAG;AACb,GAAA,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM;AAClC,IAAA,EAAE,EAAE,CAAC,CAAC,EAAE;IACR,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACxB,QAAQ,EAAE,CAAC,CAAC,QAAS,KAAI,IAAI;AAC9B,IAAC,CAAC,CAAA;GACF;;AAED;;;;AAIC;AACA;AACA;;AAED,EAAA,YAAY,GAAG;AACd,GAAA,OAAO,IAAI,CAAC,UAAS;AACpB,KAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAG,KAAM,SAAS,CAAA;KAClC,GAAG,CAAC,CAAC,IAAI,KAAK;KACd,IAAI,KAAI,GAAI,GAAC;KACb,IAAI,IAAI,CAAC,IAAG,KAAM,QAAQ,EAAE;AAC3B,MAAA,MAAM,GAAI,GAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAA;MACpC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;OACvB,KAAI,GAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAA;OAC1D,MAAK,IAAI,GAAE,KAAM,QAAQ,GAAE,KAAM,SAAQ,IAAK,GAAI,KAAI,EAAE,EAAE;AAC3D,OAAA,KAAI,GAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,EAAA;AACnC,OAAA;AACD,MAAA,MAAO,IAAI,IAAI,CAAC,IAAK,KAAI,eAAe,EAAE;MACzC,KAAI,GAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAA;QACzB,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAE,KAAI,IAAG,IAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAE,KAAI,YAAY,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAA,GAAI,EAAE,CAAC,CAAC,CAAA;AACrI,QAAC,IAAI,CAAC,IAAI,EAAA;AACZ,MAAA;AACA,KAAA,IAAI,KAAG;KACP,IAAI,IAAI,CAAC,SAAS,MAAM,EAAE;AACzB,MAAA,IAAG,GAAI,KAAG;MACT,MAAK,IAAI,IAAI,CAAC,IAAK,KAAI,QAAQ,EAAE;MAClC,IAAK,GAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAE,IAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAA;MACvD,MAAK;MACN,IAAG,GAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAA;AAC/B,MAAA;KACA,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAK,EAAA;KAC/D,CAAA;GACF;;AAED;;;;AAIC;;AAEA;AACA;;AAED,EAAA,aAAa,GAAG;;;;AAIf,GAAA,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAO,KAAI,CAAC,EAAE;AACvC,IAAA,OAAO,EAAC;AACT,IAAA;AACA,GAAA,MAAM,UAAW,GAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAK,KAAI,MAAK,IAAK,CAAC,CAAC,SAAS,SAAS,EAAA;GAC1F,MAAM,eAAc,GAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK;AACnD,IAAA,IAAI,CAAC,CAAC,IAAK,KAAI,QAAQ,EAAE;KACxB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA,IAAK,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AACtD,KAAA;IACA,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;IAC5B,EAAA;;;;;GAKD,IAAI,mBAAmB,CAAC,EAAE;AACzB,IAAA,OAAO,EAAC;AACT,IAAA;AACA,GAAA,OAAO,UAAU,CAAC,eAAe,CAAC,CAAC,EAAC;GACpC;EACD;;AAED,CAAA,OAAO,GAAG;;;;AAIT,EAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAA,IAAK,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAA;EACzF;;AAED,CAAA,OAAO,EAAE;AACR;;;;;;;AAOC;AACA;;;EAGD,gBAAgB,CAAC,MAAM,EAAE;GACxB,MAAM,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAC,KAAM,MAAM,EAAA;AACxD,GAAA,IAAI,QAAQ,IAAI,CAAC,SAAS,YAAW,IAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAE,IAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;AAC9F,IAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAA;AACpB,IAAA;GACA;;AAED;;AAEC;AACA;;;;;;;;AAQA;;AAEA;AACA;;;;AAID,EAAA,SAAS,CAAC,IAAI,EAAE;GACf,MAAM,GAAE,GAAI,CAAC,IAAG,IAAK,IAAI,CAAC,KAAK,MAAM,IAAK,IAAG,IAAI,CAAC,EAAE,CAAA,IAAK,GAAC;AAC1D,GAAA,OAAO,GAAE,KAAM,EAAC,GAAI,KAAK,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;GAC7C;;AAED;;AAEC;AACA;;;;;;;;AAQA;AACA;AACA;;AAED,EAAA,QAAQ,CAAC,IAAI,EAAE;GACd,MAAM,GAAE,GAAI,CAAC,IAAG,IAAK,IAAI,CAAC,IAAI,KAAK,GAAC;AACpC,GAAA,OAAO,GAAE,KAAM,EAAC,GAAI,KAAK,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;GAC7C;;AAED,EAAA,QAAQ,CAAC,IAAI,EAAE;AACd,GAAA,OAAO,UAAU,IAAI,CAAC,EAAC;GACvB;;AAED,EAAA,aAAa,CAAC,EAAE,EAAE;GACjB,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAQ,GAAE,EAAE,CAAA,IAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAM,GAAI,EAAE,CAAA;GAChE;;AAED,EAAA,SAAS,CAAC,IAAI,EAAE;AACf,GAAA,IAAI,IAAI,CAAC,UAAU,OAAO,IAAI,CAAC,MAAO,KAAI,QAAQ,EAAE;AACnD,IAAA,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAA;AACrE,IAAA;;AAEA,GAAA,OAAO,CAAC,IAAI,CAAC,UAAW,IAAG,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAK,EAAG,CAAC,CAAA;GACjF;;AAED;;;;;AAKC;AACA;AACA;AACA;;AAED,EAAA,UAAU,CAAC,IAAI,EAAE;GAChB,IAAI,OAAQ,GAAE,IAAI,CAAC,OAAM,IAAK,GAAC;GAC/B,IAAI,IAAI,CAAC,aAAa,EAAE;AACvB,IAAA,OAAM,GAAI,IAAI,CAAC,cAAc,CAAC,IAAI,EAAA;AACnC,IAAA,MAAO,IAAI,IAAI,CAAC,SAAQ,IAAK,IAAI,CAAC,eAAe,EAAE;IAClD,MAAM,WAAY,GAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAA;AACpD,IAAA,OAAQ,GAAE,CAAC,WAAY,KAAI,IAAK,IAAG,WAAY,KAAI,SAAU,IAAG,WAAY,KAAI,EAAE;AACjF,OAAE,EAAC;AACH,QAAG,IAAI,CAAC,eAAe,CAAC,WAAW,KAAK,EAAE,EAAA;AAC5C,IAAA;;;;;;AAMA;GACA,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK;IAC9B,IAAI,CAAC,MAAK,IAAK,OAAO,MAAO,KAAI,QAAS,IAAG,CAAC,MAAM,CAAC,KAAK,EAAE;KAC3D,OAAO,MAAK;AACb,KAAA;AACA,IAAA,MAAM,UAAS,GAAI,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAE,GAAA;IACtE,IAAI,MAAM,CAAC,WAAW,EAAE;KACvB,UAAU,CAAC,WAAY,GAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,EAAA;AAC7D,KAAA;AACA,IAAA,OAAO,UAAS;IAChB,CAAA;GACD;;AAED;;;AAGC;;;;;AAKA;AACA;;;;AAID,EAAA,cAAc,CAAC,IAAI,EAAE;GACpB,IAAI,IAAK,GAAE,IAAI,CAAC,YAAU;GAC1B,KAAK,MAAM,GAAE,IAAK,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IACxD,IAAI,SAAS,QAAQ,IAAG,KAAM,SAAU,IAAG,OAAO,IAAK,KAAI,QAAQ,EAAE;AACpE,KAAA,OAAO,EAAC;AACT,KAAA;IACA,IAAG,GAAI,IAAI,CAAC,GAAG,EAAA;AAChB,IAAA;GACA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AACzB,IAAA,OAAO,EAAC;AACT,IAAA;AACA,GAAA,OAAO,IAAG;KACR,MAAM,CAAC,CAAC,KAAK,KAAK,KAAM,IAAG,OAAO,KAAI,KAAM,QAAQ,CAAA;AACrD,KAAC,GAAG,CAAC,CAAC,KAAK,KAAK;KACf,MAAM,KAAM,GAAE,KAAK,CAAC,KAAM,KAAI,SAAQ,GAAI,KAAK,CAAC,KAAI,GAAI,KAAK,CAAC,GAAC;KAC/D,MAAM,MAAK,GAAI;AACd,MAAA,GAAG,KAAK;MACR,KAAK;AACL,MAAA,KAAK,EAAE,KAAK,CAAC,SAAS,KAAK,CAAC,IAAK,IAAG,MAAM,CAAC,KAAK,CAAC;AAClD,OAAA;AACA,KAAA,IAAI,CAAC,MAAM,CAAC,SAAS,OAAO,KAAK,CAAC,WAAU,KAAM,QAAS,IAAG,KAAK,CAAC,WAAY,GAAE,CAAC,EAAE;AACpF,MAAA,MAAM,CAAC,KAAM,GAAE,CAAC,EAAE,KAAK,EAAEA,SAAC,CAAC,eAAe,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,aAAa,EAAA;AACnF,MAAA;KACA,OAAO,MAAK;KACZ,CAAA;AACD,KAAC,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,UAAU,SAAS,CAAA;GAC/C;;AAED;;AAEC;AACA;AACA;;AAED,EAAA,YAAY,CAAC,IAAI,EAAE;GAClB,OAAO,IAAI,CAAC,OAAM,KAAM,OAAM;GAC9B;;AAED;;AAEC;AACA;;;EAGD,gBAAgB,CAAC,IAAI,EAAE;GACtB,OAAO,CAAC,CAAC,IAAI,CAAC,aAAY,IAAK,IAAI,CAAC,kBAAmB,KAAI,IAAG;GAC9D;;AAED;;;AAGC;AACA;AACA;AACA;;AAED,EAAA,SAAS,CAAC,IAAI,EAAE;AACf,GAAA,MAAM,KAAM,GAAE,IAAI,CAAC,YAAY,CAAC,IAAI,EAAA;GACpC,IAAI,IAAI,CAAC,aAAa,IAAI,EAAE;AAC3B,IAAA,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAA,GAAI,KAAI,GAAI,EAAC;AACxC,IAAA;AACA,GAAA,OAAO,KAAI,KAAM,YAAY,IAAK,GAAE,KAAI;GACxC;;EAED,gBAAgB,CAAC,IAAI,EAAE;AACtB,GAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;IACpB,OAAO,KAAI;AACZ,IAAA;GACA,MAAM,WAAY,GAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAA;AACpD,GAAA,OAAO,WAAY,KAAI,IAAG,IAAK,WAAU,KAAM,SAAU,IAAG,WAAU,KAAM,EAAC;GAC7E;;AAED,EAAA,aAAa,CAAC,IAAI,EAAE;AACnB,GAAA,MAAM,MAAK,GAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAU,KAAI,IAAI,CAAC,SAAS,EAAA;GACzE,MAAM,KAAM,GAAE,MAAO,IAAG,MAAM,CAAC,KAAI,IAAK,MAAM,CAAC,EAAE,IAAI,IAAI,CAAC,UAAQ;GAClE,OAAOA,SAAC,CAAC,eAAe,EAAE,wBAAwB,EAAE,EAAE,IAAI,EAAE,KAAI,EAAG,CAAA;GACnE;;AAED;AACC;AACA;;;;;AAKA;AACA;AACA;;AAEA;;EAED,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE;GACxB,IAAI,KAAI,IAAK,OAAO,UAAU,QAAO,IAAK,KAAK,CAAC,KAAK,EAAE;AACtD,IAAA,OAAO,KAAK,CAAC,KAAI;AAClB,IAAA;AACA,GAAA,MAAM,KAAI,GAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAE,IAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,MAAM,CAAC,KAAK,CAAC,EAAA;GACtF,OAAO,CAAC,KAAI,IAAK,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAI,GAAI,MAAM,CAAC,KAAK,CAAA;GAC1D;;AAED,EAAA,SAAS,CAAC,IAAI,EAAE;AACf,GAAA,MAAM,CAAE,GAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAA;GAClC,IAAI,IAAI,CAAC,aAAa,IAAI,EAAE;AAC3B,IAAA,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA,IAAK,CAAC,CAAC,SAAS,CAAA;AACvC,IAAA;AACA,GAAA,OAAO,CAAE,KAAI,IAAK,IAAG,CAAE,KAAI,SAAQ,IAAK,CAAA,KAAM,EAAC;GAC/C;;AAED,EAAA,YAAY,CAAC,IAAI,EAAE;AAClB,GAAA,MAAM,GAAI,GAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAA;GACpC,IAAI,IAAI,CAAC,aAAa,IAAI,EAAE;IAC3B,OAAO,CAAC,GAAE,IAAK,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAA,IAAK,CAAC,CAAC,KAAI,KAAM,SAAQ,GAAI,CAAC,CAAC,KAAI,GAAI,CAAC,CAAC,CAAA;AACzE,IAAA;AACA,GAAA,OAAO,GAAI,IAAG,GAAG,CAAC,UAAU,YAAY,GAAG,CAAC,KAAM,GAAE,GAAE;GACtD;;AAED,EAAA,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE;GACrB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAE,GAAE,KAAG;AAC/B,GAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAA,GAAI,MAAI;AAChC,GAAA,IAAI,IAAI,CAAC,SAAS,EAAE;IACnB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAA,GAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAA;AAC3D,IAAA;;AAEA,GAAA,KAAK,MAAM,SAAS,IAAI,CAAC,UAAU,EAAE;IACpC,IAAI,KAAK,CAAC,SAAU,IAAG,KAAK,CAAC,SAAU,KAAI,IAAI,CAAC,SAAS,EAAE;KAC1D,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAE,GAAE,KAAK,CAAC,QAAO,KAAM,IAAG,GAAI,EAAG,GAAE,KAAG;AAC/D,KAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAE,GAAE,MAAI;AACjC,KAAA,IAAI,KAAK,CAAC,SAAS,EAAE;AACpB,MAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,CAAA,GAAI,GAAC;AACvC,MAAA;AACD,KAAA;AACD,IAAA;AACA;AACA,GAAA,KAAK,MAAM,GAAI,IAAG,IAAI,CAAC,UAAU,EAAE;IAClC,IAAI,GAAG,CAAC,WAAY,IAAG,GAAG,CAAC,WAAY,KAAI,IAAI,CAAC,SAAS,EAAE;KAC1D,IAAI,CAAC,eAAe,CAAC,GAAG,EAAA;AACzB,KAAA;AACD,IAAA;GACA;;AAED;;AAEC;;AAEA;AACA;AACA;;;AAGD,EAAA,eAAe,CAAC,IAAI,EAAE;AACrB,GAAA,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAE,KAAI,IAAI,EAAE;IACvC,MAAK;AACN,IAAA;GACA,MAAM,cAAc,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,EAAA;AACtD,GAAA,IAAI,WAAY,KAAI,IAAG,IAAK,WAAU,KAAM,SAAQ,IAAK,WAAU,KAAM,EAAE,EAAE;IAC5E,MAAK;AACN,IAAA;AACA,GAAA,MAAM,SAAS,CAAC,IAAI,CAAC,UAAS,IAAK,EAAE,EAAE,WAAW,EAAA;AAClD,GAAA,IAAI,MAAO,KAAI,QAAQ,MAAO,KAAI,SAAS,EAAE;IAC5C,MAAK;AACN,IAAA;GACA,MAAM,GAAE,GAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,MAAM,CAAE,IAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAE,GAAA;GAC5G,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAA,GAAI,IAAE;AAC9B,GAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AACnB,IAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAE,GAAE,OAAK;AAC1C,IAAA;GACA;;AAED;;;;;;;AAOC;AACA;AACA;;EAED,MAAM,YAAY,CAAC,MAAM,EAAE;GAC1B,MAAM,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAC,KAAM,MAAM,EAAA;AACxD,GAAA,IAAI,CAAC,IAAI,EAAE;AACV,IAAA,OAAO,IAAG;AACX,IAAA;GACA,IAAI,IAAI,CAAC,IAAG,KAAM,QAAQ,EAAE;IAC3B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;;;;AAI1B,KAAA,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;AAC/B,MAAA,OAAO,IAAG;AACX,MAAA;KACA,OAAO,IAAI,CAAC,QAAO,KAAM,IAAG;QACzBA,SAAC,CAAC,eAAe,EAAE,sCAAsC,CAAA;QACzD,IAAG;AACP,KAAA;AACA,IAAA,IAAI;AACH,KAAA,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,EAAA;KACnE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAE,GAAE,KAAG;AAC7B,KAAA,OAAO,IAAG;KACT,CAAA,OAAO,GAAG,EAAE;KACb,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAA;AAC7B,KAAA;AACD,IAAA;AACA,GAAA,IAAI,IAAI,CAAC,IAAK,KAAI,eAAe,EAAE;AAClC,IAAA,IAAI;KACH,MAAM,KAAM,GAAE,GAAC;AACf,KAAA,KAAK,MAAM,KAAM,IAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;AACzC,MAAA,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,EAAA;AAC9C,MAAA;KACA,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAA;KAC3B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAE,GAAE,KAAG;AAC7B,KAAA,OAAO,IAAG;KACT,CAAA,OAAO,GAAG,EAAE;KACb,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAA;AAC7B,KAAA;AACD,IAAA;AACA,GAAA,IAAI,IAAI,CAAC,IAAK,KAAI,YAAa,IAAG,IAAI,CAAC,QAAS,KAAI,IAAK,IAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;IACtF,OAAOA,SAAC,CAAC,eAAe,EAAE,yCAAyC,CAAA;AACpE,IAAA;AACA,GAAA,OAAO,IAAG;GACV;;AAED;;AAEC;;;;EAID,MAAM,UAAU,CAAC,KAAK,EAAE;GACvB,MAAM,CAAC,EAAE,OAAO,EAAE,KAAI,EAAG,EAAE,EAAE,WAAU,EAAG,CAAE,GAAE,MAAM,OAAO,CAAC,GAAG,CAAC;IAC/D,OAAO,kBAAkB,CAAC;IAC1B,OAAO,mBAAmB,CAAC;IAC3B,EAAA;AACD,GAAA,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAA;GAC3E;;AAED,EAAA,MAAM,SAAS,CAAC,IAAI,EAAE;GACrB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAE,GAAE,KAAG;AAC3B,GAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAE,GAAE,KAAG;AAChC,GAAA,IAAI;IACH,MAAM,CAAC,EAAE,OAAO,EAAE,KAAI,EAAG,EAAE,EAAE,WAAU,EAAG,CAAE,GAAE,MAAM,OAAO,CAAC,GAAG,CAAC;KAC/D,OAAO,kBAAkB,CAAC;KAC1B,OAAO,mBAAmB,CAAC;KAC3B,EAAA;IACD,MAAM,EAAE,IAAK,EAAA,GAAI,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAA;IACpG,MAAM,MAAK,GAAI;AACd,KAAA,OAAO,EAAE,IAAG,IAAK,IAAI,CAAC,OAAM,KAAM,KAAK;KACvC,OAAO,EAAE,CAAC,IAAG,IAAK,IAAI,CAAC,OAAO,KAAKA,SAAC,CAAC,eAAe,EAAE,OAAO,CAAC;AAC/D,MAAA;AACA,IAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAA,GAAI,OAAK;AAClC,IAAA,IAAI,MAAM,CAAC,OAAO,EAAE;KACnB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAE,GAAE,KAAG;AAC9B,KAAA;AACA;;AAEC;;AAED,IAAA,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,EAAA;IAC9E,CAAA,OAAO,GAAG,EAAE;AACb,IAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAA,GAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAE,GAAA;IAC/E,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAA,EAAG,EAAA;AACtH,IAAA,SAAU;IACT,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,MAAI;AAC7B,IAAA;GACA;;AAED,EAAA,UAAU,CAAC,EAAE,EAAE;GACd,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,EAAE,CAAA,KAAM,IAAG,KAAM,IAAI,CAAC,YAAY,CAAC,EAAE,CAAA,IAAK,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAA;GACtH;;AAED;;AAEC;AACA;;AAEA;;AAED,EAAA,YAAY,CAAC,EAAE,EAAE;AAChB,GAAA,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAA;GACxC;;EAED,QAAQ,GAAG;GACV,IAAI,IAAI,CAAC,KAAK,CAAC,MAAO,IAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE;AACrD,IAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,EAAA;AACzE,IAAA;AACA;AACC;;AAED,GAAA,IAAI,CAAC,KAAK,CAAC,UAAU,EAAA;GACrB;;AAED,EAAA,YAAY,CAAC,OAAO,EAAE;;GAErB,MAAM,IAAG,GAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAG,KAAI,OAAO,CAAC,MAAM,EAAA;GAChE,IAAI,QAAQ,IAAI,CAAC,WAAW,EAAE;IAC7B,IAAI,CAAC,eAAe,CAAC,IAAI,EAAA;AAC1B,IAAA;AACA,GAAA,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAA;AACpC;;;;AAIA,GAAA,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,OAAO,EAAA;GACjC;;AAED,EAAA,OAAO,GAAG;AACT;AACC;;AAED,GAAA,IAAI,CAAC,KAAK,CAAC,OAAO,EAAA;GAClB;;AAED,EAAA,YAAY,CAAC,GAAG,EAAE;AACjB,GAAA,MAAM,IAAK,GAAE,GAAE,IAAK,GAAG,CAAC,QAAS,IAAG,GAAG,CAAC,QAAQ,CAAC,KAAG;AACpD,GAAA,IAAI,IAAK,KAAI,IAAI,CAAC,OAAM,IAAK,IAAI,CAAC,KAAK,CAAC,EAAE;IACzC,OAAO,IAAI,CAAC,OAAM,IAAK,IAAI,CAAC,KAAI;AACjC,IAAA;AACA,GAAA,OAAO,CAAC,GAAI,IAAG,GAAG,CAAC,OAAO,KAAKA,SAAC,CAAC,eAAe,EAAE,uBAAuB,CAAA;GACzE;EACD;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"CnSetupWizard.vue2.js","sources":["../../../../src/components/CnSetupWizard/CnSetupWizard.vue"],"sourcesContent":["<!-- SPDX-License-Identifier: EUPL-1.2 -->\n<!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->\n<template>\n\t<CnWizardDialog\n\t\tref=\"wizard\"\n\t\t:steps=\"wizardSteps\"\n\t\t:dialogTitle=\"resolvedDialogTitle\"\n\t\t:submitLabel=\"submitLabel\"\n\t\t:cancelLabel=\"cancelLabel\"\n\t\t:nextLabel=\"nextLabel\"\n\t\t:backLabel=\"backLabel\"\n\t\t:successText=\"successText\"\n\t\t:validate=\"validateStep\"\n\t\t:cancellable=\"cancellable\"\n\t\t:initialStep=\"initialStepId\"\n\t\t@stepChange=\"onStepChange\"\n\t\t@submit=\"onSubmit\"\n\t\t@close=\"onClose\">\n\t\t<!-- This `<template v-for>` defines dynamic SLOTS, not a rendered list.\n\t\t `@vue/compiler-sfc` DISCARDS a `:key` on a slot-defining\n\t\t `<template>` (verified against the generated `createSlots` call)\n\t\t and honours it only on the child, so the rule's advice is inverted\n\t\t here — moving the key up would throw it away. -->\n\t\t<!-- eslint-disable vue/no-v-for-template-key-on-child -->\n\t\t<template v-for=\"step in setupSteps\" #[stepSlot(step)]=\"scope\">\n\t\t\t<div :key=\"step.id\" class=\"cn-setup-step\" :data-step-type=\"step.type\">\n\t\t\t\t<!-- @slot step-{id} Override a step's body (for `component` steps or\n\t\t\t\t any bespoke step). Scope: the CnWizardDialog step scope plus\n\t\t\t\t `{ step, runAction, saveConfig }`. -->\n\t\t\t\t<slot\n\t\t\t\t\tv-if=\"hasCustomSlot(step.id)\"\n\t\t\t\t\t:name=\"stepSlot(step)\"\n\t\t\t\t\tv-bind=\"scope\"\n\t\t\t\t\t:step=\"step\"\n\t\t\t\t\t:runAction=\"() => runAction(step)\"\n\t\t\t\t\t:saveConfig=\"(patch) => saveConfig(patch)\" />\n\n\t\t\t\t<!-- info -->\n\t\t\t\t<template v-else-if=\"step.type === 'info'\">\n\t\t\t\t\t<NcNoteCard type=\"info\" :heading=\"stepTitle(step)\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- choice -->\n\t\t\t\t<template v-else-if=\"step.type === 'choice'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<CnChoiceCards\n\t\t\t\t\t\tv-if=\"isCardChoice(step)\"\n\t\t\t\t\t\t:label=\"stepTitle(step)\"\n\t\t\t\t\t\t:options=\"optionsFor(step)\"\n\t\t\t\t\t\t:multiple=\"step.multiple === true\"\n\t\t\t\t\t\t:disabled=\"isChoiceDisabled(step)\"\n\t\t\t\t\t\t:loading=\"isOptionsLoading(step)\"\n\t\t\t\t\t\t:modelValue=\"cardModel(step)\"\n\t\t\t\t\t\t@update:modelValue=\"(v) => onChoice(step, v)\" />\n\t\t\t\t\t<NcSelect\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:inputLabel=\"stepTitle(step)\"\n\t\t\t\t\t\t:options=\"optionsFor(step)\"\n\t\t\t\t\t\t:multiple=\"step.multiple === true\"\n\t\t\t\t\t\t:disabled=\"isChoiceDisabled(step)\"\n\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t:modelValue=\"choiceModel[step.id]\"\n\t\t\t\t\t\t@update:modelValue=\"(v) => onChoice(step, v)\" />\n\t\t\t\t\t<NcNoteCard v-if=\"isChoiceDisabled(step)\" type=\"warning\">\n\t\t\t\t\t\t{{ dependsOnHint(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- config-fields -->\n\t\t\t\t<template v-else-if=\"step.type === 'config-fields'\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-for=\"field in fieldsFor(step)\"\n\t\t\t\t\t\t:key=\"field.key\"\n\t\t\t\t\t\tclass=\"cn-setup-field\">\n\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\tv-if=\"field.widget === 'checkbox'\"\n\t\t\t\t\t\t\t:modelValue=\"!!configModel[field.key]\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\">\n\t\t\t\t\t\t\t{{ field.label }}\n\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\tv-else-if=\"field.widget === 'select'\"\n\t\t\t\t\t\t\t:inputLabel=\"field.label\"\n\t\t\t\t\t\t\t:options=\"field.enum || []\"\n\t\t\t\t\t\t\t:modelValue=\"configModel[field.key]\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\" />\n\t\t\t\t\t\t<NcTextField\n\t\t\t\t\t\t\tv-else\n\t\t\t\t\t\t\t:label=\"field.label\"\n\t\t\t\t\t\t\t:type=\"field.widget === 'number' ? 'number' : 'text'\"\n\t\t\t\t\t\t\t:modelValue=\"configModel[field.key] != null ? String(configModel[field.key]) : ''\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\" />\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- run-action -->\n\t\t\t\t<template v-else-if=\"step.type === 'run-action'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<!-- The action starts automatically on entering this step\n\t\t\t\t\t (see `maybeAutoRunStep`), so the default state is the\n\t\t\t\t\t spinner, not an idle button. -->\n\t\t\t\t\t<div v-if=\"running[step.id]\" class=\"cn-setup-step__running\">\n\t\t\t\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t\t\t\t<span>{{ runningLabel }}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<template v-else>\n\t\t\t\t\t\t<NcNoteCard\n\t\t\t\t\t\t\tv-if=\"actionResult[step.id]\"\n\t\t\t\t\t\t\t:type=\"actionResult[step.id].success ? 'success' : 'error'\">\n\t\t\t\t\t\t\t{{ actionResult[step.id].message }}\n\t\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t\t<div class=\"cn-setup-step__nav\">\n\t\t\t\t\t\t\t<NcButton :variant=\"actionResult[step.id] ? 'secondary' : 'primary'\" @click=\"runAction(step)\">\n\t\t\t\t\t\t\t\t{{ actionResult[step.id] ? rerunLabel : runLabel }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- summary -->\n\t\t\t\t<template v-else-if=\"step.type === 'summary'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<ul class=\"cn-setup-summary\">\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tv-for=\"item in summaryItems\"\n\t\t\t\t\t\t\t:key=\"item.id\"\n\t\t\t\t\t\t\tclass=\"cn-setup-summary__item\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-setup-summary__item--done': item.done, 'cn-setup-summary__item--not-run': item.notRun }\">\n\t\t\t\t\t\t\t<span class=\"cn-setup-summary__mark\">{{ item.done ? '✓' : '○' }}</span>\n\t\t\t\t\t\t\t<span class=\"cn-setup-summary__label\">{{ item.title }}</span>\n\t\t\t\t\t\t\t<span v-if=\"item.value\" class=\"cn-setup-summary__value\">{{ item.value }}</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</template>\n\t\t<!-- eslint-enable vue/no-v-for-template-key-on-child -->\n\t</CnWizardDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcCheckboxRadioSwitch, NcLoadingIcon, NcNoteCard, NcSelect, NcTextField } from '@nextcloud/vue'\nimport CnChoiceCards from '../CnChoiceCards/CnChoiceCards.vue'\nimport CnWizardDialog from '../CnWizardDialog/CnWizardDialog.vue'\nimport { useSetupStatus } from '../../composables/useSetupStatus.js'\nimport { fieldsFromSchema } from '../../utils/schema.js'\n\n/**\n * CnSetupWizard — abstract, manifest-driven first-time setup wizard (ADR-042).\n *\n * Wraps {@link CnWizardDialog} and renders a `manifest.setup.steps[]` array by\n * each step's `type`: `info` (note), `config-fields` (fields from a JSON Schema\n * via `fieldsFromSchema`, the same field shapes the admin pages use), `choice`\n * (`NcSelect` persisting to an app-config key), `run-action` (POST a privileged\n * server action), `summary` (recap), and `component` (a parent-provided\n * `#step-<id>` slot). It NEVER writes OpenRegister objects from the browser —\n * all persistence goes through the per-app setup contract\n * (`POST /apps/{appId}/api/setup/config` and `/api/setup/action/{actionId}`).\n *\n * Mount it gated by `CnAppRoot`'s setup phase, or open it on demand from\n * `CnAdminSettingsShell`.\n *\n * ```vue\n * <CnSetupWizard\n * :app-id=\"'procest'\"\n * :steps=\"manifest.setup.steps\"\n * @complete=\"onSetupComplete\"\n * @close=\"showWizard = false\" />\n * ```\n */\nexport default {\n\tname: 'CnSetupWizard',\n\n\tcomponents: {\n\t\tCnWizardDialog,\n\t\tCnChoiceCards,\n\t\tNcButton,\n\t\tNcNoteCard,\n\t\tNcSelect,\n\t\tNcTextField,\n\t\tNcCheckboxRadioSwitch,\n\t\tNcLoadingIcon,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Consumer translation function, provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id). Step field\n\t\t * labels come from schema property titles, authored in English as the\n\t\t * canonical source; the visible label is resolved through this function\n\t\t * so it follows the user's language. Defaults to identity when used\n\t\t * standalone (no CnAppRoot ancestor).\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** The Nextcloud app id; used to build the `/apps/{appId}/api/setup/*` URLs. */\n\t\tappId: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** The `manifest.setup.steps` array to render. */\n\t\tsteps: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Dialog title. Overridden by `appName` when that prop is set. */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Set up this app'),\n\t\t},\n\n\t\t/**\n\t\t * The app's human-readable display name. When set, the dialog title\n\t\t * becomes \"Set up {appName}\" instead of the generic `dialogTitle`\n\t\t * default — pass the same display name CnAppRoot already resolves\n\t\t * (`appDisplayName || manifest.name || appId`).\n\t\t */\n\t\tappName: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Final-step submit button label. */\n\t\tsubmitLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Finish'),\n\t\t},\n\n\t\t/** Cancel button label. */\n\t\tcancelLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Cancel'),\n\t\t},\n\n\t\t/** Next button label. */\n\t\tnextLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Next'),\n\t\t},\n\n\t\t/** Back button label. */\n\t\tbackLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Back'),\n\t\t},\n\n\t\t/** Run-action button label (shown before the first automatic run). */\n\t\trunLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Run'),\n\t\t},\n\n\t\t/** Run-action button label offered after a run already finished. */\n\t\trerunLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Run again'),\n\t\t},\n\n\t\t/** Label shown next to the spinner while a run-action step is running. */\n\t\trunningLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Loading…'),\n\t\t},\n\n\t\t/** Result-phase success text. */\n\t\tsuccessText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Setup complete.'),\n\t\t},\n\n\t\t/**\n\t\t * Whether the wizard can be dismissed before finishing (Cancel\n\t\t * button, ESC, backdrop click). Pass `false` when a REQUIRED step\n\t\t * is unmet and the host is gating its shell behind this wizard\n\t\t * (ADR-042) — an offered-but-non-functional Cancel would be\n\t\t * misleading. Optional-only setup stays cancellable (default).\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 * Ids of steps the SERVER already reports as done (e.g.\n\t\t * `useSetupStatus(...).steps` filtered to `done === true`), passed by\n\t\t * the host so a freshly (re)mounted wizard doesn't re-ask something\n\t\t * already persisted in an earlier session — this component's own\n\t\t * `localDone`/`choiceModel` only track the CURRENT session and reset\n\t\t * blank on every mount. Drives both the initial step (`initialStepId`)\n\t\t * and the summary page's done markers.\n\t\t *\n\t\t * @type {Array<string>}\n\t\t */\n\t\tcompletedStepIds: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\t},\n\n\temits: ['complete', 'close', 'step-change', 'action-result'],\n\n\t/**\n\t * Live option lists come from the app's own setup status document, so a\n\t * step that offers a choice of things the SERVER ships never has to\n\t * restate them in the manifest. `useSetupStatus` caches per app id, so the\n\t * host's own status fetch (CnAppRoot's setup gate) is the one that runs —\n\t * this reads the same refs rather than asking again.\n\t *\n\t * Only called when a step actually declares `optionsSource`: a wizard with\n\t * none must not start making requests it never made before.\n\t *\n\t * @param {object} props The component props.\n\t * @return {object} `setupStatus` / `setupStatusLoading` for the option resolver.\n\t */\n\tsetup(props) {\n\t\tconst wantsSource = (props.steps || []).some((s) => s && s.optionsSource)\n\t\tif (!wantsSource) {\n\t\t\treturn {}\n\t\t}\n\t\tconst { status, loading } = useSetupStatus(props.appId, { setup: { steps: props.steps } })\n\t\treturn { setupStatus: status, setupStatusLoading: loading }\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tchoiceModel: {},\n\t\t\tchoiceValues: {},\n\t\t\tconfigModel: {},\n\t\t\trunning: {},\n\t\t\tactionResult: {},\n\t\t\tlocalDone: {},\n\t\t\tuserTouched: {},\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The title actually rendered by CnWizardDialog: \"Set up {appName}\"\n\t\t * when a display name was passed, otherwise whatever `dialogTitle`\n\t\t * resolves to (a caller override, or its own generic default).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedDialogTitle() {\n\t\t\treturn this.appName\n\t\t\t\t? t('nextcloud-vue', 'Set up {app}', { app: this.appName })\n\t\t\t\t: this.dialogTitle\n\t\t},\n\n\t\tsetupSteps() {\n\t\t\treturn (this.steps || []).filter((s) => s && s.id && s.type)\n\t\t},\n\n\t\twizardSteps() {\n\t\t\treturn this.setupSteps.map((s) => ({\n\t\t\t\tid: s.id,\n\t\t\t\tlabel: this.stepTitle(s),\n\t\t\t\toptional: s.required !== true,\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Recap rows for the `summary` step — one per non-summary step, with\n\t\t * the value the user selected (choice label / config field values) and\n\t\t * a done marker (info steps always done; choice steps done when picked;\n\t\t * run-action steps done when the action succeeded).\n\t\t *\n\t\t * An on-demand step (`onDemand: true`) is the exception: it is done\n\t\t * only when its action succeeded in THIS session. Apps report such a\n\t\t * step as `done` on purpose so it never auto-runs (learniq's \"Remove\n\t\t * the example data\"), and reading that flag here ticked a removal\n\t\t * nobody ran. When it did not run it gets `notRun: true` and the value\n\t\t * \"Not run\" instead.\n\t\t *\n\t\t * @return {Array<{ id: string, title: string, value: string, done: boolean, notRun: boolean }>}\n\t\t */\n\t\tsummaryItems() {\n\t\t\treturn this.setupSteps\n\t\t\t\t.filter((s) => s.type !== 'summary')\n\t\t\t\t.map((step) => {\n\t\t\t\t\tlet value = ''\n\t\t\t\t\tif (step.type === 'choice') {\n\t\t\t\t\t\tconst raw = this.choiceModel[step.id]\n\t\t\t\t\t\tif (Array.isArray(raw)) {\n\t\t\t\t\t\t\tvalue = raw.map((o) => this.choiceLabel(step, o)).join(', ')\n\t\t\t\t\t\t} else if (raw !== null && raw !== undefined && raw !== '') {\n\t\t\t\t\t\t\tvalue = this.choiceLabel(step, raw)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (step.type === 'config-fields') {\n\t\t\t\t\t\tvalue = this.fieldsFor(step)\n\t\t\t\t\t\t\t.map((f) => `${f.label}: ${this.configModel[f.key] !== null && this.configModel[f.key] !== undefined ? this.configModel[f.key] : ''}`)\n\t\t\t\t\t\t\t.join(', ')\n\t\t\t\t\t}\n\t\t\t\t\tif (this.isOnDemand(step)) {\n\t\t\t\t\t\tconst ran = this.ranThisSession(step.id)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: step.id,\n\t\t\t\t\t\t\ttitle: this.stepTitle(step),\n\t\t\t\t\t\t\tvalue: ran ? '' : t('nextcloud-vue', 'Not run'),\n\t\t\t\t\t\t\tdone: ran,\n\t\t\t\t\t\t\tnotRun: !ran,\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlet done\n\t\t\t\t\tif (step.type === 'info') {\n\t\t\t\t\t\tdone = true\n\t\t\t\t\t} else if (step.type === 'choice') {\n\t\t\t\t\t\tdone = this.hasChoice(step) || this.isServerDone(step.id)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdone = this.isStepDone(step.id)\n\t\t\t\t\t}\n\t\t\t\t\treturn { id: step.id, title: this.stepTitle(step), value, done, notRun: false }\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Id of the step the wizard should open on when RESUMING: the first\n\t\t * non-`info`/`summary` step not already done, per the CURRENT session's\n\t\t * local state OR the server-reported `completedStepIds` (a prior\n\t\t * session). Falls back to `''` (CnWizardDialog's own first-step default)\n\t\t * on a fresh setup and when every actionable step is already done.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tinitialStepId() {\n\t\t\t// Fresh setup — nothing done anywhere yet, so there is nothing to\n\t\t\t// resume past. Start at step one so a leading `info`/welcome step is\n\t\t\t// actually seen; resuming is only for returning sessions.\n\t\t\tif (this.completedStepIds.length === 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\t// An on-demand step is never outstanding work, so it is never the\n\t\t\t// step to resume on.\n\t\t\tconst actionable = this.setupSteps.filter((s) => s.type !== 'info' && s.type !== 'summary' && !this.isOnDemand(s))\n\t\t\tconst firstUnmetIndex = actionable.findIndex((s) => {\n\t\t\t\tif (s.type === 'choice') {\n\t\t\t\t\treturn !(this.hasChoice(s) || this.isServerDone(s.id))\n\t\t\t\t}\n\t\t\t\treturn !this.isStepDone(s.id)\n\t\t\t})\n\t\t\t// Done is not the same as seen: an app that pre-satisfies a step at\n\t\t\t// install time (buildiq seeds templates from a repair step) reports it\n\t\t\t// done before anyone opens the wizard. Only finished work BEFORE the\n\t\t\t// outstanding step means there is something to resume past.\n\t\t\tif (firstUnmetIndex <= 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn actionable[firstUnmetIndex].id\n\t\t},\n\t},\n\n\tmounted() {\n\t\t// Covers a RESUMED wizard opening straight onto its run-action step\n\t\t// (`initialStepId`) — `onStepChange` only fires on later navigation,\n\t\t// so a step already active at mount time needs its own trigger.\n\t\tthis.maybeAutoRunStep(this.initialStepId || (this.setupSteps[0] && this.setupSteps[0].id))\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Start a `run-action` step's action automatically the moment it\n\t\t * becomes current, instead of waiting for a manual \"Run\" click —\n\t\t * the step has nothing else for the user to decide by then (the\n\t\t * choice it acts on was already made on an earlier step), so\n\t\t * requiring a click before showing progress just adds a stall.\n\t\t * No-ops for any other step type, or one already run/running, and\n\t\t * never fires an on-demand step (`onDemand: true`): those run only\n\t\t * when the user clicks Run.\n\t\t *\n\t\t * @param {string} stepId The step id becoming current.\n\t\t * @return {void}\n\t\t */\n\t\tmaybeAutoRunStep(stepId) {\n\t\t\tconst step = this.setupSteps.find((s) => s.id === stepId)\n\t\t\tif (step && step.type === 'run-action' && !this.isOnDemand(step) && !this.isStepDone(step.id) && !this.running[step.id]) {\n\t\t\t\tthis.runAction(step)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The visible title for a step, resolved through the host app's\n\t\t * translation function.\n\t\t *\n\t\t * `manifest.setup.steps[].title` is authored in English as the\n\t\t * canonical source, exactly like the schema property titles this\n\t\t * component already routes through `cnTranslate` for field labels\n\t\t * (see `fieldsFromSchema` below). The step titles were the one\n\t\t * remaining place rendering the manifest string verbatim, so an\n\t\t * nl-locale user saw a wizard whose field labels were translated and\n\t\t * whose step headings were not.\n\t\t *\n\t\t * Falls back to the step id when a step declares no title, which is\n\t\t * the same fallback the raw bindings used.\n\t\t *\n\t\t * @param {object} step A `manifest.setup.steps[]` entry.\n\t\t * @return {string} The translated title, or the step id.\n\t\t */\n\t\tstepTitle(step) {\n\t\t\tconst raw = (step && step.title) || (step && step.id) || ''\n\t\t\treturn raw === '' ? '' : this.cnTranslate(raw)\n\t\t},\n\n\t\t/**\n\t\t * The visible body for a step, resolved through the host app's\n\t\t * translation function.\n\t\t *\n\t\t * 🔴 THIS USED TO RENDER THE MANIFEST STRING VERBATIM, IN FOUR PLACES.\n\t\t * `stepTitle()` was routed through `cnTranslate` and the body was not,\n\t\t * so a wizard on a Dutch instance showed a translated heading over an\n\t\t * English paragraph, with translated Cancel/Next buttons underneath.\n\t\t * That reads as a bug rather than as a missing string, and the app could\n\t\t * not fix it: decidiq shipped correct Dutch for its setup copy in\n\t\t * `l10n/nl.json`, and the component never asked for it.\n\t\t *\n\t\t * @param {object} step The step declaration.\n\t\t * @return {string} The translated body, or ''.\n\t\t */\n\t\tstepBody(step) {\n\t\t\tconst raw = (step && step.body) || ''\n\t\t\treturn raw === '' ? '' : this.cnTranslate(raw)\n\t\t},\n\n\t\tstepSlot(step) {\n\t\t\treturn 'step-' + step.id\n\t\t},\n\n\t\thasCustomSlot(id) {\n\t\t\treturn !!this.$slots['step-' + id] || !!this.$slots['step-' + id]\n\t\t},\n\n\t\tfieldsFor(step) {\n\t\t\tif (step.schema && typeof step.schema === 'object') {\n\t\t\t\treturn fieldsFromSchema(step.schema, { translate: this.cnTranslate })\n\t\t\t}\n\t\t\t// Fallback: a plain text field per declared config key.\n\t\t\treturn (step.configKeys || []).map((key) => ({ key, label: key, widget: 'text' }))\n\t\t},\n\n\t\t/**\n\t\t * Options for a `choice` step. When the step declares `dependsOn`\n\t\t * (a parent step's configKey) + `optionsByParent`, the option list\n\t\t * is the entry keyed by the parent's currently-selected value — this\n\t\t * is the country → organisation-type cascade. Otherwise the static\n\t\t * `options` array.\n\t\t *\n\t\t * @param {object} step The choice step definition.\n\t\t * @return {Array} The option list to render.\n\t\t */\n\t\toptionsFor(step) {\n\t\t\tlet options = step.options || []\n\t\t\tif (step.optionsSource) {\n\t\t\t\toptions = this.sourcedOptions(step)\n\t\t\t} else if (step.dependsOn && step.optionsByParent) {\n\t\t\t\tconst parentValue = this.choiceValues[step.dependsOn]\n\t\t\t\toptions = (parentValue === null || parentValue === undefined || parentValue === '')\n\t\t\t\t\t? []\n\t\t\t\t\t: (step.optionsByParent[parentValue] || [])\n\t\t\t}\n\t\t\t// The LABEL is translated, the VALUE never is. `scalarChoice()` reads\n\t\t\t// `.value` and that is what reaches `POST /api/setup/config`, so a\n\t\t\t// translated label cannot change what gets stored — while an\n\t\t\t// untranslated one leaves the choice itself in English on a\n\t\t\t// localised instance, which is the half-translated screen this fix\n\t\t\t// exists to remove.\n\t\t\treturn options.map((option) => {\n\t\t\t\tif (!option || typeof option !== 'object' || !option.label) {\n\t\t\t\t\treturn option\n\t\t\t\t}\n\t\t\t\tconst translated = { ...option, label: this.cnTranslate(option.label) }\n\t\t\t\tif (option.description) {\n\t\t\t\t\ttranslated.description = this.cnTranslate(option.description)\n\t\t\t\t}\n\t\t\t\treturn translated\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The option list a `choice` step declares `optionsSource` for, read\n\t\t * from the setup status document the app already serves.\n\t\t *\n\t\t * `optionsSource` names a key in that document (dots walk into nested\n\t\t * objects), and the entries are normalised to the option shape: `id` is\n\t\t * accepted for `value`, `name` for `label`, and a bare `objectCount`\n\t\t * becomes the one stat a card shows. A server that already sends\n\t\t * `stats` keeps them.\n\t\t *\n\t\t * @param {object} step The choice step declaring `optionsSource`.\n\t\t * @return {Array<object>} The options, or [] while the status is loading.\n\t\t */\n\t\tsourcedOptions(step) {\n\t\t\tlet node = this.setupStatus\n\t\t\tfor (const key of String(step.optionsSource).split('.')) {\n\t\t\t\tif (node === null || node === undefined || typeof node !== 'object') {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\tnode = node[key]\n\t\t\t}\n\t\t\tif (!Array.isArray(node)) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn node\n\t\t\t\t.filter((entry) => entry && typeof entry === 'object')\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tconst value = entry.value !== undefined ? entry.value : entry.id\n\t\t\t\t\tconst option = {\n\t\t\t\t\t\t...entry,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tlabel: entry.label || entry.name || String(value),\n\t\t\t\t\t}\n\t\t\t\t\tif (!option.stats && typeof entry.objectCount === 'number' && entry.objectCount > 0) {\n\t\t\t\t\t\toption.stats = [{ label: t('nextcloud-vue', 'Objects'), value: entry.objectCount }]\n\t\t\t\t\t}\n\t\t\t\t\treturn option\n\t\t\t\t})\n\t\t\t\t.filter((option) => option.value !== undefined)\n\t\t},\n\n\t\t/**\n\t\t * Whether a choice step renders as a card grid rather than a dropdown.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {boolean} True for `display: \"cards\"`.\n\t\t */\n\t\tisCardChoice(step) {\n\t\t\treturn step.display === 'cards'\n\t\t},\n\n\t\t/**\n\t\t * Whether this step is still waiting for its live option list.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {boolean} True while the status document is in flight.\n\t\t */\n\t\tisOptionsLoading(step) {\n\t\t\treturn !!step.optionsSource && this.setupStatusLoading === true\n\t\t},\n\n\t\t/**\n\t\t * The card grid's model: plain values, not the option objects NcSelect\n\t\t * binds. `scalarChoice` already reduces either shape to values, so both\n\t\t * renderers can share one `choiceModel` entry.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {unknown} The selected value, or [] / null when nothing is picked.\n\t\t */\n\t\tcardModel(step) {\n\t\t\tconst value = this.scalarChoice(step)\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn Array.isArray(value) ? value : []\n\t\t\t}\n\t\t\treturn value === undefined ? null : value\n\t\t},\n\n\t\tisChoiceDisabled(step) {\n\t\t\tif (!step.dependsOn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst parentValue = this.choiceValues[step.dependsOn]\n\t\t\treturn parentValue === null || parentValue === undefined || parentValue === ''\n\t\t},\n\n\t\tdependsOnHint(step) {\n\t\t\tconst parent = this.setupSteps.find((s) => s.configKey === step.dependsOn)\n\t\t\tconst label = parent ? (parent.title || parent.id) : step.dependsOn\n\t\t\treturn t('nextcloud-vue', 'Select \"{step}\" first.', { step: label })\n\t\t},\n\n\t\t/**\n\t\t * The visible label for one selected choice entry.\n\t\t *\n\t\t * A card grid stores plain VALUES where NcSelect stores option objects,\n\t\t * so the recap looked one up and printed the other: the summary read\n\t\t * \"municipality\" instead of \"Municipality\". Resolves a bare value back\n\t\t * to its option, and falls back to the value when the option list is\n\t\t * not (yet) available.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @param {unknown} entry One selected entry: an option object or a value.\n\t\t * @return {string} The label to show.\n\t\t */\n\t\tchoiceLabel(step, entry) {\n\t\t\tif (entry && typeof entry === 'object' && entry.label) {\n\t\t\t\treturn entry.label\n\t\t\t}\n\t\t\tconst match = this.optionsFor(step).find((o) => o && String(o.value) === String(entry))\n\t\t\treturn (match && match.label) ? match.label : String(entry)\n\t\t},\n\n\t\thasChoice(step) {\n\t\t\tconst v = this.choiceModel[step.id]\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn Array.isArray(v) && v.length > 0\n\t\t\t}\n\t\t\treturn v !== null && v !== undefined && v !== ''\n\t\t},\n\n\t\tscalarChoice(step) {\n\t\t\tconst raw = this.choiceModel[step.id]\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn (raw || []).map((o) => (o && o.value !== undefined ? o.value : o))\n\t\t\t}\n\t\t\treturn raw && raw.value !== undefined ? raw.value : raw\n\t\t},\n\n\t\tonChoice(step, value) {\n\t\t\tthis.userTouched[step.id] = true\n\t\t\tthis.choiceModel[step.id] = value\n\t\t\tif (step.configKey) {\n\t\t\t\tthis.choiceValues[step.configKey] = this.scalarChoice(step)\n\t\t\t}\n\t\t\t// Reset any dependent child choices when the parent changes.\n\t\t\tfor (const child of this.setupSteps) {\n\t\t\t\tif (child.dependsOn && child.dependsOn === step.configKey) {\n\t\t\t\t\tthis.choiceModel[child.id] = child.multiple === true ? [] : null\n\t\t\t\t\tthis.userTouched[child.id] = false\n\t\t\t\t\tif (child.configKey) {\n\t\t\t\t\t\tthis.choiceValues[child.configKey] = ''\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Re-apply auto-suggestions for steps that derive a default from this one.\n\t\t\tfor (const dep of this.setupSteps) {\n\t\t\t\tif (dep.suggestFrom && dep.suggestFrom === step.configKey) {\n\t\t\t\t\tthis.applySuggestion(dep)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Auto-fill a `choice` step's suggested default from an earlier choice\n\t\t * (its `suggestFrom` configKey → `suggestMap[parentValue]`). No-op once\n\t\t * the user has manually picked here, so a suggestion never clobbers an\n\t\t * explicit choice.\n\t\t *\n\t\t * @param {object} step The dependent choice step.\n\t\t * @return {void}\n\t\t */\n\t\tapplySuggestion(step) {\n\t\t\tif (this.userTouched[step.id] === true) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst parentValue = this.choiceValues[step.suggestFrom]\n\t\t\tif (parentValue === null || parentValue === undefined || parentValue === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst wanted = (step.suggestMap || {})[parentValue]\n\t\t\tif (wanted === null || wanted === undefined) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst opt = this.optionsFor(step).find((o) => o.value === wanted) || { value: wanted, label: String(wanted) }\n\t\t\tthis.choiceModel[step.id] = opt\n\t\t\tif (step.configKey) {\n\t\t\t\tthis.choiceValues[step.configKey] = wanted\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * CnWizardDialog `validate` hook — intercepts Next/Submit to persist\n\t\t * the active step before advancing. `choice`/`config-fields` steps\n\t\t * POST their value via the setup contract; required `choice` steps\n\t\t * block advance until a value is picked; required `run-action` steps\n\t\t * block until the action has succeeded. Returns `true` to advance or\n\t\t * an error string to surface above the step and block navigation.\n\t\t *\n\t\t * @param {string} stepId The active step id.\n\t\t * @return {Promise<boolean|string>} True to advance, or an error message.\n\t\t */\n\t\tasync validateStep(stepId) {\n\t\t\tconst step = this.setupSteps.find((s) => s.id === stepId)\n\t\t\tif (!step) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (step.type === 'choice') {\n\t\t\t\tif (!this.hasChoice(step)) {\n\t\t\t\t\t// Already persisted server-side and the user only back-navigated\n\t\t\t\t\t// onto it — `choiceModel` is blank because it's session-local, not\n\t\t\t\t\t// because nothing is set. Don't force a re-pick, and don't re-POST.\n\t\t\t\t\tif (this.isServerDone(step.id)) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t\treturn step.required === true\n\t\t\t\t\t\t? t('nextcloud-vue', 'Please make a selection to continue.')\n\t\t\t\t\t\t: true\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait this.saveConfig({ [step.configKey]: this.scalarChoice(step) })\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t\treturn true\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn this.errorMessage(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (step.type === 'config-fields') {\n\t\t\t\ttry {\n\t\t\t\t\tconst patch = {}\n\t\t\t\t\tfor (const field of this.fieldsFor(step)) {\n\t\t\t\t\t\tpatch[field.key] = this.configModel[field.key]\n\t\t\t\t\t}\n\t\t\t\t\tawait this.saveConfig(patch)\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t\treturn true\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn this.errorMessage(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (step.type === 'run-action' && step.required === true && !this.isStepDone(step.id)) {\n\t\t\t\treturn t('nextcloud-vue', 'Please run this step before continuing.')\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\n\t\t/**\n\t\t * Persist one or more app-config values via the setup contract.\n\t\t *\n\t\t * @param {object} patch `{ <configKey>: value }` to write.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync saveConfig(patch) {\n\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\timport('@nextcloud/router'),\n\t\t\t])\n\t\t\tawait axios.post(generateUrl(`/apps/${this.appId}/api/setup/config`), patch)\n\t\t},\n\n\t\tasync runAction(step) {\n\t\t\tthis.running[step.id] = true\n\t\t\tthis.actionResult[step.id] = null\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst { data } = await axios.post(generateUrl(`/apps/${this.appId}/api/setup/action/${step.action}`))\n\t\t\t\tconst result = {\n\t\t\t\t\tsuccess: data && data.success !== false,\n\t\t\t\t\tmessage: (data && data.message) || t('nextcloud-vue', 'Done.'),\n\t\t\t\t}\n\t\t\t\tthis.actionResult[step.id] = result\n\t\t\t\tif (result.success) {\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * @event action-result Emitted when a `run-action` step finishes.\n\t\t\t\t * @type {{ stepId: string, action: string, success: boolean, message: string }}\n\t\t\t\t */\n\t\t\t\tthis.$emit('action-result', { stepId: step.id, action: step.action, ...result })\n\t\t\t} catch (err) {\n\t\t\t\tthis.actionResult[step.id] = { success: false, message: this.errorMessage(err) }\n\t\t\t\tthis.$emit('action-result', { stepId: step.id, action: step.action, success: false, message: this.errorMessage(err) })\n\t\t\t} finally {\n\t\t\t\tthis.running[step.id] = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Whether a step is marked on-demand (`onDemand: true`): it runs only\n\t\t * when the user asks, never automatically, and the summary ticks it\n\t\t * only when it ran in this session.\n\t\t *\n\t\t * @param {object} step The manifest step.\n\t\t * @return {boolean}\n\t\t */\n\t\tisOnDemand(step) {\n\t\t\treturn !!step && step.onDemand === true\n\t\t},\n\n\t\t/**\n\t\t * Whether a step's action succeeded in the CURRENT session, ignoring\n\t\t * whatever the server reports.\n\t\t *\n\t\t * @param {string} id Step id.\n\t\t * @return {boolean}\n\t\t */\n\t\tranThisSession(id) {\n\t\t\treturn !!(this.actionResult[id] && this.actionResult[id].success)\n\t\t},\n\n\t\tisStepDone(id) {\n\t\t\treturn this.isServerDone(id) || this.localDone[id] === true || (this.actionResult[id] && this.actionResult[id].success)\n\t\t},\n\n\t\t/**\n\t\t * Whether the server already reported this step done in a prior\n\t\t * session, via the `completedStepIds` prop.\n\t\t *\n\t\t * @param {string} id Step id.\n\t\t * @return {boolean}\n\t\t */\n\t\tisServerDone(id) {\n\t\t\treturn this.completedStepIds.includes(id)\n\t\t},\n\n\t\tonSubmit() {\n\t\t\tif (this.$refs.wizard && this.$refs.wizard.setResult) {\n\t\t\t\tthis.$refs.wizard.setResult({ success: true, message: this.successText })\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event complete Emitted when the last step is submitted (setup finished).\n\t\t\t */\n\t\t\tthis.$emit('complete')\n\t\t},\n\n\t\tonStepChange(payload) {\n\t\t\t// Pre-fill a suggested default when entering a step that derives one.\n\t\t\tconst step = this.setupSteps.find((s) => s.id === payload.stepId)\n\t\t\tif (step && step.suggestFrom) {\n\t\t\t\tthis.applySuggestion(step)\n\t\t\t}\n\t\t\tthis.maybeAutoRunStep(payload.stepId)\n\t\t\t/**\n\t\t\t * @event step-change Emitted when the active step changes.\n\t\t\t * @type {{ stepId: string, stepIndex: number, direction: string }}\n\t\t\t */\n\t\t\tthis.$emit('step-change', payload)\n\t\t},\n\n\t\tonClose() {\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\n\t\terrorMessage(err) {\n\t\t\tconst data = err && err.response && err.response.data\n\t\t\tif (data && (data.message || data.error)) {\n\t\t\t\treturn data.message || data.error\n\t\t\t}\n\t\t\treturn (err && err.message) || t('nextcloud-vue', 'Something went wrong.')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-setup-step {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n.cn-setup-step__nav {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tgap: 8px;\n\tmargin-top: 8px;\n}\n\n.cn-setup-step__running {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 8px;\n\tpadding: 24px 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-setup-field {\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.cn-setup-summary {\n\tlist-style: none;\n\tpadding: 0;\n\tmargin: 0;\n}\n\n.cn-setup-summary__item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 4px 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-setup-summary__item--done {\n\tcolor: var(--color-main-text);\n}\n\n.cn-setup-summary__mark {\n\tfont-weight: bold;\n\tcolor: var(--color-success);\n}\n\n.cn-setup-summary__label {\n\tflex: 0 0 auto;\n}\n\n.cn-setup-summary__value {\n\tmargin-inline-start: auto;\n\tfont-weight: 600;\n\tcolor: var(--color-main-text);\n}\n\n/* An on-demand step that did not run says so quietly: it is a choice the\n user did not make, not a failure. */\n.cn-setup-summary__item--not-run .cn-setup-summary__value {\n\tfont-weight: normal;\n\tcolor: var(--color-text-maxcontrast);\n}\n</style>\n"],"names":["CnWizardDialog","CnChoiceCards","t"],"mappings":"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"}
|
|
@@ -206,7 +206,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
206
206
|
(openBlock(true), createElementBlock(Fragment, null, renderList($options.summaryItems, (item) => {
|
|
207
207
|
return (openBlock(), createElementBlock("li", {
|
|
208
208
|
key: item.id,
|
|
209
|
-
class: normalizeClass(["cn-setup-summary__item", { 'cn-setup-summary__item--done': item.done }])
|
|
209
|
+
class: normalizeClass(["cn-setup-summary__item", { 'cn-setup-summary__item--done': item.done, 'cn-setup-summary__item--not-run': item.notRun }])
|
|
210
210
|
}, [
|
|
211
211
|
createElementVNode("span", _hoisted_5, toDisplayString(item.done ? '✓' : '○'), 1 /* TEXT */),
|
|
212
212
|
createElementVNode("span", _hoisted_6, toDisplayString(item.title), 1 /* TEXT */),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnSetupWizard.vue3.js","sources":["../../../../src/components/CnSetupWizard/CnSetupWizard.vue?vue&type=template&id=75b2078b&lang.js"],"sourcesContent":["<!-- SPDX-License-Identifier: EUPL-1.2 -->\n<!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->\n<template>\n\t<CnWizardDialog\n\t\tref=\"wizard\"\n\t\t:steps=\"wizardSteps\"\n\t\t:dialogTitle=\"resolvedDialogTitle\"\n\t\t:submitLabel=\"submitLabel\"\n\t\t:cancelLabel=\"cancelLabel\"\n\t\t:nextLabel=\"nextLabel\"\n\t\t:backLabel=\"backLabel\"\n\t\t:successText=\"successText\"\n\t\t:validate=\"validateStep\"\n\t\t:cancellable=\"cancellable\"\n\t\t:initialStep=\"initialStepId\"\n\t\t@stepChange=\"onStepChange\"\n\t\t@submit=\"onSubmit\"\n\t\t@close=\"onClose\">\n\t\t<!-- This `<template v-for>` defines dynamic SLOTS, not a rendered list.\n\t\t `@vue/compiler-sfc` DISCARDS a `:key` on a slot-defining\n\t\t `<template>` (verified against the generated `createSlots` call)\n\t\t and honours it only on the child, so the rule's advice is inverted\n\t\t here — moving the key up would throw it away. -->\n\t\t<!-- eslint-disable vue/no-v-for-template-key-on-child -->\n\t\t<template v-for=\"step in setupSteps\" #[stepSlot(step)]=\"scope\">\n\t\t\t<div :key=\"step.id\" class=\"cn-setup-step\" :data-step-type=\"step.type\">\n\t\t\t\t<!-- @slot step-{id} Override a step's body (for `component` steps or\n\t\t\t\t any bespoke step). Scope: the CnWizardDialog step scope plus\n\t\t\t\t `{ step, runAction, saveConfig }`. -->\n\t\t\t\t<slot\n\t\t\t\t\tv-if=\"hasCustomSlot(step.id)\"\n\t\t\t\t\t:name=\"stepSlot(step)\"\n\t\t\t\t\tv-bind=\"scope\"\n\t\t\t\t\t:step=\"step\"\n\t\t\t\t\t:runAction=\"() => runAction(step)\"\n\t\t\t\t\t:saveConfig=\"(patch) => saveConfig(patch)\" />\n\n\t\t\t\t<!-- info -->\n\t\t\t\t<template v-else-if=\"step.type === 'info'\">\n\t\t\t\t\t<NcNoteCard type=\"info\" :heading=\"stepTitle(step)\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- choice -->\n\t\t\t\t<template v-else-if=\"step.type === 'choice'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<CnChoiceCards\n\t\t\t\t\t\tv-if=\"isCardChoice(step)\"\n\t\t\t\t\t\t:label=\"stepTitle(step)\"\n\t\t\t\t\t\t:options=\"optionsFor(step)\"\n\t\t\t\t\t\t:multiple=\"step.multiple === true\"\n\t\t\t\t\t\t:disabled=\"isChoiceDisabled(step)\"\n\t\t\t\t\t\t:loading=\"isOptionsLoading(step)\"\n\t\t\t\t\t\t:modelValue=\"cardModel(step)\"\n\t\t\t\t\t\t@update:modelValue=\"(v) => onChoice(step, v)\" />\n\t\t\t\t\t<NcSelect\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:inputLabel=\"stepTitle(step)\"\n\t\t\t\t\t\t:options=\"optionsFor(step)\"\n\t\t\t\t\t\t:multiple=\"step.multiple === true\"\n\t\t\t\t\t\t:disabled=\"isChoiceDisabled(step)\"\n\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t:modelValue=\"choiceModel[step.id]\"\n\t\t\t\t\t\t@update:modelValue=\"(v) => onChoice(step, v)\" />\n\t\t\t\t\t<NcNoteCard v-if=\"isChoiceDisabled(step)\" type=\"warning\">\n\t\t\t\t\t\t{{ dependsOnHint(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- config-fields -->\n\t\t\t\t<template v-else-if=\"step.type === 'config-fields'\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-for=\"field in fieldsFor(step)\"\n\t\t\t\t\t\t:key=\"field.key\"\n\t\t\t\t\t\tclass=\"cn-setup-field\">\n\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\tv-if=\"field.widget === 'checkbox'\"\n\t\t\t\t\t\t\t:modelValue=\"!!configModel[field.key]\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\">\n\t\t\t\t\t\t\t{{ field.label }}\n\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\tv-else-if=\"field.widget === 'select'\"\n\t\t\t\t\t\t\t:inputLabel=\"field.label\"\n\t\t\t\t\t\t\t:options=\"field.enum || []\"\n\t\t\t\t\t\t\t:modelValue=\"configModel[field.key]\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\" />\n\t\t\t\t\t\t<NcTextField\n\t\t\t\t\t\t\tv-else\n\t\t\t\t\t\t\t:label=\"field.label\"\n\t\t\t\t\t\t\t:type=\"field.widget === 'number' ? 'number' : 'text'\"\n\t\t\t\t\t\t\t:modelValue=\"configModel[field.key] != null ? String(configModel[field.key]) : ''\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\" />\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- run-action -->\n\t\t\t\t<template v-else-if=\"step.type === 'run-action'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<!-- The action starts automatically on entering this step\n\t\t\t\t\t (see `maybeAutoRunStep`), so the default state is the\n\t\t\t\t\t spinner, not an idle button. -->\n\t\t\t\t\t<div v-if=\"running[step.id]\" class=\"cn-setup-step__running\">\n\t\t\t\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t\t\t\t<span>{{ runningLabel }}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<template v-else>\n\t\t\t\t\t\t<NcNoteCard\n\t\t\t\t\t\t\tv-if=\"actionResult[step.id]\"\n\t\t\t\t\t\t\t:type=\"actionResult[step.id].success ? 'success' : 'error'\">\n\t\t\t\t\t\t\t{{ actionResult[step.id].message }}\n\t\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t\t<div class=\"cn-setup-step__nav\">\n\t\t\t\t\t\t\t<NcButton :variant=\"actionResult[step.id] ? 'secondary' : 'primary'\" @click=\"runAction(step)\">\n\t\t\t\t\t\t\t\t{{ actionResult[step.id] ? rerunLabel : runLabel }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- summary -->\n\t\t\t\t<template v-else-if=\"step.type === 'summary'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<ul class=\"cn-setup-summary\">\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tv-for=\"item in summaryItems\"\n\t\t\t\t\t\t\t:key=\"item.id\"\n\t\t\t\t\t\t\tclass=\"cn-setup-summary__item\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-setup-summary__item--done': item.done }\">\n\t\t\t\t\t\t\t<span class=\"cn-setup-summary__mark\">{{ item.done ? '✓' : '○' }}</span>\n\t\t\t\t\t\t\t<span class=\"cn-setup-summary__label\">{{ item.title }}</span>\n\t\t\t\t\t\t\t<span v-if=\"item.value\" class=\"cn-setup-summary__value\">{{ item.value }}</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</template>\n\t\t<!-- eslint-enable vue/no-v-for-template-key-on-child -->\n\t</CnWizardDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcCheckboxRadioSwitch, NcLoadingIcon, NcNoteCard, NcSelect, NcTextField } from '@nextcloud/vue'\nimport CnChoiceCards from '../CnChoiceCards/CnChoiceCards.vue'\nimport CnWizardDialog from '../CnWizardDialog/CnWizardDialog.vue'\nimport { useSetupStatus } from '../../composables/useSetupStatus.js'\nimport { fieldsFromSchema } from '../../utils/schema.js'\n\n/**\n * CnSetupWizard — abstract, manifest-driven first-time setup wizard (ADR-042).\n *\n * Wraps {@link CnWizardDialog} and renders a `manifest.setup.steps[]` array by\n * each step's `type`: `info` (note), `config-fields` (fields from a JSON Schema\n * via `fieldsFromSchema`, the same field shapes the admin pages use), `choice`\n * (`NcSelect` persisting to an app-config key), `run-action` (POST a privileged\n * server action), `summary` (recap), and `component` (a parent-provided\n * `#step-<id>` slot). It NEVER writes OpenRegister objects from the browser —\n * all persistence goes through the per-app setup contract\n * (`POST /apps/{appId}/api/setup/config` and `/api/setup/action/{actionId}`).\n *\n * Mount it gated by `CnAppRoot`'s setup phase, or open it on demand from\n * `CnAdminSettingsShell`.\n *\n * ```vue\n * <CnSetupWizard\n * :app-id=\"'procest'\"\n * :steps=\"manifest.setup.steps\"\n * @complete=\"onSetupComplete\"\n * @close=\"showWizard = false\" />\n * ```\n */\nexport default {\n\tname: 'CnSetupWizard',\n\n\tcomponents: {\n\t\tCnWizardDialog,\n\t\tCnChoiceCards,\n\t\tNcButton,\n\t\tNcNoteCard,\n\t\tNcSelect,\n\t\tNcTextField,\n\t\tNcCheckboxRadioSwitch,\n\t\tNcLoadingIcon,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Consumer translation function, provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id). Step field\n\t\t * labels come from schema property titles, authored in English as the\n\t\t * canonical source; the visible label is resolved through this function\n\t\t * so it follows the user's language. Defaults to identity when used\n\t\t * standalone (no CnAppRoot ancestor).\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** The Nextcloud app id; used to build the `/apps/{appId}/api/setup/*` URLs. */\n\t\tappId: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** The `manifest.setup.steps` array to render. */\n\t\tsteps: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Dialog title. Overridden by `appName` when that prop is set. */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Set up this app'),\n\t\t},\n\n\t\t/**\n\t\t * The app's human-readable display name. When set, the dialog title\n\t\t * becomes \"Set up {appName}\" instead of the generic `dialogTitle`\n\t\t * default — pass the same display name CnAppRoot already resolves\n\t\t * (`appDisplayName || manifest.name || appId`).\n\t\t */\n\t\tappName: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Final-step submit button label. */\n\t\tsubmitLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Finish'),\n\t\t},\n\n\t\t/** Cancel button label. */\n\t\tcancelLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Cancel'),\n\t\t},\n\n\t\t/** Next button label. */\n\t\tnextLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Next'),\n\t\t},\n\n\t\t/** Back button label. */\n\t\tbackLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Back'),\n\t\t},\n\n\t\t/** Run-action button label (shown before the first automatic run). */\n\t\trunLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Run'),\n\t\t},\n\n\t\t/** Run-action button label offered after a run already finished. */\n\t\trerunLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Run again'),\n\t\t},\n\n\t\t/** Label shown next to the spinner while a run-action step is running. */\n\t\trunningLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Loading…'),\n\t\t},\n\n\t\t/** Result-phase success text. */\n\t\tsuccessText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Setup complete.'),\n\t\t},\n\n\t\t/**\n\t\t * Whether the wizard can be dismissed before finishing (Cancel\n\t\t * button, ESC, backdrop click). Pass `false` when a REQUIRED step\n\t\t * is unmet and the host is gating its shell behind this wizard\n\t\t * (ADR-042) — an offered-but-non-functional Cancel would be\n\t\t * misleading. Optional-only setup stays cancellable (default).\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 * Ids of steps the SERVER already reports as done (e.g.\n\t\t * `useSetupStatus(...).steps` filtered to `done === true`), passed by\n\t\t * the host so a freshly (re)mounted wizard doesn't re-ask something\n\t\t * already persisted in an earlier session — this component's own\n\t\t * `localDone`/`choiceModel` only track the CURRENT session and reset\n\t\t * blank on every mount. Drives both the initial step (`initialStepId`)\n\t\t * and the summary page's done markers.\n\t\t *\n\t\t * @type {Array<string>}\n\t\t */\n\t\tcompletedStepIds: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\t},\n\n\temits: ['complete', 'close', 'step-change', 'action-result'],\n\n\t/**\n\t * Live option lists come from the app's own setup status document, so a\n\t * step that offers a choice of things the SERVER ships never has to\n\t * restate them in the manifest. `useSetupStatus` caches per app id, so the\n\t * host's own status fetch (CnAppRoot's setup gate) is the one that runs —\n\t * this reads the same refs rather than asking again.\n\t *\n\t * Only called when a step actually declares `optionsSource`: a wizard with\n\t * none must not start making requests it never made before.\n\t *\n\t * @param {object} props The component props.\n\t * @return {object} `setupStatus` / `setupStatusLoading` for the option resolver.\n\t */\n\tsetup(props) {\n\t\tconst wantsSource = (props.steps || []).some((s) => s && s.optionsSource)\n\t\tif (!wantsSource) {\n\t\t\treturn {}\n\t\t}\n\t\tconst { status, loading } = useSetupStatus(props.appId, { setup: { steps: props.steps } })\n\t\treturn { setupStatus: status, setupStatusLoading: loading }\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tchoiceModel: {},\n\t\t\tchoiceValues: {},\n\t\t\tconfigModel: {},\n\t\t\trunning: {},\n\t\t\tactionResult: {},\n\t\t\tlocalDone: {},\n\t\t\tuserTouched: {},\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The title actually rendered by CnWizardDialog: \"Set up {appName}\"\n\t\t * when a display name was passed, otherwise whatever `dialogTitle`\n\t\t * resolves to (a caller override, or its own generic default).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedDialogTitle() {\n\t\t\treturn this.appName\n\t\t\t\t? t('nextcloud-vue', 'Set up {app}', { app: this.appName })\n\t\t\t\t: this.dialogTitle\n\t\t},\n\n\t\tsetupSteps() {\n\t\t\treturn (this.steps || []).filter((s) => s && s.id && s.type)\n\t\t},\n\n\t\twizardSteps() {\n\t\t\treturn this.setupSteps.map((s) => ({\n\t\t\t\tid: s.id,\n\t\t\t\tlabel: this.stepTitle(s),\n\t\t\t\toptional: s.required !== true,\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Recap rows for the `summary` step — one per non-summary step, with\n\t\t * the value the user selected (choice label / config field values) and\n\t\t * a done marker (info steps always done; choice steps done when picked;\n\t\t * run-action steps done when the action succeeded).\n\t\t *\n\t\t * @return {Array<{ id: string, title: string, value: string, done: boolean }>}\n\t\t */\n\t\tsummaryItems() {\n\t\t\treturn this.setupSteps\n\t\t\t\t.filter((s) => s.type !== 'summary')\n\t\t\t\t.map((step) => {\n\t\t\t\t\tlet value = ''\n\t\t\t\t\tif (step.type === 'choice') {\n\t\t\t\t\t\tconst raw = this.choiceModel[step.id]\n\t\t\t\t\t\tif (Array.isArray(raw)) {\n\t\t\t\t\t\t\tvalue = raw.map((o) => this.choiceLabel(step, o)).join(', ')\n\t\t\t\t\t\t} else if (raw !== null && raw !== undefined && raw !== '') {\n\t\t\t\t\t\t\tvalue = this.choiceLabel(step, raw)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (step.type === 'config-fields') {\n\t\t\t\t\t\tvalue = this.fieldsFor(step)\n\t\t\t\t\t\t\t.map((f) => `${f.label}: ${this.configModel[f.key] !== null && this.configModel[f.key] !== undefined ? this.configModel[f.key] : ''}`)\n\t\t\t\t\t\t\t.join(', ')\n\t\t\t\t\t}\n\t\t\t\t\tlet done\n\t\t\t\t\tif (step.type === 'info') {\n\t\t\t\t\t\tdone = true\n\t\t\t\t\t} else if (step.type === 'choice') {\n\t\t\t\t\t\tdone = this.hasChoice(step) || this.isServerDone(step.id)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdone = this.isStepDone(step.id)\n\t\t\t\t\t}\n\t\t\t\t\treturn { id: step.id, title: this.stepTitle(step), value, done }\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Id of the step the wizard should open on when RESUMING: the first\n\t\t * non-`info`/`summary` step not already done, per the CURRENT session's\n\t\t * local state OR the server-reported `completedStepIds` (a prior\n\t\t * session). Falls back to `''` (CnWizardDialog's own first-step default)\n\t\t * on a fresh setup and when every actionable step is already done.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tinitialStepId() {\n\t\t\t// Fresh setup — nothing done anywhere yet, so there is nothing to\n\t\t\t// resume past. Start at step one so a leading `info`/welcome step is\n\t\t\t// actually seen; resuming is only for returning sessions.\n\t\t\tif (this.completedStepIds.length === 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst actionable = this.setupSteps.filter((s) => s.type !== 'info' && s.type !== 'summary')\n\t\t\tconst firstUnmetIndex = actionable.findIndex((s) => {\n\t\t\t\tif (s.type === 'choice') {\n\t\t\t\t\treturn !(this.hasChoice(s) || this.isServerDone(s.id))\n\t\t\t\t}\n\t\t\t\treturn !this.isStepDone(s.id)\n\t\t\t})\n\t\t\t// Done is not the same as seen: an app that pre-satisfies a step at\n\t\t\t// install time (buildiq seeds templates from a repair step) reports it\n\t\t\t// done before anyone opens the wizard. Only finished work BEFORE the\n\t\t\t// outstanding step means there is something to resume past.\n\t\t\tif (firstUnmetIndex <= 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn actionable[firstUnmetIndex].id\n\t\t},\n\t},\n\n\tmounted() {\n\t\t// Covers a RESUMED wizard opening straight onto its run-action step\n\t\t// (`initialStepId`) — `onStepChange` only fires on later navigation,\n\t\t// so a step already active at mount time needs its own trigger.\n\t\tthis.maybeAutoRunStep(this.initialStepId || (this.setupSteps[0] && this.setupSteps[0].id))\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Start a `run-action` step's action automatically the moment it\n\t\t * becomes current, instead of waiting for a manual \"Run\" click —\n\t\t * the step has nothing else for the user to decide by then (the\n\t\t * choice it acts on was already made on an earlier step), so\n\t\t * requiring a click before showing progress just adds a stall.\n\t\t * No-ops for any other step type, or one already run/running.\n\t\t *\n\t\t * @param {string} stepId The step id becoming current.\n\t\t * @return {void}\n\t\t */\n\t\tmaybeAutoRunStep(stepId) {\n\t\t\tconst step = this.setupSteps.find((s) => s.id === stepId)\n\t\t\tif (step && step.type === 'run-action' && !this.isStepDone(step.id) && !this.running[step.id]) {\n\t\t\t\tthis.runAction(step)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The visible title for a step, resolved through the host app's\n\t\t * translation function.\n\t\t *\n\t\t * `manifest.setup.steps[].title` is authored in English as the\n\t\t * canonical source, exactly like the schema property titles this\n\t\t * component already routes through `cnTranslate` for field labels\n\t\t * (see `fieldsFromSchema` below). The step titles were the one\n\t\t * remaining place rendering the manifest string verbatim, so an\n\t\t * nl-locale user saw a wizard whose field labels were translated and\n\t\t * whose step headings were not.\n\t\t *\n\t\t * Falls back to the step id when a step declares no title, which is\n\t\t * the same fallback the raw bindings used.\n\t\t *\n\t\t * @param {object} step A `manifest.setup.steps[]` entry.\n\t\t * @return {string} The translated title, or the step id.\n\t\t */\n\t\tstepTitle(step) {\n\t\t\tconst raw = (step && step.title) || (step && step.id) || ''\n\t\t\treturn raw === '' ? '' : this.cnTranslate(raw)\n\t\t},\n\n\t\t/**\n\t\t * The visible body for a step, resolved through the host app's\n\t\t * translation function.\n\t\t *\n\t\t * 🔴 THIS USED TO RENDER THE MANIFEST STRING VERBATIM, IN FOUR PLACES.\n\t\t * `stepTitle()` was routed through `cnTranslate` and the body was not,\n\t\t * so a wizard on a Dutch instance showed a translated heading over an\n\t\t * English paragraph, with translated Cancel/Next buttons underneath.\n\t\t * That reads as a bug rather than as a missing string, and the app could\n\t\t * not fix it: decidiq shipped correct Dutch for its setup copy in\n\t\t * `l10n/nl.json`, and the component never asked for it.\n\t\t *\n\t\t * @param {object} step The step declaration.\n\t\t * @return {string} The translated body, or ''.\n\t\t */\n\t\tstepBody(step) {\n\t\t\tconst raw = (step && step.body) || ''\n\t\t\treturn raw === '' ? '' : this.cnTranslate(raw)\n\t\t},\n\n\t\tstepSlot(step) {\n\t\t\treturn 'step-' + step.id\n\t\t},\n\n\t\thasCustomSlot(id) {\n\t\t\treturn !!this.$slots['step-' + id] || !!this.$slots['step-' + id]\n\t\t},\n\n\t\tfieldsFor(step) {\n\t\t\tif (step.schema && typeof step.schema === 'object') {\n\t\t\t\treturn fieldsFromSchema(step.schema, { translate: this.cnTranslate })\n\t\t\t}\n\t\t\t// Fallback: a plain text field per declared config key.\n\t\t\treturn (step.configKeys || []).map((key) => ({ key, label: key, widget: 'text' }))\n\t\t},\n\n\t\t/**\n\t\t * Options for a `choice` step. When the step declares `dependsOn`\n\t\t * (a parent step's configKey) + `optionsByParent`, the option list\n\t\t * is the entry keyed by the parent's currently-selected value — this\n\t\t * is the country → organisation-type cascade. Otherwise the static\n\t\t * `options` array.\n\t\t *\n\t\t * @param {object} step The choice step definition.\n\t\t * @return {Array} The option list to render.\n\t\t */\n\t\toptionsFor(step) {\n\t\t\tlet options = step.options || []\n\t\t\tif (step.optionsSource) {\n\t\t\t\toptions = this.sourcedOptions(step)\n\t\t\t} else if (step.dependsOn && step.optionsByParent) {\n\t\t\t\tconst parentValue = this.choiceValues[step.dependsOn]\n\t\t\t\toptions = (parentValue === null || parentValue === undefined || parentValue === '')\n\t\t\t\t\t? []\n\t\t\t\t\t: (step.optionsByParent[parentValue] || [])\n\t\t\t}\n\t\t\t// The LABEL is translated, the VALUE never is. `scalarChoice()` reads\n\t\t\t// `.value` and that is what reaches `POST /api/setup/config`, so a\n\t\t\t// translated label cannot change what gets stored — while an\n\t\t\t// untranslated one leaves the choice itself in English on a\n\t\t\t// localised instance, which is the half-translated screen this fix\n\t\t\t// exists to remove.\n\t\t\treturn options.map((option) => {\n\t\t\t\tif (!option || typeof option !== 'object' || !option.label) {\n\t\t\t\t\treturn option\n\t\t\t\t}\n\t\t\t\tconst translated = { ...option, label: this.cnTranslate(option.label) }\n\t\t\t\tif (option.description) {\n\t\t\t\t\ttranslated.description = this.cnTranslate(option.description)\n\t\t\t\t}\n\t\t\t\treturn translated\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The option list a `choice` step declares `optionsSource` for, read\n\t\t * from the setup status document the app already serves.\n\t\t *\n\t\t * `optionsSource` names a key in that document (dots walk into nested\n\t\t * objects), and the entries are normalised to the option shape: `id` is\n\t\t * accepted for `value`, `name` for `label`, and a bare `objectCount`\n\t\t * becomes the one stat a card shows. A server that already sends\n\t\t * `stats` keeps them.\n\t\t *\n\t\t * @param {object} step The choice step declaring `optionsSource`.\n\t\t * @return {Array<object>} The options, or [] while the status is loading.\n\t\t */\n\t\tsourcedOptions(step) {\n\t\t\tlet node = this.setupStatus\n\t\t\tfor (const key of String(step.optionsSource).split('.')) {\n\t\t\t\tif (node === null || node === undefined || typeof node !== 'object') {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\tnode = node[key]\n\t\t\t}\n\t\t\tif (!Array.isArray(node)) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn node\n\t\t\t\t.filter((entry) => entry && typeof entry === 'object')\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tconst value = entry.value !== undefined ? entry.value : entry.id\n\t\t\t\t\tconst option = {\n\t\t\t\t\t\t...entry,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tlabel: entry.label || entry.name || String(value),\n\t\t\t\t\t}\n\t\t\t\t\tif (!option.stats && typeof entry.objectCount === 'number' && entry.objectCount > 0) {\n\t\t\t\t\t\toption.stats = [{ label: t('nextcloud-vue', 'Objects'), value: entry.objectCount }]\n\t\t\t\t\t}\n\t\t\t\t\treturn option\n\t\t\t\t})\n\t\t\t\t.filter((option) => option.value !== undefined)\n\t\t},\n\n\t\t/**\n\t\t * Whether a choice step renders as a card grid rather than a dropdown.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {boolean} True for `display: \"cards\"`.\n\t\t */\n\t\tisCardChoice(step) {\n\t\t\treturn step.display === 'cards'\n\t\t},\n\n\t\t/**\n\t\t * Whether this step is still waiting for its live option list.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {boolean} True while the status document is in flight.\n\t\t */\n\t\tisOptionsLoading(step) {\n\t\t\treturn !!step.optionsSource && this.setupStatusLoading === true\n\t\t},\n\n\t\t/**\n\t\t * The card grid's model: plain values, not the option objects NcSelect\n\t\t * binds. `scalarChoice` already reduces either shape to values, so both\n\t\t * renderers can share one `choiceModel` entry.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {unknown} The selected value, or [] / null when nothing is picked.\n\t\t */\n\t\tcardModel(step) {\n\t\t\tconst value = this.scalarChoice(step)\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn Array.isArray(value) ? value : []\n\t\t\t}\n\t\t\treturn value === undefined ? null : value\n\t\t},\n\n\t\tisChoiceDisabled(step) {\n\t\t\tif (!step.dependsOn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst parentValue = this.choiceValues[step.dependsOn]\n\t\t\treturn parentValue === null || parentValue === undefined || parentValue === ''\n\t\t},\n\n\t\tdependsOnHint(step) {\n\t\t\tconst parent = this.setupSteps.find((s) => s.configKey === step.dependsOn)\n\t\t\tconst label = parent ? (parent.title || parent.id) : step.dependsOn\n\t\t\treturn t('nextcloud-vue', 'Select \"{step}\" first.', { step: label })\n\t\t},\n\n\t\t/**\n\t\t * The visible label for one selected choice entry.\n\t\t *\n\t\t * A card grid stores plain VALUES where NcSelect stores option objects,\n\t\t * so the recap looked one up and printed the other: the summary read\n\t\t * \"municipality\" instead of \"Municipality\". Resolves a bare value back\n\t\t * to its option, and falls back to the value when the option list is\n\t\t * not (yet) available.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @param {unknown} entry One selected entry: an option object or a value.\n\t\t * @return {string} The label to show.\n\t\t */\n\t\tchoiceLabel(step, entry) {\n\t\t\tif (entry && typeof entry === 'object' && entry.label) {\n\t\t\t\treturn entry.label\n\t\t\t}\n\t\t\tconst match = this.optionsFor(step).find((o) => o && String(o.value) === String(entry))\n\t\t\treturn (match && match.label) ? match.label : String(entry)\n\t\t},\n\n\t\thasChoice(step) {\n\t\t\tconst v = this.choiceModel[step.id]\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn Array.isArray(v) && v.length > 0\n\t\t\t}\n\t\t\treturn v !== null && v !== undefined && v !== ''\n\t\t},\n\n\t\tscalarChoice(step) {\n\t\t\tconst raw = this.choiceModel[step.id]\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn (raw || []).map((o) => (o && o.value !== undefined ? o.value : o))\n\t\t\t}\n\t\t\treturn raw && raw.value !== undefined ? raw.value : raw\n\t\t},\n\n\t\tonChoice(step, value) {\n\t\t\tthis.userTouched[step.id] = true\n\t\t\tthis.choiceModel[step.id] = value\n\t\t\tif (step.configKey) {\n\t\t\t\tthis.choiceValues[step.configKey] = this.scalarChoice(step)\n\t\t\t}\n\t\t\t// Reset any dependent child choices when the parent changes.\n\t\t\tfor (const child of this.setupSteps) {\n\t\t\t\tif (child.dependsOn && child.dependsOn === step.configKey) {\n\t\t\t\t\tthis.choiceModel[child.id] = child.multiple === true ? [] : null\n\t\t\t\t\tthis.userTouched[child.id] = false\n\t\t\t\t\tif (child.configKey) {\n\t\t\t\t\t\tthis.choiceValues[child.configKey] = ''\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Re-apply auto-suggestions for steps that derive a default from this one.\n\t\t\tfor (const dep of this.setupSteps) {\n\t\t\t\tif (dep.suggestFrom && dep.suggestFrom === step.configKey) {\n\t\t\t\t\tthis.applySuggestion(dep)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Auto-fill a `choice` step's suggested default from an earlier choice\n\t\t * (its `suggestFrom` configKey → `suggestMap[parentValue]`). No-op once\n\t\t * the user has manually picked here, so a suggestion never clobbers an\n\t\t * explicit choice.\n\t\t *\n\t\t * @param {object} step The dependent choice step.\n\t\t * @return {void}\n\t\t */\n\t\tapplySuggestion(step) {\n\t\t\tif (this.userTouched[step.id] === true) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst parentValue = this.choiceValues[step.suggestFrom]\n\t\t\tif (parentValue === null || parentValue === undefined || parentValue === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst wanted = (step.suggestMap || {})[parentValue]\n\t\t\tif (wanted === null || wanted === undefined) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst opt = this.optionsFor(step).find((o) => o.value === wanted) || { value: wanted, label: String(wanted) }\n\t\t\tthis.choiceModel[step.id] = opt\n\t\t\tif (step.configKey) {\n\t\t\t\tthis.choiceValues[step.configKey] = wanted\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * CnWizardDialog `validate` hook — intercepts Next/Submit to persist\n\t\t * the active step before advancing. `choice`/`config-fields` steps\n\t\t * POST their value via the setup contract; required `choice` steps\n\t\t * block advance until a value is picked; required `run-action` steps\n\t\t * block until the action has succeeded. Returns `true` to advance or\n\t\t * an error string to surface above the step and block navigation.\n\t\t *\n\t\t * @param {string} stepId The active step id.\n\t\t * @return {Promise<boolean|string>} True to advance, or an error message.\n\t\t */\n\t\tasync validateStep(stepId) {\n\t\t\tconst step = this.setupSteps.find((s) => s.id === stepId)\n\t\t\tif (!step) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (step.type === 'choice') {\n\t\t\t\tif (!this.hasChoice(step)) {\n\t\t\t\t\t// Already persisted server-side and the user only back-navigated\n\t\t\t\t\t// onto it — `choiceModel` is blank because it's session-local, not\n\t\t\t\t\t// because nothing is set. Don't force a re-pick, and don't re-POST.\n\t\t\t\t\tif (this.isServerDone(step.id)) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t\treturn step.required === true\n\t\t\t\t\t\t? t('nextcloud-vue', 'Please make a selection to continue.')\n\t\t\t\t\t\t: true\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait this.saveConfig({ [step.configKey]: this.scalarChoice(step) })\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t\treturn true\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn this.errorMessage(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (step.type === 'config-fields') {\n\t\t\t\ttry {\n\t\t\t\t\tconst patch = {}\n\t\t\t\t\tfor (const field of this.fieldsFor(step)) {\n\t\t\t\t\t\tpatch[field.key] = this.configModel[field.key]\n\t\t\t\t\t}\n\t\t\t\t\tawait this.saveConfig(patch)\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t\treturn true\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn this.errorMessage(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (step.type === 'run-action' && step.required === true && !this.isStepDone(step.id)) {\n\t\t\t\treturn t('nextcloud-vue', 'Please run this step before continuing.')\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\n\t\t/**\n\t\t * Persist one or more app-config values via the setup contract.\n\t\t *\n\t\t * @param {object} patch `{ <configKey>: value }` to write.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync saveConfig(patch) {\n\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\timport('@nextcloud/router'),\n\t\t\t])\n\t\t\tawait axios.post(generateUrl(`/apps/${this.appId}/api/setup/config`), patch)\n\t\t},\n\n\t\tasync runAction(step) {\n\t\t\tthis.running[step.id] = true\n\t\t\tthis.actionResult[step.id] = null\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst { data } = await axios.post(generateUrl(`/apps/${this.appId}/api/setup/action/${step.action}`))\n\t\t\t\tconst result = {\n\t\t\t\t\tsuccess: data && data.success !== false,\n\t\t\t\t\tmessage: (data && data.message) || t('nextcloud-vue', 'Done.'),\n\t\t\t\t}\n\t\t\t\tthis.actionResult[step.id] = result\n\t\t\t\tif (result.success) {\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * @event action-result Emitted when a `run-action` step finishes.\n\t\t\t\t * @type {{ stepId: string, action: string, success: boolean, message: string }}\n\t\t\t\t */\n\t\t\t\tthis.$emit('action-result', { stepId: step.id, action: step.action, ...result })\n\t\t\t} catch (err) {\n\t\t\t\tthis.actionResult[step.id] = { success: false, message: this.errorMessage(err) }\n\t\t\t\tthis.$emit('action-result', { stepId: step.id, action: step.action, success: false, message: this.errorMessage(err) })\n\t\t\t} finally {\n\t\t\t\tthis.running[step.id] = false\n\t\t\t}\n\t\t},\n\n\t\tisStepDone(id) {\n\t\t\treturn this.isServerDone(id) || this.localDone[id] === true || (this.actionResult[id] && this.actionResult[id].success)\n\t\t},\n\n\t\t/**\n\t\t * Whether the server already reported this step done in a prior\n\t\t * session, via the `completedStepIds` prop.\n\t\t *\n\t\t * @param {string} id Step id.\n\t\t * @return {boolean}\n\t\t */\n\t\tisServerDone(id) {\n\t\t\treturn this.completedStepIds.includes(id)\n\t\t},\n\n\t\tonSubmit() {\n\t\t\tif (this.$refs.wizard && this.$refs.wizard.setResult) {\n\t\t\t\tthis.$refs.wizard.setResult({ success: true, message: this.successText })\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event complete Emitted when the last step is submitted (setup finished).\n\t\t\t */\n\t\t\tthis.$emit('complete')\n\t\t},\n\n\t\tonStepChange(payload) {\n\t\t\t// Pre-fill a suggested default when entering a step that derives one.\n\t\t\tconst step = this.setupSteps.find((s) => s.id === payload.stepId)\n\t\t\tif (step && step.suggestFrom) {\n\t\t\t\tthis.applySuggestion(step)\n\t\t\t}\n\t\t\tthis.maybeAutoRunStep(payload.stepId)\n\t\t\t/**\n\t\t\t * @event step-change Emitted when the active step changes.\n\t\t\t * @type {{ stepId: string, stepIndex: number, direction: string }}\n\t\t\t */\n\t\t\tthis.$emit('step-change', payload)\n\t\t},\n\n\t\tonClose() {\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\n\t\terrorMessage(err) {\n\t\t\tconst data = err && err.response && err.response.data\n\t\t\tif (data && (data.message || data.error)) {\n\t\t\t\treturn data.message || data.error\n\t\t\t}\n\t\t\treturn (err && err.message) || t('nextcloud-vue', 'Something went wrong.')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-setup-step {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n.cn-setup-step__nav {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tgap: 8px;\n\tmargin-top: 8px;\n}\n\n.cn-setup-step__running {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 8px;\n\tpadding: 24px 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-setup-field {\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.cn-setup-summary {\n\tlist-style: none;\n\tpadding: 0;\n\tmargin: 0;\n}\n\n.cn-setup-summary__item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 4px 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-setup-summary__item--done {\n\tcolor: var(--color-main-text);\n}\n\n.cn-setup-summary__mark {\n\tfont-weight: bold;\n\tcolor: var(--color-success);\n}\n\n.cn-setup-summary__label {\n\tflex: 0 0 auto;\n}\n\n.cn-setup-summary__value {\n\tmargin-inline-start: auto;\n\tfont-weight: 600;\n\tcolor: var(--color-main-text);\n}\n</style>\n"],"names":["_createBlock","_renderList","_renderSlot","_mergeProps","_createTextVNode","_toDisplayString","_createElementBlock","_Fragment","_openBlock","_createVNode","_createElementVNode","_normalizeClass"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnSetupWizard.vue3.js","sources":["../../../../src/components/CnSetupWizard/CnSetupWizard.vue?vue&type=template&id=75b2078b&lang.js"],"sourcesContent":["<!-- SPDX-License-Identifier: EUPL-1.2 -->\n<!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->\n<template>\n\t<CnWizardDialog\n\t\tref=\"wizard\"\n\t\t:steps=\"wizardSteps\"\n\t\t:dialogTitle=\"resolvedDialogTitle\"\n\t\t:submitLabel=\"submitLabel\"\n\t\t:cancelLabel=\"cancelLabel\"\n\t\t:nextLabel=\"nextLabel\"\n\t\t:backLabel=\"backLabel\"\n\t\t:successText=\"successText\"\n\t\t:validate=\"validateStep\"\n\t\t:cancellable=\"cancellable\"\n\t\t:initialStep=\"initialStepId\"\n\t\t@stepChange=\"onStepChange\"\n\t\t@submit=\"onSubmit\"\n\t\t@close=\"onClose\">\n\t\t<!-- This `<template v-for>` defines dynamic SLOTS, not a rendered list.\n\t\t `@vue/compiler-sfc` DISCARDS a `:key` on a slot-defining\n\t\t `<template>` (verified against the generated `createSlots` call)\n\t\t and honours it only on the child, so the rule's advice is inverted\n\t\t here — moving the key up would throw it away. -->\n\t\t<!-- eslint-disable vue/no-v-for-template-key-on-child -->\n\t\t<template v-for=\"step in setupSteps\" #[stepSlot(step)]=\"scope\">\n\t\t\t<div :key=\"step.id\" class=\"cn-setup-step\" :data-step-type=\"step.type\">\n\t\t\t\t<!-- @slot step-{id} Override a step's body (for `component` steps or\n\t\t\t\t any bespoke step). Scope: the CnWizardDialog step scope plus\n\t\t\t\t `{ step, runAction, saveConfig }`. -->\n\t\t\t\t<slot\n\t\t\t\t\tv-if=\"hasCustomSlot(step.id)\"\n\t\t\t\t\t:name=\"stepSlot(step)\"\n\t\t\t\t\tv-bind=\"scope\"\n\t\t\t\t\t:step=\"step\"\n\t\t\t\t\t:runAction=\"() => runAction(step)\"\n\t\t\t\t\t:saveConfig=\"(patch) => saveConfig(patch)\" />\n\n\t\t\t\t<!-- info -->\n\t\t\t\t<template v-else-if=\"step.type === 'info'\">\n\t\t\t\t\t<NcNoteCard type=\"info\" :heading=\"stepTitle(step)\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- choice -->\n\t\t\t\t<template v-else-if=\"step.type === 'choice'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<CnChoiceCards\n\t\t\t\t\t\tv-if=\"isCardChoice(step)\"\n\t\t\t\t\t\t:label=\"stepTitle(step)\"\n\t\t\t\t\t\t:options=\"optionsFor(step)\"\n\t\t\t\t\t\t:multiple=\"step.multiple === true\"\n\t\t\t\t\t\t:disabled=\"isChoiceDisabled(step)\"\n\t\t\t\t\t\t:loading=\"isOptionsLoading(step)\"\n\t\t\t\t\t\t:modelValue=\"cardModel(step)\"\n\t\t\t\t\t\t@update:modelValue=\"(v) => onChoice(step, v)\" />\n\t\t\t\t\t<NcSelect\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:inputLabel=\"stepTitle(step)\"\n\t\t\t\t\t\t:options=\"optionsFor(step)\"\n\t\t\t\t\t\t:multiple=\"step.multiple === true\"\n\t\t\t\t\t\t:disabled=\"isChoiceDisabled(step)\"\n\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t:modelValue=\"choiceModel[step.id]\"\n\t\t\t\t\t\t@update:modelValue=\"(v) => onChoice(step, v)\" />\n\t\t\t\t\t<NcNoteCard v-if=\"isChoiceDisabled(step)\" type=\"warning\">\n\t\t\t\t\t\t{{ dependsOnHint(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- config-fields -->\n\t\t\t\t<template v-else-if=\"step.type === 'config-fields'\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-for=\"field in fieldsFor(step)\"\n\t\t\t\t\t\t:key=\"field.key\"\n\t\t\t\t\t\tclass=\"cn-setup-field\">\n\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\tv-if=\"field.widget === 'checkbox'\"\n\t\t\t\t\t\t\t:modelValue=\"!!configModel[field.key]\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\">\n\t\t\t\t\t\t\t{{ field.label }}\n\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\tv-else-if=\"field.widget === 'select'\"\n\t\t\t\t\t\t\t:inputLabel=\"field.label\"\n\t\t\t\t\t\t\t:options=\"field.enum || []\"\n\t\t\t\t\t\t\t:modelValue=\"configModel[field.key]\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\" />\n\t\t\t\t\t\t<NcTextField\n\t\t\t\t\t\t\tv-else\n\t\t\t\t\t\t\t:label=\"field.label\"\n\t\t\t\t\t\t\t:type=\"field.widget === 'number' ? 'number' : 'text'\"\n\t\t\t\t\t\t\t:modelValue=\"configModel[field.key] != null ? String(configModel[field.key]) : ''\"\n\t\t\t\t\t\t\t@update:modelValue=\"(v) => configModel[field.key] = v\" />\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- run-action -->\n\t\t\t\t<template v-else-if=\"step.type === 'run-action'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<!-- The action starts automatically on entering this step\n\t\t\t\t\t (see `maybeAutoRunStep`), so the default state is the\n\t\t\t\t\t spinner, not an idle button. -->\n\t\t\t\t\t<div v-if=\"running[step.id]\" class=\"cn-setup-step__running\">\n\t\t\t\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t\t\t\t<span>{{ runningLabel }}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<template v-else>\n\t\t\t\t\t\t<NcNoteCard\n\t\t\t\t\t\t\tv-if=\"actionResult[step.id]\"\n\t\t\t\t\t\t\t:type=\"actionResult[step.id].success ? 'success' : 'error'\">\n\t\t\t\t\t\t\t{{ actionResult[step.id].message }}\n\t\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t\t<div class=\"cn-setup-step__nav\">\n\t\t\t\t\t\t\t<NcButton :variant=\"actionResult[step.id] ? 'secondary' : 'primary'\" @click=\"runAction(step)\">\n\t\t\t\t\t\t\t\t{{ actionResult[step.id] ? rerunLabel : runLabel }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t</template>\n\n\t\t\t\t<!-- summary -->\n\t\t\t\t<template v-else-if=\"step.type === 'summary'\">\n\t\t\t\t\t<NcNoteCard v-if=\"step.body\" type=\"info\">\n\t\t\t\t\t\t{{ stepBody(step) }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t\t<ul class=\"cn-setup-summary\">\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tv-for=\"item in summaryItems\"\n\t\t\t\t\t\t\t:key=\"item.id\"\n\t\t\t\t\t\t\tclass=\"cn-setup-summary__item\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-setup-summary__item--done': item.done, 'cn-setup-summary__item--not-run': item.notRun }\">\n\t\t\t\t\t\t\t<span class=\"cn-setup-summary__mark\">{{ item.done ? '✓' : '○' }}</span>\n\t\t\t\t\t\t\t<span class=\"cn-setup-summary__label\">{{ item.title }}</span>\n\t\t\t\t\t\t\t<span v-if=\"item.value\" class=\"cn-setup-summary__value\">{{ item.value }}</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</template>\n\t\t<!-- eslint-enable vue/no-v-for-template-key-on-child -->\n\t</CnWizardDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcCheckboxRadioSwitch, NcLoadingIcon, NcNoteCard, NcSelect, NcTextField } from '@nextcloud/vue'\nimport CnChoiceCards from '../CnChoiceCards/CnChoiceCards.vue'\nimport CnWizardDialog from '../CnWizardDialog/CnWizardDialog.vue'\nimport { useSetupStatus } from '../../composables/useSetupStatus.js'\nimport { fieldsFromSchema } from '../../utils/schema.js'\n\n/**\n * CnSetupWizard — abstract, manifest-driven first-time setup wizard (ADR-042).\n *\n * Wraps {@link CnWizardDialog} and renders a `manifest.setup.steps[]` array by\n * each step's `type`: `info` (note), `config-fields` (fields from a JSON Schema\n * via `fieldsFromSchema`, the same field shapes the admin pages use), `choice`\n * (`NcSelect` persisting to an app-config key), `run-action` (POST a privileged\n * server action), `summary` (recap), and `component` (a parent-provided\n * `#step-<id>` slot). It NEVER writes OpenRegister objects from the browser —\n * all persistence goes through the per-app setup contract\n * (`POST /apps/{appId}/api/setup/config` and `/api/setup/action/{actionId}`).\n *\n * Mount it gated by `CnAppRoot`'s setup phase, or open it on demand from\n * `CnAdminSettingsShell`.\n *\n * ```vue\n * <CnSetupWizard\n * :app-id=\"'procest'\"\n * :steps=\"manifest.setup.steps\"\n * @complete=\"onSetupComplete\"\n * @close=\"showWizard = false\" />\n * ```\n */\nexport default {\n\tname: 'CnSetupWizard',\n\n\tcomponents: {\n\t\tCnWizardDialog,\n\t\tCnChoiceCards,\n\t\tNcButton,\n\t\tNcNoteCard,\n\t\tNcSelect,\n\t\tNcTextField,\n\t\tNcCheckboxRadioSwitch,\n\t\tNcLoadingIcon,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Consumer translation function, provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id). Step field\n\t\t * labels come from schema property titles, authored in English as the\n\t\t * canonical source; the visible label is resolved through this function\n\t\t * so it follows the user's language. Defaults to identity when used\n\t\t * standalone (no CnAppRoot ancestor).\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** The Nextcloud app id; used to build the `/apps/{appId}/api/setup/*` URLs. */\n\t\tappId: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** The `manifest.setup.steps` array to render. */\n\t\tsteps: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Dialog title. Overridden by `appName` when that prop is set. */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Set up this app'),\n\t\t},\n\n\t\t/**\n\t\t * The app's human-readable display name. When set, the dialog title\n\t\t * becomes \"Set up {appName}\" instead of the generic `dialogTitle`\n\t\t * default — pass the same display name CnAppRoot already resolves\n\t\t * (`appDisplayName || manifest.name || appId`).\n\t\t */\n\t\tappName: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Final-step submit button label. */\n\t\tsubmitLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Finish'),\n\t\t},\n\n\t\t/** Cancel button label. */\n\t\tcancelLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Cancel'),\n\t\t},\n\n\t\t/** Next button label. */\n\t\tnextLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Next'),\n\t\t},\n\n\t\t/** Back button label. */\n\t\tbackLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Back'),\n\t\t},\n\n\t\t/** Run-action button label (shown before the first automatic run). */\n\t\trunLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Run'),\n\t\t},\n\n\t\t/** Run-action button label offered after a run already finished. */\n\t\trerunLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Run again'),\n\t\t},\n\n\t\t/** Label shown next to the spinner while a run-action step is running. */\n\t\trunningLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Loading…'),\n\t\t},\n\n\t\t/** Result-phase success text. */\n\t\tsuccessText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Setup complete.'),\n\t\t},\n\n\t\t/**\n\t\t * Whether the wizard can be dismissed before finishing (Cancel\n\t\t * button, ESC, backdrop click). Pass `false` when a REQUIRED step\n\t\t * is unmet and the host is gating its shell behind this wizard\n\t\t * (ADR-042) — an offered-but-non-functional Cancel would be\n\t\t * misleading. Optional-only setup stays cancellable (default).\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 * Ids of steps the SERVER already reports as done (e.g.\n\t\t * `useSetupStatus(...).steps` filtered to `done === true`), passed by\n\t\t * the host so a freshly (re)mounted wizard doesn't re-ask something\n\t\t * already persisted in an earlier session — this component's own\n\t\t * `localDone`/`choiceModel` only track the CURRENT session and reset\n\t\t * blank on every mount. Drives both the initial step (`initialStepId`)\n\t\t * and the summary page's done markers.\n\t\t *\n\t\t * @type {Array<string>}\n\t\t */\n\t\tcompletedStepIds: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\t},\n\n\temits: ['complete', 'close', 'step-change', 'action-result'],\n\n\t/**\n\t * Live option lists come from the app's own setup status document, so a\n\t * step that offers a choice of things the SERVER ships never has to\n\t * restate them in the manifest. `useSetupStatus` caches per app id, so the\n\t * host's own status fetch (CnAppRoot's setup gate) is the one that runs —\n\t * this reads the same refs rather than asking again.\n\t *\n\t * Only called when a step actually declares `optionsSource`: a wizard with\n\t * none must not start making requests it never made before.\n\t *\n\t * @param {object} props The component props.\n\t * @return {object} `setupStatus` / `setupStatusLoading` for the option resolver.\n\t */\n\tsetup(props) {\n\t\tconst wantsSource = (props.steps || []).some((s) => s && s.optionsSource)\n\t\tif (!wantsSource) {\n\t\t\treturn {}\n\t\t}\n\t\tconst { status, loading } = useSetupStatus(props.appId, { setup: { steps: props.steps } })\n\t\treturn { setupStatus: status, setupStatusLoading: loading }\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tchoiceModel: {},\n\t\t\tchoiceValues: {},\n\t\t\tconfigModel: {},\n\t\t\trunning: {},\n\t\t\tactionResult: {},\n\t\t\tlocalDone: {},\n\t\t\tuserTouched: {},\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The title actually rendered by CnWizardDialog: \"Set up {appName}\"\n\t\t * when a display name was passed, otherwise whatever `dialogTitle`\n\t\t * resolves to (a caller override, or its own generic default).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedDialogTitle() {\n\t\t\treturn this.appName\n\t\t\t\t? t('nextcloud-vue', 'Set up {app}', { app: this.appName })\n\t\t\t\t: this.dialogTitle\n\t\t},\n\n\t\tsetupSteps() {\n\t\t\treturn (this.steps || []).filter((s) => s && s.id && s.type)\n\t\t},\n\n\t\twizardSteps() {\n\t\t\treturn this.setupSteps.map((s) => ({\n\t\t\t\tid: s.id,\n\t\t\t\tlabel: this.stepTitle(s),\n\t\t\t\toptional: s.required !== true,\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Recap rows for the `summary` step — one per non-summary step, with\n\t\t * the value the user selected (choice label / config field values) and\n\t\t * a done marker (info steps always done; choice steps done when picked;\n\t\t * run-action steps done when the action succeeded).\n\t\t *\n\t\t * An on-demand step (`onDemand: true`) is the exception: it is done\n\t\t * only when its action succeeded in THIS session. Apps report such a\n\t\t * step as `done` on purpose so it never auto-runs (learniq's \"Remove\n\t\t * the example data\"), and reading that flag here ticked a removal\n\t\t * nobody ran. When it did not run it gets `notRun: true` and the value\n\t\t * \"Not run\" instead.\n\t\t *\n\t\t * @return {Array<{ id: string, title: string, value: string, done: boolean, notRun: boolean }>}\n\t\t */\n\t\tsummaryItems() {\n\t\t\treturn this.setupSteps\n\t\t\t\t.filter((s) => s.type !== 'summary')\n\t\t\t\t.map((step) => {\n\t\t\t\t\tlet value = ''\n\t\t\t\t\tif (step.type === 'choice') {\n\t\t\t\t\t\tconst raw = this.choiceModel[step.id]\n\t\t\t\t\t\tif (Array.isArray(raw)) {\n\t\t\t\t\t\t\tvalue = raw.map((o) => this.choiceLabel(step, o)).join(', ')\n\t\t\t\t\t\t} else if (raw !== null && raw !== undefined && raw !== '') {\n\t\t\t\t\t\t\tvalue = this.choiceLabel(step, raw)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (step.type === 'config-fields') {\n\t\t\t\t\t\tvalue = this.fieldsFor(step)\n\t\t\t\t\t\t\t.map((f) => `${f.label}: ${this.configModel[f.key] !== null && this.configModel[f.key] !== undefined ? this.configModel[f.key] : ''}`)\n\t\t\t\t\t\t\t.join(', ')\n\t\t\t\t\t}\n\t\t\t\t\tif (this.isOnDemand(step)) {\n\t\t\t\t\t\tconst ran = this.ranThisSession(step.id)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: step.id,\n\t\t\t\t\t\t\ttitle: this.stepTitle(step),\n\t\t\t\t\t\t\tvalue: ran ? '' : t('nextcloud-vue', 'Not run'),\n\t\t\t\t\t\t\tdone: ran,\n\t\t\t\t\t\t\tnotRun: !ran,\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlet done\n\t\t\t\t\tif (step.type === 'info') {\n\t\t\t\t\t\tdone = true\n\t\t\t\t\t} else if (step.type === 'choice') {\n\t\t\t\t\t\tdone = this.hasChoice(step) || this.isServerDone(step.id)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdone = this.isStepDone(step.id)\n\t\t\t\t\t}\n\t\t\t\t\treturn { id: step.id, title: this.stepTitle(step), value, done, notRun: false }\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Id of the step the wizard should open on when RESUMING: the first\n\t\t * non-`info`/`summary` step not already done, per the CURRENT session's\n\t\t * local state OR the server-reported `completedStepIds` (a prior\n\t\t * session). Falls back to `''` (CnWizardDialog's own first-step default)\n\t\t * on a fresh setup and when every actionable step is already done.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tinitialStepId() {\n\t\t\t// Fresh setup — nothing done anywhere yet, so there is nothing to\n\t\t\t// resume past. Start at step one so a leading `info`/welcome step is\n\t\t\t// actually seen; resuming is only for returning sessions.\n\t\t\tif (this.completedStepIds.length === 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\t// An on-demand step is never outstanding work, so it is never the\n\t\t\t// step to resume on.\n\t\t\tconst actionable = this.setupSteps.filter((s) => s.type !== 'info' && s.type !== 'summary' && !this.isOnDemand(s))\n\t\t\tconst firstUnmetIndex = actionable.findIndex((s) => {\n\t\t\t\tif (s.type === 'choice') {\n\t\t\t\t\treturn !(this.hasChoice(s) || this.isServerDone(s.id))\n\t\t\t\t}\n\t\t\t\treturn !this.isStepDone(s.id)\n\t\t\t})\n\t\t\t// Done is not the same as seen: an app that pre-satisfies a step at\n\t\t\t// install time (buildiq seeds templates from a repair step) reports it\n\t\t\t// done before anyone opens the wizard. Only finished work BEFORE the\n\t\t\t// outstanding step means there is something to resume past.\n\t\t\tif (firstUnmetIndex <= 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn actionable[firstUnmetIndex].id\n\t\t},\n\t},\n\n\tmounted() {\n\t\t// Covers a RESUMED wizard opening straight onto its run-action step\n\t\t// (`initialStepId`) — `onStepChange` only fires on later navigation,\n\t\t// so a step already active at mount time needs its own trigger.\n\t\tthis.maybeAutoRunStep(this.initialStepId || (this.setupSteps[0] && this.setupSteps[0].id))\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Start a `run-action` step's action automatically the moment it\n\t\t * becomes current, instead of waiting for a manual \"Run\" click —\n\t\t * the step has nothing else for the user to decide by then (the\n\t\t * choice it acts on was already made on an earlier step), so\n\t\t * requiring a click before showing progress just adds a stall.\n\t\t * No-ops for any other step type, or one already run/running, and\n\t\t * never fires an on-demand step (`onDemand: true`): those run only\n\t\t * when the user clicks Run.\n\t\t *\n\t\t * @param {string} stepId The step id becoming current.\n\t\t * @return {void}\n\t\t */\n\t\tmaybeAutoRunStep(stepId) {\n\t\t\tconst step = this.setupSteps.find((s) => s.id === stepId)\n\t\t\tif (step && step.type === 'run-action' && !this.isOnDemand(step) && !this.isStepDone(step.id) && !this.running[step.id]) {\n\t\t\t\tthis.runAction(step)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The visible title for a step, resolved through the host app's\n\t\t * translation function.\n\t\t *\n\t\t * `manifest.setup.steps[].title` is authored in English as the\n\t\t * canonical source, exactly like the schema property titles this\n\t\t * component already routes through `cnTranslate` for field labels\n\t\t * (see `fieldsFromSchema` below). The step titles were the one\n\t\t * remaining place rendering the manifest string verbatim, so an\n\t\t * nl-locale user saw a wizard whose field labels were translated and\n\t\t * whose step headings were not.\n\t\t *\n\t\t * Falls back to the step id when a step declares no title, which is\n\t\t * the same fallback the raw bindings used.\n\t\t *\n\t\t * @param {object} step A `manifest.setup.steps[]` entry.\n\t\t * @return {string} The translated title, or the step id.\n\t\t */\n\t\tstepTitle(step) {\n\t\t\tconst raw = (step && step.title) || (step && step.id) || ''\n\t\t\treturn raw === '' ? '' : this.cnTranslate(raw)\n\t\t},\n\n\t\t/**\n\t\t * The visible body for a step, resolved through the host app's\n\t\t * translation function.\n\t\t *\n\t\t * 🔴 THIS USED TO RENDER THE MANIFEST STRING VERBATIM, IN FOUR PLACES.\n\t\t * `stepTitle()` was routed through `cnTranslate` and the body was not,\n\t\t * so a wizard on a Dutch instance showed a translated heading over an\n\t\t * English paragraph, with translated Cancel/Next buttons underneath.\n\t\t * That reads as a bug rather than as a missing string, and the app could\n\t\t * not fix it: decidiq shipped correct Dutch for its setup copy in\n\t\t * `l10n/nl.json`, and the component never asked for it.\n\t\t *\n\t\t * @param {object} step The step declaration.\n\t\t * @return {string} The translated body, or ''.\n\t\t */\n\t\tstepBody(step) {\n\t\t\tconst raw = (step && step.body) || ''\n\t\t\treturn raw === '' ? '' : this.cnTranslate(raw)\n\t\t},\n\n\t\tstepSlot(step) {\n\t\t\treturn 'step-' + step.id\n\t\t},\n\n\t\thasCustomSlot(id) {\n\t\t\treturn !!this.$slots['step-' + id] || !!this.$slots['step-' + id]\n\t\t},\n\n\t\tfieldsFor(step) {\n\t\t\tif (step.schema && typeof step.schema === 'object') {\n\t\t\t\treturn fieldsFromSchema(step.schema, { translate: this.cnTranslate })\n\t\t\t}\n\t\t\t// Fallback: a plain text field per declared config key.\n\t\t\treturn (step.configKeys || []).map((key) => ({ key, label: key, widget: 'text' }))\n\t\t},\n\n\t\t/**\n\t\t * Options for a `choice` step. When the step declares `dependsOn`\n\t\t * (a parent step's configKey) + `optionsByParent`, the option list\n\t\t * is the entry keyed by the parent's currently-selected value — this\n\t\t * is the country → organisation-type cascade. Otherwise the static\n\t\t * `options` array.\n\t\t *\n\t\t * @param {object} step The choice step definition.\n\t\t * @return {Array} The option list to render.\n\t\t */\n\t\toptionsFor(step) {\n\t\t\tlet options = step.options || []\n\t\t\tif (step.optionsSource) {\n\t\t\t\toptions = this.sourcedOptions(step)\n\t\t\t} else if (step.dependsOn && step.optionsByParent) {\n\t\t\t\tconst parentValue = this.choiceValues[step.dependsOn]\n\t\t\t\toptions = (parentValue === null || parentValue === undefined || parentValue === '')\n\t\t\t\t\t? []\n\t\t\t\t\t: (step.optionsByParent[parentValue] || [])\n\t\t\t}\n\t\t\t// The LABEL is translated, the VALUE never is. `scalarChoice()` reads\n\t\t\t// `.value` and that is what reaches `POST /api/setup/config`, so a\n\t\t\t// translated label cannot change what gets stored — while an\n\t\t\t// untranslated one leaves the choice itself in English on a\n\t\t\t// localised instance, which is the half-translated screen this fix\n\t\t\t// exists to remove.\n\t\t\treturn options.map((option) => {\n\t\t\t\tif (!option || typeof option !== 'object' || !option.label) {\n\t\t\t\t\treturn option\n\t\t\t\t}\n\t\t\t\tconst translated = { ...option, label: this.cnTranslate(option.label) }\n\t\t\t\tif (option.description) {\n\t\t\t\t\ttranslated.description = this.cnTranslate(option.description)\n\t\t\t\t}\n\t\t\t\treturn translated\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The option list a `choice` step declares `optionsSource` for, read\n\t\t * from the setup status document the app already serves.\n\t\t *\n\t\t * `optionsSource` names a key in that document (dots walk into nested\n\t\t * objects), and the entries are normalised to the option shape: `id` is\n\t\t * accepted for `value`, `name` for `label`, and a bare `objectCount`\n\t\t * becomes the one stat a card shows. A server that already sends\n\t\t * `stats` keeps them.\n\t\t *\n\t\t * @param {object} step The choice step declaring `optionsSource`.\n\t\t * @return {Array<object>} The options, or [] while the status is loading.\n\t\t */\n\t\tsourcedOptions(step) {\n\t\t\tlet node = this.setupStatus\n\t\t\tfor (const key of String(step.optionsSource).split('.')) {\n\t\t\t\tif (node === null || node === undefined || typeof node !== 'object') {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\tnode = node[key]\n\t\t\t}\n\t\t\tif (!Array.isArray(node)) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn node\n\t\t\t\t.filter((entry) => entry && typeof entry === 'object')\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tconst value = entry.value !== undefined ? entry.value : entry.id\n\t\t\t\t\tconst option = {\n\t\t\t\t\t\t...entry,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tlabel: entry.label || entry.name || String(value),\n\t\t\t\t\t}\n\t\t\t\t\tif (!option.stats && typeof entry.objectCount === 'number' && entry.objectCount > 0) {\n\t\t\t\t\t\toption.stats = [{ label: t('nextcloud-vue', 'Objects'), value: entry.objectCount }]\n\t\t\t\t\t}\n\t\t\t\t\treturn option\n\t\t\t\t})\n\t\t\t\t.filter((option) => option.value !== undefined)\n\t\t},\n\n\t\t/**\n\t\t * Whether a choice step renders as a card grid rather than a dropdown.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {boolean} True for `display: \"cards\"`.\n\t\t */\n\t\tisCardChoice(step) {\n\t\t\treturn step.display === 'cards'\n\t\t},\n\n\t\t/**\n\t\t * Whether this step is still waiting for its live option list.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {boolean} True while the status document is in flight.\n\t\t */\n\t\tisOptionsLoading(step) {\n\t\t\treturn !!step.optionsSource && this.setupStatusLoading === true\n\t\t},\n\n\t\t/**\n\t\t * The card grid's model: plain values, not the option objects NcSelect\n\t\t * binds. `scalarChoice` already reduces either shape to values, so both\n\t\t * renderers can share one `choiceModel` entry.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @return {unknown} The selected value, or [] / null when nothing is picked.\n\t\t */\n\t\tcardModel(step) {\n\t\t\tconst value = this.scalarChoice(step)\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn Array.isArray(value) ? value : []\n\t\t\t}\n\t\t\treturn value === undefined ? null : value\n\t\t},\n\n\t\tisChoiceDisabled(step) {\n\t\t\tif (!step.dependsOn) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst parentValue = this.choiceValues[step.dependsOn]\n\t\t\treturn parentValue === null || parentValue === undefined || parentValue === ''\n\t\t},\n\n\t\tdependsOnHint(step) {\n\t\t\tconst parent = this.setupSteps.find((s) => s.configKey === step.dependsOn)\n\t\t\tconst label = parent ? (parent.title || parent.id) : step.dependsOn\n\t\t\treturn t('nextcloud-vue', 'Select \"{step}\" first.', { step: label })\n\t\t},\n\n\t\t/**\n\t\t * The visible label for one selected choice entry.\n\t\t *\n\t\t * A card grid stores plain VALUES where NcSelect stores option objects,\n\t\t * so the recap looked one up and printed the other: the summary read\n\t\t * \"municipality\" instead of \"Municipality\". Resolves a bare value back\n\t\t * to its option, and falls back to the value when the option list is\n\t\t * not (yet) available.\n\t\t *\n\t\t * @param {object} step The choice step.\n\t\t * @param {unknown} entry One selected entry: an option object or a value.\n\t\t * @return {string} The label to show.\n\t\t */\n\t\tchoiceLabel(step, entry) {\n\t\t\tif (entry && typeof entry === 'object' && entry.label) {\n\t\t\t\treturn entry.label\n\t\t\t}\n\t\t\tconst match = this.optionsFor(step).find((o) => o && String(o.value) === String(entry))\n\t\t\treturn (match && match.label) ? match.label : String(entry)\n\t\t},\n\n\t\thasChoice(step) {\n\t\t\tconst v = this.choiceModel[step.id]\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn Array.isArray(v) && v.length > 0\n\t\t\t}\n\t\t\treturn v !== null && v !== undefined && v !== ''\n\t\t},\n\n\t\tscalarChoice(step) {\n\t\t\tconst raw = this.choiceModel[step.id]\n\t\t\tif (step.multiple === true) {\n\t\t\t\treturn (raw || []).map((o) => (o && o.value !== undefined ? o.value : o))\n\t\t\t}\n\t\t\treturn raw && raw.value !== undefined ? raw.value : raw\n\t\t},\n\n\t\tonChoice(step, value) {\n\t\t\tthis.userTouched[step.id] = true\n\t\t\tthis.choiceModel[step.id] = value\n\t\t\tif (step.configKey) {\n\t\t\t\tthis.choiceValues[step.configKey] = this.scalarChoice(step)\n\t\t\t}\n\t\t\t// Reset any dependent child choices when the parent changes.\n\t\t\tfor (const child of this.setupSteps) {\n\t\t\t\tif (child.dependsOn && child.dependsOn === step.configKey) {\n\t\t\t\t\tthis.choiceModel[child.id] = child.multiple === true ? [] : null\n\t\t\t\t\tthis.userTouched[child.id] = false\n\t\t\t\t\tif (child.configKey) {\n\t\t\t\t\t\tthis.choiceValues[child.configKey] = ''\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Re-apply auto-suggestions for steps that derive a default from this one.\n\t\t\tfor (const dep of this.setupSteps) {\n\t\t\t\tif (dep.suggestFrom && dep.suggestFrom === step.configKey) {\n\t\t\t\t\tthis.applySuggestion(dep)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Auto-fill a `choice` step's suggested default from an earlier choice\n\t\t * (its `suggestFrom` configKey → `suggestMap[parentValue]`). No-op once\n\t\t * the user has manually picked here, so a suggestion never clobbers an\n\t\t * explicit choice.\n\t\t *\n\t\t * @param {object} step The dependent choice step.\n\t\t * @return {void}\n\t\t */\n\t\tapplySuggestion(step) {\n\t\t\tif (this.userTouched[step.id] === true) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst parentValue = this.choiceValues[step.suggestFrom]\n\t\t\tif (parentValue === null || parentValue === undefined || parentValue === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst wanted = (step.suggestMap || {})[parentValue]\n\t\t\tif (wanted === null || wanted === undefined) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst opt = this.optionsFor(step).find((o) => o.value === wanted) || { value: wanted, label: String(wanted) }\n\t\t\tthis.choiceModel[step.id] = opt\n\t\t\tif (step.configKey) {\n\t\t\t\tthis.choiceValues[step.configKey] = wanted\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * CnWizardDialog `validate` hook — intercepts Next/Submit to persist\n\t\t * the active step before advancing. `choice`/`config-fields` steps\n\t\t * POST their value via the setup contract; required `choice` steps\n\t\t * block advance until a value is picked; required `run-action` steps\n\t\t * block until the action has succeeded. Returns `true` to advance or\n\t\t * an error string to surface above the step and block navigation.\n\t\t *\n\t\t * @param {string} stepId The active step id.\n\t\t * @return {Promise<boolean|string>} True to advance, or an error message.\n\t\t */\n\t\tasync validateStep(stepId) {\n\t\t\tconst step = this.setupSteps.find((s) => s.id === stepId)\n\t\t\tif (!step) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (step.type === 'choice') {\n\t\t\t\tif (!this.hasChoice(step)) {\n\t\t\t\t\t// Already persisted server-side and the user only back-navigated\n\t\t\t\t\t// onto it — `choiceModel` is blank because it's session-local, not\n\t\t\t\t\t// because nothing is set. Don't force a re-pick, and don't re-POST.\n\t\t\t\t\tif (this.isServerDone(step.id)) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t\treturn step.required === true\n\t\t\t\t\t\t? t('nextcloud-vue', 'Please make a selection to continue.')\n\t\t\t\t\t\t: true\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait this.saveConfig({ [step.configKey]: this.scalarChoice(step) })\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t\treturn true\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn this.errorMessage(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (step.type === 'config-fields') {\n\t\t\t\ttry {\n\t\t\t\t\tconst patch = {}\n\t\t\t\t\tfor (const field of this.fieldsFor(step)) {\n\t\t\t\t\t\tpatch[field.key] = this.configModel[field.key]\n\t\t\t\t\t}\n\t\t\t\t\tawait this.saveConfig(patch)\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t\treturn true\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn this.errorMessage(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (step.type === 'run-action' && step.required === true && !this.isStepDone(step.id)) {\n\t\t\t\treturn t('nextcloud-vue', 'Please run this step before continuing.')\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\n\t\t/**\n\t\t * Persist one or more app-config values via the setup contract.\n\t\t *\n\t\t * @param {object} patch `{ <configKey>: value }` to write.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync saveConfig(patch) {\n\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\timport('@nextcloud/router'),\n\t\t\t])\n\t\t\tawait axios.post(generateUrl(`/apps/${this.appId}/api/setup/config`), patch)\n\t\t},\n\n\t\tasync runAction(step) {\n\t\t\tthis.running[step.id] = true\n\t\t\tthis.actionResult[step.id] = null\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst { data } = await axios.post(generateUrl(`/apps/${this.appId}/api/setup/action/${step.action}`))\n\t\t\t\tconst result = {\n\t\t\t\t\tsuccess: data && data.success !== false,\n\t\t\t\t\tmessage: (data && data.message) || t('nextcloud-vue', 'Done.'),\n\t\t\t\t}\n\t\t\t\tthis.actionResult[step.id] = result\n\t\t\t\tif (result.success) {\n\t\t\t\t\tthis.localDone[step.id] = true\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * @event action-result Emitted when a `run-action` step finishes.\n\t\t\t\t * @type {{ stepId: string, action: string, success: boolean, message: string }}\n\t\t\t\t */\n\t\t\t\tthis.$emit('action-result', { stepId: step.id, action: step.action, ...result })\n\t\t\t} catch (err) {\n\t\t\t\tthis.actionResult[step.id] = { success: false, message: this.errorMessage(err) }\n\t\t\t\tthis.$emit('action-result', { stepId: step.id, action: step.action, success: false, message: this.errorMessage(err) })\n\t\t\t} finally {\n\t\t\t\tthis.running[step.id] = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Whether a step is marked on-demand (`onDemand: true`): it runs only\n\t\t * when the user asks, never automatically, and the summary ticks it\n\t\t * only when it ran in this session.\n\t\t *\n\t\t * @param {object} step The manifest step.\n\t\t * @return {boolean}\n\t\t */\n\t\tisOnDemand(step) {\n\t\t\treturn !!step && step.onDemand === true\n\t\t},\n\n\t\t/**\n\t\t * Whether a step's action succeeded in the CURRENT session, ignoring\n\t\t * whatever the server reports.\n\t\t *\n\t\t * @param {string} id Step id.\n\t\t * @return {boolean}\n\t\t */\n\t\tranThisSession(id) {\n\t\t\treturn !!(this.actionResult[id] && this.actionResult[id].success)\n\t\t},\n\n\t\tisStepDone(id) {\n\t\t\treturn this.isServerDone(id) || this.localDone[id] === true || (this.actionResult[id] && this.actionResult[id].success)\n\t\t},\n\n\t\t/**\n\t\t * Whether the server already reported this step done in a prior\n\t\t * session, via the `completedStepIds` prop.\n\t\t *\n\t\t * @param {string} id Step id.\n\t\t * @return {boolean}\n\t\t */\n\t\tisServerDone(id) {\n\t\t\treturn this.completedStepIds.includes(id)\n\t\t},\n\n\t\tonSubmit() {\n\t\t\tif (this.$refs.wizard && this.$refs.wizard.setResult) {\n\t\t\t\tthis.$refs.wizard.setResult({ success: true, message: this.successText })\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event complete Emitted when the last step is submitted (setup finished).\n\t\t\t */\n\t\t\tthis.$emit('complete')\n\t\t},\n\n\t\tonStepChange(payload) {\n\t\t\t// Pre-fill a suggested default when entering a step that derives one.\n\t\t\tconst step = this.setupSteps.find((s) => s.id === payload.stepId)\n\t\t\tif (step && step.suggestFrom) {\n\t\t\t\tthis.applySuggestion(step)\n\t\t\t}\n\t\t\tthis.maybeAutoRunStep(payload.stepId)\n\t\t\t/**\n\t\t\t * @event step-change Emitted when the active step changes.\n\t\t\t * @type {{ stepId: string, stepIndex: number, direction: string }}\n\t\t\t */\n\t\t\tthis.$emit('step-change', payload)\n\t\t},\n\n\t\tonClose() {\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\n\t\terrorMessage(err) {\n\t\t\tconst data = err && err.response && err.response.data\n\t\t\tif (data && (data.message || data.error)) {\n\t\t\t\treturn data.message || data.error\n\t\t\t}\n\t\t\treturn (err && err.message) || t('nextcloud-vue', 'Something went wrong.')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-setup-step {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n.cn-setup-step__nav {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tgap: 8px;\n\tmargin-top: 8px;\n}\n\n.cn-setup-step__running {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 8px;\n\tpadding: 24px 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-setup-field {\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.cn-setup-summary {\n\tlist-style: none;\n\tpadding: 0;\n\tmargin: 0;\n}\n\n.cn-setup-summary__item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 4px 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-setup-summary__item--done {\n\tcolor: var(--color-main-text);\n}\n\n.cn-setup-summary__mark {\n\tfont-weight: bold;\n\tcolor: var(--color-success);\n}\n\n.cn-setup-summary__label {\n\tflex: 0 0 auto;\n}\n\n.cn-setup-summary__value {\n\tmargin-inline-start: auto;\n\tfont-weight: 600;\n\tcolor: var(--color-main-text);\n}\n\n/* An on-demand step that did not run says so quietly: it is a choice the\n user did not make, not a failure. */\n.cn-setup-summary__item--not-run .cn-setup-summary__value {\n\tfont-weight: normal;\n\tcolor: var(--color-text-maxcontrast);\n}\n</style>\n"],"names":["_createBlock","_renderList","_renderSlot","_mergeProps","_createTextVNode","_toDisplayString","_createElementBlock","_Fragment","_openBlock","_createVNode","_createElementVNode","_normalizeClass"],"mappings":"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"}
|
package/dist/esm/l10n/en.json.js
CHANGED
|
@@ -351,6 +351,7 @@ var translations = {
|
|
|
351
351
|
"No widgets configured": "No widgets configured",
|
|
352
352
|
"Not configured": "Not configured",
|
|
353
353
|
"Not set": "Not set",
|
|
354
|
+
"Not run": "Not run",
|
|
354
355
|
Notes: "Notes",
|
|
355
356
|
"Number": "Number",
|
|
356
357
|
"Number configuration": "Number configuration",
|