Add view only project users modal for project card [SCI-5337]

This commit is contained in:
Oleksii Kriuchykhin 2021-01-11 16:13:40 +01:00
parent b4a6644f13
commit 8a0a0cbacc
12 changed files with 106 additions and 73 deletions

View file

@ -237,6 +237,16 @@
});
}
// Initialize view project users modal remote loading.
function initViewProjectUsersLink() {
$('#cardsWrapper').on('ajax:success', '.view-project-users-link', function(e, data) {
let viewProjectUsersModal = $('#viewProjectUsersModal');
viewProjectUsersModal.find('.modal-title').html(data.html_title);
viewProjectUsersModal.find('.modal-body').html(data.html_body);
viewProjectUsersModal.modal('show');
});
}
// Initialize reloading manage user modal content after posting new
// user.
function initAddUserForm() {
@ -627,6 +637,7 @@
initExportProjectsModal();
initExportProjects();
initArchiveRestoreToolbarButtons();
initViewProjectUsersLink();
initManageProjectUsersLink();
initAddUserForm();
initRemoveUserLinks();

View file

@ -460,6 +460,12 @@ li.module-hover {
}
.projects-index {
.project-users-list {
hr {
margin: .5em 0;
}
}
.filter-container {
.projects-filters {
.select-block {
@ -525,6 +531,15 @@ li.module-hover {
}
.card {
.project-users-link {
color: $color-silver-chalice;
display: inline;
&:hover {
text-decoration: none;
}
}
&.folder-card {
text-align: center;
@ -664,15 +679,8 @@ li.module-hover {
}
.new-user {
align-items: center;
background: $color-concrete;
border-radius: 50%;
color: $color-silver-chalice;
cursor: pointer;
display: flex;
height: 2em;
justify-content: center;
width: 2em;
text-align: center;
}
}
}

View file

@ -10,16 +10,13 @@ class UserProjectsController < ApplicationController
before_action :check_manage_permissions, only: %i(update destroy)
def index
@users = @project.user_projects
@user_projects = @project.user_projects
respond_to do |format|
format.json do
render json: {
html: render_to_string(
partial: 'index.html.erb'
),
project_id: @project.id,
counter: @project.users.count # Used for counter badge
html_title: t('projects.index.modal_view_users.modal_title', name: @project.name),
html_body: render_to_string(partial: 'index.html.erb')
}
end
end
@ -33,7 +30,6 @@ class UserProjectsController < ApplicationController
respond_to do |format|
format.json do
render json: {
project: @project,
html_title: t('projects.index.modal_manage_users.modal_title', name: @project.name),
html_body: render_to_string(partial: 'index_edit.html.erb'),
html_footer: render_to_string(partial: 'index_edit_footer.html.erb')
@ -51,7 +47,7 @@ class UserProjectsController < ApplicationController
respond_to do |format|
format.json do
redirect_to project_users_edit_path(format: :json), turbolinks: false
redirect_to edit_project_users_path(format: :json), turbolinks: false
end
end
else
@ -77,7 +73,7 @@ class UserProjectsController < ApplicationController
respond_to do |format|
format.json do
redirect_to project_users_edit_path(format: :json), turbolinks: false
redirect_to edit_project_users_path(format: :json), turbolinks: false
end
end
else
@ -97,7 +93,7 @@ class UserProjectsController < ApplicationController
log_activity(:unassign_user_from_project)
respond_to do |format|
format.json do
redirect_to project_users_edit_path(format: :json),
redirect_to edit_project_users_path(format: :json),
turbolinks: false,
status: :see_other
end

View file

@ -17,6 +17,7 @@
<%= render partial: 'projects/index/modals/edit_modal' %>
<%= render partial: 'projects/index/modals/move_to_modal' %>
<%= render partial: 'projects/index/modals/view_users' %>
<%= render partial: 'projects/index/modals/manage_users' %>
<%= render partial: 'projects/index/modals/export_projects' %>

View file

@ -50,29 +50,17 @@
<div class="data-row user-cell table-cell">
<span class="card-label"><%= t('projects.index.card.users') %></span>
<div class="value">
<% project.user_projects[0..3].each do |user_project| %>
<span class="global-avatar-container">
<%= image_tag(avatar_path(user_project.user, :icon_small), title: user_name_with_role(user_project)) %>
</span>
<% end %>
<% more_users = project.user_projects[4..-1].to_a %>
<% if more_users.any? %>
<a href="" class="more-users" title="<%= user_names_with_roles(more_users) %>">
+<%= more_users.size %>
</a>
<% end %>
<% if can_manage_project?(project) %>
<%= link_to project_users_edit_path(project),
class: 'manage-users-link manage-project-users-link',
remote: true,
data: { 'view-mode': 'active' } do %>
<span class="new-user">
<%= link_to edit_project_users_path(project), class: 'project-users-link manage-project-users-link', remote: true do %>
<%= render partial: 'projects/index/users_list.html.erb', locals: { project: project } %>
<span class="new-user global-avatar-container">
<i class="fas fa-plus"></i>
</span>
<% end %>
<% else %>
<%= link_to project_users_path(project), class: 'project-users-link view-project-users-link', remote: true do %>
<%= render partial: 'projects/index/users_list.html.erb', locals: { project: project } %>
<% end %>
<% end %>
</div>
</div>

View file

@ -0,0 +1,12 @@
<% project.user_projects[0..3].each do |user_project| %>
<span class="global-avatar-container">
<%= image_tag(avatar_path(user_project.user, :icon_small), title: user_name_with_role(user_project)) %>
</span>
<% end %>
<% more_users = project.user_projects[4..-1].to_a %>
<% if more_users.any? %>
<a href="" class="more-users" title="<%= user_names_with_roles(more_users) %>">
+<%= more_users.size %>
</a>
<% end %>

View file

@ -0,0 +1,16 @@
<div class="modal" id="viewProjectUsersModal" tabindex="-1" role="dialog" aria-labelledby="viewProjectUsersModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="<%= t('general.close') %>"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="viewProjectUsersModalLabel"></h4>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">
<%= t('general.close') %>
</button>
</div>
</div>
</div>
</div>

View file

@ -1,30 +1,28 @@
<h5 class="text-center"><%= t("projects.index.users_tab") %></h5>
<hr>
<ul class="no-style content-users" data-hook="project-users-tab-list">
<% if @users.size == 0 then %>
<li><em><%= t 'projects.index.no_users' %></em></li>
<ul class="no-style project-users-list">
<% if @user_projects.blank? %>
<li>
<em><%= t('projects.index.modal_view_users.no_users') %></em>
</li>
<% else %>
<% @users.each_with_index do |user_proj, i| user = user_proj.user %>
<% @user_projects.each do |user_project| %>
<li>
<% if i > 0 %><hr><% end %>
<div class="row">
<div class="col-xs-2">
<div class="col-xs-1">
<span class='global-avatar-container'>
<%= image_tag avatar_path(user, :icon_small), class: 'img-circle pull-left' %>
<%= image_tag avatar_path(user_project.user, :icon_small), class: 'img-circle pull-left' %>
</span>
</div>
<div class="col-xs-10" style="line-height: 15px">
<span><%= user.full_name %></span>
<br><span class="text-muted"><%= t('user_projects.enums.role.'<< user_proj.role.to_s) %></span>
<div class="col-xs-11">
<span><%= user_project.user.full_name %></span>
<% if user_project.user == current_user %>
<%= t('projects.index.modal_view_users.current_user_label') %>
<% end %>
<br>
<small class="text-muted"><%= t('user_projects.enums.role.'<< user_project.role) %></small>
</div>
</div>
<hr>
</li>
<% end %>
<% end %>
</ul>
<% if can_manage_project?(@project) %>
<p>
<hr>
<%= link_to t("projects.index.manage_users"), project_users_edit_path(@project, format: :json), class: "manage-users-link", remote: true %>
</p>
<% end %>

View file

@ -16,16 +16,17 @@
</span>
</div>
<div class="col-xs-10 col-sm-4" style="line-height: 15px">
<div class="col-xs-10 col-sm-4">
<span><%= user.full_name %></span>
<br><span class="text-muted"><%= t('user_projects.enums.role.'<< user_project.role) %></span>
<br>
<small class="text-muted"><%= t('user_projects.enums.role.'<< user_project.role) %></small>
</div>
<% unless user.id == current_user.id %>
<div class="visible-xs">&nbsp;</div>
<div class="col-xs-7 col-xs-offset-2 col-sm-4 col-sm-offset-0">
<%= form_for user_project,
url: project_user_project_path(@project, user_project.id),
url: project_user_path(@project, user_project.id),
format: :json,
method: 'put',
remote: true,
@ -43,7 +44,7 @@
<% end %>
</div>
<div class="col-xs-3 col-sm-2">
<%= link_to project_user_project_path(@project, user_project, format: :json), method: :delete, remote: true, class: 'btn btn-link remove-user-link' do %>
<%= link_to project_user_path(@project, user_project, format: :json), method: :delete, remote: true, class: 'btn btn-link remove-user-link' do %>
<span class="fas fa-times"></span>
<% end %>
</div>
@ -58,10 +59,9 @@
<li>
<hr>
<div class="row">
<%= bootstrap_form_for [@project, @new_user_project], remote: true, format: :json, html: { class: 'add-user-form' } do |f| %>
<%= hidden_field_tag :project_id, @project.id %>
<%= bootstrap_form_for [@project, @new_user_project], url: project_users_path(@project), remote: true, format: :json, html: { class: 'add-user-form' } do |f| %>
<div class="col-xs-12 col-sm-4">
<%= collection_select(:user_project, :user_id, @unassigned_users, :id, :full_name, {}, { class: 'selectpicker' }) %>
<%= collection_select(:user_project, :user_id, @unassigned_users, :id, :full_name, {}, { class: 'selectpicker' }) %>
</div>
<div class="visible-xs">&nbsp;</div>
<div class="col-xs-8 col-sm-4">
@ -75,10 +75,10 @@
</select>
</div>
<div class="col-xs-4 col-sm-2">
<%= f.button class: 'btn btn-primary' do %>
<span class="fas fa-plus"></span>
<span class="hidden-xs"><%= t("projects.index.modal_manage_users.create") %></span>
<% end %>
<%= f.button class: 'btn btn-primary' do %>
<span class="fas fa-plus"></span>
<span class="hidden-xs"><%= t('projects.index.modal_manage_users.create') %></span>
<% end %>
</div>
<% end %>
</div>

View file

@ -424,6 +424,10 @@ en:
invite_users_link: "Invite users"
invite_users_details: "to team %{team}."
contact_admins: "To invite additional users to team %{team}, contact its administrator/s."
modal_view_users:
modal_title: "Members of %{name}"
no_users: "No users!"
current_user_label: "(you)"
filters_modal:
members:
label: "Members"

View file

@ -228,8 +228,11 @@ Rails.application.routes.draw do
end
resources :projects, except: [:destroy] do
resources :user_projects, path: '/users',
only: [:create, :index, :update, :destroy]
resources :user_projects, path: '/users', only: %i(create index update destroy), as: :users do
collection do
get 'edit', to: 'user_projects#index_edit'
end
end
resources :project_comments,
path: '/comments',
only: [:create, :index, :edit, :update, :destroy]
@ -294,10 +297,6 @@ Rails.application.routes.draw do
get 'sidebar'
end
# This route is defined outside of member block
# to preserve original :project_id parameter in URL.
get 'users/edit', to: 'user_projects#index_edit'
collection do
get 'cards', to: 'projects#cards'
get 'users_filter'

View file

@ -132,7 +132,7 @@ Feature: Home page
And I click element with css "html body.modal-open div#content-wrapper div#wrapper.container-fluid div#fluid-content.container-fluid div#new-project-modal.modal.in form#new_project.new_project div.modal-dialog div.modal-content div.modal-footer input.btn.btn-primary"
And I click element with css ".fa-users"
And I click element with css ".manage-users-link"
And I click element with css "#project-actions-modal > div:nth-child(1) > div:nth-child(1) > div:nth-child(3) > span:nth-child(1) > a:nth-child(1)"
And I click element with css "#manageProjectUsersModal > div:nth-child(1) > div:nth-child(1) > div:nth-child(3) > span:nth-child(1) > a:nth-child(1)"
And I click element with css ".dropdown-teams-user"
And I click element with css ".open > ul:nth-child(2) > li:nth-child(7) > a:nth-child(1)"
And I click "Remove" button