Commit b2fc6326 authored by Fatih Acet's avatar Fatih Acet

Merge branch '31053-pipeline-ux' into 'master'

Adds left connector class to the rendered graph

Closes #31053

See merge request !11179
parents a353c966 0c3abe3e
...@@ -64,6 +64,24 @@ ...@@ -64,6 +64,24 @@
capitalizeStageName(name) { capitalizeStageName(name) {
return name.charAt(0).toUpperCase() + name.slice(1); return name.charAt(0).toUpperCase() + name.slice(1);
}, },
isFirstColumn(index) {
return index === 0;
},
stageConnectorClass(index, stage) {
let className;
// If it's the first stage column and only has one job
if (index === 0 && stage.groups.length === 1) {
className = 'no-margin';
} else if (index > 0) {
// If it is not the first column
className = 'left-margin';
}
return className;
},
}, },
}; };
</script> </script>
...@@ -82,10 +100,12 @@ ...@@ -82,10 +100,12 @@
v-if="!isLoading" v-if="!isLoading"
class="stage-column-list"> class="stage-column-list">
<stage-column-component <stage-column-component
v-for="stage in state.graph" v-for="(stage, index) in state.graph"
:title="capitalizeStageName(stage.name)" :title="capitalizeStageName(stage.name)"
:jobs="stage.groups" :jobs="stage.groups"
:key="stage.name"/> :key="stage.name"
:stage-connector-class="stageConnectorClass(index, stage)"
:is-first-column="isFirstColumn(index)"/>
</ul> </ul>
</div> </div>
</div> </div>
......
...@@ -13,6 +13,18 @@ export default { ...@@ -13,6 +13,18 @@ export default {
type: Array, type: Array,
required: true, required: true,
}, },
isFirstColumn: {
type: Boolean,
required: false,
default: false,
},
stageConnectorClass: {
type: String,
required: false,
default: '',
},
}, },
components: { components: {
...@@ -28,20 +40,27 @@ export default { ...@@ -28,20 +40,27 @@ export default {
jobId(job) { jobId(job) {
return `ci-badge-${job.name}`; return `ci-badge-${job.name}`;
}, },
buildConnnectorClass(index) {
return index === 0 && !this.isFirstColumn ? 'left-connector' : '';
},
}, },
}; };
</script> </script>
<template> <template>
<li class="stage-column"> <li
class="stage-column"
:class="stageConnectorClass">
<div class="stage-name"> <div class="stage-name">
{{title}} {{title}}
</div> </div>
<div class="builds-container"> <div class="builds-container">
<ul> <ul>
<li <li
v-for="job in jobs" v-for="(job, index) in jobs"
:key="job.id" :key="job.id"
class="build" class="build"
:class="buildConnnectorClass(index)"
:id="jobId(job)"> :id="jobId(job)">
<div class="curve"></div> <div class="curve"></div>
......
import cancelSVG from 'icons/_icon_action_cancel.svg'; import cancelSVG from 'icons/_icon_action_cancel.svg';
import retrySVG from 'icons/_icon_action_retry.svg'; import retrySVG from 'icons/_icon_action_retry.svg';
import playSVG from 'icons/_icon_action_play.svg'; import playSVG from 'icons/_icon_action_play.svg';
import stopSVG from 'icons/_icon_action_stop.svg';
export default function getActionIcon(action) { export default function getActionIcon(action) {
let icon; let icon;
...@@ -14,6 +15,9 @@ export default function getActionIcon(action) { ...@@ -14,6 +15,9 @@ export default function getActionIcon(action) {
case 'icon_action_play': case 'icon_action_play':
icon = playSVG; icon = playSVG;
break; break;
case 'icon_action_stop':
icon = stopSVG;
break;
default: default:
icon = ''; icon = '';
} }
......
...@@ -66,6 +66,56 @@ describe('graph component', () => { ...@@ -66,6 +66,56 @@ describe('graph component', () => {
}, },
}, },
}], }],
},
{
name: 'test_1',
title: 'test_1: passed',
status: {
icon: 'icon_status_success',
text: 'passed',
label: 'passed',
details_path: '/root/ci-mock/pipelines/123#test',
},
path: '/root/ci-mock/pipelines/123#test',
groups: [{
name: 'test',
size: 1,
jobs: [{
id: 4153,
name: 'test',
status: {
icon: 'icon_status_success',
text: 'passed',
label: 'passed',
details_path: '/root/ci-mock/builds/4153',
action: {
icon: 'icon_action_retry',
title: 'Retry',
path: '/root/ci-mock/builds/4153/retry',
method: 'post',
},
},
}],
}, {
name: 'test',
size: 1,
jobs: [{
id: 4153,
name: 'test',
status: {
icon: 'icon_status_success',
text: 'passed',
label: 'passed',
details_path: '/root/ci-mock/builds/4153',
action: {
icon: 'icon_action_retry',
title: 'Retry',
path: '/root/ci-mock/builds/4153/retry',
method: 'post',
},
},
}],
}],
}], }],
}], }],
}, },
...@@ -91,6 +141,18 @@ describe('graph component', () => { ...@@ -91,6 +141,18 @@ describe('graph component', () => {
setTimeout(() => { setTimeout(() => {
expect(component.$el.classList.contains('js-pipeline-graph')).toEqual(true); expect(component.$el.classList.contains('js-pipeline-graph')).toEqual(true);
expect(
component.$el.querySelector('.stage-column:first-child').classList.contains('no-margin'),
).toEqual(true);
expect(
component.$el.querySelector('.stage-column:nth-child(2)').classList.contains('left-margin'),
).toEqual(true);
expect(
component.$el.querySelector('.stage-column:nth-child(2) .build:nth-child(1)').classList.contains('left-connector'),
).toEqual(true);
expect(component.$el.querySelector('loading-icon')).toBe(null); expect(component.$el.querySelector('loading-icon')).toBe(null);
expect(component.$el.querySelector('.stage-column-list')).toBeDefined(); expect(component.$el.querySelector('.stage-column-list')).toBeDefined();
......
...@@ -2,6 +2,7 @@ import getActionIcon from '~/vue_shared/ci_action_icons'; ...@@ -2,6 +2,7 @@ import getActionIcon from '~/vue_shared/ci_action_icons';
import cancelSVG from 'icons/_icon_action_cancel.svg'; import cancelSVG from 'icons/_icon_action_cancel.svg';
import retrySVG from 'icons/_icon_action_retry.svg'; import retrySVG from 'icons/_icon_action_retry.svg';
import playSVG from 'icons/_icon_action_play.svg'; import playSVG from 'icons/_icon_action_play.svg';
import stopSVG from 'icons/_icon_action_stop.svg';
describe('getActionIcon', () => { describe('getActionIcon', () => {
it('should return an empty string', () => { it('should return an empty string', () => {
...@@ -19,4 +20,8 @@ describe('getActionIcon', () => { ...@@ -19,4 +20,8 @@ describe('getActionIcon', () => {
it('should return play svg', () => { it('should return play svg', () => {
expect(getActionIcon('icon_action_play')).toEqual(playSVG); expect(getActionIcon('icon_action_play')).toEqual(playSVG);
}); });
it('should render stop svg', () => {
expect(getActionIcon('icon_action_stop')).toEqual(stopSVG);
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment