2018-05-09 12:01:36 +05:30
|
|
|
import $ from 'jquery';
|
2020-10-24 23:57:45 +05:30
|
|
|
import { deprecatedCreateFlash as flash } from './flash';
|
2018-03-17 18:26:18 +05:30
|
|
|
import axios from './lib/utils/axios_utils';
|
2019-09-04 21:01:54 +05:30
|
|
|
import { __ } from './locale';
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* In each pipelines table we have a mini pipeline graph for each pipeline.
|
|
|
|
*
|
|
|
|
* When we click in a pipeline stage, we need to make an API call to get the
|
|
|
|
* builds list to render in a dropdown.
|
|
|
|
*
|
|
|
|
* The container should be the table element.
|
|
|
|
*
|
|
|
|
* The stage icon clicked needs to have the following HTML structure:
|
|
|
|
* <div class="dropdown">
|
|
|
|
* <button class="dropdown js-builds-dropdown-button" data-toggle="dropdown"></button>
|
|
|
|
* <div class="js-builds-dropdown-container dropdown-menu"></div>
|
|
|
|
* </div>
|
|
|
|
*/
|
|
|
|
|
|
|
|
export default class MiniPipelineGraph {
|
|
|
|
constructor(opts = {}) {
|
|
|
|
this.container = opts.container || '';
|
|
|
|
this.dropdownListSelector = '.js-builds-dropdown-container';
|
|
|
|
this.getBuildsList = this.getBuildsList.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds the event listener when the dropdown is opened.
|
|
|
|
* All dropdown events are fired at the .dropdown-menu's parent element.
|
|
|
|
*/
|
|
|
|
bindEvents() {
|
|
|
|
$(document)
|
|
|
|
.off('shown.bs.dropdown', this.container)
|
|
|
|
.on('shown.bs.dropdown', this.container, this.getBuildsList);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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() {
|
|
|
|
$(document).on(
|
|
|
|
'click',
|
|
|
|
`${this.container} .js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item`,
|
2021-03-08 18:12:59 +05:30
|
|
|
(e) => {
|
2017-08-17 22:00:37 +05:30
|
|
|
e.stopPropagation();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For the clicked stage, renders the given data in the dropdown list.
|
|
|
|
*
|
|
|
|
* @param {HTMLElement} stageContainer
|
|
|
|
* @param {Object} data
|
|
|
|
*/
|
|
|
|
renderBuildsList(stageContainer, data) {
|
|
|
|
const dropdownContainer = stageContainer.parentElement.querySelector(
|
2018-10-15 14:42:47 +05:30
|
|
|
`${this.dropdownListSelector} .js-builds-dropdown-list ul`,
|
2017-08-17 22:00:37 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
dropdownContainer.innerHTML = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For the clicked stage, gets the list of builds.
|
|
|
|
*
|
|
|
|
* All dropdown events have a relatedTarget property,
|
|
|
|
* whose value is the toggling anchor element.
|
|
|
|
*
|
|
|
|
* @param {Object} e bootstrap dropdown event
|
|
|
|
* @return {Promise}
|
|
|
|
*/
|
|
|
|
getBuildsList(e) {
|
|
|
|
const button = e.relatedTarget;
|
|
|
|
const endpoint = button.dataset.stageEndpoint;
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
this.renderBuildsList(button, '');
|
|
|
|
this.toggleLoading(button);
|
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
axios
|
|
|
|
.get(endpoint)
|
2018-03-17 18:26:18 +05:30
|
|
|
.then(({ data }) => {
|
2017-08-17 22:00:37 +05:30
|
|
|
this.toggleLoading(button);
|
|
|
|
this.renderBuildsList(button, data.html);
|
|
|
|
this.stopDropdownClickPropagation();
|
2018-03-17 18:26:18 +05:30
|
|
|
})
|
|
|
|
.catch(() => {
|
2017-08-17 22:00:37 +05:30
|
|
|
this.toggleLoading(button);
|
2021-03-08 18:12:59 +05:30
|
|
|
if ($(button).parent().hasClass('open')) {
|
2017-08-17 22:00:37 +05:30
|
|
|
$(button).dropdown('toggle');
|
|
|
|
}
|
2019-09-04 21:01:54 +05:30
|
|
|
flash(__('An error occurred while fetching the builds.'), 'alert');
|
2018-03-17 18:26:18 +05:30
|
|
|
});
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Toggles the visibility of the loading icon.
|
|
|
|
*
|
|
|
|
* @param {HTMLElement} stageContainer
|
|
|
|
* @return {type}
|
|
|
|
*/
|
|
|
|
toggleLoading(stageContainer) {
|
2018-12-13 13:39:08 +05:30
|
|
|
stageContainer.parentElement
|
|
|
|
.querySelector(`${this.dropdownListSelector} .js-builds-dropdown-loading`)
|
|
|
|
.classList.toggle('hidden');
|
2017-08-17 22:00:37 +05:30
|
|
|
}
|
|
|
|
}
|