Merge pull request #6865 from G-Chubinidze/gc_SCI_9840

"Move" feature for multiple selected tasks and experiments (bulk action) [SCI-9840]
This commit is contained in:
Martin Artnik 2024-01-23 14:32:23 +01:00 committed by GitHub
commit bd4471b98b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 49 additions and 40 deletions

View file

@ -335,10 +335,9 @@
if (data.path) {
window.location.replace(data.path);
}
refreshCurrentView();
})
.on('ajax:error', '.experiment-action-form', function(ev, data) {
$(this).renderFormErrors('experiment', data.responseJSON);
HelperModule.flashAlertMsg(data.responseJSON.message, 'danger');
});
window.initActionToolbar();

View file

@ -10,17 +10,17 @@ class ExperimentsController < ApplicationController
before_action :load_project, only: %i(new create archive_group restore_group)
before_action :load_experiment, except: %i(new create archive_group restore_group
inventory_assigning_experiment_filter actions_toolbar)
inventory_assigning_experiment_filter actions_toolbar move_modal move)
before_action :load_experiments, only: %i(move_modal move)
before_action :check_read_permissions, except: %i(edit archive clone move new
create archive_group restore_group
inventory_assigning_experiment_filter actions_toolbar)
inventory_assigning_experiment_filter actions_toolbar move_modal)
before_action :check_canvas_read_permissions, only: %i(canvas)
before_action :check_create_permissions, only: %i(new create)
before_action :check_manage_permissions, only: %i(edit batch_clone_my_modules)
before_action :check_update_permissions, only: %i(update)
before_action :check_archive_permissions, only: :archive
before_action :check_clone_permissions, only: %i(clone_modal clone)
before_action :check_move_permissions, only: %i(move_modal move)
before_action :set_inline_name_editing, only: %i(canvas table module_archive)
before_action :set_breadcrumbs_items, only: %i(canvas table module_archive)
before_action :set_navigator, only: %i(canvas module_archive table)
@ -274,7 +274,7 @@ class ExperimentsController < ApplicationController
# GET: move_modal_experiment_path(id)
def move_modal
@projects = @experiment.movable_projects(current_user)
@projects = @experiments.first.movable_projects(current_user)
render json: {
html: render_to_string(partial: 'move_modal', formats: :html)
}
@ -297,23 +297,31 @@ class ExperimentsController < ApplicationController
# POST: move_experiment(id)
def move
service = Experiments::MoveToProjectService
.call(experiment_id: @experiment.id,
project_id: move_experiment_param,
user_id: current_user.id)
if service.succeed?
flash[:success] = t('experiments.move.success_flash',
experiment: @experiment.name)
status = :ok
view_state = @experiment.current_view_state(current_user)
view_type = view_state.state['my_modules']['view_type'] || 'canvas'
path = view_mode_redirect_url(view_type)
else
message = "#{service.errors.values.join('. ')}."
status = :unprocessable_entity
end
project = Project.viewable_by_user(current_user, current_team)
.find_by(id: params[:project_id])
render json: { message: message, path: path }, status: status
project.transaction do
@experiments.each do |experiment|
service = Experiments::MoveToProjectService
.call(experiment_id: experiment.id,
project_id: params[:project_id],
user_id: current_user.id)
raise StandardError unless service.succeed?
end
flash[:success] = t('experiments.table.move_success_flash', project: escape_input(project.name))
render json: { message: t('experiments.table.move_success_flash',
project: escape_input(project.name)), path: project_path(project) }
rescue StandardError => e
Rails.logger.error(e.message)
Rails.logger.error(e.backtrace.join("\n"))
render json: {
message: t('experiments.table.move_error_flash', project: escape_input(project.name))
}, status: :unprocessable_entity
raise ActiveRecord::Rollback
end
rescue ActiveRecord::RecordNotFound
render_404
end
def move_modules_modal
@ -531,6 +539,11 @@ class ExperimentsController < ApplicationController
render_404 unless @experiment
end
def load_experiments
@experiments = Experiment.preload(user_assignments: %i(user user_role)).where(id: params[:ids])
render_404 unless @experiments
end
def load_project
@project = Project.find_by(id: params[:project_id])
render_404 unless @project

