mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-06 03:46:39 +08:00
Enable leave for team owners for yourself [SCI-9957]
This commit is contained in:
parent
6e95ba13f9
commit
8e94cd5ce6
7 changed files with 68 additions and 131 deletions
|
@ -110,10 +110,9 @@
|
||||||
function(e, data) {
|
function(e, data) {
|
||||||
// Populate the modal heading & body
|
// Populate the modal heading & body
|
||||||
var modal = $('#destroy-user-team-modal');
|
var modal = $('#destroy-user-team-modal');
|
||||||
var modalHeading = modal.find('.modal-header').find('.modal-title');
|
const modalContent = modal.find('.modal-content');
|
||||||
var modalBody = modal.find('.modal-body');
|
|
||||||
modalHeading.text($('<div>').html(data.heading).text());
|
modalContent.html(data.html);
|
||||||
modalBody.html(data.html);
|
|
||||||
|
|
||||||
// Show the modal
|
// Show the modal
|
||||||
modal.modal('show');
|
modal.modal('show');
|
||||||
|
@ -122,13 +121,14 @@
|
||||||
'ajax:error',
|
'ajax:error',
|
||||||
"[data-action='destroy-user-team']",
|
"[data-action='destroy-user-team']",
|
||||||
function() {
|
function() {
|
||||||
// TODO
|
HelperModule.flashAlertMsg(I18n.t('users.settings.user_teams.general_error'), 'danger');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Also, bind the click action on the modal
|
// Also, bind the click action on the modal
|
||||||
$('#destroy-user-team-modal')
|
$('#destroy-user-team-modal')
|
||||||
.on('click', "[data-action='submit']", function() {
|
.on('click', "[data-action='submit']", function() {
|
||||||
|
animateSpinner();
|
||||||
var btn = $(this);
|
var btn = $(this);
|
||||||
var form = btn
|
var form = btn
|
||||||
.closest('.modal')
|
.closest('.modal')
|
||||||
|
@ -154,14 +154,16 @@
|
||||||
// Hide the modal
|
// Hide the modal
|
||||||
modal.modal('hide');
|
modal.modal('hide');
|
||||||
|
|
||||||
|
animateSpinner(null, false);
|
||||||
// Reload the whole table
|
// Reload the whole table
|
||||||
usersDatatable.ajax.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
).on(
|
).on(
|
||||||
'ajax:error',
|
'ajax:error',
|
||||||
"[data-id='destroy-user-team-form']",
|
"[data-id='destroy-user-team-form']",
|
||||||
function() {
|
function() {
|
||||||
// TODO
|
animateSpinner(null, false);
|
||||||
|
HelperModule.flashAlertMsg(I18n.t('users.settings.user_teams.general_error'), 'danger');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,11 +51,6 @@ module Users
|
||||||
'destroy_user_team_modal_body',
|
'destroy_user_team_modal_body',
|
||||||
locals: { user_assignment: @user_assignment },
|
locals: { user_assignment: @user_assignment },
|
||||||
formats: :html
|
formats: :html
|
||||||
),
|
|
||||||
heading: I18n.t(
|
|
||||||
'users.settings.user_teams.destroy_uo_heading',
|
|
||||||
user: escape_input(@user_assignment.user.full_name),
|
|
||||||
team: escape_input(@user_assignment.assignable.name)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -63,29 +58,12 @@ module Users
|
||||||
def destroy
|
def destroy
|
||||||
# If user is last administrator of team,
|
# If user is last administrator of team,
|
||||||
# he/she cannot be deleted from it.
|
# he/she cannot be deleted from it.
|
||||||
invalid =
|
invalid = @user_assignment.last_with_permission?(TeamPermissions::USERS_MANAGE)
|
||||||
managing_team_user_roles_collection.include?(@user_assignment.user_role) &&
|
|
||||||
@user_assignment
|
|
||||||
.assignable
|
|
||||||
.user_assignments
|
|
||||||
.where(user_role: managing_team_user_roles_collection)
|
|
||||||
.count <= 1
|
|
||||||
|
|
||||||
unless invalid
|
unless invalid
|
||||||
begin
|
begin
|
||||||
@user_assignment.transaction do
|
@user_assignment.transaction do
|
||||||
# If user leaves on his/her own accord,
|
|
||||||
# new owner for projects is the first
|
|
||||||
# administrator of team
|
|
||||||
if params[:leave]
|
if params[:leave]
|
||||||
new_owner =
|
|
||||||
@user_assignment
|
|
||||||
.assignable
|
|
||||||
.user_assignments
|
|
||||||
.where(user_role: managing_team_user_roles_collection)
|
|
||||||
.where.not(id: @user_assignment.id)
|
|
||||||
.first
|
|
||||||
.user
|
|
||||||
Activities::CreateActivityService
|
Activities::CreateActivityService
|
||||||
.call(activity_type: :user_leave_team,
|
.call(activity_type: :user_leave_team,
|
||||||
owner: current_user,
|
owner: current_user,
|
||||||
|
@ -95,10 +73,6 @@ module Users
|
||||||
team: @user_assignment.assignable.id
|
team: @user_assignment.assignable.id
|
||||||
})
|
})
|
||||||
else
|
else
|
||||||
# Otherwise, the new owner for projects is
|
|
||||||
# the current user (= an administrator removing
|
|
||||||
# the user from the team)
|
|
||||||
new_owner = current_user
|
|
||||||
Activities::CreateActivityService
|
Activities::CreateActivityService
|
||||||
.call(activity_type: :remove_user_from_team,
|
.call(activity_type: :remove_user_from_team,
|
||||||
owner: current_user,
|
owner: current_user,
|
||||||
|
@ -110,8 +84,7 @@ module Users
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
reset_user_current_team(@user_assignment)
|
reset_user_current_team(@user_assignment)
|
||||||
|
@user_assignment.destroy!
|
||||||
remove_user_from_team!(@user_assignment, new_owner)
|
|
||||||
end
|
end
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
Rails.logger.error e.message
|
Rails.logger.error e.message
|
||||||
|
@ -119,21 +92,27 @@ module Users
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !invalid
|
if invalid
|
||||||
if params[:leave]
|
render json: @user_assignment.errors, status: :unprocessable_entity
|
||||||
flash[:notice] = I18n.t(
|
else
|
||||||
|
flash[:success] = if params[:leave]
|
||||||
|
I18n.t(
|
||||||
'users.settings.user_teams.leave_flash',
|
'users.settings.user_teams.leave_flash',
|
||||||
team: @user_assignment.assignable.name
|
team: @user_assignment.assignable.name
|
||||||
)
|
)
|
||||||
flash.keep(:notice)
|
else
|
||||||
|
I18n.t(
|
||||||
|
'users.settings.user_teams.remove_flash',
|
||||||
|
user: @user_assignment.user.full_name,
|
||||||
|
team: @user_assignment.assignable.name
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
generate_notification(current_user,
|
generate_notification(current_user,
|
||||||
@user_assignment.user,
|
@user_assignment.user,
|
||||||
@user_assignment.assignable,
|
@user_assignment.assignable,
|
||||||
false)
|
false)
|
||||||
render json: { status: :ok }
|
render json: { status: :ok }
|
||||||
else
|
|
||||||
render json: @user_assignment.errors, status: :unprocessable_entity
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -165,33 +144,6 @@ module Users
|
||||||
user_assignment.user.current_team_id = ids.first
|
user_assignment.user.current_team_id = ids.first
|
||||||
user_assignment.user.save
|
user_assignment.user.save
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_user_from_team!(user_assignment, new_owner)
|
|
||||||
return user_assignment.destroy! unless new_owner
|
|
||||||
|
|
||||||
# Also, make new owner author of all protocols that belong
|
|
||||||
# to the departing user and belong to this team.
|
|
||||||
p_ids = user_assignment.user.added_protocols.where(team: user_assignment.assignable).pluck(:id)
|
|
||||||
Protocol.where(id: p_ids).find_each do |protocol|
|
|
||||||
protocol.record_timestamps = false
|
|
||||||
protocol.added_by = new_owner
|
|
||||||
protocol.archived_by = new_owner if protocol.archived_by == user_assignment.user
|
|
||||||
protocol.restored_by = new_owner if protocol.restored_by == user_assignment.user
|
|
||||||
protocol.save!(validate: false)
|
|
||||||
protocol.user_assignments.find_by(user: new_owner)&.destroy!
|
|
||||||
protocol.user_assignments.create!(
|
|
||||||
user: new_owner,
|
|
||||||
user_role: UserRole.find_predefined_owner_role,
|
|
||||||
assigned: :manually
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Make new owner author of all inventory items that were added
|
|
||||||
# by departing user and belong to this team.
|
|
||||||
RepositoryRow.change_owner(user_assignment.assignable, user_assignment.user, new_owner)
|
|
||||||
|
|
||||||
user_assignment.destroy!
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<% if user_assignment.user == user %>
|
<% if user_assignment.user == user %>
|
||||||
<button class="btn btn-light btn-xs icon-btn" type="button" disabled="disabled">
|
<button class="btn btn-light btn-xs icon-btn" id="leave-team-btn" type="button" disabled="disabled">
|
||||||
<span class="sn-icon sn-icon-down"></span>
|
<span class="sn-icon sn-icon-down"></span>
|
||||||
</button>
|
</button>
|
||||||
<% else %>
|
<% else %>
|
||||||
|
|
|
@ -5,18 +5,6 @@
|
||||||
aria-labelledby="destroy-user-team-modal-label">
|
aria-labelledby="destroy-user-team-modal-label">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="sn-icon sn-icon-close"></i></button>
|
|
||||||
<h4 class="modal-title" id="destroy-user-team-modal-label">
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body"></div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t 'general.cancel' %></button>
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-danger"
|
|
||||||
data-action="submit"><%=t 'users.settings.user_teams.destroy_uo_confirm' %></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,21 +1,28 @@
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="sn-icon sn-icon-close"></i></button>
|
||||||
|
<h4 class="modal-title" id="destroy-user-team-modal-label">
|
||||||
|
<%= t('users.settings.user_teams.destroy_uo_heading',
|
||||||
|
user: user_assignment.user.full_name,
|
||||||
|
team: user_assignment.assignable.name,
|
||||||
|
role: user_assignment.user_role.name.downcase) %>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
<%= form_with model: user_assignment,
|
<%= form_with model: user_assignment,
|
||||||
url: destroy_user_team_path(user_assignment, format: :json),
|
url: destroy_user_team_path(user_assignment, format: :json),
|
||||||
data: { remote: true, id: 'destroy-user-team-form' },
|
data: { remote: true, id: 'destroy-user-team-form' },
|
||||||
method: :delete do |f| %>
|
method: :delete do |f| %>
|
||||||
<p><%= t("users.settings.user_teams.destroy_uo_message",
|
<div class='flex flex-col gap-6'>
|
||||||
user: user_assignment.user.full_name,
|
<div><%= t("users.settings.user_teams.destroy_message", role: user_assignment.user_role.name.downcase) %></div>
|
||||||
team: user_assignment.assignable.name) %></p>
|
<div><%= t("users.settings.user_teams.message_owner") %></div>
|
||||||
<% if user_assignment.user.confirmed? %>
|
<div><%= t("users.settings.user_teams.message_alert") %></div>
|
||||||
<div class="alert alert-danger" role="alert">
|
|
||||||
<span class="fas fa-exclamation-triangle"></span>
|
|
||||||
|
|
||||||
<%= t("users.settings.user_teams.destroy_uo_alert_heading") %>
|
|
||||||
<ul>
|
|
||||||
<li><%= t("users.settings.user_teams.destroy_uo_alert_line_1") %></li>
|
|
||||||
<li><%= t("users.settings.user_teams.destroy_uo_alert_line_2").html_safe %></li>
|
|
||||||
<li><%= t("users.settings.user_teams.destroy_uo_alert_line_3") %></li>
|
|
||||||
<li><%= t("users.settings.user_teams.destroy_uo_alert_line_4") %></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t 'general.cancel' %></button>
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-danger"
|
||||||
|
data-action="submit"><%=t 'users.settings.user_teams.destroy_uo_confirm' %>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
|
@ -4,16 +4,9 @@
|
||||||
method: :delete,
|
method: :delete,
|
||||||
data: { id: 'leave-user-team-form' } do |f| %>
|
data: { id: 'leave-user-team-form' } do |f| %>
|
||||||
<%= hidden_field_tag :leave, true %>
|
<%= hidden_field_tag :leave, true %>
|
||||||
<p><%= t("users.settings.user_teams.leave_uo_message", team: @user_assignment.team.name) %></p>
|
<div class='flex flex-col gap-6'>
|
||||||
<div class="alert alert-danger" role="alert">
|
<div><%= t("users.settings.user_teams.leave_message") %></div>
|
||||||
<span class="fas fa-exclamation-triangle"></span>
|
<div><%= t("users.settings.user_teams.message_owner") %></div>
|
||||||
|
<div><%= t("users.settings.user_teams.message_alert") %></div>
|
||||||
<%= t("users.settings.user_teams.leave_uo_alert_heading") %>
|
|
||||||
<ul>
|
|
||||||
<li><%= t("users.settings.user_teams.leave_uo_alert_line_1") %></li>
|
|
||||||
<li><%= t("users.settings.user_teams.leave_uo_alert_line_2").html_safe %></li>
|
|
||||||
<li><%= t("users.settings.user_teams.leave_uo_alert_line_3")%></li>
|
|
||||||
<li><%= t("users.settings.user_teams.leave_uo_alert_line_4")%></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -2988,22 +2988,17 @@ en:
|
||||||
flash_success: "Team %{team} was successfully deleted."
|
flash_success: "Team %{team} was successfully deleted."
|
||||||
user_teams:
|
user_teams:
|
||||||
leave_uo_heading: "Leave team %{team}"
|
leave_uo_heading: "Leave team %{team}"
|
||||||
leave_uo_message: "Are you sure you wish to leave team %{team}? This action is irreversible."
|
leave_message: "You will lose access to all content associated with the team, including projects, inventories, and protocol templates."
|
||||||
leave_uo_alert_heading: "Leaving team has following consequences:"
|
destroy_message: 'Removing a team %{role} will revoke their access to all content associated with the team, including projects, inventories, and protocol templates.'
|
||||||
leave_uo_alert_line_1: "you will lose access to all content belonging to the team (including projects, tasks, protocols and activities);"
|
leave_uo_confirm: "Leave team"
|
||||||
leave_uo_alert_line_2: "all projects in the team where you were the sole <b>Owner</b> will receive a new owner from the team administrators;"
|
destroy_uo_heading: "Remove team %{role} %{user} from team %{team}"
|
||||||
leave_uo_alert_line_3: "all repository protocols in the team belonging to you will be reassigned onto a new owner from team administrators;"
|
message_owner: "Other team owner(s) will be able to view and manage access to the content."
|
||||||
leave_uo_alert_line_4: "all inventory items in the team added by you will be reassigned onto a new owner from team administrators."
|
message_alert: "This action cannot be undone."
|
||||||
leave_uo_confirm: "Leave"
|
destroy_uo_alert_line_3: "This action cannot be undone."
|
||||||
destroy_uo_heading: "Remove user %{user} from team %{team}"
|
|
||||||
destroy_uo_message: "Are you sure you wish to remove user %{user} from team %{team}?"
|
|
||||||
destroy_uo_alert_heading: "Removing user from team has following consequences:"
|
|
||||||
destroy_uo_alert_line_1: "user will lose access to all content belonging to the team (including projects, tasks, protocols and activities);"
|
|
||||||
destroy_uo_alert_line_2: "all projects in the team where user was the sole <b>Owner</b> will be reassigned onto you as a new owner;"
|
|
||||||
destroy_uo_alert_line_3: "all repository protocols in the team belonging to user will be reassigned onto you;"
|
|
||||||
destroy_uo_alert_line_4: "all inventory items in the team added by user will be reassigned onto you."
|
|
||||||
destroy_uo_confirm: "Remove"
|
destroy_uo_confirm: "Remove"
|
||||||
leave_flash: "Successfully left team %{team}."
|
leave_flash: "You have left %{team}."
|
||||||
|
remove_flash: "%{user} has been successfully removed from the team %{team}"
|
||||||
|
general_error: "Something went wrong"
|
||||||
|
|
||||||
user_roles:
|
user_roles:
|
||||||
predefined:
|
predefined:
|
||||||
|
|
Loading…
Add table
Reference in a new issue