mirror of
				https://github.com/scinote-eln/scinote-web.git
				synced 2025-11-01 00:56:05 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			247 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| class ResultsController < ApplicationController
 | |
|   include Breadcrumbs
 | |
|   include TeamsHelper
 | |
| 
 | |
|   before_action :load_my_module
 | |
|   before_action :load_vars, only: %i(destroy elements assets upload_attachment archive restore destroy
 | |
|                                      update_view_state update_asset_view_mode update duplicate)
 | |
|   before_action :check_destroy_permissions, only: :destroy
 | |
|   before_action :set_breadcrumbs_items, only: %i(index)
 | |
|   before_action :set_navigator, only: %i(index)
 | |
|   before_action :set_inline_name_editing, only: %i(index)
 | |
| 
 | |
|   def index
 | |
|     respond_to do |format|
 | |
|       format.json do
 | |
|         # API endpoint
 | |
|         @results = if params[:view_mode] == 'archived'
 | |
|                      @my_module.results.archived
 | |
|                    else
 | |
|                      @my_module.results.active
 | |
|                    end
 | |
| 
 | |
|         update_and_apply_user_sort_preference!
 | |
|         apply_filters!
 | |
| 
 | |
|         @results = @results.page(params.dig(:page, :number) || 1)
 | |
| 
 | |
|         render json: @results, each_serializer: ResultSerializer, scope: current_user,
 | |
|                meta: { sort: @sort_preference }
 | |
|       end
 | |
| 
 | |
|       format.html do
 | |
|         # Main view
 | |
|         @experiment = @my_module.experiment
 | |
|         @project = @experiment.project
 | |
|         render(:index, formats: :html)
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def create
 | |
|     result = @my_module.results.create!(user: current_user)
 | |
|     log_activity(:add_result, { result: result })
 | |
|     render json: result
 | |
|   end
 | |
| 
 | |
|   def update
 | |
|     @result.update!(result_params)
 | |
|     log_activity(:edit_result, { result: @result })
 | |
|     render json: @result
 | |
|   end
 | |
| 
 | |
|   def archive
 | |
|     if @result.archive(current_user)
 | |
|       log_activity(:archive_result, { result: @result })
 | |
|       render json: {}, status: :ok
 | |
|     else
 | |
|       render json: { errors: @result.errors.full_messages }, status: :unprocessable_entity
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def restore
 | |
|     if @result.restore(current_user)
 | |
|       log_activity(:result_restored, { result: @result })
 | |
|       render json: {}, status: :ok
 | |
|     else
 | |
|       render json: { errors: @result.errors.full_messages }, status: :unprocessable_entity
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def elements
 | |
|     render json: @result.result_orderable_elements.order(:position),
 | |
|            each_serializer: ResultOrderableElementSerializer,
 | |
|            user: current_user
 | |
|   end
 | |
| 
 | |
|   def assets
 | |
|     render json: @result.assets.preload(:preview_image_attachment, file_attachment: :blob, result: { my_module: { experiment: :project, user_assignments: %i(user user_role) } }),
 | |
|            each_serializer: AssetSerializer,
 | |
|            user: current_user,
 | |
|            managable_result: can_manage_result?(@result)
 | |
|   end
 | |
| 
 | |
|   def upload_attachment
 | |
|     @result.transaction do
 | |
|       @asset = @result.assets.create!(
 | |
|         created_by: current_user,
 | |
|         last_modified_by: current_user,
 | |
|         team: @my_module.team,
 | |
|         view_mode: @result.assets_view_mode
 | |
|       )
 | |
|       @asset.attach_file_version(params[:signed_blob_id])
 | |
|       @asset.post_process_file
 | |
|     end
 | |
| 
 | |
|     log_activity(:result_file_added, { file: @asset.file_name, result: @result })
 | |
|     render json: @asset,
 | |
|            serializer: AssetSerializer,
 | |
|            user: current_user
 | |
|   end
 | |
| 
 | |
|   def update_view_state
 | |
|     view_state = @result.current_view_state(current_user)
 | |
|     view_state.state['assets']['sort'] = params.require(:assets).require(:order)
 | |
|     view_state.save! if view_state.changed?
 | |
| 
 | |
|     render json: {}, status: :ok
 | |
|   end
 | |
| 
 | |
|   def update_asset_view_mode
 | |
|     ActiveRecord::Base.transaction do
 | |
|       @result.assets_view_mode = params[:assets_view_mode]
 | |
|       @result.save!(touch: false)
 | |
|       @result.assets.update_all(view_mode: @result.assets_view_mode)
 | |
|     end
 | |
|     render json: { view_mode: @result.assets_view_mode }, status: :ok
 | |
|   rescue ActiveRecord::RecordInvalid => e
 | |
|     Rails.logger.error(e.message)
 | |
|     render json: { errors: e.message }, status: :unprocessable_entity
 | |
|   end
 | |
| 
 | |
|   def destroy
 | |
|     name = @result.name
 | |
