2019-01-15 20:45:05 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-07-27 22:18:26 +08:00
|
|
|
class ExperimentsController < ApplicationController
|
2017-01-25 00:06:51 +08:00
|
|
|
include TeamsHelper
|
2017-01-04 22:04:12 +08:00
|
|
|
include InputSanitizeHelper
|
2017-04-06 20:55:18 +08:00
|
|
|
include ActionView::Helpers::TextHelper
|
|
|
|
include ApplicationHelper
|
|
|
|
include Rails.application.routes.url_helpers
|
2016-10-12 15:30:55 +08:00
|
|
|
|
2021-02-03 21:23:38 +08:00
|
|
|
before_action :load_project, only: %i(new create archive_group restore_group)
|
|
|
|
before_action :load_experiment, except: %i(new create archive_group restore_group)
|
2021-09-30 17:32:11 +08:00
|
|
|
before_action :check_read_permissions, except: %i(edit archive clone move new create archive_group restore_group)
|
|
|
|
before_action :check_canvas_read_permissions, only: %i(canvas)
|
2020-11-20 21:53:50 +08:00
|
|
|
before_action :check_create_permissions, only: %i(new create)
|
2020-12-29 00:44:47 +08:00
|
|
|
before_action :check_manage_permissions, only: %i(edit)
|
2021-09-30 17:32:11 +08:00
|
|
|
before_action :check_update_permissions, only: %i(update)
|
2018-02-19 21:47:36 +08:00
|
|
|
before_action :check_archive_permissions, only: :archive
|
2018-02-07 18:49:15 +08:00
|
|
|
before_action :check_clone_permissions, only: %i(clone_modal clone)
|
|
|
|
before_action :check_move_permissions, only: %i(move_modal move)
|
2019-05-20 19:13:31 +08:00
|
|
|
before_action :set_inline_name_editing, only: %i(canvas module_archive)
|
2016-07-27 22:18:26 +08:00
|
|
|
|
2020-11-20 21:53:50 +08:00
|
|
|
layout 'fluid'
|
2016-07-28 17:30:34 +08:00
|
|
|
|
2016-07-27 22:18:26 +08:00
|
|
|
def new
|
|
|
|
@experiment = Experiment.new
|
2016-07-28 20:44:44 +08:00
|
|
|
respond_to do |format|
|
2016-07-29 16:41:08 +08:00
|
|
|
format.json do
|
|
|
|
render json: {
|
|
|
|
html: render_to_string(
|
|
|
|
partial: 'new_modal.html.erb'
|
|
|
|
)
|
2016-07-28 20:44:44 +08:00
|
|
|
}
|
2016-07-29 16:41:08 +08:00
|
|
|
end
|
2016-07-28 20:44:44 +08:00
|
|
|
end
|
2016-07-27 22:18:26 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def create
|
|
|
|
@experiment = Experiment.new(experiment_params)
|
|
|
|
@experiment.created_by = current_user
|
2016-07-28 20:44:44 +08:00
|
|
|
@experiment.last_modified_by = current_user
|
|
|
|
@experiment.project = @project
|
2016-07-27 22:18:26 +08:00
|
|
|
if @experiment.save
|
2017-04-06 20:55:18 +08:00
|
|
|
experiment_annotation_notification
|
2021-02-03 21:23:38 +08:00
|
|
|
log_activity(:create_experiment, @experiment)
|
2016-08-03 15:34:10 +08:00
|
|
|
flash[:success] = t('experiments.create.success_flash',
|
|
|
|
experiment: @experiment.name)
|
2016-09-02 17:46:48 +08:00
|
|
|
respond_to do |format|
|
|
|
|
format.json do
|
2017-04-20 23:55:28 +08:00
|
|
|
render json: { path: canvas_experiment_url(@experiment) }, status: :ok
|
2016-09-02 17:46:48 +08:00
|
|
|
end
|
|
|
|
end
|
2016-07-27 22:18:26 +08:00
|
|
|
else
|
2016-09-02 17:46:48 +08:00
|
|
|
respond_to do |format|
|
|
|
|
format.json do
|
|
|
|
render json: @experiment.errors, status: :unprocessable_entity
|
|
|
|
end
|
|
|
|
end
|
2016-07-27 22:18:26 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-01-28 04:53:39 +08:00
|
|
|
def show
|
|
|
|
render json: {
|
|
|
|
html: render_to_string(partial: 'experiments/details_modal.html.erb')
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2016-07-28 15:01:44 +08:00
|
|
|
def canvas
|
2021-01-08 00:18:52 +08:00
|
|
|
redirect_to module_archive_experiment_path(@experiment) if @experiment.archived_branch?
|
2016-07-28 15:01:44 +08:00
|
|
|
@project = @experiment.project
|
2022-05-09 17:40:31 +08:00
|
|
|
@active_modules = @experiment.my_modules.active.order(:name)
|
|
|
|
.left_outer_joins(:designated_users, :task_comments)
|
|
|
|
.preload(:tags, outputs: :to)
|
|
|
|
.preload(:my_module_status, :my_module_group, user_assignments: %i(user user_role))
|
2022-05-11 04:23:42 +08:00
|
|
|
.select('COUNT(DISTINCT users.id) as designated_users_count')
|
|
|
|
.select('COUNT(DISTINCT comments.id) as task_comments_count')
|
2022-05-09 17:40:31 +08:00
|
|
|
.select('my_modules.*').group(:id)
|
2016-07-27 22:18:26 +08:00
|
|
|
end
|
|
|
|
|
2016-08-03 15:34:10 +08:00
|
|
|
def edit
|
|
|
|
respond_to do |format|
|
|
|
|
format.json do
|
|
|
|
render json: {
|
|
|
|
html: render_to_string(
|
|
|
|
partial: 'edit_modal.html.erb'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-07-27 22:18:26 +08:00
|
|
|
def update
|
2017-04-06 20:55:18 +08:00
|
|
|
old_text = @experiment.description
|
2020-05-26 21:34:20 +08:00
|
|
|
@experiment.assign_attributes(experiment_params)
|
2016-07-27 22:18:26 +08:00
|
|
|
@experiment.last_modified_by = current_user
|
2020-05-26 21:34:20 +08:00
|
|
|
name_changed = @experiment.name_changed?
|
|
|
|
description_changed = @experiment.description_changed?
|
2018-02-19 21:47:36 +08:00
|
|
|
|
2016-07-27 22:18:26 +08:00
|
|
|
if @experiment.save
|
2020-03-09 20:38:38 +08:00
|
|
|
experiment_annotation_notification(old_text) if old_text
|
2019-03-07 00:18:35 +08:00
|
|
|
|
2019-03-15 18:12:10 +08:00
|
|
|
activity_type = if experiment_params[:archived] == 'false'
|
|
|
|
:restore_experiment
|
2020-05-26 21:34:20 +08:00
|
|
|
elsif name_changed && !description_changed
|
|
|
|
:rename_experiment
|
2019-03-15 18:12:10 +08:00
|
|
|
else
|
|
|
|
:edit_experiment
|
|
|
|
end
|
2021-02-03 21:23:38 +08:00
|
|
|
log_activity(activity_type, @experiment)
|
2019-03-07 00:18:35 +08:00
|
|
|
|
2016-09-02 20:13:59 +08:00
|
|
|
respond_to do |format|
|
|
|
|
format.json do
|
|
|
|
render json: {}, status: :ok
|
|
|
|
end
|
2016-09-21 14:34:32 +08:00
|
|
|
format.html do
|
2021-01-28 04:53:39 +08:00
|
|
|
flash[:success] = t('experiments.update.success_flash', experiment: @experiment.name)
|
2016-09-21 14:34:32 +08:00
|
|
|
redirect_to project_path(@experiment.project)
|
|
|
|
end
|
2016-09-02 20:13:59 +08:00
|
|
|
end
|
2016-07-27 22:18:26 +08:00
|
|
|
else
|
2016-09-02 20:13:59 +08:00
|
|
|
respond_to do |format|
|
|
|
|
format.json do
|
|
|
|
render json: @experiment.errors, status: :unprocessable_entity
|
|
|
|
end
|
2016-09-21 14:34:32 +08:00
|
|
|
format.html do
|
2019-03-06 16:17:34 +08:00
|
|
|
flash[:alert] = t('experiments.update.error_flash')
|
2017-12-08 00:59:23 +08:00
|
|
|
redirect_back(fallback_location: root_path)
|
2016-09-21 14:34:32 +08:00
|
|
|
end
|
2016-09-02 20:13:59 +08:00
|
|
|
end
|
2016-07-27 22:18:26 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-08-03 15:34:10 +08:00
|
|
|
def archive
|
2021-01-28 04:53:39 +08:00
|
|
|
@experiment.archive(current_user)
|
2016-07-27 22:18:26 +08:00
|
|
|
if @experiment.save
|
2021-02-03 21:23:38 +08:00
|
|
|
log_activity(:archive_experiment, @experiment)
|
2016-08-03 15:34:10 +08:00
|
|
|
flash[:success] = t('experiments.archive.success_flash',
|
|
|
|
experiment: @experiment.name)
|
2016-08-05 21:23:01 +08:00
|
|
|
|
2016-08-03 15:34:10 +08:00
|
|
|
redirect_to project_path(@experiment.project)
|
2016-07-27 22:18:26 +08:00
|
|
|
else
|
2016-07-28 22:01:53 +08:00
|
|
|
flash[:alert] = t('experiments.archive.error_flash')
|
2017-12-08 00:59:23 +08:00
|
|
|
redirect_back(fallback_location: root_path)
|
2016-07-27 22:18:26 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-02-03 21:23:38 +08:00
|
|
|
def archive_group
|
|
|
|
experiments = @project.experiments.active.where(id: params[:experiments_ids])
|
|
|
|
counter = 0
|
|
|
|
experiments.each do |experiment|
|
|
|
|
next unless can_archive_experiment?(experiment)
|
|
|
|
|
|
|
|
experiment.transaction do
|
|
|
|
experiment.archived_on = DateTime.now
|
|
|
|
experiment.archive!(current_user)
|
|
|
|
log_activity(:archive_experiment, experiment)
|
|
|
|
counter += 1
|
|
|
|
rescue StandardError => e
|
|
|
|
Rails.logger.error e.message
|
|
|
|
raise ActiveRecord::Rollback
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if counter.positive?
|
|
|
|
render json: { message: t('experiments.archive_group.success_flash', number: counter) }
|
|
|
|
else
|
|
|
|
render json: { message: t('experiments.archive_group.error_flash') }, status: :unprocessable_entity
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def restore_group
|
|
|
|
experiments = @project.experiments.archived.where(id: params[:experiments_ids])
|
|
|
|
counter = 0
|
|
|
|
experiments.each do |experiment|
|
|
|
|
next unless can_restore_experiment?(experiment)
|
|
|
|
|
|
|
|
experiment.transaction do
|
|
|
|
experiment.restore!(current_user)
|
|
|
|
log_activity(:restore_experiment, experiment)
|
|
|
|
counter += 1
|
|
|
|
rescue StandardError => e
|
|
|
|
Rails.logger.error e.message
|
|
|
|
raise ActiveRecord::Rollback
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if counter.positive?
|
|
|
|
render json: { message: t('experiments.restore_group.success_flash', number: counter) }
|
|
|
|
else
|
|
|
|
render json: { message: t('experiments.restore_group.error_flash') }, status: :unprocessable_entity
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-08-11 15:46:15 +08:00
|
|
|
# GET: clone_modal_experiment_path(id)
|
|
|
|
def clone_modal
|
2021-10-27 19:55:49 +08:00
|
|
|
@projects = @experiment.project.team.projects
|
|
|
|
.with_user_permission(current_user, ProjectPermissions::EXPERIMENTS_CREATE)
|
2016-08-11 15:46:15 +08:00
|
|
|
respond_to do |format|
|
|
|
|
format.json do
|
|
|
|
render json: {
|
|
|
|
html: render_to_string(
|
|
|
|
partial: 'clone_modal.html.erb'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# POST: clone_experiment(id)
|
|
|
|
def clone
|
2021-10-28 00:17:38 +08:00
|
|
|
project = current_team.projects.find(move_experiment_param)
|
|
|
|
return render_403 unless can_create_project_experiments?(project)
|
|
|
|
|
|
|
|
service = Experiments::CopyExperimentAsTemplateService.call(experiment: @experiment,
|
|
|
|
project: project,
|
|
|
|
user: current_user)
|
2016-08-11 23:00:33 +08:00
|
|
|
|
2019-01-21 23:08:42 +08:00
|
|
|
if service.succeed?
|
2016-08-11 21:13:36 +08:00
|
|
|
flash[:success] = t('experiments.clone.success_flash',
|
|
|
|
experiment: @experiment.name)
|
2019-01-21 23:08:42 +08:00
|
|
|
redirect_to canvas_experiment_path(service.cloned_experiment)
|
2016-08-11 21:13:36 +08:00
|
|
|
else
|
|
|
|
flash[:error] = t('experiments.clone.error_flash',
|
2016-08-16 15:15:29 +08:00
|
|
|
experiment: @experiment.name)
|
2016-08-11 21:13:36 +08:00
|
|
|
redirect_to project_path(@experiment.project)
|
|
|
|
end
|
2016-08-11 15:46:15 +08:00
|
|
|
end
|
|
|
|
|
2016-08-12 17:26:18 +08:00
|
|
|
# GET: move_modal_experiment_path(id)
|
|
|
|
def move_modal
|
2021-09-30 17:32:11 +08:00
|
|
|
@projects = @experiment.movable_projects(current_user)
|
2016-08-12 17:26:18 +08:00
|
|
|
respond_to do |format|
|
|
|
|
format.json do
|
|
|
|
render json: {
|
|
|
|
html: render_to_string(
|
|
|
|
partial: 'move_modal.html.erb'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# POST: move_experiment(id)
|
|
|
|
def move
|
2019-01-15 20:45:05 +08:00
|
|
|
service = Experiments::MoveToProjectService
|
|
|
|
.call(experiment_id: @experiment.id,
|
|
|
|
project_id: move_experiment_param,
|
|
|
|
user_id: current_user.id)
|
|
|
|
if service.succeed?
|
2016-08-12 17:26:18 +08:00
|
|
|
flash[:success] = t('experiments.move.success_flash',
|
|
|
|
experiment: @experiment.name)
|
2019-01-15 20:45:05 +08:00
|
|
|
path = canvas_experiment_url(@experiment)
|
|
|
|
status = :ok
|
2016-08-12 17:26:18 +08:00
|
|
|
else
|
2021-12-01 18:24:01 +08:00
|
|
|
message = service.errors.values.join(', ')
|
2019-01-15 20:45:05 +08:00
|
|
|
status = :unprocessable_entity
|
2016-08-12 17:26:18 +08:00
|
|
|
end
|
2019-01-15 20:45:05 +08:00
|
|
|
|
|
|
|
render json: { message: message, path: path }, status: status
|
2016-08-12 17:26:18 +08:00
|
|
|
end
|
|
|
|
|
2016-08-08 21:04:02 +08:00
|
|
|
def module_archive
|
2020-12-13 05:46:30 +08:00
|
|
|
@my_modules = @experiment.archived_branch? ? @experiment.my_modules : @experiment.my_modules.archived
|
2021-11-19 20:24:57 +08:00
|
|
|
@my_modules = @my_modules.with_granted_permissions(current_user, MyModulePermissions::READ_ARCHIVED)
|
2022-05-10 21:39:59 +08:00
|
|
|
.left_outer_joins(:designated_users, :task_comments)
|
|
|
|
.preload(:tags, outputs: :to)
|
|
|
|
.preload(:my_module_status, :my_module_group, user_assignments: %i(user user_role))
|
2022-06-01 17:43:15 +08:00
|
|
|
.select('COUNT(DISTINCT users.id) as designated_users_count')
|
|
|
|
.select('COUNT(DISTINCT comments.id) as task_comments_count')
|
2022-05-10 21:39:59 +08:00
|
|
|
.select('my_modules.*').group(:id)
|
2016-08-08 21:04:02 +08:00
|
|
|
end
|
|
|
|
|
2020-10-16 20:21:25 +08:00
|
|
|
def fetch_workflow_img
|
|
|
|
unless @experiment.workflowimg_exists?
|
|
|
|
Experiment.no_touching do
|
|
|
|
Experiments::GenerateWorkflowImageService.call(experiment: @experiment)
|
2016-08-19 21:36:12 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
respond_to do |format|
|
|
|
|
format.json do
|
|
|
|
render json: {
|
2016-08-22 17:29:19 +08:00
|
|
|
workflowimg: render_to_string(
|
2022-08-31 21:26:10 +08:00
|
|
|
partial: 'projects/show/workflow_img',
|
2020-10-16 20:21:25 +08:00
|
|
|
locals: { experiment: @experiment }
|
2016-08-22 17:29:19 +08:00
|
|
|
)
|
2016-08-19 21:36:12 +08:00
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-11-20 21:53:50 +08:00
|
|
|
def sidebar
|
|
|
|
respond_to do |format|
|
|
|
|
format.json do
|
|
|
|
render json: {
|
|
|
|
html: render_to_string(
|
|
|
|
partial: 'shared/sidebar/my_modules.html.erb', locals: { experiment: @experiment }
|
|
|
|
)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-07-27 22:18:26 +08:00
|
|
|
private
|
|
|
|
|
2020-11-20 21:53:50 +08:00
|
|
|
def load_experiment
|
2022-05-09 17:40:31 +08:00
|
|
|
@experiment = Experiment.preload(user_assignments: %i(user user_role)).find_by(id: params[:id])
|
2016-07-28 16:15:58 +08:00
|
|
|
render_404 unless @experiment
|
2016-07-27 22:18:26 +08:00
|
|
|
end
|
|
|
|
|
2020-11-20 21:53:50 +08:00
|
|
|
def load_project
|
|
|
|
@project = Project.find_by(id: params[:project_id])
|
2016-07-28 16:15:58 +08:00
|
|
|
render_404 unless @project
|
2016-07-27 22:18:26 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def experiment_params
|
2016-08-08 22:35:45 +08:00
|
|
|
params.require(:experiment).permit(:name, :description, :archived)
|
2016-07-27 22:18:26 +08:00
|
|
|
end
|
2016-07-28 17:00:56 +08:00
|
|
|
|
2019-01-15 20:45:05 +08:00
|
|
|
def move_experiment_param
|
|
|
|
params.require(:experiment).require(:project_id)
|
|
|
|
end
|
|
|
|
|
2021-09-30 17:32:11 +08:00
|
|
|
def check_read_permissions
|
|
|
|
render_403 unless can_read_experiment?(@experiment) ||
|
|
|
|
@experiment.archived? && can_read_archived_experiment?(@experiment)
|
|
|
|
end
|
|
|
|
|
|
|
|
def check_canvas_read_permissions
|
2021-10-01 17:52:20 +08:00
|
|
|
render_403 unless can_read_experiment_canvas?(@experiment)
|
2016-08-08 21:04:02 +08:00
|
|
|
end
|
|
|
|
|
2020-11-20 21:53:50 +08:00
|
|
|
def check_create_permissions
|
2021-09-07 17:27:52 +08:00
|
|
|
render_403 unless can_create_project_experiments?(@project)
|
2020-11-20 21:53:50 +08:00
|
|
|
end
|
|
|
|
|
2018-02-19 21:47:36 +08:00
|
|
|
def check_manage_permissions
|
|
|
|
render_403 unless can_manage_experiment?(@experiment)
|
|
|
|
end
|
|
|
|
|
2021-09-30 17:32:11 +08:00
|
|
|
def check_update_permissions
|
|
|
|
if experiment_params[:archived] == 'false'
|
|
|
|
render_403 unless can_restore_experiment?(@experiment)
|
|
|
|
else
|
|
|
|
render_403 unless can_manage_experiment?(@experiment)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-02-19 21:47:36 +08:00
|
|
|
def check_archive_permissions
|
|
|
|
render_403 unless can_archive_experiment?(@experiment)
|
|
|
|
end
|
|
|
|
|
2018-02-07 18:49:15 +08:00
|
|
|
def check_clone_permissions
|
|
|
|
render_403 unless can_clone_experiment?(@experiment)
|
|
|
|
end
|
|
|
|
|
|
|
|
def check_move_permissions
|
|
|
|
render_403 unless can_move_experiment?(@experiment)
|
2016-08-12 17:26:18 +08:00
|
|
|
end
|
|
|
|
|
2019-05-20 19:13:31 +08:00
|
|
|
def set_inline_name_editing
|
|
|
|
return unless can_manage_experiment?(@experiment)
|
2021-02-03 21:23:38 +08:00
|
|
|
|
2019-05-20 19:13:31 +08:00
|
|
|
@inline_editable_title_config = {
|
|
|
|
name: 'title',
|
|
|
|
params_group: 'experiment',
|
2020-01-06 23:07:23 +08:00
|
|
|
item_id: @experiment.id,
|
2019-05-20 19:13:31 +08:00
|
|
|
field_to_udpate: 'name',
|
|
|
|
path_to_update: experiment_path(@experiment)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2017-04-06 20:55:18 +08:00
|
|
|
def experiment_annotation_notification(old_text = nil)
|
|
|
|
smart_annotation_notification(
|
|
|
|
old_text: old_text,
|
|
|
|
new_text: @experiment.description,
|
|
|
|
title: t('notifications.experiment_annotation_title',
|
|
|
|
experiment: @experiment.name,
|
|
|
|
user: current_user.full_name),
|
|
|
|
message: t('notifications.experiment_annotation_message_html',
|
|
|
|
project: link_to(@experiment.project.name,
|
|
|
|
project_url(@experiment.project)),
|
|
|
|
experiment: link_to(@experiment.name,
|
|
|
|
canvas_experiment_url(@experiment)))
|
|
|
|
)
|
|
|
|
end
|
2019-03-05 18:39:57 +08:00
|
|
|
|
2021-02-03 21:23:38 +08:00
|
|
|
def log_activity(type_of, experiment)
|
2019-03-05 18:39:57 +08:00
|
|
|
Activities::CreateActivityService
|
|
|
|
.call(activity_type: type_of,
|
|
|
|
owner: current_user,
|
2021-02-03 21:23:38 +08:00
|
|
|
team: experiment.project.team,
|
|
|
|
project: experiment.project,
|
|
|
|
subject: experiment,
|
|
|
|
message_items: { experiment: experiment.id })
|
2019-03-05 18:39:57 +08:00
|
|
|
end
|
2016-07-27 22:18:26 +08:00
|
|
|
end
|