Commit 2c0bc1b1 authored by Frédéric Caplette's avatar Frédéric Caplette Committed by Nicolò Maria Mezzopera

Fix pipeline viz missing classes

Due to some migration of scss from the pipelines bundle,
some classes were no longer applied and it broke
the visualization style. This uses new gitlab utilities
to re-apply those styles and avoid having scss bundle.
parent c7cdd60c
...@@ -57,7 +57,7 @@ export default { ...@@ -57,7 +57,7 @@ export default {
<tooltip-on-truncate :title="jobName" truncate-target="child" placement="top"> <tooltip-on-truncate :title="jobName" truncate-target="child" placement="top">
<div <div
:id="jobId" :id="jobId"
class="pipeline-job-pill gl-bg-white gl-text-center gl-text-truncate gl-rounded-pill gl-mb-3 gl-px-5 gl-py-2 gl-relative gl-z-index-1 gl-transition-duration-slow gl-transition-timing-function-ease" class="gl-w-15 gl-bg-white gl-text-center gl-text-truncate gl-rounded-pill gl-mb-3 gl-px-5 gl-py-2 gl-relative gl-z-index-1 gl-transition-duration-slow gl-transition-timing-function-ease"
:class="jobPillClasses" :class="jobPillClasses"
@mouseover="onMouseEnter" @mouseover="onMouseEnter"
@mouseleave="onMouseLeave" @mouseleave="onMouseLeave"
......
...@@ -97,15 +97,20 @@ export default { ...@@ -97,15 +97,20 @@ export default {
this.reportFailure(DRAW_FAILURE); this.reportFailure(DRAW_FAILURE);
} }
}, },
getStageBackgroundClass(index) { getStageBackgroundClasses(index) {
const { length } = this.pipelineData.stages; const { length } = this.pipelineData.stages;
// It's possible for a graph to have only one stage, in which
// case we concatenate both the left and right rounding classes
if (length === 1) { if (length === 1) {
return 'stage-rounded'; return 'gl-rounded-bottom-left-6 gl-rounded-top-left-6 gl-rounded-bottom-right-6 gl-rounded-top-right-6';
} else if (index === 0) { }
return 'stage-left-rounded';
} else if (index === length - 1) { if (index === 0) {
return 'stage-right-rounded'; return 'gl-rounded-bottom-left-6 gl-rounded-top-left-6';
}
if (index === length - 1) {
return 'gl-rounded-bottom-right-6 gl-rounded-top-right-6';
} }
return ''; return '';
...@@ -190,7 +195,8 @@ export default { ...@@ -190,7 +195,8 @@ export default {
> >
<div <div
class="gl-display-flex gl-align-items-center gl-bg-white gl-w-full gl-px-8 gl-py-4 gl-mb-5" class="gl-display-flex gl-align-items-center gl-bg-white gl-w-full gl-px-8 gl-py-4 gl-mb-5"
:class="getStageBackgroundClass(index)" :class="getStageBackgroundClasses(index)"
data-testid="stage-background"
> >
<stage-pill :stage-name="stage.name" :is-empty="stage.groups.length === 0" /> <stage-pill :stage-name="stage.name" :is-empty="stage.groups.length === 0" />
</div> </div>
......
...@@ -26,7 +26,7 @@ export default { ...@@ -26,7 +26,7 @@ export default {
<template> <template>
<tooltip-on-truncate :title="stageName" truncate-target="child" placement="top"> <tooltip-on-truncate :title="stageName" truncate-target="child" placement="top">
<div <div
class="gl-px-5 gl-py-2 gl-text-white gl-text-center gl-text-truncate gl-rounded-pill pipeline-stage-pill" class="gl-px-5 gl-py-2 gl-text-white gl-text-center gl-text-truncate gl-rounded-pill gl-w-20"
:class="emptyClass" :class="emptyClass"
> >
{{ stageName }} {{ stageName }}
......
...@@ -486,23 +486,3 @@ ...@@ -486,23 +486,3 @@
.progress-bar.bg-primary { .progress-bar.bg-primary {
background-color: $blue-500 !important; background-color: $blue-500 !important;
} }
.pipeline-stage-pill {
width: 10rem;
}
.pipeline-job-pill {
width: 8rem;
}
.stage-rounded {
border-radius: 2rem;
}
.stage-left-rounded {
border-radius: 2rem 0 0 2rem;
}
.stage-right-rounded {
border-radius: 0 2rem 2rem 0;
}
...@@ -91,3 +91,18 @@ export const pipelineData = { ...@@ -91,3 +91,18 @@ export const pipelineData = {
[jobId4]: {}, [jobId4]: {},
}, },
}; };
export const singleStageData = {
stages: [
{
name: 'build',
groups: [
{
name: 'build_1',
jobs: [{ script: 'echo hello', stage: 'build' }],
id: jobId1,
},
],
},
],
};
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { pipelineData } from './mock_data'; import { pipelineData, singleStageData } from './mock_data';
import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue'; import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue';
import StagePill from '~/pipelines/components/pipeline_graph/stage_pill.vue'; import StagePill from '~/pipelines/components/pipeline_graph/stage_pill.vue';
import JobPill from '~/pipelines/components/pipeline_graph/job_pill.vue'; import JobPill from '~/pipelines/components/pipeline_graph/job_pill.vue';
...@@ -18,6 +18,8 @@ describe('pipeline graph component', () => { ...@@ -18,6 +18,8 @@ describe('pipeline graph component', () => {
}; };
const findAllStagePills = () => wrapper.findAll(StagePill); const findAllStagePills = () => wrapper.findAll(StagePill);
const findAllStageBackgroundElements = () => wrapper.findAll('[data-testid="stage-background"]');
const findStageBackgroundElementAt = index => findAllStageBackgroundElements().at(index);
const findAllJobPills = () => wrapper.findAll(JobPill); const findAllJobPills = () => wrapper.findAll(JobPill);
afterEach(() => { afterEach(() => {
...@@ -41,12 +43,43 @@ describe('pipeline graph component', () => { ...@@ -41,12 +43,43 @@ describe('pipeline graph component', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createComponent(); wrapper = createComponent();
}); });
it('renders the right number of stage pills', () => { it('renders the right number of stage pills', () => {
const expectedStagesLength = pipelineData.stages.length; const expectedStagesLength = pipelineData.stages.length;
expect(findAllStagePills()).toHaveLength(expectedStagesLength); expect(findAllStagePills()).toHaveLength(expectedStagesLength);
}); });
it.each`
cssClass | expectedState
${'gl-rounded-bottom-left-6'} | ${true}
${'gl-rounded-top-left-6'} | ${true}
${'gl-rounded-top-right-6'} | ${false}
${'gl-rounded-bottom-right-6'} | ${false}
`(
'rounds corner: $class should be $expectedState on the first element',
({ cssClass, expectedState }) => {
const classes = findStageBackgroundElementAt(0).classes();
expect(classes.includes(cssClass)).toBe(expectedState);
},
);
it.each`
cssClass | expectedState
${'gl-rounded-bottom-left-6'} | ${false}
${'gl-rounded-top-left-6'} | ${false}
${'gl-rounded-top-right-6'} | ${true}
${'gl-rounded-bottom-right-6'} | ${true}
`(
'rounds corner: $class should be $expectedState on the last element',
({ cssClass, expectedState }) => {
const classes = findStageBackgroundElementAt(pipelineData.stages.length - 1).classes();
expect(classes.includes(cssClass)).toBe(expectedState);
},
);
it('renders the right number of job pills', () => { it('renders the right number of job pills', () => {
// We count the number of jobs in the mock data // We count the number of jobs in the mock data
const expectedJobsLength = pipelineData.stages.reduce((acc, val) => { const expectedJobsLength = pipelineData.stages.reduce((acc, val) => {
...@@ -56,4 +89,25 @@ describe('pipeline graph component', () => { ...@@ -56,4 +89,25 @@ describe('pipeline graph component', () => {
expect(findAllJobPills()).toHaveLength(expectedJobsLength); expect(findAllJobPills()).toHaveLength(expectedJobsLength);
}); });
}); });
describe('with only one stage', () => {
beforeEach(() => {
wrapper = createComponent({ pipelineData: singleStageData });
});
it.each`
cssClass | expectedState
${'gl-rounded-bottom-left-6'} | ${true}
${'gl-rounded-top-left-6'} | ${true}
${'gl-rounded-top-right-6'} | ${true}
${'gl-rounded-bottom-right-6'} | ${true}
`(
'rounds corner: $class should be $expectedState on the only element',
({ cssClass, expectedState }) => {
const classes = findStageBackgroundElementAt(0).classes();
expect(classes.includes(cssClass)).toBe(expectedState);
},
);
});
}); });
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