diff options
Diffstat (limited to 'app/assets/javascripts/groups_select.js')
-rw-r--r-- | app/assets/javascripts/groups_select.js | 162 |
1 files changed, 104 insertions, 58 deletions
diff --git a/app/assets/javascripts/groups_select.js b/app/assets/javascripts/groups_select.js index a50bc4a9057..602a3b78189 100644 --- a/app/assets/javascripts/groups_select.js +++ b/app/assets/javascripts/groups_select.js @@ -1,71 +1,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 */ -(function() { - var slice = [].slice; +var slice = [].slice; - this.GroupsSelect = (function() { - function GroupsSelect() { - $('.ajax-groups-select').each((function(_this) { - return function(i, select) { - var all_available, skip_groups; - all_available = $(select).data('all-available'); - skip_groups = $(select).data('skip-groups') || []; - return $(select).select2({ - placeholder: "Search for a group", - multiple: $(select).hasClass('multiselect'), - minimumInputLength: 0, - query: function(query) { - var options = { all_available: all_available, skip_groups: skip_groups }; - return Api.groups(query.term, options, function(groups) { - var data; - data = { - results: groups +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, + }, }; - return query.callback(data); - }); - }, - initSelection: function(element, callback) { - var id; - id = $(element).val(); - if (id !== "") { - return Api.group(id, callback); - } + }).then(params.success).fail(params.error); }, - formatResult: function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return _this.formatResult.apply(_this, args); + data: function (search, page) { + return { + search, + page, + per_page: GroupsSelect.PER_PAGE, + all_available, + skip_groups, + }; }, - formatSelection: function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return _this.formatSelection.apply(_this, args); + results: function (data, page) { + if (data.length) return { results: [] }; + + const results = data.length ? data : data.results || []; + const more = data.pagination ? data.pagination.more : false; + + return { + results, + page, + more, + }; }, - dropdownCssClass: "ajax-groups-dropdown", - // we do not want to escape markup since we are displaying html in results - escapeMarkup: function(m) { - return m; + }, + initSelection: function(element, callback) { + var id; + id = $(element).val(); + if (id !== "") { + return Api.group(id, callback); } - }); - }; - })(this)); + }, + 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.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.name + "</div> <div class='group-path'>" + group.path + "</div> </div>"; - }; + 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.prototype.formatSelection = function(group) { - return group.name; - }; + GroupsSelect.PER_PAGE = 20; - return GroupsSelect; - })(); -}).call(this); + return GroupsSelect; +})(); |