2018-03-09 15:18:59 -05:00
|
|
|
import $ from 'jquery';
|
2018-03-07 10:58:50 -05:00
|
|
|
import _ from 'underscore';
|
|
|
|
import { __, sprintf } from './locale';
|
2018-02-09 06:14:48 -05:00
|
|
|
import axios from './lib/utils/axios_utils';
|
|
|
|
import flash from './flash';
|
2018-11-21 10:13:04 -05:00
|
|
|
import { parseBoolean } from './lib/utils/common_utils';
|
2018-02-09 06:14:48 -05:00
|
|
|
|
2017-10-26 14:03:48 -04:00
|
|
|
class ImporterStatus {
|
2018-03-07 10:58:50 -05:00
|
|
|
constructor({ jobsUrl, importUrl, ciCdOnly }) {
|
2017-10-26 14:03:48 -04:00
|
|
|
this.jobsUrl = jobsUrl;
|
|
|
|
this.importUrl = importUrl;
|
2018-03-07 10:58:50 -05:00
|
|
|
this.ciCdOnly = ciCdOnly;
|
2017-10-26 14:03:48 -04:00
|
|
|
this.initStatusPage();
|
|
|
|
this.setAutoUpdate();
|
|
|
|
}
|
2016-12-14 00:26:26 -05:00
|
|
|
|
2017-10-26 14:03:48 -04:00
|
|
|
initStatusPage() {
|
|
|
|
$('.js-add-to-import')
|
|
|
|
.off('click')
|
2018-02-09 06:14:48 -05:00
|
|
|
.on('click', this.addToImport.bind(this));
|
2017-10-26 14:03:48 -04:00
|
|
|
|
|
|
|
$('.js-import-all')
|
|
|
|
.off('click')
|
|
|
|
.on('click', function onClickImportAll() {
|
|
|
|
const $btn = $(this);
|
2016-07-24 16:45:11 -04:00
|
|
|
$btn.disable().addClass('is-loading');
|
2017-10-26 14:03:48 -04:00
|
|
|
return $('.js-add-to-import').each(function triggerAddImport() {
|
2016-07-24 16:45:11 -04:00
|
|
|
return $(this).trigger('click');
|
|
|
|
});
|
|
|
|
});
|
2017-10-26 14:03:48 -04:00
|
|
|
}
|
|
|
|
|
2018-02-09 06:14:48 -05:00
|
|
|
addToImport(event) {
|
|
|
|
const $btn = $(event.currentTarget);
|
|
|
|
const $tr = $btn.closest('tr');
|
|
|
|
const $targetField = $tr.find('.import-target');
|
|
|
|
const $namespaceInput = $targetField.find('.js-select-namespace option:selected');
|
|
|
|
const id = $tr.attr('id').replace('repo_', '');
|
2018-07-05 17:09:01 -04:00
|
|
|
const repoData = $tr.data();
|
|
|
|
|
2018-02-09 06:14:48 -05:00
|
|
|
let targetNamespace;
|
|
|
|
let newName;
|
|
|
|
if ($namespaceInput.length > 0) {
|
|
|
|
targetNamespace = $namespaceInput[0].innerHTML;
|
|
|
|
newName = $targetField.find('#path').prop('value');
|
|
|
|
$targetField.empty().append(`${targetNamespace}/${newName}`);
|
|
|
|
}
|
|
|
|
$btn.disable().addClass('is-loading');
|
|
|
|
|
2018-07-01 09:19:40 -04:00
|
|
|
this.id = id;
|
|
|
|
|
2018-07-05 17:09:01 -04:00
|
|
|
let attributes = {
|
2018-02-09 06:14:48 -05:00
|
|
|
repo_id: id,
|
|
|
|
target_namespace: targetNamespace,
|
|
|
|
new_name: newName,
|
2018-07-06 00:52:24 -04:00
|
|
|
ci_cd_only: this.ciCdOnly,
|
2018-07-05 17:09:01 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
if (repoData) {
|
|
|
|
attributes = Object.assign(repoData, attributes);
|
|
|
|
}
|
|
|
|
|
2018-10-24 15:17:03 -04:00
|
|
|
return axios
|
|
|
|
.post(this.importUrl, attributes)
|
|
|
|
.then(({ data }) => {
|
|
|
|
const job = $(`tr#repo_${id}`);
|
|
|
|
job.attr('id', `project_${data.id}`);
|
|
|
|
|
|
|
|
job.find('.import-target').html(`<a href="${data.full_path}">${data.full_path}</a>`);
|
|
|
|
$('table.import-jobs tbody').prepend(job);
|
|
|
|
|
|
|
|
job.addClass('table-active');
|
|
|
|
const connectingVerb = this.ciCdOnly ? __('connecting') : __('importing');
|
|
|
|
job.find('.import-actions').html(
|
|
|
|
sprintf(
|
|
|
|
_.escape(__('%{loadingIcon} Started')),
|
|
|
|
{
|
|
|
|
loadingIcon: `<i class="fa fa-spinner fa-spin" aria-label="${_.escape(
|
|
|
|
connectingVerb,
|
|
|
|
)}"></i>`,
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
let details = error;
|
|
|
|
|
|
|
|
const $statusField = $(`#repo_${this.id} .job-status`);
|
|
|
|
$statusField.text(__('Failed'));
|
|
|
|
|
|
|
|
if (error.response && error.response.data && error.response.data.errors) {
|
|
|
|
details = error.response.data.errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
flash(sprintf(__('An error occurred while importing project: %{details}'), { details }));
|
|
|
|
});
|
2018-02-09 06:14:48 -05:00
|
|
|
}
|
|
|
|
|
2018-02-15 16:51:41 -05:00
|
|
|
autoUpdate() {
|
2018-10-24 15:17:03 -04:00
|
|
|
return axios.get(this.jobsUrl).then(({ data = [] }) => {
|
|
|
|
data.forEach(job => {
|
|
|
|
const jobItem = $(`#project_${job.id}`);
|
|
|
|
const statusField = jobItem.find('.job-status');
|
|
|
|
|
|
|
|
const spinner = '<i class="fa fa-spinner fa-spin"></i>';
|
|
|
|
|
|
|
|
switch (job.import_status) {
|
|
|
|
case 'finished':
|
|
|
|
jobItem.removeClass('table-active').addClass('table-success');
|
|
|
|
statusField.html(`<span><i class="fa fa-check"></i> ${__('Done')}</span>`);
|
|
|
|
break;
|
|
|
|
case 'scheduled':
|
|
|
|
statusField.html(`${spinner} ${__('Scheduled')}`);
|
|
|
|
break;
|
|
|
|
case 'started':
|
|
|
|
statusField.html(`${spinner} ${__('Started')}`);
|
|
|
|
break;
|
|
|
|
case 'failed':
|
|
|
|
statusField.html(__('Failed'));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
statusField.html(job.import_status);
|
|
|
|
break;
|
|
|
|
}
|
2018-02-15 16:51:41 -05:00
|
|
|
});
|
2018-10-24 15:17:03 -04:00
|
|
|
});
|
2018-02-15 16:51:41 -05:00
|
|
|
}
|
2016-07-24 16:45:11 -04:00
|
|
|
|
2018-02-15 16:51:41 -05:00
|
|
|
setAutoUpdate() {
|
|
|
|
setInterval(this.autoUpdate.bind(this), 4000);
|
2017-10-26 14:03:48 -04:00
|
|
|
}
|
|
|
|
}
|
2016-07-24 16:45:11 -04:00
|
|
|
|
2017-10-26 14:03:48 -04:00
|
|
|
// eslint-disable-next-line consistent-return
|
2018-02-09 06:14:48 -05:00
|
|
|
function initImporterStatus() {
|
2017-10-30 08:23:52 -04:00
|
|
|
const importerStatus = document.querySelector('.js-importer-status');
|
2016-08-30 13:34:37 -04:00
|
|
|
|
2017-10-30 08:23:52 -04:00
|
|
|
if (importerStatus) {
|
|
|
|
const data = importerStatus.dataset;
|
2018-03-07 10:58:50 -05:00
|
|
|
return new ImporterStatus({
|
|
|
|
jobsUrl: data.jobsImportPath,
|
|
|
|
importUrl: data.importPath,
|
2018-11-21 10:13:04 -05:00
|
|
|
ciCdOnly: parseBoolean(data.ciCdOnly),
|
2018-03-07 10:58:50 -05:00
|
|
|
});
|
2017-10-26 14:03:48 -04:00
|
|
|
}
|
|
|
|
}
|
2018-02-09 06:14:48 -05:00
|
|
|
|
2018-10-24 15:17:03 -04:00
|
|
|
export { initImporterStatus as default, ImporterStatus };
|