# frozen_string_literal: true module Dashboard class RecentWorkService include PermissionExtends include InputSanitizeHelper include Rails.application.routes.url_helpers def initialize(user, team, mode) @user = user @team = team @mode = mode end def call all_activities = @team.activities.where(owner_id: @user.id) all_activities = join_project_user_roles(all_activities) all_activities = join_report_project_user_roles(all_activities) all_activities = join_experiment_user_roles(all_activities) all_activities = join_my_module_user_roles(all_activities) all_activities = join_result_user_roles(all_activities) all_activities = join_protocol_user_roles(all_activities) all_activities = join_step_user_roles(all_activities) team_activities = all_activities.where(subject_type: %w(Team RepositoryBase ProjectFolder)) project_activities = all_activities.where.not(project_user_roles: { id: nil }) report_activities = all_activities.where.not(report_project_user_roles: { id: nil }) experiment_activities = all_activities.where.not(experiment_user_roles: { id: nil }) my_module_activities = all_activities.where.not(my_module_user_roles: { id: nil }) result_activities = all_activities.where.not(result_my_module_user_roles: { id: nil }) protocol_activities = all_activities.where.not(protocol_my_module_user_roles: { id: nil }) protocol_repository_activities = all_activities.where(project_id: nil, subject_type: 'Protocol') step_activities = all_activities.where.not(step_my_module_user_roles: { id: nil }) activities = team_activities.or(project_activities) .or(report_activities) .or(experiment_activities) .or(my_module_activities) .or(result_activities) .or(protocol_activities) .or(step_activities) .or(protocol_repository_activities) activities = activities.where.not(type_of: Extends::DASHBOARD_BLACKLIST_ACTIVITY_TYPES) .select('MAX(activities.created_at) AS last_change', :subject_id, :subject_type) .group(:subject_id, :subject_type) .order(last_change: :desc) query = Activity.from("(#{activities.to_sql}) AS activities") .results_joins .protocols_joins .my_modules_joins(:from_results, :from_protocols) .experiments_joins(:from_my_modules) .projects_joins(:from_experiments) .repositories_joins .reports_joins .where('repositories.archived IS NOT TRUE') .where('projects.archived IS NOT TRUE') .where('experiments.archived IS NOT TRUE') .where('my_modules.archived IS NOT TRUE') .where('protocols.protocol_type != ? OR protocols.protocol_type IS NULL', Protocol.protocol_types[:in_repository_archived]) .select(' CASE WHEN my_modules.id IS NOT NULL THEN CONCAT(\'tsk\', my_modules.id) WHEN experiments.id IS NOT NULL THEN CONCAT(\'exp\', experiments.id) WHEN projects.id IS NOT NULL THEN CONCAT(\'pro\', projects.id) WHEN protocols.id IS NOT NULL THEN CONCAT(\'prt\', protocols.id) WHEN repositories.id IS NOT NULL THEN CONCAT(\'inv\', repositories.id) WHEN reports.id IS NOT NULL THEN CONCAT(\'rpt\', reports.id) END AS group_id, COALESCE ( my_modules.name, experiments.name, projects.name, protocols.name, repositories.name, reports.name ) AS name, reports.project_id AS report_project_id, subject_id, subject_type, last_change ') ordered_query = Activity.from("(#{query.to_sql}) AS activities").where.not(group_id: nil) .select(:group_id, :name, 'MAX(last_change) AS last_change', 'MAX(report_project_id) AS report_project_id') .group(:group_id, :name) .order('MAX(last_change) DESC').limit(Constants::SEARCH_LIMIT) query_filter = "(group_id LIKE 'tsk%' OR group_id LIKE 'exp%' OR group_id LIKE 'pro%')" if @mode == 'projects' query_filter = "group_id LIKE 'prt%'" if @mode == 'protocols' query_filter = "group_id LIKE 'inv%'" if @mode == 'repositories' query_filter = "group_id LIKE 'rpt%'" if @mode == 'reports' ordered_query = ordered_query.where(query_filter) unless @mode == 'all' recent_objects = ordered_query.as_json.map do |recent_object| recent_object.deep_symbolize_keys! recent_object.delete_if { |_k, v| v.nil? } recent_object[:last_change] = I18n.l( DateTime.parse(recent_object[:last_change]).in_time_zone(@user.settings[:time_zone] || 'UTC'), format: :full_with_comma ) recent_object[:subject_type] = override_subject_type(recent_object) recent_object[:name] = escape_input(recent_object[:name]) recent_object[:url] = generate_url(recent_object) recent_object end recent_objects end private def join_project_user_roles(activities) activities.joins( "LEFT OUTER JOIN projects project_subjects ON project_subjects.id = activities.subject_id AND activities.subject_type='Project' LEFT OUTER JOIN user_assignments project_user_assignments ON project_user_assignments.assignable_type = 'Project' AND project_user_assignments.assignable_id = project_subjects.id AND project_user_assignments.user_id = #{@user.id} LEFT OUTER JOIN user_roles project_user_roles ON project_user_roles.id = project_user_assignments.user_role_id AND project_user_roles.permissions @> ARRAY['#{ProjectPermissions::ACTIVITIES_READ}']::varchar[]" ) end def join_report_project_user_roles(activities) activities.joins( "LEFT OUTER JOIN projects report_project_subjects ON report_project_subjects.id = activities.project_id AND activities.subject_type='Report' LEFT OUTER JOIN user_assignments report_project_user_assignments ON report_project_user_assignments.assignable_type = 'Project' AND report_project_user_assignments.assignable_id = report_project_subjects.id AND report_project_user_assignments.user_id = #{@user.id} LEFT OUTER JOIN user_roles report_project_user_roles ON report_project_user_roles.id = report_project_user_assignments.user_role_id AND report_project_user_roles.permissions @> ARRAY['#{ProjectPermissions::ACTIVITIES_READ}']::varchar[]" ) end def join_experiment_user_roles(activities) activities.joins( "LEFT OUTER JOIN experiments experiment_subjects ON experiment_subjects.id = activities.subject_id AND activities.subject_type='Experiment' LEFT OUTER JOIN user_assignments experiment_user_assignments ON experiment_user_assignments.assignable_type = 'Experiment' AND experiment_user_assignments.assignable_id = experiment_subjects.id AND experiment_user_assignments.user_id = #{@user.id} LEFT OUTER JOIN user_roles experiment_user_roles ON experiment_user_roles.id = experiment_user_assignments.user_role_id AND experiment_user_roles.permissions @> ARRAY['#{ExperimentPermissions::ACTIVITIES_READ}']::varchar[]" ) end def join_my_module_user_roles(activities) activities.joins( "LEFT OUTER JOIN my_modules my_module_subjects ON my_module_subjects.id = activities.subject_id AND activities.subject_type='MyModule' LEFT OUTER JOIN user_assignments my_module_user_assignments ON my_module_user_assignments.assignable_type = 'MyModule' AND my_module_user_assignments.assignable_id = my_module_subjects.id AND my_module_user_assignments.user_id = #{@user.id} LEFT OUTER JOIN user_roles my_module_user_roles ON my_module_user_roles.id = my_module_user_assignments.user_role_id AND my_module_user_roles.permissions @> ARRAY['#{MyModulePermissions::ACTIVITIES_READ}']::varchar[]" ) end def join_result_user_roles(activities) activities.joins( "LEFT OUTER JOIN results result_subjects ON result_subjects.id = activities.subject_id AND activities.subject_type='Result' LEFT OUTER JOIN my_modules result_my_modules ON result_subjects.my_module_id = result_my_modules.id LEFT OUTER JOIN user_assignments result_my_module_user_assignments ON result_my_module_user_assignments.assignable_type = 'MyModule' AND result_my_module_user_assignments.assignable_id = result_my_modules.id AND result_my_module_user_assignments.user_id = #{@user.id} LEFT OUTER JOIN user_roles result_my_module_user_roles ON result_my_module_user_roles.id = result_my_module_user_assignments.user_role_id AND result_my_module_user_roles.permissions @> ARRAY['#{MyModulePermissions::ACTIVITIES_READ}']::varchar[]" ) end def join_protocol_user_roles(activities) activities.joins( "LEFT OUTER JOIN protocols protocol_subjects ON protocol_subjects.id = activities.subject_id AND activities.subject_type='Protocol' LEFT OUTER JOIN my_modules protocol_my_modules ON protocol_subjects.my_module_id = protocol_my_modules.id LEFT OUTER JOIN user_assignments protocol_my_module_user_assignments ON protocol_my_module_user_assignments.assignable_type = 'MyModule' AND protocol_my_module_user_assignments.assignable_id = protocol_my_modules.id AND protocol_my_module_user_assignments.user_id = #{@user.id} LEFT OUTER JOIN user_roles protocol_my_module_user_roles ON protocol_my_module_user_roles.id = protocol_my_module_user_assignments.user_role_id AND protocol_my_module_user_roles.permissions @> ARRAY['#{MyModulePermissions::ACTIVITIES_READ}']::varchar[]" ) end def join_step_user_roles(activities) activities.joins( "LEFT OUTER JOIN steps step_subjects ON step_subjects.id = activities.subject_id AND activities.subject_type='Step' LEFT OUTER JOIN protocols step_protocols ON step_subjects.protocol_id = step_protocols.id LEFT OUTER JOIN my_modules step_my_modules ON step_protocols.my_module_id = step_my_modules.id LEFT OUTER JOIN user_assignments step_my_module_user_assignments ON step_my_module_user_assignments.assignable_type = 'MyModule' AND step_my_module_user_assignments.assignable_id = step_my_modules.id AND step_my_module_user_assignments.user_id = #{@user.id} LEFT OUTER JOIN user_roles step_my_module_user_roles ON step_my_module_user_roles.id = step_my_module_user_assignments.user_role_id AND step_my_module_user_roles.permissions @> ARRAY['#{MyModulePermissions::ACTIVITIES_READ}']::varchar[]" ) end def generate_url(recent_object) object_id = recent_object[:group_id].gsub(/[^0-9]/, '') case recent_object[:subject_type] when 'MyModule' protocols_my_module_path(object_id) when 'Experiment' canvas_experiment_path(object_id) when 'Project' project_path(object_id) when 'Protocol' protocol_path(object_id) when 'RepositoryBase' repository_path(object_id) when 'Report' edit_project_report_path(recent_object[:report_project_id], object_id) if recent_object[:report_project_id] end end def override_subject_type(recent_object) if recent_object[:group_id].include?('pro') 'Project' elsif recent_object[:group_id].include?('exp') 'Experiment' elsif recent_object[:group_id].include?('tsk') 'MyModule' elsif recent_object[:group_id].include?('prt') 'Protocol' elsif recent_object[:group_id].include?('inv') 'RepositoryBase' elsif recent_object[:group_id].include?('rpt') 'Report' end end end end