mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
UX: shows a save changes for intermediate steps (#6612)
This commit is contained in:
parent
d5df746cc3
commit
1730e0bc73
@ -40,6 +40,16 @@ export default Ember.Component.extend({
|
|||||||
@computed("step.displayIndex", "wizard.totalSteps")
|
@computed("step.displayIndex", "wizard.totalSteps")
|
||||||
showDoneButton: (current, total) => current === total,
|
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;
|
||||||
|
},
|
||||||
|
|
||||||
@computed("step.index")
|
@computed("step.index")
|
||||||
showBackButton: index => index > 0,
|
showBackButton: index => index > 0,
|
||||||
|
|
||||||
@ -112,6 +122,24 @@ export default Ember.Component.extend({
|
|||||||
document.location = getUrl("/");
|
document.location = getUrl("/");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
exitEarly() {
|
||||||
|
const step = this.get("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();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
backStep() {
|
backStep() {
|
||||||
if (this.get("saving")) {
|
if (this.get("saving")) {
|
||||||
return;
|
return;
|
||||||
|
@ -43,6 +43,12 @@
|
|||||||
</button>
|
</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if showFinishButton}}
|
||||||
|
<button class='wizard-btn finish' {{action "exitEarly"}} disabled={{saving}} tabindex="10">
|
||||||
|
{{i18n "save"}}
|
||||||
|
</button>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#if showDoneButton}}
|
{{#if showDoneButton}}
|
||||||
<button class='wizard-btn done' {{action "quit"}} disabled={{saving}} tabindex="10">
|
<button class='wizard-btn done' {{action "quit"}} disabled={{saving}} tabindex="10">
|
||||||
{{i18n "wizard.done"}}
|
{{i18n "wizard.done"}}
|
||||||
|
@ -24,7 +24,7 @@ test("Going back and forth in steps", async assert => {
|
|||||||
exists(".wizard-step-hello-world"),
|
exists(".wizard-step-hello-world"),
|
||||||
"it adds a class for the step id"
|
"it adds a class for the step id"
|
||||||
);
|
);
|
||||||
|
assert.ok(!exists(".wizard-btn.finish"), "can’t finish on first step");
|
||||||
assert.ok(exists(".wizard-progress"));
|
assert.ok(exists(".wizard-progress"));
|
||||||
assert.ok(exists(".wizard-step-title"));
|
assert.ok(exists(".wizard-step-title"));
|
||||||
assert.ok(exists(".wizard-step-description"));
|
assert.ok(exists(".wizard-step-description"));
|
||||||
@ -50,15 +50,19 @@ test("Going back and forth in steps", async assert => {
|
|||||||
await fillIn("input.field-full-name", "Evil Trout");
|
await fillIn("input.field-full-name", "Evil Trout");
|
||||||
await click(".wizard-btn.next");
|
await click(".wizard-btn.next");
|
||||||
assert.ok(!exists(".wizard-field .field-error-description"));
|
assert.ok(!exists(".wizard-field .field-error-description"));
|
||||||
assert.ok(!exists(".wizard-step-title"));
|
|
||||||
assert.ok(!exists(".wizard-step-description"));
|
assert.ok(!exists(".wizard-step-description"));
|
||||||
|
assert.ok(
|
||||||
|
exists(".wizard-btn.finish"),
|
||||||
|
"shows finish on an intermediate step"
|
||||||
|
);
|
||||||
|
|
||||||
|
await click(".wizard-btn.next");
|
||||||
assert.ok(exists(".select-kit.field-snack"), "went to the next step");
|
assert.ok(exists(".select-kit.field-snack"), "went to the next step");
|
||||||
assert.ok(exists(".preview-area"), "renders the component field");
|
assert.ok(exists(".preview-area"), "renders the component field");
|
||||||
|
|
||||||
assert.ok(!exists(".wizard-btn.next"));
|
|
||||||
assert.ok(exists(".wizard-btn.done"), "last step shows a done button");
|
assert.ok(exists(".wizard-btn.done"), "last step shows a done button");
|
||||||
assert.ok(exists(".action-link.back"), "shows the back button");
|
assert.ok(exists(".action-link.back"), "shows the back button");
|
||||||
|
assert.ok(!exists(".wizard-step-title"));
|
||||||
|
assert.ok(!exists(".wizard-btn.finish"), "can’t finish on last step");
|
||||||
|
|
||||||
await click(".action-link.back");
|
await click(".action-link.back");
|
||||||
assert.ok(exists(".wizard-step-title"));
|
assert.ok(exists(".wizard-step-title"));
|
||||||
|
@ -33,6 +33,7 @@ export default function() {
|
|||||||
return response(200, {
|
return response(200, {
|
||||||
wizard: {
|
wizard: {
|
||||||
start: "hello-world",
|
start: "hello-world",
|
||||||
|
completed: true,
|
||||||
steps: [
|
steps: [
|
||||||
{
|
{
|
||||||
id: "hello-world",
|
id: "hello-world",
|
||||||
@ -51,13 +52,21 @@ export default function() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "second-step",
|
id: "second-step",
|
||||||
|
title: "Second step",
|
||||||
index: 1,
|
index: 1,
|
||||||
|
fields: [{ id: "some-title", type: "text" }],
|
||||||
|
previous: "hello-world",
|
||||||
|
next: "last-step"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "last-step",
|
||||||
|
index: 2,
|
||||||
fields: [
|
fields: [
|
||||||
{ id: "snack", type: "dropdown", required: true },
|
{ id: "snack", type: "dropdown", required: true },
|
||||||
{ id: "theme-preview", type: "component" },
|
{ id: "theme-preview", type: "component" },
|
||||||
{ id: "an-image", type: "image" }
|
{ id: "an-image", type: "image" }
|
||||||
],
|
],
|
||||||
previous: "hello-world"
|
previous: "second-step"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -370,7 +370,8 @@ body.wizard {
|
|||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.wizard-btn.done {
|
button.wizard-btn.done,
|
||||||
|
button.wizard-btn.finish {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #33b333;
|
background-color: #33b333;
|
||||||
|
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
class WizardSerializer < ApplicationSerializer
|
class WizardSerializer < ApplicationSerializer
|
||||||
attributes :start
|
attributes :start, :completed
|
||||||
|
|
||||||
has_many :steps, serializer: WizardStepSerializer, embed: :objects
|
has_many :steps, serializer: WizardStepSerializer, embed: :objects
|
||||||
|
|
||||||
def start
|
def start
|
||||||
object.start.id
|
object.start.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def completed
|
||||||
|
object.completed?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user