diff options
-rw-r--r-- | app/assets/javascripts/jobs/components/stuck_block.vue | 63 | ||||
-rw-r--r-- | changelogs/unreleased/50101-stuck-component.yml | 5 | ||||
-rw-r--r-- | locale/gitlab.pot | 6 | ||||
-rw-r--r-- | spec/javascripts/jobs/stuck_block_spec.js | 81 |
4 files changed, 155 insertions, 0 deletions
diff --git a/app/assets/javascripts/jobs/components/stuck_block.vue b/app/assets/javascripts/jobs/components/stuck_block.vue new file mode 100644 index 00000000000..18883fea950 --- /dev/null +++ b/app/assets/javascripts/jobs/components/stuck_block.vue @@ -0,0 +1,63 @@ +<script> +/** + * Renders Stuck Runners block for job's view. + */ +export default { + props: { + hasNoRunnersForProject: { + type: Boolean, + required: true, + }, + tags: { + type: Array, + required: false, + default: () => [], + }, + runnersPath: { + type: String, + required: true, + }, + }, +}; +</script> +<template> + <div class="bs-callout bs-callout-warning"> + <p + v-if="hasNoRunnersForProject" + class="js-stuck-no-runners" + > + {{ s__(`Job|This job is stuck, because the project + doesn't have any runners online assigned to it.`) }} + </p> + <p + v-else-if="tags.length" + class="js-stuck-with-tags" + > + {{ s__(`This job is stuck, because you don't have + any active runners online with any of these tags assigned to them:`) }} + <span + v-for="(tag, index) in tags" + :key="index" + class="badge badge-primary" + > + {{ tag }} + </span> + </p> + <p + v-else + class="js-stuck-no-active-runner" + > + {{ s__(`This job is stuck, because you don't + have any active runners that can run this job.`) }} + </p> + + {{ __("Go to") }} + <a + v-if="runnersPath" + :href="runnersPath" + class="js-runners-path" + > + {{ __("Runners page") }} + </a> + </div> +</template> diff --git a/changelogs/unreleased/50101-stuck-component.yml b/changelogs/unreleased/50101-stuck-component.yml new file mode 100644 index 00000000000..bfe4009a2b3 --- /dev/null +++ b/changelogs/unreleased/50101-stuck-component.yml @@ -0,0 +1,5 @@ +--- +title: Creates Vvue component for warning block about stuck runners +merge_request: +author: +type: other diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 4c660ae45c1..c5bd27754b7 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2729,6 +2729,9 @@ msgstr "" msgid "Go back" msgstr "" +msgid "Go to" +msgstr "" + msgid "Go to %{link_to_google_takeout}." msgstr "" @@ -4630,6 +4633,9 @@ msgstr "" msgid "Runners can be placed on separate users, servers, and even on your local machine." msgstr "" +msgid "Runners page" +msgstr "" + msgid "Running" msgstr "" diff --git a/spec/javascripts/jobs/stuck_block_spec.js b/spec/javascripts/jobs/stuck_block_spec.js new file mode 100644 index 00000000000..4e2108dfdfb --- /dev/null +++ b/spec/javascripts/jobs/stuck_block_spec.js @@ -0,0 +1,81 @@ +import Vue from 'vue'; +import component from '~/jobs/components/stuck_block.vue'; +import mountComponent from '../helpers/vue_mount_component_helper'; + +describe('Stuck Block Job component', () => { + const Component = Vue.extend(component); + let vm; + + afterEach(() => { + vm.$destroy(); + }); + + describe('with no runners for project', () => { + beforeEach(() => { + vm = mountComponent(Component, { + hasNoRunnersForProject: true, + runnersPath: '/root/project/runners#js-runners-settings', + }); + }); + + it('renders only information about project not having runners', () => { + expect(vm.$el.querySelector('.js-stuck-no-runners')).not.toBeNull(); + expect(vm.$el.querySelector('.js-stuck-with-tags')).toBeNull(); + expect(vm.$el.querySelector('.js-stuck-no-active-runner')).toBeNull(); + }); + + it('renders link to runners page', () => { + expect(vm.$el.querySelector('.js-runners-path').getAttribute('href')).toEqual( + '/root/project/runners#js-runners-settings', + ); + }); + }); + + describe('with tags', () => { + beforeEach(() => { + vm = mountComponent(Component, { + hasNoRunnersForProject: false, + tags: ['docker', 'gitlab-org'], + runnersPath: '/root/project/runners#js-runners-settings', + }); + }); + + it('renders information about the tags not being set', () => { + expect(vm.$el.querySelector('.js-stuck-no-runners')).toBeNull(); + expect(vm.$el.querySelector('.js-stuck-with-tags')).not.toBeNull(); + expect(vm.$el.querySelector('.js-stuck-no-active-runner')).toBeNull(); + }); + + it('renders tags', () => { + expect(vm.$el.textContent).toContain('docker'); + expect(vm.$el.textContent).toContain('gitlab-org'); + }); + + it('renders link to runners page', () => { + expect(vm.$el.querySelector('.js-runners-path').getAttribute('href')).toEqual( + '/root/project/runners#js-runners-settings', + ); + }); + }); + + describe('without active runners', () => { + beforeEach(() => { + vm = mountComponent(Component, { + hasNoRunnersForProject: false, + runnersPath: '/root/project/runners#js-runners-settings', + }); + }); + + it('renders information about project not having runners', () => { + expect(vm.$el.querySelector('.js-stuck-no-runners')).toBeNull(); + expect(vm.$el.querySelector('.js-stuck-with-tags')).toBeNull(); + expect(vm.$el.querySelector('.js-stuck-no-active-runner')).not.toBeNull(); + }); + + it('renders link to runners page', () => { + expect(vm.$el.querySelector('.js-runners-path').getAttribute('href')).toEqual( + '/root/project/runners#js-runners-settings', + ); + }); + }); +}); |