Finish user assignment for experiment table [SCI-7510]

This commit is contained in:
Anton 2022-11-30 14:56:19 +01:00
parent 7ea57d9ffe
commit 234c4dfaeb
6 changed files with 134 additions and 78 deletions

View file

@ -133,7 +133,13 @@ var ExperimnetTable = {
$(`
<div class="user-container">
<div class="sci-checkbox-container">
<input type="checkbox" class="sci-checkbox user-selector" value="${user.value}">
<input type="checkbox"
class="sci-checkbox user-selector"
${user.params.designated ? 'checked' : ''}
value="${user.value}"
data-assign-url="${user.params.assign_url}"
data-unassign-url="${user.params.unassign_url}"
>
<span class="sci-checkbox-label"></span>
</div>
<div class="user-avatar">
@ -147,6 +153,53 @@ var ExperimnetTable = {
});
});
});
$(this.table).on('click', '.dropdown-menu', (e) => {
if (e.target.tagName === 'INPUT') return;
e.preventDefault();
e.stopPropagation();
});
$(this.table).on('change keyup', '.assign-users-dropdown .user-search', (e) => {
let query = e.target.value;
let usersList = $(e.target).closest('.dropdown-menu').find('.user-container');
$.each(usersList, (_i, user) => {
$(user).removeClass('hidden');
if (query.length && !$(user).find('.user-name').text().toLowerCase()
.includes(query.toLowerCase())) {
$(user).addClass('hidden');
}
});
});
$(this.table).on('change', '.assign-users-dropdown .user-selector', (e) => {
let checkbox = e.target;
if (checkbox.checked) {
$.post(checkbox.dataset.assignUrl, {
table: true,
user_my_module: {
my_module_id: $(checkbox).closest('.table-row').data('id'),
user_id: checkbox.value
}
}, (result) => {
checkbox.dataset.unassignUrl = result.unassign_url;
$(checkbox).closest('.table-row').find('.assigned-users-container')
.replaceWith($(result.html).find('.assigned-users-container'));
}).error((data) => {
HelperModule.flashAlertMsg(data.responseJSON.errors, 'danger');
});
} else {
$.ajax({
url: checkbox.dataset.unassignUrl,
method: 'DELETE',
data: { table: true },
success: (result) => {
$(checkbox).closest('.table-row').find('.assigned-users-container')
.replaceWith($(result.html).find('.assigned-users-container'));
},
error: (data) => {
HelperModule.flashAlertMsg(data.responseJSON.errors, 'danger');
}
});
}
});
},
checkActionPermission: function(permission) {
let allMyModules;
@ -358,49 +411,7 @@ ExperimnetTable.render.status = function(data) {
};
ExperimnetTable.render.assigned = function(data) {
let users = '';
$.each(data.users, (i, user) => {
users += `
<span class="avatar-container" style="z-index: ${5 - i}">
<img src=${user.image_url} title=${user.title}>
</span>
`;
});
if (data.count > 4) {
users += `
<span class="more-users avatar-container" title="${data.more_users_title}">
+${data.count - 4}
</span>
`;
}
if (data.create_url) {
users += `
<span class="new-user avatar-container">
<i class="fas fa-plus"></i>
</span>
`;
}
return `
<div ref="dropdown"
class="assign-users-dropdown dropdown"
>
<div class="assigned-users-container" data-toggle="dropdown" >
${users}
</div>
<div class="dropdown-menu dropdown-menu-right">
<div class="sci-input-container left-icon">
<input type="text" class="sci-input-field" placeholder="${I18n.t('experiments.table.search')}"></input>
<i class="fas fa-search"></i>
</div>
<div class="users-list" data-list-url="${data.list_url}">
</div>
</div>
</div>
`;
return data.html;
};
ExperimnetTable.render.tags = function(data) {

View file

@ -137,7 +137,7 @@
}
.users-list {
max-height: 400px;
max-height: 300px;
overflow: auto;
}
@ -148,6 +148,10 @@
.user-avatar {
padding: 0 .75em;
img {
border-radius: 50%;
}
}
}

View file

@ -61,14 +61,22 @@ class UserMyModulesController < ApplicationController
respond_to do |format|
format.json do
render json: {
user: {
id: @um.user.id,
full_name: @um.user.full_name,
avatar_url: avatar_path(@um.user, :icon_small),
user_module_id: @um.id
}, status: :ok
}
if params[:table]
render json: {
html: render_to_string(partial: 'experiments/assigned_users.html.erb',
locals: { my_module: @my_module, user: current_user }),
unassign_url: my_module_user_my_module_path(@my_module, @um)
}
else
render json: {
user: {
id: @um.user.id,
full_name: @um.user.full_name,
avatar_url: avatar_path(@um.user, :icon_small),
user_module_id: @um.id
}, status: :ok
}
end
end
end
else
@ -88,7 +96,14 @@ class UserMyModulesController < ApplicationController
respond_to do |format|
format.json do
render json: {}, status: :ok
if params[:table]
render json: {
html: render_to_string(partial: 'experiments/assigned_users.html.erb',
locals: { my_module: @my_module, user: current_user })
}
else
render json: {}, status: :ok
end
end
end
else
@ -107,20 +122,33 @@ class UserMyModulesController < ApplicationController
.joins("LEFT OUTER JOIN user_my_modules ON user_my_modules.user_id = users.id "\
"AND user_my_modules.my_module_id = #{@my_module.id}")
.search(false, params[:query])
.order(:full_name)
.limit(Constants::SEARCH_LIMIT)
.select('users.*')
.select('users.*', 'user_my_modules.id as user_my_module_id')
.select('CASE WHEN user_my_modules.id IS NOT NULL '\
'THEN true ELSE false END as designated')
users = users.map do |user|
{
next if params[:skip_assigned] && user.designated
user_hash = {
value: user.id,
label: sanitize_input(user.full_name),
params: { avatar_url: avatar_path(user, :icon_small), designated: user.designated }
params: {
avatar_url: avatar_path(user, :icon_small),
designated: user.designated,
assign_url: my_module_user_my_modules_path(@my_module)
}
}
if user.designated
user_hash[:params][:unassign_url] = my_module_user_my_module_path(@my_module, user.user_my_module_id)
end
user_hash
end
render json: users
render json: users.compact
end
private

View file

@ -132,25 +132,10 @@ module Experiments
end
def assigned_presenter(my_module)
users = my_module.designated_users
result = {
count: users.length,
users: []
}
users[0..3].each do |user|
result[:users].push({
image_url: avatar_path(user, :icon_small),
title: user.full_name
})
end
result[:more_users_title] = users[4..].map(&:full_name).join('&#013;') if users.length > 4
result[:list_url] = search_my_module_user_my_module_path(my_module, my_module_id: my_module.id)
if can_manage_my_module_users?(@user, my_module)
result[:create_url] = my_module_user_my_modules_path(my_module_id: my_module.id)
end
result
{ html: ApplicationController.renderer.render(
partial: 'experiments/assigned_users.html.erb',
locals: { my_module: my_module, user: @user }
) }
end
def tags_presenter(my_module)

View file

@ -0,0 +1,28 @@
<% users = my_module.designated_users.order(:full_name) %>
<div ref="dropdown" class="assign-users-dropdown dropdown">
<div class="assigned-users-container" data-toggle="dropdown">
<% users[0..3].each_with_index do |user, i| %>
<span class="avatar-container" style="z-index: <%= 5 - i %>">
<%= image_tag avatar_path(user, :icon_small), title: user.full_name %>
</span>
<% end %>
<% if users.length > 4 %>
<span class="more-users avatar-container" title="<%= sanitize_input(users[4..].map(&:full_name).join('&#013;')) %>">
+<%= users.length - 4 %>
</span>
<% end %>
<% if can_manage_my_module_users?(user, my_module) %>
<span class="new-user avatar-container">
<i class="fas fa-plus"></i>
</span>
<% end %>
</div>
<div class="dropdown-menu">
<div class="sci-input-container left-icon">
<input type="text" class="sci-input-field user-search" placeholder="<%= I18n.t('experiments.table.search') %>">
<i class="fas fa-search"></i>
</div>
<div class="users-list" data-list-url="<%= search_my_module_user_my_module_path(my_module, my_module_id: my_module.id) %>">
</div>
</div>
</div>

View file

@ -14,7 +14,7 @@
'data-project-id': my_module.experiment.project_id,
'data-placeholder': t('my_modules.details.no_assigned_users'),
'data-users-create-url': my_module_user_my_modules_path(my_module_id: my_module.id),
'data-ajax-url': search_my_module_user_my_module_path(my_module),
'data-ajax-url': search_my_module_user_my_module_path(my_module, skip_assigned: true),
'data-update-module-users-url': my_module_user_my_modules_url(my_module),
'data-view-mode': !can_manage_my_module_designated_users?(my_module)
} %>