import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; import { on } from "@ember/modifier"; import { action } from "@ember/object"; import didInsert from "@ember/render-modifiers/modifiers/did-insert"; import didUpdate from "@ember/render-modifiers/modifiers/did-update"; import { schedule } from "@ember/runloop"; import { htmlSafe } from "@ember/template"; import emoji from "discourse/helpers/emoji"; import I18n from "discourse-i18n"; import WizardField from "./wizard-field"; const i18n = (...args) => I18n.t(...args); export default class WizardStepComponent extends Component { @tracked saving = false; get wizard() { return this.args.wizard; } get step() { return this.args.step; } get id() { return this.step.id; } /** * Step Back Button? Primary Action Secondary Action * ------------------------------------------------------------------ * First No Next N/A * ------------------------------------------------------------------ * ... Yes Next N/A * ------------------------------------------------------------------ * Ready Yes Jump In Configure More * ------------------------------------------------------------------ * ... Yes Next Exit Setup * ------------------------------------------------------------------ * Last Yes Jump In N/A * ------------------------------------------------------------------ * * Back Button: without saving, go back to the last page * Next Button: save, and if successful, go to the next page * Configure More: re-skinned next button * Exit Setup: without saving, go to the home page ("finish") * Jump In: on the "ready" page, it exits the setup ("finish"), on the * last page, it saves, and if successful, go to the home page */ get isFinalStep() { return this.step.displayIndex === this.wizard.steps.length; } get showBackButton() { return this.step.index > 0; } get showFinishButton() { const ready = this.wizard.findStep("ready"); const isReady = ready && this.step.index > ready.index; return isReady && !this.isFinalStep; } get showConfigureMore() { return this.id === "ready"; } get showJumpInButton() { return this.id === "ready" || this.isFinalStep; } get includeSidebar() { return !!this.step.fields.find((f) => f.showInSidebar); } @action stepChanged() { this.saving = false; this.autoFocus(); } @action onKeyUp(event) { if (event.key === "Enter") { if (this.showJumpInButton) { this.jumpIn(); } else { this.nextStep(); } } } @action autoFocus() { schedule("afterRender", () => { const firstInvalidElement = document.querySelector( ".wizard-container__input.invalid:nth-of-type(1) .wizard-focusable" ); if (firstInvalidElement) { return firstInvalidElement.focus(); } document.querySelector(".wizard-focusable:nth-of-type(1)")?.focus(); }); } async advance() { try { this.saving = true; const response = await this.step.save(); this.args.goNext(response); } finally { this.saving = false; } } @action finish(event) { event?.preventDefault(); if (this.saving) { return; } this.args.goHome(); } @action jumpIn(event) { event?.preventDefault(); if (this.saving) { return; } if (this.id === "ready") { this.finish(); } else { this.nextStep(); } } @action backStep(event) { event?.preventDefault(); if (this.saving) { return; } this.args.goBack(); } @action nextStep(event) { event?.preventDefault(); if (this.saving) { return; } if (this.step.validate()) { this.advance(); } else { this.autoFocus(); } } }