1# frozen_string_literal: true 2 3class Dashboard::ProjectsController < Dashboard::ApplicationController 4 include ParamsBackwardCompatibility 5 include RendersMemberAccess 6 include RendersProjectsList 7 include SortingHelper 8 include SortingPreference 9 include FiltersEvents 10 11 prepend_before_action(only: [:index]) { authenticate_sessionless_user!(:rss) } 12 before_action :set_non_archived_param, only: [:index, :starred] 13 before_action :set_sorting 14 before_action :projects, only: [:index] 15 skip_cross_project_access_check :index, :starred 16 17 feature_category :projects 18 19 def index 20 respond_to do |format| 21 format.html do 22 render_projects 23 end 24 format.atom do 25 load_events 26 render layout: 'xml.atom' 27 end 28 format.json do 29 render json: { 30 html: view_to_html_string("dashboard/projects/_projects", projects: @projects) 31 } 32 end 33 end 34 end 35 36 # rubocop: disable CodeReuse/ActiveRecord 37 def starred 38 @projects = load_projects(params.merge(starred: true)) 39 .includes(:forked_from_project, :topics) 40 41 @groups = [] 42 43 respond_to do |format| 44 format.html 45 format.json do 46 render json: { 47 html: view_to_html_string("dashboard/projects/_projects", projects: @projects) 48 } 49 end 50 end 51 end 52 # rubocop: enable CodeReuse/ActiveRecord 53 54 private 55 56 def projects 57 @projects ||= load_projects(params.merge(non_public: true)) 58 end 59 60 def render_projects 61 # n+1: https://gitlab.com/gitlab-org/gitlab-foss/issues/40260 62 Gitlab::GitalyClient.allow_n_plus_1_calls do 63 render 64 end 65 end 66 67 def load_projects(finder_params) 68 @total_user_projects_count = ProjectsFinder.new(params: { non_public: true, without_deleted: true }, current_user: current_user).execute 69 @total_starred_projects_count = ProjectsFinder.new(params: { starred: true, without_deleted: true }, current_user: current_user).execute 70 71 finder_params[:use_cte] = true if use_cte_for_finder? 72 finder_params[:without_deleted] = true 73 74 projects = ProjectsFinder.new(params: finder_params, current_user: current_user).execute 75 76 projects = preload_associations(projects) 77 projects = projects.page(finder_params[:page]) 78 79 prepare_projects_for_rendering(projects) 80 end 81 82 # rubocop: disable CodeReuse/ActiveRecord 83 def preload_associations(projects) 84 projects.includes(:route, :creator, :group, :topics, namespace: [:route, :owner]).preload(:project_feature) 85 end 86 # rubocop: enable CodeReuse/ActiveRecord 87 88 def use_cte_for_finder? 89 # The starred action loads public projects, which causes the CTE to be less efficient 90 action_name == 'index' 91 end 92 93 def load_events 94 projects = ProjectsFinder 95 .new(params: params.merge(non_public: true, without_deleted: true), current_user: current_user) 96 .execute 97 98 @events = EventCollection 99 .new(projects, offset: params[:offset].to_i, filter: event_filter) 100 .to_a 101 102 Events::RenderService.new(current_user).execute(@events, atom_request: request.format.atom?) 103 end 104 105 def set_sorting 106 params[:sort] = set_sort_order 107 @sort = params[:sort] 108 end 109 110 def default_sort_order 111 sort_value_name 112 end 113 114 def sorting_field 115 Project::SORTING_PREFERENCE_FIELD 116 end 117end 118 119Dashboard::ProjectsController.prepend_mod_with('Dashboard::ProjectsController') 120