discourse/app/assets/javascripts/wizard/components/wizard-step.js.es6

192 lines
4.1 KiB
Plaintext
Raw Normal View History

2019-10-30 02:52:36 +08:00
import { scheduleOnce } from "@ember/runloop";
import Component from "@ember/component";
2018-06-15 23:03:24 +08:00
import getUrl from "discourse-common/lib/get-url";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
2016-08-26 01:14:56 +08:00
2018-06-15 23:03:24 +08:00
jQuery.fn.wiggle = function(times, duration) {
if (times > 0) {
2018-06-15 23:03:24 +08:00
this.animate(
{
marginLeft: times-- % 2 === 0 ? -15 : 15
},
duration,
0,
() => this.wiggle(times, duration)
);
} else {
this.animate({ marginLeft: 0 }, duration, 0);
}
return this;
};
const alreadyWarned = {};
export default Component.extend({
2018-06-15 23:03:24 +08:00
classNames: ["wizard-step"],
2016-08-26 01:14:56 +08:00
saving: null,
didInsertElement() {
this._super(...arguments);
2016-08-26 01:14:56 +08:00
this.autoFocus();
},
2018-07-30 23:56:48 +08:00
@computed("step.index")
showQuitButton: index => index === 0,
2018-06-15 23:03:24 +08:00
@computed("step.displayIndex", "wizard.totalSteps")
2016-08-26 01:14:56 +08:00
showNextButton: (current, total) => current < total,
2018-06-15 23:03:24 +08:00
@computed("step.displayIndex", "wizard.totalSteps")
showDoneButton: (current, total) => current === total,
@computed(
"step.index",
"step.displayIndex",
"wizard.totalSteps",
"wizard.completed"
)
showFinishButton: (index, displayIndex, total, completed) => {
return index !== 0 && displayIndex !== total && completed;
},
2018-07-30 23:56:48 +08:00
@computed("step.index")
showBackButton: index => index > 0,
2016-08-26 01:14:56 +08:00
2018-06-15 23:03:24 +08:00
@computed("step.banner")
bannerImage(src) {
2018-06-15 23:03:24 +08:00
if (!src) {
return;
}
return getUrl(`/images/wizard/${src}`);
},
2018-06-15 23:03:24 +08:00
@observes("step.id")
2016-08-26 01:14:56 +08:00
_stepChanged() {
2018-06-15 23:03:24 +08:00
this.set("saving", false);
2016-08-26 01:14:56 +08:00
this.autoFocus();
},
keyPress(key) {
if (key.keyCode === 13) {
if (this.showDoneButton) {
2018-06-15 23:03:24 +08:00
this.send("quit");
} else {
2018-06-15 23:03:24 +08:00
this.send("nextStep");
}
2016-08-26 01:14:56 +08:00
}
},
2018-06-15 23:03:24 +08:00
@computed("step.index", "wizard.totalSteps")
2016-08-26 01:14:56 +08:00
barStyle(displayIndex, totalSteps) {
2016-09-21 02:04:18 +08:00
let ratio = parseFloat(displayIndex) / parseFloat(totalSteps - 1);
2018-06-15 23:03:24 +08:00
if (ratio < 0) {
ratio = 0;
}
if (ratio > 1) {
ratio = 1;
}
2016-09-21 02:04:18 +08:00
return Ember.String.htmlSafe(`width: ${ratio * 200}px`);
2016-08-26 01:14:56 +08:00
},
autoFocus() {
2019-10-30 02:52:36 +08:00
scheduleOnce("afterRender", () => {
2018-06-15 23:03:24 +08:00
const $invalid = $(".wizard-field.invalid:eq(0) .wizard-focusable");
2016-08-26 01:14:56 +08:00
if ($invalid.length) {
return $invalid.focus();
}
2018-06-15 23:03:24 +08:00
$(".wizard-focusable:eq(0)").focus();
2016-08-26 01:14:56 +08:00
});
},
animateInvalidFields() {
2019-10-30 02:52:36 +08:00
scheduleOnce("afterRender", () =>
2018-06-15 23:03:24 +08:00
$(".invalid input[type=text], .invalid textarea").wiggle(2, 100)
);
},
advance() {
2018-06-15 23:03:24 +08:00
this.set("saving", true);
this.step
2018-06-15 23:03:24 +08:00
.save()
.then(response => this.goNext(response))
.catch(() => this.animateInvalidFields())
2018-06-15 23:03:24 +08:00
.finally(() => this.set("saving", false));
},
2016-08-26 01:14:56 +08:00
actions: {
quit() {
document.location = getUrl("/");
},
exitEarly() {
const step = this.step;
step.validate();
if (step.get("valid")) {
this.set("saving", true);
step
.save()
.then(() => this.send("quit"))
.catch(() => this.animateInvalidFields())
.finally(() => this.set("saving", false));
} else {
this.animateInvalidFields();
this.autoFocus();
}
},
2016-08-26 01:14:56 +08:00
backStep() {
if (this.saving) {
2018-06-15 23:03:24 +08:00
return;
}
this.goBack();
2016-08-26 01:14:56 +08:00
},
nextStep() {
if (this.saving) {
2018-06-15 23:03:24 +08:00
return;
}
2016-08-26 01:14:56 +08:00
const step = this.step;
const result = step.validate();
if (result.warnings.length) {
const unwarned = result.warnings.filter(w => !alreadyWarned[w]);
if (unwarned.length) {
2018-06-15 23:03:24 +08:00
unwarned.forEach(w => (alreadyWarned[w] = true));
return window.swal(
{
customClass: "wizard-warning",
title: "",
text: unwarned.map(w => I18n.t(`wizard.${w}`)).join("\n"),
type: "warning",
showCancelButton: true,
confirmButtonColor: "#6699ff"
},
confirmed => {
if (confirmed) {
this.advance();
}
}
2018-06-15 23:03:24 +08:00
);
}
}
2016-08-26 01:14:56 +08:00
2018-06-15 23:03:24 +08:00
if (step.get("valid")) {
this.advance();
2016-08-26 01:14:56 +08:00
} else {
this.animateInvalidFields();
2016-08-26 01:14:56 +08:00
this.autoFocus();
}
}
}
});