Add dynamic timer for delayed jobs on single job page
This commit is contained in:
parent
74f22d26a9
commit
ff72bba12c
2 changed files with 44 additions and 1 deletions
|
@ -14,6 +14,8 @@ import Log from './job_log.vue';
|
||||||
import LogTopBar from './job_log_controllers.vue';
|
import LogTopBar from './job_log_controllers.vue';
|
||||||
import StuckBlock from './stuck_block.vue';
|
import StuckBlock from './stuck_block.vue';
|
||||||
import Sidebar from './sidebar.vue';
|
import Sidebar from './sidebar.vue';
|
||||||
|
import { sprintf } from '~/locale';
|
||||||
|
import delayedJobMixin from '../mixins/delayed_job_mixin';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'JobPageApp',
|
name: 'JobPageApp',
|
||||||
|
@ -30,6 +32,7 @@ export default {
|
||||||
StuckBlock,
|
StuckBlock,
|
||||||
Sidebar,
|
Sidebar,
|
||||||
},
|
},
|
||||||
|
mixins: [delayedJobMixin],
|
||||||
props: {
|
props: {
|
||||||
runnerSettingsUrl: {
|
runnerSettingsUrl: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -89,6 +92,17 @@ export default {
|
||||||
shouldRenderContent() {
|
shouldRenderContent() {
|
||||||
return !this.isLoading && !this.hasError;
|
return !this.isLoading && !this.hasError;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
emptyStateTitle() {
|
||||||
|
const { emptyStateIllustration, remainingTime } = this;
|
||||||
|
const { title } = emptyStateIllustration;
|
||||||
|
|
||||||
|
if (this.isDelayedJob) {
|
||||||
|
return sprintf(title, { remainingTime });
|
||||||
|
}
|
||||||
|
|
||||||
|
return title;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
// Once the job log is loaded,
|
// Once the job log is loaded,
|
||||||
|
@ -250,7 +264,7 @@ export default {
|
||||||
class="js-job-empty-state"
|
class="js-job-empty-state"
|
||||||
:illustration-path="emptyStateIllustration.image"
|
:illustration-path="emptyStateIllustration.image"
|
||||||
:illustration-size-class="emptyStateIllustration.size"
|
:illustration-size-class="emptyStateIllustration.size"
|
||||||
:title="emptyStateIllustration.title"
|
:title="emptyStateTitle"
|
||||||
:content="emptyStateIllustration.content"
|
:content="emptyStateIllustration.content"
|
||||||
:action="emptyStateAction"
|
:action="emptyStateAction"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { resetStore } from '../store/helpers';
|
||||||
import job from '../mock_data';
|
import job from '../mock_data';
|
||||||
|
|
||||||
describe('Job App ', () => {
|
describe('Job App ', () => {
|
||||||
|
const delayedJobFixture = getJSONFixture('jobs/delayed.json');
|
||||||
const Component = Vue.extend(jobApp);
|
const Component = Vue.extend(jobApp);
|
||||||
let store;
|
let store;
|
||||||
let vm;
|
let vm;
|
||||||
|
@ -420,6 +421,34 @@ describe('Job App ', () => {
|
||||||
done();
|
done();
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('displays remaining time for a delayed job', (done) => {
|
||||||
|
const oneHourInMilliseconds = 3600000;
|
||||||
|
spyOn(Date, 'now').and.callFake(() => new Date(delayedJobFixture.scheduled_at).getTime() - oneHourInMilliseconds);
|
||||||
|
mock.onGet(props.endpoint).replyOnce(200, { ... delayedJobFixture });
|
||||||
|
|
||||||
|
vm = mountComponentWithStore(Component, {
|
||||||
|
props,
|
||||||
|
store,
|
||||||
|
});
|
||||||
|
|
||||||
|
store.subscribeAction((action) => {
|
||||||
|
if (action.type !== 'receiveJobSuccess') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.nextTick()
|
||||||
|
.then(() => {
|
||||||
|
expect(vm.$el.querySelector('.js-job-empty-state')).not.toBeNull();
|
||||||
|
|
||||||
|
const title = vm.$el.querySelector('.js-job-empty-state-title');
|
||||||
|
|
||||||
|
expect(title).toContainText('01:00:00');
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue