debian-mirror-gitlab/app/assets/javascripts/pipelines/components/stage.vue

195 lines
4.7 KiB
Vue
Raw Normal View History

2017-08-17 22:00:37 +05:30
<script>
2018-10-15 14:42:47 +05:30
/**
* 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';
2019-02-15 15:39:39 +05:30
import { GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
2018-10-15 14:42:47 +05:30
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';
2018-12-13 13:39:08 +05:30
import JobItem from './graph/job_item.vue';
2018-10-15 14:42:47 +05:30
import { PIPELINES_TABLE } from '../constants';
export default {
components: {
Icon,
2018-12-13 13:39:08 +05:30
JobItem,
GlLoadingIcon,
2018-10-15 14:42:47 +05:30
},
directives: {
2019-02-15 15:39:39 +05:30
GlTooltip: GlTooltipDirective,
2018-10-15 14:42:47 +05:30
},
props: {
stage: {
type: Object,
required: true,
2017-08-17 22:00:37 +05:30
},
2018-10-15 14:42:47 +05:30
updateDropdown: {
type: Boolean,
required: false,
default: false,
2017-08-17 22:00:37 +05:30
},
2018-10-15 14:42:47 +05:30
type: {
type: String,
required: false,
default: '',
},
},
data() {
return {
isLoading: false,
dropdownContent: '',
};
},
computed: {
dropdownClass() {
return this.dropdownContent.length > 0
? 'js-builds-dropdown-container'
: 'js-builds-dropdown-loading';
2017-08-17 22:00:37 +05:30
},
2018-10-15 14:42:47 +05:30
triggerButtonClass() {
return `ci-status-icon-${this.stage.status.group}`;
2017-08-17 22:00:37 +05:30
},
2018-10-15 14:42:47 +05:30
borderlessIcon() {
return `${this.stage.status.icon}_borderless`;
},
},
2017-08-17 22:00:37 +05:30
2018-10-15 14:42:47 +05:30
watch: {
updateDropdown() {
if (this.updateDropdown && this.isDropdownOpen() && !this.isLoading) {
this.fetchJobs();
}
},
},
updated() {
if (this.dropdownContent.length > 0) {
this.stopDropdownClickPropagation();
}
},
methods: {
onClickStage() {
if (!this.isDropdownOpen()) {
eventHub.$emit('clickedDropdown');
this.isLoading = true;
this.fetchJobs();
}
},
2017-08-17 22:00:37 +05:30
2018-10-15 14:42:47 +05:30
fetchJobs() {
axios
.get(this.stage.dropdown_path)
.then(({ data }) => {
this.dropdownContent = data.latest_statuses;
this.isLoading = false;
})
.catch(() => {
this.closeDropdown();
this.isLoading = false;
Flash(__('Something went wrong on our end.'));
});
2017-08-17 22:00:37 +05:30
},
2018-10-15 14:42:47 +05:30
/**
* 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() {
$(
'.js-builds-dropdown-list button, .js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item',
this.$el,
).on('click', e => {
e.stopPropagation();
});
2017-08-17 22:00:37 +05:30
},
2018-10-15 14:42:47 +05:30
closeDropdown() {
if (this.isDropdownOpen()) {
$(this.$refs.dropdown).dropdown('toggle');
2018-03-17 18:26:18 +05:30
}
2017-08-17 22:00:37 +05:30
},
2018-10-15 14:42:47 +05:30
isDropdownOpen() {
2020-05-24 23:13:21 +05:30
return this.$el.classList.contains('show');
2018-10-15 14:42:47 +05:30
},
pipelineActionRequestComplete() {
if (this.type === PIPELINES_TABLE) {
// warn the table to update
eventHub.$emit('refreshPipelinesTable');
} else {
// close the dropdown in mr widget
$(this.$refs.dropdown).dropdown('toggle');
}
2017-08-17 22:00:37 +05:30
},
2018-10-15 14:42:47 +05:30
},
};
2017-08-17 22:00:37 +05:30
</script>
<template>
<div class="dropdown">
<button
2018-11-08 19:23:39 +05:30
id="stageDropdown"
ref="dropdown"
2019-02-15 15:39:39 +05:30
v-gl-tooltip.hover
2017-08-17 22:00:37 +05:30
:class="triggerButtonClass"
:title="stage.title"
2018-11-08 19:23:39 +05:30
class="mini-pipeline-graph-dropdown-toggle js-builds-dropdown-button"
2017-08-17 22:00:37 +05:30
data-toggle="dropdown"
2018-11-08 19:23:39 +05:30
data-display="static"
2017-08-17 22:00:37 +05:30
type="button"
aria-haspopup="true"
2018-03-17 18:26:18 +05:30
aria-expanded="false"
2018-11-08 19:23:39 +05:30
@click="onClickStage"
2018-03-17 18:26:18 +05:30
>
2019-02-15 15:39:39 +05:30
<span :aria-label="stage.title" aria-hidden="true" class="no-pointer-events">
2018-03-17 18:26:18 +05:30
<icon :name="borderlessIcon" />
2017-08-17 22:00:37 +05:30
</span>
</button>
2018-11-08 19:23:39 +05:30
<div
2017-08-17 22:00:37 +05:30
class="dropdown-menu mini-pipeline-graph-dropdown-menu js-builds-dropdown-container"
2018-03-17 18:26:18 +05:30
aria-labelledby="stageDropdown"
>
2019-02-15 15:39:39 +05:30
<gl-loading-icon v-if="isLoading" />
<ul v-else class="js-builds-dropdown-list scrollable-menu">
<li v-for="job in dropdownContent" :key="job.id">
2018-12-13 13:39:08 +05:30
<job-item
2018-11-08 19:23:39 +05:30
:dropdown-length="dropdownContent.length"
:job="job"
css-class-job-name="mini-pipeline-graph-dropdown-item"
@pipelineActionRequestComplete="pipelineActionRequestComplete"
/>
</li>
</ul>
</div>
2017-08-17 22:00:37 +05:30
</div>
2018-03-17 18:26:18 +05:30
</template>