mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 11:55:03 +03:00
✨ success/failure state spinner buttons (#566)
refs https://github.com/TryGhost/Ghost/issues/7515 - changes to `gh-task-button`: - can take `buttonText` (default: "Save"), `runningText` ("Saving"), `successText` ("Saved"), and `failureText` ("Retry") params - positional param for `buttonText` - default button display can be overridden by passing in a block, in that scenario the component will yield a hash containing all states to be used in this fashion: ``` {{#gh-task-button task=myTask as |task|}} {{if task.isIdle "Save me"}} {{if task.isRunning "Saving"}} {{if task.isSuccess "Thank you!"}} {{if task.isFailure "Nooooooo!"}} {{/gh-task-button}} ``` - update existing uses of `gh-task-button` to match new component signature
This commit is contained in:
parent
c5b0301e87
commit
f1512d12c2
@ -1,6 +1,7 @@
|
|||||||
import Component from 'ember-component';
|
import Component from 'ember-component';
|
||||||
import observer from 'ember-metal/observer';
|
import observer from 'ember-metal/observer';
|
||||||
import {reads} from 'ember-computed';
|
import computed, {reads} from 'ember-computed';
|
||||||
|
import {isBlank} from 'ember-utils';
|
||||||
import {invokeAction} from 'ember-invoke-action';
|
import {invokeAction} from 'ember-invoke-action';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,16 +15,41 @@ import {invokeAction} from 'ember-invoke-action';
|
|||||||
* component, all running promises will automatically be cancelled when this
|
* component, all running promises will automatically be cancelled when this
|
||||||
* component is removed from the DOM
|
* component is removed from the DOM
|
||||||
*/
|
*/
|
||||||
export default Component.extend({
|
const GhTaskButton = Component.extend({
|
||||||
tagName: 'button',
|
tagName: 'button',
|
||||||
classNameBindings: ['isRunning:appear-disabled'],
|
classNameBindings: ['isRunning:appear-disabled', 'isSuccess:gh-btn-green', 'isFailure:gh-btn-red'],
|
||||||
attributeBindings: ['disabled', 'type', 'tabindex'],
|
attributeBindings: ['disabled', 'type', 'tabindex'],
|
||||||
|
|
||||||
task: null,
|
task: null,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
buttonText: 'Save',
|
||||||
|
runningText: reads('buttonText'),
|
||||||
|
successText: 'Saved',
|
||||||
|
failureText: 'Retry',
|
||||||
|
|
||||||
isRunning: reads('task.last.isRunning'),
|
isRunning: reads('task.last.isRunning'),
|
||||||
|
|
||||||
|
isSuccess: computed('isRunning', 'task.last.value', function () {
|
||||||
|
if (this.get('isRunning')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = this.get('task.last.value');
|
||||||
|
return !isBlank(value) && value !== false;
|
||||||
|
}),
|
||||||
|
|
||||||
|
isFailure: computed('isRunning', 'isSuccess', 'task.last.error', function () {
|
||||||
|
if (this.get('isRunning') || this.get('isSuccess')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.get('task.last.error') !== undefined;
|
||||||
|
}),
|
||||||
|
|
||||||
|
isIdle: computed('isRunning', 'isSuccess', 'isFailure', function () {
|
||||||
|
return !this.get('isRunning') && !this.get('isSuccess') && !this.get('isFailure');
|
||||||
|
}),
|
||||||
|
|
||||||
click() {
|
click() {
|
||||||
// do nothing if disabled externally
|
// do nothing if disabled externally
|
||||||
if (this.get('disabled')) {
|
if (this.get('disabled')) {
|
||||||
@ -56,3 +82,9 @@ export default Component.extend({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
GhTaskButton.reopenClass({
|
||||||
|
positionalParams: ['buttonText']
|
||||||
|
});
|
||||||
|
|
||||||
|
export default GhTaskButton;
|
||||||
|
@ -11,8 +11,7 @@ export default ModalComponent.extend({
|
|||||||
this.send('closeModal');
|
this.send('closeModal');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// TODO: server-side validation errors should be serialized
|
// TODO: server-side validation errors should be serialized
|
||||||
// properly so that errors are added to the model's errors
|
// properly so that errors are added to model.errors automatically
|
||||||
// property
|
|
||||||
if (error && isInvalidError(error)) {
|
if (error && isInvalidError(error)) {
|
||||||
let [firstError] = error.errors;
|
let [firstError] = error.errors;
|
||||||
let {message} = firstError;
|
let {message} = firstError;
|
||||||
@ -24,9 +23,10 @@ export default ModalComponent.extend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is a route action so it should bubble up to the global
|
// route action so it should bubble up to the global error handler
|
||||||
// error handler
|
if (error) {
|
||||||
throw error;
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}).drop(),
|
}).drop(),
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@ fieldset[disabled] .gh-btn {
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: replace with svg icons */
|
||||||
|
.gh-btn i {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
/* Button highlights
|
/* Button highlights
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
{{#if confirm}}
|
{{#if confirm}}
|
||||||
<footer class="modal-footer">
|
<footer class="modal-footer">
|
||||||
{{! Buttons must be on one line to prevent white-space errors }}
|
{{! Buttons must be on one line to prevent white-space errors }}
|
||||||
<button type="button" class="{{rejectButtonClass}} btn-minor js-button-reject" {{action "confirm" "reject"}}>{{confirm.reject.text}}</button><button type="button" class="{{acceptButtonClass}} js-button-accept" {{action "confirm" "accept"}}>{{confirm.accept.text}}</button>
|
<button type="button" class="{{rejectButtonClass}} btn-minor" {{action "confirm" "reject"}} data-test-modal-reject-button>{{confirm.reject.text}}</button><button type="button" class="{{acceptButtonClass}}" {{action "confirm" "accept"}} data-test-modal-accept-button>{{confirm.accept.text}}</button>
|
||||||
</footer>
|
</footer>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</section>
|
</section>
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
{{#if isRunning}}
|
{{#if hasBlock}}
|
||||||
<span class="spinner"></span>
|
{{yield (hash
|
||||||
|
isIdle=isIdle
|
||||||
|
isRunning=isRunning
|
||||||
|
isSuccess=isSuccess
|
||||||
|
isFailure=isFailure
|
||||||
|
)}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if buttonText}}
|
<span>
|
||||||
{{buttonText}}
|
{{#if isRunning}}<span class="spinner"></span>{{/if}}
|
||||||
{{else}}
|
{{if (or isIdle isRunning) buttonText}}
|
||||||
{{{yield}}}
|
{{#if isSuccess}}<i class="icon-check"></i> {{successText}}{{/if}}
|
||||||
{{/if}}
|
{{#if isFailure}}<i class="icon-x"></i> {{failureText}}{{/if}}
|
||||||
{{/if}}
|
</span>
|
||||||
|
{{/if}}
|
||||||
|
@ -9,5 +9,5 @@
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
||||||
{{#gh-task-button task=deleteAll class="gh-btn gh-btn-red"}}<span>Delete</span>{{/gh-task-button}}
|
{{gh-task-button "Delete" successText="Deleted" task=deleteAll class="gh-btn gh-btn-red"}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,5 +11,5 @@
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
||||||
{{#gh-task-button task=deletePost class="gh-btn gh-btn-red"}}<span>Delete</span>{{/gh-task-button}}
|
{{gh-task-button "Delete" successText="Deleted" task=deletePost class="gh-btn gh-btn-red"}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,5 +9,5 @@
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
||||||
{{#gh-task-button task=deleteSubscriber class="gh-btn gh-btn-red"}}<span>Delete</span>{{/gh-task-button}}
|
{{gh-task-button "Delete" successText="Deleted" task=deleteSubscriber class="gh-btn gh-btn-red"}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,5 +12,5 @@
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
||||||
{{#gh-task-button task=deleteTag class="gh-btn gh-btn-red"}}<span>Delete</span>{{/gh-task-button}}
|
{{gh-task-button "Delete" successText="Deleted" task=deleteTag class="gh-btn gh-btn-red"}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,5 +9,5 @@
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button {{action "closeModal"}} class="gh-btn" data-test-cancel-button><span>Cancel</span></button>
|
<button {{action "closeModal"}} class="gh-btn" data-test-cancel-button><span>Cancel</span></button>
|
||||||
{{#gh-task-button task=deleteTheme class="gh-btn gh-btn-red" data-test-delete-button=true}}<span>Delete</span>{{/gh-task-button}}
|
{{gh-task-button "Delete" successText="Deleted" task=deleteTheme class="gh-btn gh-btn-red" data-test-delete-button=true}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,5 +13,5 @@
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
||||||
{{#gh-task-button task=deleteUser class="gh-btn gh-btn-red"}}<span>Delete</span>{{/gh-task-button}}
|
{{gh-task-button "Delete" successText="Deleted" task=deleteUser class="gh-btn gh-btn-red"}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,5 +42,5 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
{{#gh-task-button task=sendInvitation class="gh-btn gh-btn-green"}}<span>Send invitation now</span>{{/gh-task-button}}
|
{{gh-task-button "Send invitation now" successText="Sent" task=sendInvitation class="gh-btn gh-btn-green"}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,5 +25,5 @@
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
||||||
{{#gh-task-button task=addSubscriber class="gh-btn gh-btn-green"}}<span>Add</span>{{/gh-task-button}}
|
{{gh-task-button "Add" successText="Added" task=addSubscriber class="gh-btn gh-btn-green"}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,13 +6,13 @@
|
|||||||
<div class="modal-body {{if authenticationError 'error'}}">
|
<div class="modal-body {{if authenticationError 'error'}}">
|
||||||
|
|
||||||
{{#if config.ghostOAuth}}
|
{{#if config.ghostOAuth}}
|
||||||
{{#gh-task-button task=reauthenticate class="login gh-btn gh-btn-blue gh-btn-block" tabindex="3" autoWidth="false"}}<span>Sign in with Ghost</span>{{/gh-task-button}}
|
{{gh-task-button "Sign in with Ghost" task=reauthenticate class="login gh-btn gh-btn-blue gh-btn-block" tabindex="3" autoWidth="false"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<form id="login" class="login-form" method="post" novalidate="novalidate" {{action "confirm" on="submit"}}>
|
<form id="login" class="login-form" method="post" novalidate="novalidate" {{action "confirm" on="submit"}}>
|
||||||
{{#gh-validation-status-container class="password-wrap" errors=errors property="password" hasValidated=hasValidated}}
|
{{#gh-validation-status-container class="password-wrap" errors=errors property="password" hasValidated=hasValidated}}
|
||||||
{{gh-input password class="password" type="password" placeholder="Password" name="password" update=(action (mut password))}}
|
{{gh-input password class="password" type="password" placeholder="Password" name="password" update=(action (mut password))}}
|
||||||
{{/gh-validation-status-container}}
|
{{/gh-validation-status-container}}
|
||||||
{{#gh-task-button task=reauthenticate class="gh-btn gh-btn-blue" type="submit"}}<span>Log in</span>{{/gh-task-button}}
|
{{gh-task-button "Log in" task=reauthenticate class="gh-btn gh-btn-blue" type="submit"}}
|
||||||
</form>
|
</form>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
@ -12,5 +12,5 @@
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
||||||
{{#gh-task-button task=transferOwnership class="gh-btn gh-btn-red"}}<span>Yep - I'm sure</span>{{/gh-task-button}}
|
{{gh-task-button "Yep - I'm sure" task=transferOwnership class="gh-btn gh-btn-red"}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,5 +20,5 @@
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
|
||||||
{{#gh-task-button task=uploadImage class="gh-btn gh-btn-blue right js-button-accept"}}<span>Save</span>{{/gh-task-button}}
|
{{gh-task-button task=uploadImage class="gh-btn gh-btn-blue right" data-test-modal-accept-button=true}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
{{gh-input ne2Password type="password" name="ne2password" placeholder="Confirm Password" class="password" autocorrect="off" autofocus="autofocus" update=(action (mut ne2Password))}}
|
{{gh-input ne2Password type="password" name="ne2password" placeholder="Confirm Password" class="password" autocorrect="off" autofocus="autofocus" update=(action (mut ne2Password))}}
|
||||||
{{/gh-form-group}}
|
{{/gh-form-group}}
|
||||||
|
|
||||||
{{#gh-task-button task=resetPassword class="gh-btn gh-btn-blue gh-btn-block" type="submit" autoWidth="false"}}<span>Reset Password</span>{{/gh-task-button}}
|
{{gh-task-button "Reset Password" task=resetPassword class="gh-btn gh-btn-blue gh-btn-block" type="submit" autoWidth="false"}}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<p class="main-error">{{{flowErrors}}}</p>
|
<p class="main-error">{{{flowErrors}}}</p>
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
</span>
|
</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#gh-task-button class="gh-btn gh-btn-blue" task=save}}<span>Save</span>{{/gh-task-button}}
|
{{gh-task-button class="gh-btn gh-btn-blue" task=save}}
|
||||||
</section>
|
</section>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@ -199,7 +199,7 @@
|
|||||||
{{/gh-form-group}}
|
{{/gh-form-group}}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
{{#gh-task-button class="gh-btn gh-btn-red button-change-password" task=user.saveNewPassword}}<span>Change Password</span>{{/gh-task-button}}
|
{{gh-task-button "Change Password" class="gh-btn gh-btn-red button-change-password" task=user.saveNewPassword}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form> {{! change password form }}
|
</form> {{! change password form }}
|
||||||
|
@ -135,7 +135,7 @@ describe('Acceptance: Settings - General', function () {
|
|||||||
expect(find('.fullscreen-modal .modal-content .gh-image-uploader').length, 'modal selector').to.equal(1);
|
expect(find('.fullscreen-modal .modal-content .gh-image-uploader').length, 'modal selector').to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
click('.fullscreen-modal .modal-footer .js-button-accept');
|
click(testSelector('modal-accept-button'));
|
||||||
|
|
||||||
andThen(() => {
|
andThen(() => {
|
||||||
expect(find('.fullscreen-modal').length).to.equal(0);
|
expect(find('.fullscreen-modal').length).to.equal(0);
|
||||||
|
@ -13,21 +13,29 @@ describe('Integration: Component: gh-task-button', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders', function () {
|
it('renders', function () {
|
||||||
this.render(hbs`{{#gh-task-button}}Test{{/gh-task-button}}`);
|
// sets button text using positional param
|
||||||
|
this.render(hbs`{{gh-task-button "Test"}}`);
|
||||||
expect(this.$('button')).to.exist;
|
expect(this.$('button')).to.exist;
|
||||||
expect(this.$('button')).to.contain('Test');
|
expect(this.$('button')).to.contain('Test');
|
||||||
expect(this.$('button')).to.have.prop('disabled', false);
|
expect(this.$('button')).to.have.prop('disabled', false);
|
||||||
|
|
||||||
this.render(hbs`{{#gh-task-button class="testing"}}Test{{/gh-task-button}}`);
|
this.render(hbs`{{gh-task-button class="testing"}}`);
|
||||||
expect(this.$('button')).to.have.class('testing');
|
expect(this.$('button')).to.have.class('testing');
|
||||||
|
// default button text is "Save"
|
||||||
|
expect(this.$('button')).to.contain('Save');
|
||||||
|
|
||||||
this.render(hbs`{{#gh-task-button disabled=true}}Test{{/gh-task-button}}`);
|
// passes disabled attr
|
||||||
|
this.render(hbs`{{gh-task-button disabled=true buttonText="Test"}}`);
|
||||||
expect(this.$('button')).to.have.prop('disabled', true);
|
expect(this.$('button')).to.have.prop('disabled', true);
|
||||||
|
// allows button text to be set via hash param
|
||||||
|
expect(this.$('button')).to.contain('Test');
|
||||||
|
|
||||||
this.render(hbs`{{#gh-task-button type="submit"}}Test{{/gh-task-button}}`);
|
// passes type attr
|
||||||
|
this.render(hbs`{{gh-task-button type="submit"}}`);
|
||||||
expect(this.$('button')).to.have.attr('type', 'submit');
|
expect(this.$('button')).to.have.attr('type', 'submit');
|
||||||
|
|
||||||
this.render(hbs`{{#gh-task-button tabindex="-1"}}Test{{/gh-task-button}}`);
|
// passes tabindex attr
|
||||||
|
this.render(hbs`{{gh-task-button tabindex="-1"}}`);
|
||||||
expect(this.$('button')).to.have.attr('tabindex', '-1');
|
expect(this.$('button')).to.have.attr('tabindex', '-1');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -36,7 +44,7 @@ describe('Integration: Component: gh-task-button', function() {
|
|||||||
yield timeout(50);
|
yield timeout(50);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.render(hbs`{{#gh-task-button task=myTask}}Test{{/gh-task-button}}`);
|
this.render(hbs`{{gh-task-button task=myTask}}`);
|
||||||
|
|
||||||
this.get('myTask').perform();
|
this.get('myTask').perform();
|
||||||
|
|
||||||
@ -52,7 +60,7 @@ describe('Integration: Component: gh-task-button', function() {
|
|||||||
yield timeout(50);
|
yield timeout(50);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.render(hbs`{{#gh-task-button task=myTask}}Test{{/gh-task-button}}`);
|
this.render(hbs`{{gh-task-button task=myTask}}`);
|
||||||
expect(this.$('button'), 'initial class').to.not.have.class('appear-disabled');
|
expect(this.$('button'), 'initial class').to.not.have.class('appear-disabled');
|
||||||
|
|
||||||
this.get('myTask').perform();
|
this.get('myTask').perform();
|
||||||
@ -68,6 +76,64 @@ describe('Integration: Component: gh-task-button', function() {
|
|||||||
wait().then(done);
|
wait().then(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('shows success on success', function (done) {
|
||||||
|
this.set('myTask', task(function* () {
|
||||||
|
yield timeout(50);
|
||||||
|
return true;
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.render(hbs`{{gh-task-button task=myTask}}`);
|
||||||
|
|
||||||
|
this.get('myTask').perform();
|
||||||
|
|
||||||
|
run.later(this, function () {
|
||||||
|
expect(this.$('button')).to.have.class('gh-btn-green');
|
||||||
|
expect(this.$('button')).to.contain('Saved');
|
||||||
|
}, 70);
|
||||||
|
|
||||||
|
wait().then(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows failure when task errors', function (done) {
|
||||||
|
this.set('myTask', task(function* () {
|
||||||
|
try {
|
||||||
|
yield timeout(50);
|
||||||
|
throw new ReferenceError('test error');
|
||||||
|
} catch (error) {
|
||||||
|
// noop, prevent mocha triggering unhandled error assert
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.render(hbs`{{gh-task-button task=myTask}}`);
|
||||||
|
|
||||||
|
this.get('myTask').perform();
|
||||||
|
|
||||||
|
run.later(this, function () {
|
||||||
|
expect(this.$('button')).to.have.class('gh-btn-red');
|
||||||
|
expect(this.$('button')).to.contain('Retry');
|
||||||
|
}, 70);
|
||||||
|
|
||||||
|
wait().then(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows failure on falsy response', function (done) {
|
||||||
|
this.set('myTask', task(function* () {
|
||||||
|
yield timeout(50);
|
||||||
|
return false;
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.render(hbs`{{gh-task-button task=myTask}}`);
|
||||||
|
|
||||||
|
this.get('myTask').perform();
|
||||||
|
|
||||||
|
run.later(this, function () {
|
||||||
|
expect(this.$('button')).to.have.class('gh-btn-red');
|
||||||
|
expect(this.$('button')).to.contain('Retry');
|
||||||
|
}, 70);
|
||||||
|
|
||||||
|
wait().then(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('performs task on click', function (done) {
|
it('performs task on click', function (done) {
|
||||||
let taskCount = 0;
|
let taskCount = 0;
|
||||||
|
|
||||||
@ -76,7 +142,7 @@ describe('Integration: Component: gh-task-button', function() {
|
|||||||
taskCount = taskCount + 1;
|
taskCount = taskCount + 1;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.render(hbs`{{#gh-task-button task=myTask}}Test{{/gh-task-button}}`);
|
this.render(hbs`{{gh-task-button task=myTask}}`);
|
||||||
this.$('button').click();
|
this.$('button').click();
|
||||||
|
|
||||||
wait().then(() => {
|
wait().then(() => {
|
||||||
@ -90,7 +156,7 @@ describe('Integration: Component: gh-task-button', function() {
|
|||||||
yield timeout(50);
|
yield timeout(50);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.render(hbs`{{#gh-task-button task=myTask}}Test{{/gh-task-button}}`);
|
this.render(hbs`{{gh-task-button task=myTask}}`);
|
||||||
let width = this.$('button').width();
|
let width = this.$('button').width();
|
||||||
let height = this.$('button').height();
|
let height = this.$('button').height();
|
||||||
expect(this.$('button')).to.not.have.attr('style');
|
expect(this.$('button')).to.not.have.attr('style');
|
||||||
|
Loading…
Reference in New Issue
Block a user