|     if @result.discard
 | |
|       log_activity(:destroy_result, { destroyed_result: name })
 | |
|       render json: {}, status: :ok
 | |
|     else
 | |
|       render json: { errors: @result.errors.full_messages }, status: :unprocessable_entity
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def duplicate
 | |
|     ActiveRecord::Base.transaction do
 | |
|       new_result = @result.duplicate(
 | |
|         @my_module, current_user, result_name: "#{@result.name} (1)"
 | |
|       )
 | |
| 
 | |
|       log_activity(:result_duplicated, { result: @result })
 | |
|       render json: new_result, serializer: ResultSerializer, user: current_user
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   private
 | |
| 
 | |
|   def result_params
 | |
|     params.require(:result).permit(:name)
 | |
|   end
 | |
| 
 | |
|   def update_and_apply_user_sort_preference!
 | |
|     if params[:sort].present?
 | |
|       current_user.update_nested_setting(key: 'results_order', id: @my_module.id.to_s, value: params[:sort])
 | |
|       @sort_preference = params[:sort]
 | |
|     else
 | |
|       @sort_preference = current_user.settings.fetch('results_order', {})[@my_module.id.to_s] || 'created_at_desc'
 | |
|     end
 | |
|     apply_sort!(@sort_preference)
 | |
|   end
 | |
| 
 | |
|   def apply_sort!(sort_order)
 | |
|     case sort_order
 | |
|     when 'updated_at_asc'
 | |
|       @results = @results.order('results.updated_at' => :asc)
 | |
|     when 'updated_at_desc'
 | |
|       @results = @results.order('results.updated_at' => :desc)
 | |
|     when 'created_at_asc'
 | |
|       @results = @results.order('results.created_at' => :asc)
 | |
|     when 'created_at_desc'
 | |
|       @results = @results.order('results.created_at' => :desc)
 | |
|     when 'name_asc'
 | |
|       @results = @results.order('results.name' => :asc)
 | |
|     when 'name_desc'
 | |
|       @results = @results.order('results.name' => :desc)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def apply_filters!
 | |
|     if params[:query].present?
 | |
|       @results = @results.search(current_user, params[:view_mode] == 'archived', params[:query])
 | |
|                          .page(params[:page] || 1)
 | |
|                          .per(Constants::SEARCH_LIMIT)
 | |
|     end
 | |
| 
 | |
|     @results = @results.where('results.created_at >= ?', params[:created_at_from]) if params[:created_at_from]
 | |
|     @results = @results.where('results.created_at <= ?', params[:created_at_to]) if params[:created_at_to]
 | |
|     @results = @results.where('results.updated_at >= ?', params[:updated_at_from]) if params[:updated_at_from]
 | |
|     @results = @results.where('results.updated_at <= ?', params[:updated_at_to]) if params[:updated_at_to]
 | |
|   end
 | |
| 
 | |
|   def load_my_module
 | |
|     @my_module = MyModule.readable_by_user(current_user).find(params[:my_module_id])
 | |
|     current_team_switch(@my_module.team) if current_team != @my_module.team
 | |
|   end
 | |
| 
 | |
|   def load_vars
 | |
|     @result = @my_module.results.find(params[:id])
 | |
| 
 | |
|     return render_403 unless @result
 | |
| 
 | |
|     @my_module = @result.my_module
 | |
|   end
 | |
| 
 | |
|   def check_destroy_permissions
 | |
|     render_403 unless can_delete_result?(@result)
 | |
|   end
 | |
| 
 | |
|   def set_navigator
 | |
|     @navigator = {
 | |
|       url: tree_navigator_my_module_path(@my_module),
 | |
|       archived: @my_module.archived_branch?,
 | |
|       id: @my_module.code
 | |
|     }
 | |
|   end
 | |
| 
 | |
|   def log_activity(element_type_of, message_items = {})
 | |
|     message_items[:my_module] = @my_module.id
 | |
|     subject = if message_items.key?(:result)
 | |
|                 result = message_items[:result]
 | |
|                 message_items[:result] = result.id
 | |
|                 result
 | |
|               else
 | |
|                 @my_module
 | |
|               end
 | |
| 
 | |
|     Activities::CreateActivityService.call(
 | |
|       activity_type: element_type_of,
 | |
|       owner: current_user,
 | |
|       team: @my_module.team,
 | |
|       subject: subject,
 | |
|       project: @my_module.experiment.project,
 | |
|       message_items: message_items
 | |
|     )
 | |
|   end
 | |
| 
 | |
|   def set_inline_name_editing
 | |
|     return unless can_manage_my_module?(@my_module)
 | |
| 
 | |
|     @inline_editable_title_config = {
 | |
|       name: 'title',
 | |
|       params_group: 'my_module',
 | |
|       item_id: @my_module.id,
 | |
|       field_to_udpate: 'name',
 | |
|       path_to_update: my_module_path(@my_module)
 | |
|     }
 | |
|   end
 | |
| end
 |