summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/importer_status.js
blob: 523bd2adb93e8fe8e283a74bbed65a3ef2ab0fdb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import _ from 'underscore';
import { __, sprintf } from './locale';
import axios from './lib/utils/axios_utils';
import flash from './flash';
import { convertPermissionToBoolean } from './lib/utils/common_utils';

class ImporterStatus {
  constructor({ jobsUrl, importUrl, ciCdOnly }) {
    this.jobsUrl = jobsUrl;
    this.importUrl = importUrl;
    this.ciCdOnly = ciCdOnly;
    this.initStatusPage();
    this.setAutoUpdate();
  }

  initStatusPage() {
    $('.js-add-to-import')
      .off('click')
      .on('click', this.addToImport.bind(this));

    $('.js-import-all')
      .off('click')
      .on('click', function onClickImportAll() {
        const $btn = $(this);
        $btn.disable().addClass('is-loading');
        return $('.js-add-to-import').each(function triggerAddImport() {
          return $(this).trigger('click');
        });
      });
  }

  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_', '');
    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');

    return axios.post(this.importUrl, {
      repo_id: id,
      target_namespace: targetNamespace,
      new_name: newName,
      ci_cd_only: this.ciCdOnly,
    })
    .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('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(() => flash(__('An error occurred while importing project')));
  }

  autoUpdate() {
    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('active').addClass('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;
          }
        });
      });
  }

  setAutoUpdate() {
    setInterval(this.autoUpdate.bind(this), 4000);
  }
}

// eslint-disable-next-line consistent-return
function initImporterStatus() {
  const importerStatus = document.querySelector('.js-importer-status');

  if (importerStatus) {
    const data = importerStatus.dataset;
    return new ImporterStatus({
      jobsUrl: data.jobsImportPath,
      importUrl: data.importPath,
      ciCdOnly: convertPermissionToBoolean(data.ciCdOnly),
    });
  }
}

export {
  initImporterStatus as default,
  ImporterStatus,
};