View file

@ -87,18 +87,14 @@ module Toolbars
end
def move_action
return unless @single
experiment = @experiments.first
return unless can_move_experiment?(experiment)
return unless @experiments.all? { |experiment| can_move_experiment?(experiment) }
{
name: 'move',
label: I18n.t('experiments.toolbar.move_button'),
icon: 'sn-icon sn-icon-move',
button_class: 'move-experiments-btn',
path: move_modal_experiments_path(id: experiment.id),
path: move_modal_experiments_path(ids: @experiments.map(&:id)),
type: 'remote-modal'
}
end

View file

@ -88,11 +88,7 @@ module Toolbars
end
def move_action
return unless @single
my_module = @my_modules.first
return unless can_move_my_module?(my_module)
return unless @my_modules.all? { |my_module| can_move_my_module?(my_module) }
{
name: 'move',

View file

@ -1,10 +1,10 @@
<div class="modal move-experiment-modal"
id="move-experiment-modal-<%= @experiment.id %>"
id="move-experiment-modal-<%= @experiments.map(&:id) %>"
tabindex="-1"
role="dialog"
aria-labelledby="move-experiment-modal-label">
<%= form_with model: @experiment,
url: move_experiment_path(@experiment),
url: move_experiment_path(id: @experiments.map(&:id)),
method: :post,
data: { remote: true },
html: { class: 'experiment-action-form' } do |f| %>
@ -12,11 +12,11 @@
<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="move-experiment-modal-label"><%= t("experiments.move.modal_title", experiment: @experiment.name ) %></h5>
<h4 class="modal-title" id="move-experiment-modal-label"><%= t("experiments.move.modal_title") %></h5>
</div>
<div class="modal-body">
<p><small><%= t("experiments.move.notice") %></small></p>
<% if @projects.any? && can_manage_all_experiment_my_modules?(@experiment) %>
<% if @projects.any? && @experiments.all? { |experiment| can_manage_all_experiment_my_modules?(experiment) } %>
<%= f.select :project_id, options_for_select(@projects.collect { |p| [ p.name, p.id ] }),
{ label: t("experiments.move.target_project") }, { class: "form-control selectpicker", "data-role" => "clear" } %>
<% else %>
@ -24,15 +24,18 @@
<i class="fas fa-exclamation-triangle"></i>
<% if @projects.blank? %>
<%= t("experiments.move.no_projects") %>
<% elsif !can_manage_all_experiment_my_modules?(@experiment) %>
<% elsif !@experiments.all? { |experiment| can_manage_all_experiment_my_modules?(experiment) } %>
<%= t("experiments.move.task_permission") %>
<% end %>
</div>
<% end %>
</div>
<% @experiments.each do |experiment| %>
<%= f.hidden_field :ids, multiple: true, value: experiment.id %>
<% end %>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t "general.cancel" %></button>
<% if @projects.any? && can_manage_all_experiment_my_modules?(@experiment) %>
<% if @projects.any? && @experiments.all? { |experiment| can_manage_all_experiment_my_modules?(experiment) } %>
<%= f.submit t("experiments.move.modal_submit"), class: "btn btn-primary" %>
<% end %>
</div>

View file

@ -1519,7 +1519,7 @@ en:
success: 'Successfully duplicated %{count} task(s) as template.'
duplicating: 'Duplicating contents...'
move:
modal_title: 'Move experiment %{experiment}'
modal_title: 'Move experiment(s)'
notice: 'Moving is possible to projects, where you have permissions to create experiments and tasks.'
target_project: 'Target project'
label_title: 'Move'
@ -1530,6 +1530,8 @@ en:
no_projects: 'No projects: You dont have edit access to any other projects.'
table:
head_title: "%{experiment} | Overview"
move_success_flash: "Successfully moved experiment(s) to project %{project}."
move_error_flash: "Failed to move experiment(s) to project %{project}."
column:
id_html: 'ID'
task_name_html: 'Task name'