Cleans up CSS - All pipeline dropdowns use the same CSS to render the action icons
This commit is contained in:
parent
9ff5041090
commit
e0b7541b9a
3 changed files with 131 additions and 317 deletions
|
@ -1,261 +1,139 @@
|
|||
<script>
|
||||
/**
|
||||
* Renders each stage of the pipeline mini graph.
|
||||
*
|
||||
* Given the provided endpoint will make a request to
|
||||
* fetch the dropdown data when the stage is clicked.
|
||||
*
|
||||
* Request is made inside this component to make it reusable between:
|
||||
* 1. Pipelines main table
|
||||
* 2. Pipelines table in commit and Merge request views
|
||||
* 3. Merge request widget
|
||||
* 4. Commit widget
|
||||
*/
|
||||
/**
|
||||
* Renders each stage of the pipeline mini graph.
|
||||
*
|
||||
* Given the provided endpoint will make a request to
|
||||
* fetch the dropdown data when the stage is clicked.
|
||||
*
|
||||
* Request is made inside this component to make it reusable between:
|
||||
* 1. Pipelines main table
|
||||
* 2. Pipelines table in commit and Merge request views
|
||||
* 3. Merge request widget
|
||||
* 4. Commit widget
|
||||
*/
|
||||
|
||||
import $ from 'jquery';
|
||||
import Flash from '../../flash';
|
||||
import axios from '../../lib/utils/axios_utils';
|
||||
import eventHub from '../event_hub';
|
||||
import Icon from '../../vue_shared/components/icon.vue';
|
||||
import LoadingIcon from '../../vue_shared/components/loading_icon.vue';
|
||||
import JobComponent from './graph/job_component.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
import $ from 'jquery';
|
||||
import { _ } from '~/locale';
|
||||
import Flash from '../../flash';
|
||||
import axios from '../../lib/utils/axios_utils';
|
||||
import eventHub from '../event_hub';
|
||||
import Icon from '../../vue_shared/components/icon.vue';
|
||||
import LoadingIcon from '../../vue_shared/components/loading_icon.vue';
|
||||
import JobComponent from './graph/job_component.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LoadingIcon,
|
||||
Icon,
|
||||
JobComponent,
|
||||
export default {
|
||||
components: {
|
||||
LoadingIcon,
|
||||
Icon,
|
||||
JobComponent,
|
||||
},
|
||||
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
|
||||
props: {
|
||||
stage: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
|
||||
directives: {
|
||||
tooltip,
|
||||
updateDropdown: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
dropdownContent: '',
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
dropdownClass() {
|
||||
return this.dropdownContent.length > 0
|
||||
? 'js-builds-dropdown-container'
|
||||
: 'js-builds-dropdown-loading';
|
||||
},
|
||||
|
||||
props: {
|
||||
stage: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
|
||||
updateDropdown: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
triggerButtonClass() {
|
||||
return `ci-status-icon-${this.stage.status.group}`;
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
dropdownContent: '',
|
||||
};
|
||||
borderlessIcon() {
|
||||
return `${this.stage.status.icon}_borderless`;
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
dropdownClass() {
|
||||
// return this.dropdownContent.length > 0
|
||||
// ? 'js-builds-dropdown-container'
|
||||
// : 'js-builds-dropdown-loading';
|
||||
},
|
||||
|
||||
triggerButtonClass() {
|
||||
return `ci-status-icon-${this.stage.status.group}`;
|
||||
},
|
||||
|
||||
borderlessIcon() {
|
||||
return `${this.stage.status.icon}_borderless`;
|
||||
},
|
||||
watch: {
|
||||
updateDropdown() {
|
||||
if (this.updateDropdown && this.isDropdownOpen() && !this.isLoading) {
|
||||
this.fetchJobs();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
updateDropdown() {
|
||||
if (this.updateDropdown && this.isDropdownOpen() && !this.isLoading) {
|
||||
this.fetchJobs();
|
||||
}
|
||||
},
|
||||
},
|
||||
updated() {
|
||||
if (this.dropdownContent.length > 0) {
|
||||
this.stopDropdownClickPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
updated() {
|
||||
if (this.dropdownContent.length > 0) {
|
||||
this.stopDropdownClickPropagation();
|
||||
methods: {
|
||||
onClickStage() {
|
||||
if (!this.isDropdownOpen()) {
|
||||
eventHub.$emit('clickedDropdown');
|
||||
this.isLoading = true;
|
||||
this.fetchJobs();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClickStage() {
|
||||
if (!this.isDropdownOpen()) {
|
||||
eventHub.$emit('clickedDropdown');
|
||||
this.isLoading = true;
|
||||
this.fetchJobs();
|
||||
}
|
||||
},
|
||||
fetchJobs() {
|
||||
axios
|
||||
.get(this.stage.dropdown_path)
|
||||
.then(({ data }) => {
|
||||
this.dropdownContent = data;
|
||||
this.isLoading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.closeDropdown();
|
||||
this.isLoading = false;
|
||||
|
||||
fetchJobs() {
|
||||
axios
|
||||
.get(this.stage.dropdown_path)
|
||||
.then(({ data }) => {
|
||||
// TODO: REMOVE THIS ONCE WE HAVE BACKEND
|
||||
this.dropdownContent = [
|
||||
{
|
||||
id: 966,
|
||||
name: 'rspec:linux 0 3',
|
||||
started: false,
|
||||
build_path: '/twitter/flight/-/jobs/966',
|
||||
cancel_path: '/twitter/flight/-/jobs/966/cancel',
|
||||
playable: false,
|
||||
created_at: '2018-04-18T12:10:14.315Z',
|
||||
updated_at: '2018-04-18T12:10:14.500Z',
|
||||
status: {
|
||||
icon: 'status_pending',
|
||||
text: 'pending',
|
||||
label: 'pending',
|
||||
group: 'pending',
|
||||
tooltip: 'pending',
|
||||
has_details: true,
|
||||
details_path: '/twitter/flight/-/jobs/966',
|
||||
favicon:
|
||||
'/assets/ci_favicons/dev/favicon_status_pending-db32e1faf94b9f89530ac519790920d1f18ea8f6af6cd2e0a26cd6840cacf101.ico',
|
||||
action: {
|
||||
icon: 'cancel',
|
||||
title: 'Cancel',
|
||||
path: '/twitter/flight/-/jobs/966/cancel',
|
||||
method: 'post',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 208,
|
||||
name: 'rspec:linux 1 3',
|
||||
started: '2018-03-07T06:41:46.233Z',
|
||||
build_path: '/twitter/flight/-/jobs/208',
|
||||
retry_path: '/twitter/flight/-/jobs/208/retry',
|
||||
playable: false,
|
||||
created_at: '2018-03-07T14:41:57.559Z',
|
||||
updated_at: '2018-03-07T14:41:57.559Z',
|
||||
status: {
|
||||
icon: 'status_success',
|
||||
text: 'passed',
|
||||
label: 'passed',
|
||||
group: 'success',
|
||||
tooltip: 'passed',
|
||||
has_details: true,
|
||||
details_path: '/twitter/flight/-/jobs/208',
|
||||
favicon:
|
||||
'/assets/ci_favicons/dev/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.ico',
|
||||
action: {
|
||||
icon: 'retry',
|
||||
title: 'Retry',
|
||||
path: '/twitter/flight/-/jobs/208/retry',
|
||||
method: 'post',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 209,
|
||||
name: 'rspec:linux 2 3',
|
||||
started: '2018-03-07T06:41:46.233Z',
|
||||
build_path: '/twitter/flight/-/jobs/209',
|
||||
retry_path: '/twitter/flight/-/jobs/209/retry',
|
||||
playable: false,
|
||||
created_at: '2018-03-07T14:41:57.605Z',
|
||||
updated_at: '2018-03-07T14:41:57.605Z',
|
||||
status: {
|
||||
icon: 'status_success',
|
||||
text: 'passed',
|
||||
label: 'passed',
|
||||
group: 'success',
|
||||
tooltip: 'passed',
|
||||
has_details: true,
|
||||
details_path: '/twitter/flight/-/jobs/209',
|
||||
favicon:
|
||||
'/assets/ci_favicons/dev/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.ico',
|
||||
action: {
|
||||
icon: 'retry',
|
||||
title: 'Retry',
|
||||
path: '/twitter/flight/-/jobs/209/retry',
|
||||
method: 'post',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 63701097,
|
||||
name: 'spinach-mysql 0 2',
|
||||
started: false,
|
||||
build_path: '/gitlab-org/gitlab-ce/-/jobs/63701097',
|
||||
playable: false,
|
||||
created_at: '2018-04-18T15:16:52.707Z',
|
||||
updated_at: '2018-04-18T15:16:52.707Z',
|
||||
status: {
|
||||
icon: 'status_created',
|
||||
text: 'created',
|
||||
label: 'created',
|
||||
group: 'created',
|
||||
tooltip: 'created',
|
||||
has_details: true,
|
||||
details_path: '/gitlab-org/gitlab-ce/-/jobs/63701097',
|
||||
favicon:
|
||||
'https://assets.gitlab-static.net/assets/ci_favicons/favicon_status_created-e997aa0b7db73165df8a9d6803932b18d7b7cc37d604d2d96e378fea2dba9c5f.ico',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 63701098,
|
||||
name: 'spinach-mysql 1 2',
|
||||
started: false,
|
||||
build_path: '/gitlab-org/gitlab-ce/-/jobs/63701098',
|
||||
playable: false,
|
||||
created_at: '2018-04-18T15:16:52.808Z',
|
||||
updated_at: '2018-04-18T15:16:52.808Z',
|
||||
status: {
|
||||
icon: 'status_created',
|
||||
text: 'created',
|
||||
label: 'created',
|
||||
group: 'created',
|
||||
tooltip: 'created',
|
||||
has_details: true,
|
||||
details_path: '/gitlab-org/gitlab-ce/-/jobs/63701098',
|
||||
favicon:
|
||||
'https://assets.gitlab-static.net/assets/ci_favicons/favicon_status_created-e997aa0b7db73165df8a9d6803932b18d7b7cc37d604d2d96e378fea2dba9c5f.ico',
|
||||
},
|
||||
},
|
||||
];
|
||||
this.isLoading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.closeDropdown();
|
||||
this.isLoading = false;
|
||||
|
||||
Flash('Something went wrong on our end.');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* When the user right clicks or cmd/ctrl + click in the job name
|
||||
* the dropdown should not be closed and the link should open in another tab,
|
||||
* so we stop propagation of the click event inside the dropdown.
|
||||
*
|
||||
* Since this component is rendered multiple times per page we need to guarantee we only
|
||||
* target the click event of this component.
|
||||
*/
|
||||
stopDropdownClickPropagation() {
|
||||
$(
|
||||
this.$el.querySelectorAll('.js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item'),
|
||||
).on('click', e => {
|
||||
e.stopPropagation();
|
||||
Flash(_('Something went wrong on our end.'));
|
||||
});
|
||||
},
|
||||
|
||||
closeDropdown() {
|
||||
if (this.isDropdownOpen()) {
|
||||
$(this.$refs.dropdown).dropdown('toggle');
|
||||
}
|
||||
},
|
||||
|
||||
isDropdownOpen() {
|
||||
return this.$el.classList.contains('open');
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* When the user right clicks or cmd/ctrl + click in the job name
|
||||
* the dropdown should not be closed and the link should open in another tab,
|
||||
* so we stop propagation of the click event inside the dropdown.
|
||||
*
|
||||
* Since this component is rendered multiple times per page we need to guarantee we only
|
||||
* target the click event of this component.
|
||||
*/
|
||||
stopDropdownClickPropagation() {
|
||||
$(
|
||||
this.$el.querySelectorAll('.js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item')
|
||||
).on('click', e => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
},
|
||||
|
||||
closeDropdown() {
|
||||
if (this.isDropdownOpen()) {
|
||||
$(this.$refs.dropdown).dropdown('toggle');
|
||||
}
|
||||
},
|
||||
|
||||
isDropdownOpen() {
|
||||
return this.$el.classList.contains('open');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
}
|
||||
|
||||
.ci-table {
|
||||
|
||||
.label {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
@ -123,7 +122,6 @@
|
|||
}
|
||||
|
||||
.branch-commit {
|
||||
|
||||
.ref-name {
|
||||
font-weight: $gl-font-weight-bold;
|
||||
max-width: 100px;
|
||||
|
@ -505,7 +503,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.build {
|
||||
position: relative;
|
||||
|
@ -548,7 +546,6 @@
|
|||
border: 1px solid $dropdown-toggle-active-border-color;
|
||||
}
|
||||
|
||||
|
||||
// Connect first build in each stage with right horizontal line
|
||||
&:first-child {
|
||||
&::after {
|
||||
|
@ -604,15 +601,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Icons inside dropdown
|
||||
Action icons inside dropdowns:
|
||||
- mini graph in pipelines table
|
||||
- dropdown in big graph
|
||||
- mini graph in MR widget pipeline
|
||||
- mini graph in Commit widget pipeline
|
||||
*/
|
||||
.big-pipeline-graph-dropdown-menu,
|
||||
.mini-pipeline-graph-dropdown-menu {
|
||||
|
||||
// override dropdown.scss
|
||||
&.dropdown-menu li button {
|
||||
&.dropdown-menu li button,
|
||||
&.dropdown-menu li a.ci-action-icon-container {
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -622,7 +622,6 @@
|
|||
right: 5px;
|
||||
top: 5px;
|
||||
|
||||
// Action Icons in big pipeline-graph nodes
|
||||
&.ci-action-icon-wrapper {
|
||||
height: $ci-action-dropdown-button-size;
|
||||
width: $ci-action-dropdown-button-size;
|
||||
|
@ -651,6 +650,11 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SVGs in the commit widget and mr widget
|
||||
a.ci-action-icon-container.ci-action-icon-wrapper svg {
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
// Triggers the dropdown in the big pipeline graph
|
||||
|
@ -780,74 +784,6 @@ button.mini-pipeline-graph-dropdown-toggle {
|
|||
@extend .mini-pipeline-graph-dropdown-item:hover;
|
||||
}
|
||||
|
||||
// Action icon on the right
|
||||
a.ci-action-icon-wrapper {
|
||||
border-radius: 50%;
|
||||
border: 1px solid $border-color;
|
||||
width: $ci-action-icon-size;
|
||||
height: $ci-action-icon-size;
|
||||
padding: 2px 0 0 5px;
|
||||
font-size: 12px;
|
||||
background-color: $white-light;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: $gl-padding;
|
||||
margin-top: -#{$ci-action-icon-size / 2};
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: $stage-hover-bg;
|
||||
border: 1px solid $dropdown-toggle-active-border-color;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: $gl-text-color-secondary;
|
||||
width: #{$ci-action-icon-size - 6};
|
||||
height: #{$ci-action-icon-size - 6};
|
||||
left: -3px;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
|
||||
&.icon-action-stop,
|
||||
&.icon-action-cancel {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
top: 1px;
|
||||
left: -1px;
|
||||
}
|
||||
|
||||
&.icon-action-play {
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
top: 1px;
|
||||
left: 1px;
|
||||
}
|
||||
|
||||
&.icon-action-retry {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
top: 0;
|
||||
left: -3px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover svg,
|
||||
&:focus svg {
|
||||
fill: $gl-text-color;
|
||||
}
|
||||
|
||||
&.icon-action-retry,
|
||||
&.icon-action-play {
|
||||
svg {
|
||||
width: #{$ci-action-icon-size - 6};
|
||||
height: #{$ci-action-icon-size - 6};
|
||||
left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// link to the build
|
||||
.mini-pipeline-graph-dropdown-item {
|
||||
align-items: center;
|
||||
|
@ -988,7 +924,7 @@ button.mini-pipeline-graph-dropdown-toggle {
|
|||
&.dropdown-menu {
|
||||
transform: translate(-80%, 0);
|
||||
|
||||
@media(min-width: $screen-md-min) {
|
||||
@media (min-width: $screen-md-min) {
|
||||
transform: translate(-50%, 0);
|
||||
right: auto;
|
||||
left: 50%;
|
||||
|
|
|
@ -16,5 +16,5 @@
|
|||
%span.ci-build-text= subject.name
|
||||
|
||||
- if status.has_action?
|
||||
= link_to status.action_path, class: "ci-action-icon-wrapper js-ci-action-icon", method: status.action_method, data: { toggle: 'tooltip', title: status.action_title, container: 'body' } do
|
||||
= link_to status.action_path, class: "ci-action-icon-container ci-action-icon-wrapper js-ci-action-icon", method: status.action_method, data: { toggle: 'tooltip', title: status.action_title, container: 'body' } do
|
||||
= sprite_icon(status.action_icon, css_class: "icon-action-#{status.action_icon}")
|
||||
|
|
Loading…
Reference in a new issue