Commit 4b461893 authored by Phil Hughes's avatar Phil Hughes

improve design of job items

allow ci icon to have a different size & be borderless
parent d61a27d5
......@@ -11,16 +11,48 @@ export default {
required: true,
},
},
computed: {
jobId() {
return `#${this.job.id}`;
},
},
};
</script>
<template>
<div>
<ci-icon :status="job.status" />
{{ job.name }}
<a
:href="job.build_path"
target="_blank"
>#{{ job.id }}</a>
<div class="ide-job-item">
<ci-icon
:status="job.status"
:borderless="true"
:size="24"
/>
<span class="prepend-left-8">
{{ job.name }}
<a
:href="job.build_path"
target="_blank"
v-text="jobId"
>
</a>
</span>
</div>
</template>
<style scoped>
.ide-job-item {
display: flex;
padding: 16px;
}
.ide-job-item:not(:last-child) {
border-bottom: 1px solid #e5e5e5;
}
.ide-job-item .ci-status-icon {
display: flex;
justify-content: center;
height: 20px;
margin-top: -2px;
overflow: hidden;
}
</style>
<script>
import { mapState } from 'vuex';
import LoadingIcon from '../../../vue_shared/components/loading_icon.vue';
import Stage from './stage.vue';
export default {
components: {
LoadingIcon,
Stage,
},
props: {
......@@ -11,15 +14,25 @@ export default {
required: true,
},
},
computed: {
...mapState('pipelines', ['isLoadingJobs']),
},
};
</script>
<template>
<div style="overflow: auto;">
<stage
v-for="stage in stages"
:key="stage.id"
:stage="stage"
<div>
<loading-icon
v-if="isLoadingJobs && !stages.length"
class="prepend-top-default"
size="2"
/>
<template v-else>
<stage
v-for="stage in stages"
:key="stage.id"
:stage="stage"
/>
</template>
</div>
</template>
<script>
import { mapActions } from 'vuex';
import tooltip from '../../../vue_shared/directives/tooltip';
import Icon from '../../../vue_shared/components/icon.vue';
import CiIcon from '../../../vue_shared/components/ci_icon.vue';
import LoadingIcon from '../../../vue_shared/components/loading_icon.vue';
import Item from './item.vue';
export default {
directives: {
tooltip,
},
components: {
Icon,
CiIcon,
......@@ -18,6 +22,11 @@ export default {
required: true,
},
},
data() {
return {
showTooltip: false,
};
},
computed: {
collapseIcon() {
return this.stage.isCollapsed ? 'angle-left' : 'angle-down';
......@@ -26,6 +35,11 @@ export default {
created() {
this.fetchJobs(this.stage);
},
mounted() {
const { stageTitle } = this.$refs;
this.showTooltip = stageTitle.scrollWidth > stageTitle.offsetWidth;
},
methods: {
...mapActions('pipelines', ['fetchJobs']),
},
......@@ -42,11 +56,18 @@ export default {
>
<ci-icon
:status="stage.status"
:size="24"
/>
<span class="prepend-left-8">
{{ stage.title }}
</span>
<div>
<strong
v-tooltip="showTooltip"
:title="showTooltip ? stage.name : null"
data-container="body"
class="prepend-left-8 ide-stage-title"
ref="stageTitle"
>
{{ stage.name }}
</strong>
<div class="append-right-8">
<span class="badge">
{{ stage.jobs.length }}
</span>
......@@ -87,4 +108,14 @@ export default {
.panel-heading .pull-right {
margin: auto 0 auto auto;
}
.panel-body {
padding: 0;
}
.ide-stage-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
......@@ -70,7 +70,7 @@ export default {
}
.ide-right-sidebar .multi-file-commit-panel-inner {
width: 300px;
width: 350px;
padding: 8px 16px;
background-color: #fff;
border-left: 1px solid #eaeaea;
......
......@@ -12,7 +12,7 @@ export default {
},
computed: {
...mapGetters('pipelines', ['jobsCount', 'failedJobsCount', 'failedStages']),
...mapState('pipelines', ['stages']),
...mapState('pipelines', ['stages', 'isLoadingJobs']),
},
created() {
this.fetchStages();
......@@ -28,7 +28,13 @@ export default {
<tabs>
<tab active>
<template slot="title">
Jobs <span class="badge">{{ jobsCount }}</span>
Jobs
<span
v-if="!isLoadingJobs || jobsCount"
class="badge"
>
{{ jobsCount }}
</span>
</template>
<jobs-list
:stages="stages"
......@@ -36,7 +42,13 @@ export default {
</tab>
<tab>
<template slot="title">
Failed Jobs <span class="badge">{{ failedJobsCount }}</span>
Failed Jobs
<span
v-if="!isLoadingJobs || failedJobsCount"
class="badge"
>
{{ failedJobsCount }}
</span>
</template>
<jobs-list
:stages="failedStages"
......
......@@ -42,6 +42,7 @@ export default {
>
<ci-icon
:status="statusIcon"
:size="24"
/>
<span class="prepend-left-8">
<strong>
......
export const hasLatestPipeline = state => !state.isLoadingPipeline && !!state.latestPipeline;
export const failedStages = state => state.stages.filter(stage => stage.status.label === 'failed');
export const failedStages = state =>
state.stages.filter(stage => stage.status.text === 'failed').map(stage => ({
...stage,
jobs: stage.jobs.filter(job => job.status.text === 'failed'),
}));
export const failedJobsCount = state =>
state.stages.reduce(
(acc, stage) => acc + stage.jobs.filter(j => j.status.label === 'failed').length,
(acc, stage) => acc + stage.jobs.filter(j => j.status.text === 'failed').length,
0,
);
......
......@@ -22,6 +22,8 @@ import Icon from '../../vue_shared/components/icon.vue';
* - Jobs show view header
* - Jobs show view sidebar
*/
const validSizes = [8, 12, 16, 18, 24, 32, 48, 72];
export default {
components: {
Icon,
......@@ -31,17 +33,36 @@ export default {
type: Object,
required: true,
},
size: {
type: Number,
required: false,
default: 16,
validator(value) {
return validSizes.includes(value);
},
},
borderless: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
cssClass() {
const status = this.status.group;
return `ci-status-icon ci-status-icon-${status} js-ci-status-icon-${status}`;
},
icon() {
return this.borderless ? `${this.status.icon}_borderless` : this.status.icon;
},
},
};
</script>
<template>
<span :class="cssClass">
<icon :name="status.icon" />
<icon
:name="icon"
:size="size"
/>
</span>
</template>
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