Skip to content
Snippets Groups Projects
Commit 7997bbbf authored by Clement Ho's avatar Clement Ho
Browse files

Backport MR from EE

parent 7911f1c0
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -468,8 +468,8 @@ GitLabDropdown = (function() {
 
// Process the data to make sure rendered data
// matches the correct layout
if (this.fullData && hasMultiSelect && this.options.processData) {
const inputValue = this.filterInput.val();
const inputValue = this.filterInput.val();
if (this.fullData && hasMultiSelect && this.options.processData && inputValue.length === 0) {
this.options.processData.call(this.options, inputValue, this.filteredFullData(), this.parseData.bind(this));
}
 
Loading
Loading
@@ -740,6 +740,12 @@ GitLabDropdown = (function() {
$input.attr('id', this.options.inputId);
}
 
if (this.options.multiSelect) {
Object.keys(selectedObject).forEach((attribute) => {
$input.attr(`data-${attribute}`, selectedObject[attribute]);
});
}
if (this.options.inputMeta) {
$input.attr('data-meta', selectedObject[this.options.inputMeta]);
}
Loading
Loading
Loading
Loading
@@ -35,6 +35,7 @@ function UsersSelect(currentUser, els) {
options.showCurrentUser = $dropdown.data('current-user');
options.todoFilter = $dropdown.data('todo-filter');
options.todoStateFilter = $dropdown.data('todo-state-filter');
options.perPage = $dropdown.data('per-page');
showNullUser = $dropdown.data('null-user');
defaultNullUser = $dropdown.data('null-user-default');
showMenuAbove = $dropdown.data('showMenuAbove');
Loading
Loading
@@ -214,7 +215,36 @@ function UsersSelect(currentUser, els) {
glDropdown.options.processData(term, users, callback);
}.bind(this));
},
processData: function(term, users, callback) {
processData: function(term, data, callback) {
let users = data;
// Only show assigned user list when there is no search term
if ($dropdown.hasClass('js-multiselect') && term.length === 0) {
const selectedInputs = getSelectedUserInputs();
// Potential duplicate entries when dealing with issue board
// because issue board is also managed by vue
const selectedUsers = _.uniq(selectedInputs, false, a => a.value)
.filter((input) => {
const userId = parseInt(input.value, 10);
const inUsersArray = users.find(u => u.id === userId);
return !inUsersArray && userId !== 0;
})
.map((input) => {
const userId = parseInt(input.value, 10);
const { avatarUrl, avatar_url, name, username } = input.dataset;
return {
avatar_url: avatarUrl || avatar_url,
id: userId,
name,
username,
};
});
users = data.concat(selectedUsers);
}
let anyUser;
let index;
let j;
Loading
Loading
@@ -645,7 +675,7 @@ UsersSelect.prototype.users = function(query, options, callback) {
url: url,
data: {
search: query,
per_page: 20,
per_page: options.perPage || 20,
active: true,
project_id: options.projectId || null,
group_id: options.groupId || null,
Loading
Loading
Loading
Loading
@@ -9,7 +9,7 @@ class AutocompleteController < ApplicationController
@users = @users.where.not(id: params[:skip_users]) if params[:skip_users].present?
@users = @users.active
@users = @users.reorder(:name)
@users = @users.page(params[:page])
@users = @users.page(params[:page]).per(params[:per_page])
 
if params[:todo_filter].present? && current_user
@users = @users.todo_authors(current_user.id, params[:todo_state_filter])
Loading
Loading
Loading
Loading
@@ -14,7 +14,10 @@
name: "issue[assignee_ids][]",
":value" => "assignee.id",
"v-if" => "issue.assignees",
"v-for" => "assignee in issue.assignees" }
"v-for" => "assignee in issue.assignees",
":data-avatar_url" => "assignee.avatar",
":data-name" => "assignee.name",
":data-username" => "assignee.username" }
.dropdown
%button.dropdown-menu-toggle.js-user-search.js-author-search.js-multiselect.js-save-user-data.js-issue-board-sidebar{ type: "button", ref: "assigneeDropdown", data: { toggle: "dropdown", field_name: "issue[assignee_ids][]", first_user: (current_user.username if current_user), current_user: "true", project_id: @project.id, null_user: "true", multi_select: "true", 'max-select' => 1, dropdown: { header: 'Assignee' } },
":data-issuable-id" => "issue.id",
Loading
Loading
Loading
Loading
@@ -32,7 +32,7 @@
 
.selectbox.hide-collapsed
- issuable.assignees.each do |assignee|
= hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", assignee.id, id: nil
= hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", assignee.id, id: nil, data: { avatar_url: assignee.avatar_url, name: assignee.name, username: assignee.username }
 
- options = { toggle_class: 'js-user-search js-author-search', title: 'Assign to', filter: true, dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author', placeholder: 'Search users', data: { first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), author_id: issuable.author_id, field_name: "#{issuable.to_ability_name}[assignee_ids][]", issue_update: issuable_json_path(issuable), ability_name: issuable.to_ability_name, null_user: true } }
 
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@
.col-sm-10{ class: ("col-lg-8" if has_due_date) }
.issuable-form-select-holder.selectbox
- issuable.assignees.each do |assignee|
= hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", assignee.id, id: nil, data: { meta: assignee.name }
= hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", assignee.id, id: nil, data: { meta: assignee.name, avatar_url: assignee.avatar_url, name: assignee.name, username: assignee.username }
 
- if issuable.assignees.length === 0
= hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", 0, id: nil, data: { meta: '' }
Loading
Loading
Loading
Loading
@@ -97,6 +97,20 @@ describe AutocompleteController do
it { expect(body.size).to eq User.count }
end
 
context 'limited users per page' do
let(:per_page) { 2 }
before do
sign_in(user)
get(:users, per_page: per_page)
end
let(:body) { JSON.parse(response.body) }
it { expect(body).to be_kind_of(Array) }
it { expect(body.size).to eq per_page }
end
context 'unauthenticated user' do
let(:public_project) { create(:project, :public) }
let(:body) { JSON.parse(response.body) }
Loading
Loading
Loading
Loading
@@ -3,6 +3,7 @@ require 'rails_helper'
describe 'New/edit issue', :feature, :js do
include GitlabRoutingHelper
include ActionView::Helpers::JavaScriptHelper
include FormHelper
 
let!(:project) { create(:project) }
let!(:user) { create(:user)}
Loading
Loading
@@ -23,6 +24,67 @@ describe 'New/edit issue', :feature, :js do
visit new_namespace_project_issue_path(project.namespace, project)
end
 
describe 'shorten users API pagination limit' do
before do
allow_any_instance_of(FormHelper).to receive(:issue_dropdown_options).and_wrap_original do |original, *args|
issuable = *args[0]
has_multiple_assignees = *args[1]
options = {
toggle_class: 'js-user-search js-assignee-search js-multiselect js-save-user-data',
title: 'Select assignee',
filter: true,
dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee',
placeholder: 'Search users',
data: {
per_page: 1,
null_user: true,
current_user: true,
project_id: project.try(:id),
field_name: "issue[assignee_ids][]",
default_label: 'Assignee',
'max-select': 1,
'dropdown-header': 'Assignee',
multi_select: true,
'input-meta': 'name',
'always-show-selectbox': true,
}
}
if has_multiple_assignees
options[:title] = 'Select assignee(s)'
options[:data][:'dropdown-header'] = 'Assignee(s)'
options[:data].delete(:'max-select')
end
options
end
visit new_namespace_project_issue_path(project.namespace, project)
click_button 'Unassigned'
wait_for_requests
end
it 'should display selected users even if they are not part of the original API call' do
find('.dropdown-input-field').native.send_keys user2.name
page.within '.dropdown-menu-user' do
expect(page).to have_content user2.name
click_link user2.name
end
find('.js-dropdown-input-clear').click
page.within '.dropdown-menu-user' do
expect(page).to have_content user.name
expect(find('.dropdown-menu-user a.is-active').first(:xpath, '..')['data-user-id']).to eq(user2.id.to_s)
end
end
end
describe 'single assignee' do
before do
click_button 'Unassigned'
Loading
Loading
Loading
Loading
@@ -57,6 +57,23 @@ feature 'Issue Sidebar', feature: true do
expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name)
end
end
it 'keeps your filtered term after filtering and dismissing the dropdown' do
find('.dropdown-input-field').native.send_keys user2.name
wait_for_requests
page.within '.dropdown-menu-user' do
expect(page).not_to have_content 'Unassigned'
click_link user2.name
end
find('.js-right-sidebar').click
find('.block.assignee .edit-link').click
expect(page.all('.dropdown-menu-user li').length).to eq(1)
expect(find('.dropdown-input-field').value).to eq(user2.name)
end
end
 
context 'as a allowed user' do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment