class ProjectsController < ApplicationController include SampleActions include RenamingUtil include TeamsHelper include InputSanitizeHelper before_action :generate_intro_demo, only: :index before_action :load_vars, only: %i(show edit update notifications reports samples experiment_archive delete_samples samples_index) before_action :load_projects_tree, only: %i(index show samples archive experiment_archive) before_action :load_archive_vars, only: :archive before_action :check_view_permissions, only: %i(show reports notifications samples experiment_archive samples_index) before_action :check_create_permissions, only: %i(new create) before_action :check_manage_permissions, only: :edit # except parameter could be used but it is not working. layout 'fluid' # Action defined in SampleActions DELETE_SAMPLES = 'Delete'.freeze def index if params[:team] current_team_switch(Team.find_by_id(params[:team])) end @teams = current_user.teams # New project for create new project modal @project = Project.new end def archive index end def new @project = Project.new end def create @project = Project.new(project_params) @project.created_by = current_user @project.last_modified_by = current_user if current_team.id == project_params[:team_id].to_i && @project.save # Create user-project association up = UserProject.new( role: :owner, user: current_user, project: @project ) up.save # Create "project created" activity Activity.create( type_of: :create_project, user: current_user, project: @project, message: t( "activities.create_project", user: current_user.full_name, project: @project.name ) ) flash[:success] = t("projects.create.success_flash", name: @project.name) respond_to do |format| format.json { render json: { url: projects_path }, status: :ok } end else respond_to do |format| format.json { render json: @project.errors, status: :unprocessable_entity } end end end def edit respond_to do |format| format.json { render json: { html: render_to_string({ partial: "edit.html.erb", locals: { project: @project } }), title: t('projects.index.modal_edit_project.modal_title', project: escape_input(@project.name)) } } end end def update return_error = false flash_error = t('projects.update.error_flash', name: @project.name) # Check archive permissions if archiving/restoring if project_params.include? :archived if (project_params[:archived] == 'true' && !can_archive_project?(@project)) || (project_params[:archived] == 'false' && !can_restore_project?(@project)) return_error = true is_archive = URI(request.referer).path == projects_archive_path ? "restore" : "archive" flash_error = t("projects.#{is_archive}.error_flash", name: @project.name) end elsif !can_manage_project?(@project) render_403 && return end message_renamed = nil message_visibility = nil if project_params.include? :name and project_params[:name] != @project.name then message_renamed = t( "activities.rename_project", user: current_user.full_name, project_old: @project.name, project_new: project_params[:name] ) end if project_params.include? :visibility and project_params[:visibility] != @project.visibility then message_visibility = t( "activities.change_project_visibility", user: current_user.full_name, project: @project.name, visibility: project_params[:visibility] == "visible" ? t("general.public") : t("general.private") ) end @project.last_modified_by = current_user if @project.update(project_params) # Add activities if needed if message_visibility.present? Activity.create( type_of: :change_project_visibility, user: current_user, project: @project, message: message_visibility ) end if message_renamed.present? Activity.create( type_of: :rename_project, user: current_user, project: @project, message: message_renamed ) end flash_success = t('projects.update.success_flash', name: @project.name) respond_to do |format| format.html { # Redirect URL for archive view is different as for other views. if URI(request.referer).path == projects_archive_path # The project should be restored unless @project.archived @project.restore(current_user) # "Restore project" activity Activity.create( type_of: :restore_project, user: current_user, project: @project, message: t( "activities.restore_project", user: current_user.full_name, project: @project.name ) ) flash_success = t('projects.restore.success_flash', name: @project.name) end redirect_to projects_archive_path else # The project should be archived if @project.archived @project.archive(current_user) # "Archive project" activity Activity.create( type_of: :archive_project, user: current_user, project: @project, message: t( "activities.archive_project", user: current_user.full_name, project: @project.name ) ) flash_success = t('projects.archive.success_flash', name: @project.name) end redirect_to projects_path end flash[:success] = flash_success } format.json { render json: { status: :ok, html: render_to_string({ partial: "projects/index/project.html.erb", locals: { project: @project } }) } } end else return_error = true end if return_error then respond_to do |format| format.html { flash[:error] = flash_error # Redirect URL for archive view is different as for other views. if URI(request.referer).path == projects_archive_path redirect_to projects_archive_path else redirect_to projects_path end } format.json { render json: @project.errors, status: :unprocessable_entity } end end end def show # save experiments order if params[:sort] @project.experiments_order = params[:sort].to_s @project.save end # This is the "info" view current_team_switch(@project.team) @current_sort = @project.experiments_order end def notifications @modules = @project .assigned_modules(current_user) .order(due_date: :desc) respond_to do |format| #format.html format.json { render :json => { :html => render_to_string({ :partial => "notifications.html.erb" }) } } end end def samples @samples_index_link = samples_index_project_path(@project, format: :json) @team = @project.team end def experiment_archive current_team_switch(@project.team) end def samples_index @team = @project.team @user = current_user respond_to do |format| format.html format.json do render json: ::SampleDatatable.new(view_context, @team, @project, nil, nil, @user) end end end private include FirstTimeDataGenerator def generate_intro_demo return unless current_user.sign_in_count == 1 team = current_user.teams.where(created_by: current_user).first seed_demo_data(current_user, team) if team && team.projects.blank? end def project_params params.require(:project).permit(:name, :team_id, :visibility, :archived) end def load_vars @project = Project.find_by_id(params[:id]) unless @project render_404 end end def load_projects_tree if current_user.teams.any? @current_team = current_team if current_team @current_team ||= current_user.teams.first @current_sort = params[:sort].to_s @projects_tree = current_user.projects_tree(@current_team, @current_sort) else @projects_tree = [] end end def load_archive_vars if current_user.teams.any? @archived_projects_by_teams = current_user.projects_by_teams(@current_team.id, @current_sort, true) else @archived_projects_by_teams = [] end end def check_view_permissions render_403 unless can_read_project?(@project) end def check_create_permissions render_403 unless can_create_projects?(current_team) end def check_manage_permissions render_403 unless can_manage_project?(@project) end end