0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-25 10:40:28 +01:00
discourse-custom-wizard/assets/javascripts/wizard/initializers/custom-wizard-step.js.es6
Angus McLeod ceef3f4bc9
Step and field conditionality (#87)
* Re structure builder logic to allow for step conditionality

Concerns
- Performance. Look at whether the additional build in the steps controller can be reduced
- Does not work if applied to the last step.
- Certain conditions will not work with the first step(?)
- How should this be scoped to known functionality?

* Add indexes and conditions to steps and fields

* Complete and add spec

* Complete backend

* Complete step conditionality and field indexing

* Fix failing spec

* Update coverage

* Apply rubocop

* Apply prettier

* Apply prettier to wizard js

* Fix schema issues created in merge

* Remove setting label for force_final

* Improve client wizard cache naming

* Improve steps controller and spec conditionality

* Improve final step attribute naming

* Fix failing spec

* Linting

* Add one more final step test

* Linting

* Fix eslint issues

* Apply prettier

* Linting, syntax, merge and copy cleanups

* Update wizard-admin.scss

* Fix template linting

* Rubocop fixes
2021-04-20 23:28:19 +05:30

199 Zeilen
5,6 KiB
JavaScript

export default {
name: "custom-wizard-step",
initialize() {
if (window.location.pathname.indexOf("/w/") < 0) {
return;
}
const CustomWizard = requirejs(
"discourse/plugins/discourse-custom-wizard/wizard/models/custom"
).default;
const updateCachedWizard = requirejs(
"discourse/plugins/discourse-custom-wizard/wizard/models/custom"
).updateCachedWizard;
const StepModel = requirejs("wizard/models/step").default;
const StepComponent = requirejs("wizard/components/wizard-step").default;
const ajax = requirejs("wizard/lib/ajax").ajax;
const getUrl = requirejs("discourse-common/lib/get-url").default;
const discourseComputed = requirejs("discourse-common/utils/decorators")
.default;
const cook = requirejs(
"discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite"
).cook;
const { schedule } = requirejs("@ember/runloop");
const { alias, not } = requirejs("@ember/object/computed");
StepModel.reopen({
save() {
const wizardId = this.get("wizardId");
const fields = {};
this.get("fields").forEach((f) => {
if (f.type !== "text_only") {
fields[f.id] = f.value;
}
});
return ajax({
url: `/w/${wizardId}/steps/${this.get("id")}`,
type: "PUT",
data: { fields },
}).catch((response) => {
if (
response &&
response.responseJSON &&
response.responseJSON.errors
) {
let wizardErrors = [];
response.responseJSON.errors.forEach((err) => {
if (err.field === wizardId) {
wizardErrors.push(err.description);
} else if (err.field) {
this.fieldError(err.field, err.description);
} else if (err) {
wizardErrors.push(err);
}
});
if (wizardErrors.length) {
this.handleWizardError(wizardErrors.join("\n"));
}
this.animateInvalidFields();
throw response;
}
if (response && response.responseText) {
const responseText = response.responseText;
const start = responseText.indexOf(">") + 1;
const end = responseText.indexOf("plugins");
const message = responseText.substring(start, end);
this.handleWizardError(message);
throw message;
}
});
},
handleWizardError(message) {
this.set("message", {
state: "error",
text: message,
});
Ember.run.later(() => this.set("message", null), 6000);
},
});
StepComponent.reopen({
classNameBindings: ["step.id"],
autoFocus() {
schedule("afterRender", () => {
const $invalid = $(
".wizard-field.invalid:nth-of-type(1) .wizard-focusable"
);
if ($invalid.length) {
return $invalid.focus();
}
$(".wizard-focusable:first").focus();
});
},
animateInvalidFields() {
schedule("afterRender", () => {
let $element = $(
".invalid input[type=text],.invalid textarea,.invalid input[type=checkbox],.invalid .select-kit"
);
if ($element.length) {
$([document.documentElement, document.body]).animate(
{
scrollTop: $element.offset().top - 200,
},
400,
function () {
$element.wiggle(2, 100);
}
);
}
});
},
ensureStartsAtTop: function () {
window.scrollTo(0, 0);
}.observes("step.id"),
showQuitButton: function () {
const index = this.get("step.index");
const required = this.get("wizard.required");
return index === 0 && !required;
}.property("step.index", "wizard.required"),
cookedTitle: function () {
return cook(this.get("step.title"));
}.property("step.title"),
cookedDescription: function () {
return cook(this.get("step.description"));
}.property("step.description"),
bannerImage: function () {
const src = this.get("step.banner");
if (!src) {
return;
}
return getUrl(src);
}.property("step.banner"),
@discourseComputed("step.fields.[]")
primaryButtonIndex(fields) {
return fields.length + 1;
},
@discourseComputed("step.fields.[]")
secondaryButtonIndex(fields) {
return fields.length + 2;
},
handleMessage: function () {
const message = this.get("step.message");
this.sendAction("showMessage", message);
}.observes("step.message"),
showNextButton: not("step.final"),
showDoneButton: alias("step.final"),
advance() {
this.set("saving", true);
this.get("step")
.save()
.then((response) => {
updateCachedWizard(CustomWizard.build(response["wizard"]));
if (response["final"]) {
CustomWizard.finished(response);
} else {
this.sendAction("goNext", response);
}
})
.catch(() => this.animateInvalidFields())
.finally(() => this.set("saving", false));
},
keyPress() {},
actions: {
quit() {
this.get("wizard").skip();
},
done() {
this.send("nextStep");
},
showMessage(message) {
this.sendAction("showMessage", message);
},
},
});
},
};