summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/groups_select.js
blob: 10363c16bae48d8a6a80ba5b9bb55d0231d2714e (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
/* eslint-disable func-names, space-before-function-paren, no-var, wrap-iife, one-var, camelcase, one-var-declaration-per-line, quotes, object-shorthand, prefer-arrow-callback, comma-dangle, consistent-return, yoda, prefer-rest-params, prefer-spread, no-unused-vars, prefer-template, max-len */
/* global Api */

var slice = [].slice;

window.GroupsSelect = (function() {
  function GroupsSelect() {
    $('.ajax-groups-select').each((function(_this) {
      const self = _this;

      return function(i, select) {
        var all_available, skip_groups;
        const $select = $(select);
        all_available = $select.data('all-available');
        skip_groups = $select.data('skip-groups') || [];

        $select.select2({
          placeholder: "Search for a group",
          multiple: $select.hasClass('multiselect'),
          minimumInputLength: 0,
          ajax: {
            url: Api.buildUrl(Api.groupsPath),
            dataType: 'json',
            quietMillis: 250,
            transport: function (params) {
              $.ajax(params).then((data, status, xhr) => {
                const results = data || [];

                const headers = gl.utils.normalizeCRLFHeaders(xhr.getAllResponseHeaders());
                const currentPage = parseInt(headers['X-PAGE'], 10) || 0;
                const totalPages = parseInt(headers['X-TOTAL-PAGES'], 10) || 0;
                const more = currentPage < totalPages;

                return {
                  results,
                  pagination: {
                    more,
                  },
                };
              }).then(params.success).fail(params.error);
            },
            data: function (search, page) {
              return {
                search,
                page,
                per_page: GroupsSelect.PER_PAGE,
                all_available,
              };
            },
            results: function (data, page) {
              if (data.length) return { results: [] };

              const groups = data.length ? data : data.results || [];
              const more = data.pagination ? data.pagination.more : false;
              const results = groups.filter(group => skip_groups.indexOf(group.id) === -1);

              return {
                results,
                page,
                more,
              };
            },
          },
          initSelection: function(element, callback) {
            var id;
            id = $(element).val();
            if (id !== "") {
              return Api.group(id, callback);
            }
          },
          formatResult: function() {
            var args;
            args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
            return self.formatResult.apply(self, args);
          },
          formatSelection: function() {
            var args;
            args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
            return self.formatSelection.apply(self, args);
          },
          dropdownCssClass: "ajax-groups-dropdown select2-infinite",
          // we do not want to escape markup since we are displaying html in results
          escapeMarkup: function(m) {
            return m;
          }
        });

        self.dropdown = document.querySelector('.select2-infinite .select2-results');

        $select.on('select2-loaded', self.forceOverflow.bind(self));
      };
    })(this));
  }

  GroupsSelect.prototype.formatResult = function(group) {
    var avatar;
    if (group.avatar_url) {
      avatar = group.avatar_url;
    } else {
      avatar = gon.default_avatar_url;
    }
    return "<div class='group-result'> <div class='group-name'>" + group.full_name + "</div> <div class='group-path'>" + group.full_path + "</div> </div>";
  };

  GroupsSelect.prototype.formatSelection = function(group) {
    return group.full_name;
  };

  GroupsSelect.prototype.forceOverflow = function (e) {
    const itemHeight = this.dropdown.querySelector('.select2-result:first-child').clientHeight;
    this.dropdown.style.height = `${Math.floor(this.dropdown.scrollHeight - (itemHeight * 0.9))}px`;
  };

  GroupsSelect.PER_PAGE = 20;

  return GroupsSelect;
})();