diff --git a/app/components/billing-summary-status.js b/app/components/billing-summary-status.js index 811a683725..827d1ebb7e 100644 --- a/app/components/billing-summary-status.js +++ b/app/components/billing-summary-status.js @@ -1,5 +1,7 @@ import Component from '@ember/component'; +import { computed } from '@ember/object'; import { reads, and, empty } from '@ember/object/computed'; +import { isEmpty } from '@ember/utils'; export default Component.extend({ account: null, @@ -8,5 +10,7 @@ export default Component.extend({ isGithubTrial: and('subscription.isGithub', 'trial.hasActiveTrial'), hasGithubTrialEnded: and('subscription.isGithub', 'trial.isEnded'), noSubscription: empty('subscription'), - isDefaultEducationView: and('noSubscription', 'account.education') + isDefaultEducationView: computed('subscription', 'account.education', 'subscription.plan_name', function () { + return this.get('subscription') && !isEmpty(this.get('subscription')) && this.get('account.education'); + }) }); diff --git a/app/components/dashboard-row.js b/app/components/dashboard-row.js index e98d2abf7b..afec5b4805 100644 --- a/app/components/dashboard-row.js +++ b/app/components/dashboard-row.js @@ -2,6 +2,8 @@ import Component from '@ember/component'; import { computed } from '@ember/object'; import { inject as service } from '@ember/service'; import { alias, reads } from '@ember/object/computed'; +import { task, timeout } from 'ember-concurrency'; +import config from 'travis/config/environment'; export default Component.extend({ permissionsService: service('permissions'), @@ -46,20 +48,76 @@ export default Component.extend({ this.set('dropupIsOpen', false); }, - triggerBuild() { - const self = this; - let data = {}; - data.request = `{ 'branch': '${this.get('repo.defaultBranch.name')}' }`; - - this.api.post(`/repo/${this.get('repo.id')}/requests`, { data: data }) - .then(() => { - self.set('isTriggering', false); - self.get('flashes') - .success(`You’ve successfully triggered a build for ${self.get('repo.slug')}. - Hold tight, it might take a moment to show up.`); - }); + fetchBuildStatus: task(function* (repoId, requestId) { + try { + return yield this.api.get(`/repo/${repoId}/request/${requestId}`); + } catch (e) { + this.displayError(e); + } + }), + + showRequestStatus: task(function* (repoId, requestId) { + const data = yield this.fetchBuildStatus.perform(repoId, requestId); + let { result } = data; + + if (result === 'rejected') { + return this.showFailedRequest(requestId); + } + + return this.showProcessingRequest(requestId); + }), + + createBuild: task(function* () { + try { + this.set('isTriggering', false); + let data = {}; + data.request = `{ 'branch': '${this.get('repo.defaultBranch.name')}' }`; + return yield this.api.post(`/repo/${this.repo.id}/requests`, { data: data }); + } catch (e) { + this.displayError(e); + } + }), + + showProcessingRequest(requestId) { + const preamble = 'Hold tight!'; + const notice = `You successfully triggered a build for ${this.repo.slug}. It might take a moment to show up though.`; + this.flashes.notice(notice, preamble); + this.onClose(); + return this.showRequest(requestId); + }, + + showFailedRequest(requestId) { + const errorMsg = `You tried to trigger a build for ${this.repo.slug} but the request was rejected.`; + this.flashes.error(errorMsg); + this.onClose(); + return this.showRequest(requestId); + }, + + triggerBuild: task(function* () { + const data = yield this.createBuild.perform(); + + if (data && data.request) { + let requestId = data.request.id; + + let { triggerBuildRequestDelay } = config.intervals; + yield timeout(triggerBuildRequestDelay); + + yield this.showRequestStatus.perform(this.repo.id, requestId); + } + this.set('isTriggering', false); this.set('dropupIsOpen', false); - this.set('isTriggering', true); + }), + + displayError(e) { + let message; + + if (e.status === 429) { + message = 'You’ve exceeded the limit for triggering builds, please wait a while before trying again.'; + } else { + message = 'Oops, something went wrong, please try again.'; + } + + this.flashes.error(message); }, actions: { @@ -68,7 +126,7 @@ export default Component.extend({ }, triggerBuild() { - this.triggerBuild(); + this.triggerBuild.perform(); }, starRepo() { diff --git a/app/templates/components/dashboard-row.hbs b/app/templates/components/dashboard-row.hbs index 3a371aa01a..efc11609e1 100644 --- a/app/templates/components/dashboard-row.hbs +++ b/app/templates/components/dashboard-row.hbs @@ -91,7 +91,7 @@ @route="build" @models={{array this.repo - this.repo.defaultBranch.lastBuild.id + this.repo.currentBuild.id }} @title="Last build on the repo" > diff --git a/tests/acceptance/profile/billing-test.js b/tests/acceptance/profile/billing-test.js index 5f6fb64c7b..e85011a9b8 100644 --- a/tests/acceptance/profile/billing-test.js +++ b/tests/acceptance/profile/billing-test.js @@ -903,7 +903,11 @@ module('Acceptance | profile/billing', function (hooks) { }); test('view billing tab on education account', async function (assert) { - this.subscription = null; + this.subscription.plan = this.server.create('plan', { id: 'travis-ci-one-build', name: 'Bootstrap', builds: 1, price: 6900, currency: 'USD' }); + this.subscription.owner = this.organization; + this.subscription.source = 'github'; + this.subscription.status = 'subscribed'; + this.subscription.save(); this.organization.attrs.education = true; this.organization.permissions = { createSubscription: true, admin: true }; this.organization.save();