Skip to content
Snippets Groups Projects
Commit da9b3b3d authored by Filipa Lacerda's avatar Filipa Lacerda
Browse files

Creates vue components for stage dropdowns and job list container for job log view

parent cf2c99cc
No related branches found
No related tags found
1 merge request!21255Creates vue components for stage dropdowns and job list container for job log view
Pipeline #28104125 passed with warnings
<script>
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import Icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
export default {
components: {
CiIcon,
Icon,
},
directives: {
tooltip,
},
props: {
jobs: {
type: Array,
required: true,
},
},
};
</script>
<template>
<div class="builds-container">
<div
class="build-job"
>
<a
v-tooltip
v-for="job in jobs"
:key="job.id"
:href="job.path"
:title="job.tooltip"
:class="{ active: job.active, retried: job.retried }"
>
<icon
v-if="job.active"
name="arrow-right"
class="js-arrow-right"
/>
<ci-icon :status="job.status" />
<span>
<template v-if="job.name">
{{ job.name }}
</template>
<template v-else>
{{ job.id }}
</template>
</span>
<icon
v-if="job.retried"
name="retry"
class="js-retry-icon"
/>
</a>
</div>
</div>
</template>
<script>
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import Icon from '~/vue_shared/components/icon.vue';
import { sprintf, __ } from '~/locale';
export default {
components: {
CiIcon,
Icon,
},
props: {
pipelineId: {
type: Number,
required: true,
},
pipelinePath: {
type: String,
required: true,
},
pipelineRef: {
type: String,
required: true,
},
pipelineRefPath: {
type: String,
required: true,
},
stages: {
type: Array,
required: true,
},
pipelineStatus: {
type: Object,
required: true,
},
},
data() {
return {
selectedStage: this.stages.length > 0 ? this.stages[0].name : __('More'),
};
},
computed: {
pipelineLink() {
return sprintf(__('Pipeline %{pipelineLinkStart} #%{pipelineId} %{pipelineLinkEnd} from %{pipelineLinkRefStart} %{pipelineRef} %{pipelineLinkRefEnd}'), {
pipelineLinkStart: `<a href=${this.pipelinePath} class="js-pipeline-path link-commit">`,
pipelineId: this.pipelineId,
pipelineLinkEnd: '</a>',
pipelineLinkRefStart: `<a href=${this.pipelineRefPath} class="link-commit ref-name">`,
pipelineRef: this.pipelineRef,
pipelineLinkRefEnd: '</a>',
}, false);
},
},
methods: {
onStageClick(stage) {
// todo: consider moving into store
this.selectedStage = stage.name;
// update dropdown with jobs
// jobs container is a new component.
this.$emit('requestSidebarStageDropdown', stage);
},
},
};
</script>
<template>
<div class="block-last">
<ci-icon :status="pipelineStatus" />
<p v-html="pipelineLink"></p>
<div class="dropdown">
<button
type="button"
data-toggle="dropdown"
>
{{ selectedStage }}
<icon name="chevron-down" />
</button>
<ul class="dropdown-menu">
<li
v-for="(stage, index) in stages"
:key="index"
>
<button
type="button"
class="stage-item"
@click="onStageClick(stage)"
>
{{ stage.name }}
</button>
</li>
</ul>
</div>
</div>
</template>
---
title: Creates vue components for stage dropdowns and job list container for job log
view
merge_request:
author:
type: other
......@@ -4110,6 +4110,9 @@ msgstr ""
msgid "Pipeline"
msgstr ""
msgid "Pipeline %{pipelineLinkStart} #%{pipelineId} %{pipelineLinkEnd} from %{pipelineLinkRefStart} %{pipelineRef} %{pipelineLinkRefEnd}"
msgstr ""
msgid "Pipeline Health"
msgstr ""
......
import Vue from 'vue';
import component from '~/jobs/components/jobs_container.vue';
import mountComponent from '../helpers/vue_mount_component_helper';
describe('Artifacts block', () => {
const Component = Vue.extend(component);
let vm;
const retried = {
status: {
details_path: '/gitlab-org/gitlab-ce/pipelines/28029444',
group: 'success',
has_details: true,
icon: 'status_success',
label: 'passed',
text: 'passed',
tooltip: 'passed',
},
path: 'job/233432756',
id: '233432756',
tooltip: 'build - passed',
retried: true,
};
const active = {
name: 'test',
status: {
details_path: '/gitlab-org/gitlab-ce/pipelines/28029444',
group: 'success',
has_details: true,
icon: 'status_success',
label: 'passed',
text: 'passed',
tooltip: 'passed',
},
path: 'job/2322756',
id: '2322756',
tooltip: 'build - passed',
active: true,
};
const job = {
name: 'build',
status: {
details_path: '/gitlab-org/gitlab-ce/pipelines/28029444',
group: 'success',
has_details: true,
icon: 'status_success',
label: 'passed',
text: 'passed',
tooltip: 'passed',
},
path: 'job/232153',
id: '232153',
tooltip: 'build - passed',
};
afterEach(() => {
vm.$destroy();
});
it('renders list of jobs', () => {
vm = mountComponent(Component, {
jobs: [job, retried, active],
});
expect(vm.$el.querySelectorAll('a').length).toEqual(3);
});
it('renders arrow right when job is active', () => {
vm = mountComponent(Component, {
jobs: [active],
});
expect(vm.$el.querySelector('a .js-arrow-right')).not.toBeNull();
});
it('does not render arrow right when job is not active', () => {
vm = mountComponent(Component, {
jobs: [job],
});
expect(vm.$el.querySelector('a .js-arrow-right')).toBeNull();
});
it('renders job name when present', () => {
vm = mountComponent(Component, {
jobs: [job],
});
expect(vm.$el.querySelector('a').textContent.trim()).toContain(job.name);
expect(vm.$el.querySelector('a').textContent.trim()).not.toContain(job.id);
});
it('renders job id when job name is not available', () => {
vm = mountComponent(Component, {
jobs: [retried],
});
expect(vm.$el.querySelector('a').textContent.trim()).toContain(retried.id);
});
it('links to the job page', () => {
vm = mountComponent(Component, {
jobs: [job],
});
expect(vm.$el.querySelector('a').getAttribute('href')).toEqual(job.path);
});
it('renders retry icon when job was retried', () => {
vm = mountComponent(Component, {
jobs: [retried],
});
expect(vm.$el.querySelector('.js-retry-icon')).not.toBeNull();
});
it('does not render retry icon when job was not retried', () => {
vm = mountComponent(Component, {
jobs: [job],
});
expect(vm.$el.querySelector('.js-retry-icon')).toBeNull();
});
});
import Vue from 'vue';
import component from '~/jobs/components/stages_dropdown.vue';
import mountComponent from '../helpers/vue_mount_component_helper';
describe('Artifacts block', () => {
const Component = Vue.extend(component);
let vm;
beforeEach(() => {
vm = mountComponent(Component, {
pipelineId: 28029444,
pipelinePath: 'pipeline/28029444',
pipelineRef: '50101-truncated-job-information',
pipelineRefPath: 'commits/50101-truncated-job-information',
stages: [
{
name: 'build',
},
{
name: 'test',
},
],
pipelineStatus: {
details_path: '/gitlab-org/gitlab-ce/pipelines/28029444',
group: 'success',
has_details: true,
icon: 'status_success',
label: 'passed',
text: 'passed',
tooltip: 'passed',
},
});
});
afterEach(() => {
vm.$destroy();
});
it('renders pipeline status', () => {
expect(vm.$el.querySelector('.js-ci-status-icon-success')).not.toBeNull();
});
it('renders pipeline link', () => {
expect(vm.$el.querySelector('.js-pipeline-path').getAttribute('href')).toEqual(
'pipeline/28029444',
);
});
it('renders dropdown with stages', () => {
expect(vm.$el.querySelector('.dropdown button').textContent).toContain('build');
});
it('updates selected stage on click', done => {
vm.$el.querySelectorAll('.stage-item')[1].click();
vm
.$nextTick()
.then(() => {
expect(vm.$el.querySelector('.dropdown button').textContent).toContain('test');
})
.then(done)
.catch(done.fail);
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment