Merge branch '58105-pipeline-author-and-commit-author-too-close-together-in-pipeline-list' into 'master'
Improve pipelines table spacing, add triggerer column Closes #38802 and #58105 See merge request gitlab-org/gitlab-ce!26136
This commit is contained in:
commit
ef440879f1
|
@ -0,0 +1,35 @@
|
||||||
|
<script>
|
||||||
|
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
UserAvatarLink,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
pipeline: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
user() {
|
||||||
|
return this.pipeline.user;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="table-section section-10 d-none d-sm-none d-md-block pipeline-triggerer">
|
||||||
|
<user-avatar-link
|
||||||
|
v-if="user"
|
||||||
|
:link-href="user.path"
|
||||||
|
:img-src="user.avatar_url"
|
||||||
|
:img-size="26"
|
||||||
|
:tooltip-text="user.name"
|
||||||
|
class="prepend-left-default js-pipeline-url-user"
|
||||||
|
/>
|
||||||
|
<span v-else class="prepend-left-default js-pipeline-url-api api">
|
||||||
|
{{ s__('Pipelines|API') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -59,19 +59,10 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="table-section section-15 d-none d-sm-none d-md-block pipeline-tags">
|
<div class="table-section section-10 d-none d-sm-none d-md-block pipeline-tags">
|
||||||
<gl-link :href="pipeline.path" class="js-pipeline-url-link">
|
<gl-link :href="pipeline.path" class="js-pipeline-url-link">
|
||||||
<span class="pipeline-id">#{{ pipeline.id }}</span>
|
<span class="pipeline-id">#{{ pipeline.id }}</span>
|
||||||
</gl-link>
|
</gl-link>
|
||||||
<span>by</span>
|
|
||||||
<user-avatar-link
|
|
||||||
v-if="user"
|
|
||||||
:link-href="user.path"
|
|
||||||
:img-src="user.avatar_url"
|
|
||||||
:tooltip-text="user.name"
|
|
||||||
class="js-pipeline-url-user"
|
|
||||||
/>
|
|
||||||
<span v-if="!user" class="js-pipeline-url-api api"> API </span>
|
|
||||||
<div class="label-container">
|
<div class="label-container">
|
||||||
<span
|
<span
|
||||||
v-if="pipeline.flags.latest"
|
v-if="pipeline.flags.latest"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { GlTooltipDirective } from '@gitlab/ui';
|
||||||
import PipelinesTableRowComponent from './pipelines_table_row.vue';
|
import PipelinesTableRowComponent from './pipelines_table_row.vue';
|
||||||
import PipelineStopModal from './pipeline_stop_modal.vue';
|
import PipelineStopModal from './pipeline_stop_modal.vue';
|
||||||
import eventHub from '../event_hub';
|
import eventHub from '../event_hub';
|
||||||
|
@ -13,6 +14,9 @@ export default {
|
||||||
PipelinesTableRowComponent,
|
PipelinesTableRowComponent,
|
||||||
PipelineStopModal,
|
PipelineStopModal,
|
||||||
},
|
},
|
||||||
|
directives: {
|
||||||
|
GlTooltip: GlTooltipDirective,
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
pipelines: {
|
pipelines: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -62,16 +66,19 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div class="ci-table">
|
<div class="ci-table">
|
||||||
<div class="gl-responsive-table-row table-row-header" role="row">
|
<div class="gl-responsive-table-row table-row-header" role="row">
|
||||||
<div class="table-section section-10 js-pipeline-status pipeline-status" role="rowheader">
|
<div class="table-section section-10 js-pipeline-status" role="rowheader">
|
||||||
{{ s__('Pipeline|Status') }}
|
{{ s__('Pipeline|Status') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="table-section section-15 js-pipeline-info pipeline-info" role="rowheader">
|
<div class="table-section section-10 js-pipeline-info pipeline-info" role="rowheader">
|
||||||
{{ s__('Pipeline|Pipeline') }}
|
{{ s__('Pipeline|Pipeline') }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="table-section section-10 js-triggerer-info triggerer-info" role="rowheader">
|
||||||
|
{{ s__('Pipeline|Triggerer') }}
|
||||||
|
</div>
|
||||||
<div class="table-section section-20 js-pipeline-commit pipeline-commit" role="rowheader">
|
<div class="table-section section-20 js-pipeline-commit pipeline-commit" role="rowheader">
|
||||||
{{ s__('Pipeline|Commit') }}
|
{{ s__('Pipeline|Commit') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="table-section section-20 js-pipeline-stages pipeline-stages" role="rowheader">
|
<div class="table-section section-15 js-pipeline-stages pipeline-stages" role="rowheader">
|
||||||
{{ s__('Pipeline|Stages') }}
|
{{ s__('Pipeline|Stages') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import PipelinesArtifactsComponent from './pipelines_artifacts.vue';
|
||||||
import CiBadge from '../../vue_shared/components/ci_badge_link.vue';
|
import CiBadge from '../../vue_shared/components/ci_badge_link.vue';
|
||||||
import PipelineStage from './stage.vue';
|
import PipelineStage from './stage.vue';
|
||||||
import PipelineUrl from './pipeline_url.vue';
|
import PipelineUrl from './pipeline_url.vue';
|
||||||
|
import PipelineTriggerer from './pipeline_triggerer.vue';
|
||||||
import PipelinesTimeago from './time_ago.vue';
|
import PipelinesTimeago from './time_ago.vue';
|
||||||
import CommitComponent from '../../vue_shared/components/commit.vue';
|
import CommitComponent from '../../vue_shared/components/commit.vue';
|
||||||
import LoadingButton from '../../vue_shared/components/loading_button.vue';
|
import LoadingButton from '../../vue_shared/components/loading_button.vue';
|
||||||
|
@ -23,6 +24,7 @@ export default {
|
||||||
CommitComponent,
|
CommitComponent,
|
||||||
PipelineStage,
|
PipelineStage,
|
||||||
PipelineUrl,
|
PipelineUrl,
|
||||||
|
PipelineTriggerer,
|
||||||
CiBadge,
|
CiBadge,
|
||||||
PipelinesTimeago,
|
PipelinesTimeago,
|
||||||
LoadingButton,
|
LoadingButton,
|
||||||
|
@ -264,8 +266,9 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<pipeline-url :pipeline="pipeline" :auto-devops-help-path="autoDevopsHelpPath" />
|
<pipeline-url :pipeline="pipeline" :auto-devops-help-path="autoDevopsHelpPath" />
|
||||||
|
<pipeline-triggerer :pipeline="pipeline" />
|
||||||
|
|
||||||
<div class="table-section section-20">
|
<div class="table-section section-wrap section-20">
|
||||||
<div class="table-mobile-header" role="rowheader">{{ s__('Pipeline|Commit') }}</div>
|
<div class="table-mobile-header" role="rowheader">{{ s__('Pipeline|Commit') }}</div>
|
||||||
<div class="table-mobile-content">
|
<div class="table-mobile-content">
|
||||||
<commit-component
|
<commit-component
|
||||||
|
@ -281,7 +284,7 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-section section-wrap section-20 stage-cell">
|
<div class="table-section section-wrap section-15 stage-cell">
|
||||||
<div class="table-mobile-header" role="rowheader">{{ s__('Pipeline|Stages') }}</div>
|
<div class="table-mobile-header" role="rowheader">{{ s__('Pipeline|Stages') }}</div>
|
||||||
<div class="table-mobile-content">
|
<div class="table-mobile-content">
|
||||||
<template v-if="pipeline.details.stages.length > 0">
|
<template v-if="pipeline.details.stages.length > 0">
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Improve pipelines table spacing, add triggerer column
|
||||||
|
merge_request: 26136
|
||||||
|
author:
|
||||||
|
type: changed
|
|
@ -6719,6 +6719,9 @@ msgstr ""
|
||||||
msgid "Pipelines settings for '%{project_name}' were successfully updated."
|
msgid "Pipelines settings for '%{project_name}' were successfully updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Pipelines|API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Pipelines|Build with confidence"
|
msgid "Pipelines|Build with confidence"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -6797,6 +6800,9 @@ msgstr ""
|
||||||
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
|
msgid "Pipeline|Stop pipeline #%{pipelineId}?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Pipeline|Triggerer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Pipeline|Variables"
|
msgid "Pipeline|Variables"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { mount } from '@vue/test-utils';
|
||||||
|
import pipelineTriggerer from '~/pipelines/components/pipeline_triggerer.vue';
|
||||||
|
|
||||||
|
describe('Pipelines Triggerer', () => {
|
||||||
|
let wrapper;
|
||||||
|
|
||||||
|
const mockData = {
|
||||||
|
pipeline: {
|
||||||
|
user: {
|
||||||
|
name: 'foo',
|
||||||
|
avatar_url: '/avatar',
|
||||||
|
path: '/path',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const createComponent = () => {
|
||||||
|
wrapper = mount(pipelineTriggerer, {
|
||||||
|
propsData: mockData,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
createComponent();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
wrapper.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a table cell', () => {
|
||||||
|
expect(wrapper.contains('.table-section')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render triggerer information when triggerer is provided', () => {
|
||||||
|
const link = wrapper.find('.js-pipeline-url-user');
|
||||||
|
|
||||||
|
expect(link.attributes('href')).toEqual(mockData.pipeline.user.path);
|
||||||
|
expect(link.find('.js-user-avatar-image-toolip').text()).toEqual(mockData.pipeline.user.name);
|
||||||
|
expect(link.find('img.avatar').attributes('src')).toEqual(
|
||||||
|
`${mockData.pipeline.user.avatar_url}?width=26`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render "API" when no triggerer is provided', () => {
|
||||||
|
wrapper.setProps({
|
||||||
|
pipeline: {
|
||||||
|
user: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.find('.js-pipeline-url-api').text()).toEqual('API');
|
||||||
|
});
|
||||||
|
});
|
|
@ -42,54 +42,6 @@ describe('Pipeline Url Component', () => {
|
||||||
expect(component.$el.querySelector('.js-pipeline-url-link span').textContent).toEqual('#1');
|
expect(component.$el.querySelector('.js-pipeline-url-link span').textContent).toEqual('#1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render user information when a user is provided', () => {
|
|
||||||
const mockData = {
|
|
||||||
pipeline: {
|
|
||||||
id: 1,
|
|
||||||
path: 'foo',
|
|
||||||
flags: {},
|
|
||||||
user: {
|
|
||||||
web_url: '/',
|
|
||||||
name: 'foo',
|
|
||||||
avatar_url: '/',
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
autoDevopsHelpPath: 'foo',
|
|
||||||
};
|
|
||||||
|
|
||||||
const component = new PipelineUrlComponent({
|
|
||||||
propsData: mockData,
|
|
||||||
}).$mount();
|
|
||||||
|
|
||||||
const image = component.$el.querySelector('.js-pipeline-url-user img');
|
|
||||||
const tooltip = component.$el.querySelector(
|
|
||||||
'.js-pipeline-url-user .js-user-avatar-image-toolip',
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(component.$el.querySelector('.js-pipeline-url-user').getAttribute('href')).toEqual(
|
|
||||||
mockData.pipeline.user.web_url,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(tooltip.textContent.trim()).toEqual(mockData.pipeline.user.name);
|
|
||||||
expect(image.getAttribute('src')).toEqual(`${mockData.pipeline.user.avatar_url}?width=20`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render "API" when no user is provided', () => {
|
|
||||||
const component = new PipelineUrlComponent({
|
|
||||||
propsData: {
|
|
||||||
pipeline: {
|
|
||||||
id: 1,
|
|
||||||
path: 'foo',
|
|
||||||
flags: {},
|
|
||||||
},
|
|
||||||
autoDevopsHelpPath: 'foo',
|
|
||||||
},
|
|
||||||
}).$mount();
|
|
||||||
|
|
||||||
expect(component.$el.querySelector('.js-pipeline-url-api').textContent).toContain('API');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render latest, yaml invalid, merge request, and stuck flags when provided', () => {
|
it('should render latest, yaml invalid, merge request, and stuck flags when provided', () => {
|
||||||
const component = new PipelineUrlComponent({
|
const component = new PipelineUrlComponent({
|
||||||
propsData: {
|
propsData: {
|
||||||
|
|
|
@ -80,13 +80,13 @@ describe('Pipelines Table Row', () => {
|
||||||
it('should render user information', () => {
|
it('should render user information', () => {
|
||||||
expect(
|
expect(
|
||||||
component.$el
|
component.$el
|
||||||
.querySelector('.table-section:nth-child(2) a:nth-child(3)')
|
.querySelector('.table-section:nth-child(3) .js-pipeline-url-user')
|
||||||
.getAttribute('href'),
|
.getAttribute('href'),
|
||||||
).toEqual(pipeline.user.path);
|
).toEqual(pipeline.user.path);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
component.$el
|
component.$el
|
||||||
.querySelector('.table-section:nth-child(2) .js-user-avatar-image-toolip')
|
.querySelector('.table-section:nth-child(3) .js-user-avatar-image-toolip')
|
||||||
.textContent.trim(),
|
.textContent.trim(),
|
||||||
).toEqual(pipeline.user.name);
|
).toEqual(pipeline.user.name);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue