scinote-web/app/services/dashboard/recent_work_service.rb
2022-11-23 15:03:35 +01:00

276 lines
13 KiB
Ruby

# 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,
:subject_id,
:name,
'MAX(last_change) AS last_change',
'MAX(report_project_id) AS report_project_id')
.group(:group_id, :subject_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|
object_class = override_subject_type(recent_object).constantize
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[:type] = I18n.t("activerecord.models.#{object_class.name.underscore}")
if object_class.include?(PrefixedIdModel)
recent_object[:code] = object_class::ID_PREFIX + recent_object[:subject_id].to_s
end
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.with_indifferent_access[: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)
group_id = recent_object.with_indifferent_access[:group_id]
if group_id.include?('pro')
'Project'
elsif group_id.include?('exp')
'Experiment'
elsif group_id.include?('tsk')
'MyModule'
elsif group_id.include?('prt')
'Protocol'
elsif group_id.include?('inv')
'RepositoryBase'
elsif group_id.include?('rpt')
'Report'
end
end
end
end