scinote-web/app/controllers/reports_controller.rb

533 lines
14 KiB
Ruby
Raw Normal View History

2016-02-12 23:52:43 +08:00
class ReportsController < ApplicationController
include TeamsHelper
2017-03-08 21:14:03 +08:00
include ReportActions
2016-02-12 23:52:43 +08:00
# Ignore CSRF protection just for PDF generation (because it's
# used via target='_blank')
2017-03-08 21:14:03 +08:00
protect_from_forgery with: :exception, except: :generate
2016-02-12 23:52:43 +08:00
BEFORE_ACTION_METHODS = %i(
create
edit
update
generate
save_modal
2021-04-06 21:27:12 +08:00
project_contents
experiment_contents_modal
module_contents_modal
step_contents_modal
result_contents_modal
experiment_contents
module_contents
step_contents
result_contents
).freeze
before_action :load_vars, only: %i(edit update document_preview)
before_action :load_vars_nested, only: BEFORE_ACTION_METHODS
before_action :load_visible_projects, only: %i(new edit)
before_action :load_available_repositories,
only: %i(new edit available_repositories)
before_action :check_manage_permissions, only: BEFORE_ACTION_METHODS
2020-04-23 22:02:36 +08:00
before_action :switch_team_with_param, only: :index
2016-02-12 23:52:43 +08:00
2016-07-21 19:11:15 +08:00
# Index showing all reports of a single project
def index; end
def datatable
respond_to do |format|
format.json do
render json: ::ReportDatatable.new(
view_context,
current_user,
Report.viewable_by_user(current_user, current_team)
)
end
end
2016-02-12 23:52:43 +08:00
end
# Report grouped by modules
2016-07-21 19:11:15 +08:00
def new
@templates = Extends::REPORT_TEMPLATES
end
def new_template_values
template = Extends::REPORT_TEMPLATES[params[:template].to_sym]
return render_404 if template.blank?
respond_to do |format|
format.json do
if lookup_context.template_exists?("reports/templates/#{template}/edit.html.erb")
render json: {
html: render_to_string(
template: "reports/templates/#{template}/edit.html.erb",
layout: 'reports/template_values_editor',
locals: { report: Report.new }
)
}
else
render json: {
html: render_to_string(partial: 'reports/wizard/no_template_values.html.erb')
}
end
end
end
2016-02-12 23:52:43 +08:00
end
# Creating new report from the _save modal of the new page
def create
continue = true
begin
report_contents = JSON.parse(params.delete(:report_contents))
rescue
continue = false
end
@report = Report.new(report_params)
@report.project = @project
@report.user = current_user
@report.team = current_team
2016-02-12 23:52:43 +08:00
@report.last_modified_by = current_user
2017-03-08 21:14:03 +08:00
if continue && @report.save_with_contents(report_contents)
2019-03-14 02:05:29 +08:00
log_activity(:create_report)
2016-02-12 23:52:43 +08:00
respond_to do |format|
2017-03-08 21:14:03 +08:00
format.json do
render json: { url: reports_path }, status: :ok
2017-03-08 21:14:03 +08:00
end
2016-02-12 23:52:43 +08:00
end
else
respond_to do |format|
2017-03-08 21:14:03 +08:00
format.json do
2016-02-12 23:52:43 +08:00
render json: @report.errors, status: :unprocessable_entity
2017-03-08 21:14:03 +08:00
end
2016-02-12 23:52:43 +08:00
end
end
end
def edit
2016-07-21 19:11:15 +08:00
# cleans all the deleted report
current_team_switch(@report.project.team)
2016-07-21 19:11:15 +08:00
@report.cleanup_report
@templates = Extends::REPORT_TEMPLATES
2016-10-11 22:46:30 +08:00
render 'reports/new.html.erb'
2016-02-12 23:52:43 +08:00
end
# Updating existing report from the _save modal of the new page
def update
continue = true
begin
report_contents = JSON.parse(params.delete(:report_contents))
rescue
continue = false
end
@report.last_modified_by = current_user
@report.assign_attributes(report_params)
2017-03-08 21:14:03 +08:00
if continue && @report.save_with_contents(report_contents)
2019-03-14 02:05:29 +08:00
log_activity(:edit_report)
2016-02-12 23:52:43 +08:00
respond_to do |format|
2017-03-08 21:14:03 +08:00
format.json do
render json: { url: reports_path }, status: :ok
2017-03-08 21:14:03 +08:00
end
2016-02-12 23:52:43 +08:00
end
else
respond_to do |format|
2017-03-08 21:14:03 +08:00
format.json do
2016-02-12 23:52:43 +08:00
render json: @report.errors, status: :unprocessable_entity
2017-03-08 21:14:03 +08:00
end
2016-02-12 23:52:43 +08:00
end
end
end
# Destroy multiple entries action
def destroy
begin
report_ids = JSON.parse(params[:report_ids])
rescue
render_404
end
report_ids.each do |report_id|
report = Report.find_by_id(report_id)
next unless report.present? && can_manage_reports?(report.project.team)
2017-03-08 21:14:03 +08:00
# record an activity
2019-03-21 04:34:47 +08:00
log_activity(:delete_report, report)
2017-03-08 21:14:03 +08:00
report.destroy
2016-02-12 23:52:43 +08:00
end
redirect_to reports_path
2016-02-12 23:52:43 +08:00
end
# Generation action
# Currently, only .PDF is supported
def generate
content = params[:data]
2018-05-17 17:21:34 +08:00
content = I18n.t('projects.reports.new.no_content_for_PDF_html') if content.blank?
template = {}
2016-02-12 23:52:43 +08:00
respond_to do |format|
2017-03-08 21:14:03 +08:00
format.pdf do
render pdf: 'report', header: { html: { template: 'reports/templates/template_1/_header.html.erb',
2021-03-31 05:47:34 +08:00
locals: { template: template},
layout: 'reports/footer_header.html.erb' } },
footer: { html: { template: 'reports/templates/template_1/_footer.html.erb',
2021-03-31 05:47:34 +08:00
locals: { template: template},
layout: 'reports/footer_header.html.erb' } },
2018-05-17 17:21:34 +08:00
locals: { content: content },
cover: render_to_string(partial: 'reports/templates/template_1/report.html.erb',
locals: {
template: template
}),
disable_javascript: true,
template: 'reports/report.pdf.erb'
2017-03-08 21:14:03 +08:00
end
format.docx do
@user = current_user
@team = current_team
@scinote_url = root_url
@data = params[:data]
headers["Content-Disposition"] = 'attachment; filename="scinote_report.docx"'
end
2016-02-12 23:52:43 +08:00
end
end
def save_pdf_to_inventory_item
save_pdf_to_inventory_item = ReportActions::SavePdfToInventoryItem.new(
current_user, current_team, save_PDF_params
)
if save_pdf_to_inventory_item.save
render json: {
message: I18n.t(
'projects.reports.new.save_PDF_to_inventory_modal.success_flash'
)
}, status: :ok
else
render json: { message: save_pdf_to_inventory_item.error_messages },
status: :unprocessable_entity
end
2018-05-17 17:21:34 +08:00
rescue ReportActions::RepositoryPermissionError => error
render json: { message: error },
status: :forbidden
rescue Exception => error
render json: { message: error.message },
status: :internal_server_error
end
2016-02-12 23:52:43 +08:00
# Modal for saving the existsing/new report
def save_modal
# Assume user is updating existing report
@report = @project.reports.find_by_id(params[:id])
2016-02-12 23:52:43 +08:00
@method = :put
# Case when saving a new report
if @report.blank?
@report = Report.new
@method = :post
@url = project_reports_path(@project, format: :json)
else
@url = project_report_path(@project, @report, format: :json)
end
2017-03-08 21:14:03 +08:00
render_403 and return unless params.include? :contents
2016-02-12 23:52:43 +08:00
@report_contents = params[:contents]
respond_to do |format|
2017-03-08 21:14:03 +08:00
format.json do
2016-02-12 23:52:43 +08:00
render json: {
2017-03-08 21:14:03 +08:00
html: render_to_string(
partial: 'reports/new/modal/save.html.erb'
)
2016-02-12 23:52:43 +08:00
}
2017-03-08 21:14:03 +08:00
end
2016-02-12 23:52:43 +08:00
end
end
# Experiment for adding contents into experiment element
def experiment_contents_modal
experiment = @project.experiments.find_by_id(params[:experiment_id])
respond_to do |format|
if experiment.blank?
format.json do
render json: {}, status: :not_found
end
else
format.json do
render json: {
html: render_to_string(
2016-08-05 14:29:49 +08:00
partial: 'reports/new/modal/experiment_contents.html.erb',
locals: { project: @project, experiment: experiment }
)
}
end
end
end
end
2016-02-12 23:52:43 +08:00
# Modal for adding contents into module element
def module_contents_modal
my_module = MyModule.find_by_id(params[:my_module_id])
return render_403 unless my_module.experiment.project == @project
2016-02-12 23:52:43 +08:00
respond_to do |format|
if my_module.blank?
format.json do
2016-02-12 23:52:43 +08:00
render json: {}, status: :not_found
end
2016-02-12 23:52:43 +08:00
else
format.json do
2016-02-12 23:52:43 +08:00
render json: {
html: render_to_string(
2017-03-08 21:14:03 +08:00
partial: 'reports/new/modal/module_contents.html.erb',
2016-02-12 23:52:43 +08:00
locals: { project: @project, my_module: my_module }
)
2016-02-12 23:52:43 +08:00
}
end
2016-02-12 23:52:43 +08:00
end
end
end
# Modal for adding contents into step element
def step_contents_modal
step = Step.find_by_id(params[:step_id])
return render_403 unless step.my_module.experiment.project == @project
respond_to do |format|
if step.blank?
format.json do
render json: {}, status: :not_found
end
else
format.json do
render json: {
html: render_to_string(
partial: 'reports/new/modal/step_contents.html.erb',
locals: { project: @project, step: step }
)
}
end
end
end
end
# Modal for adding contents into result element
def result_contents_modal
result = Result.find_by_id(params[:result_id])
return render_403 unless result.experiment.project == @project
respond_to do |format|
if result.blank?
format.json do
render json: {}, status: :not_found
end
else
format.json do
render json: {
html: render_to_string(
partial: 'reports/new/modal/result_contents.html.erb',
locals: { project: @project, result: result }
)
}
end
end
end
end
2016-02-12 23:52:43 +08:00
def project_contents
2021-04-06 21:27:12 +08:00
render json: {
html: render_to_string(
partial: 'reports/wizard/second_step.html.erb',
locals: { project: @project }
)
}
2016-02-12 23:52:43 +08:00
end
2016-08-02 15:05:11 +08:00
def experiment_contents
experiment = @project.experiments.find_by(id: params[:id])
module_ids = (params[:modules].select { |_, p| p == '1' }).keys.collect(&:to_i)
selected_modules = experiment.my_modules.where(id: module_ids)
2016-08-02 15:05:11 +08:00
respond_to do |format|
if experiment.blank?
format.json { render json: {}, status: :not_found }
elsif selected_modules.blank?
format.json { render json: {}, status: :no_content }
else
elements = generate_experiment_contents_json(selected_modules)
end
2016-08-02 15:05:11 +08:00
if elements_empty? elements
format.json { render json: {}, status: :no_content }
else
2016-08-05 14:29:49 +08:00
format.json do
2016-08-02 15:05:11 +08:00
render json: {
status: :ok,
elements: elements
}
2016-08-05 14:29:49 +08:00
end
2016-08-02 15:05:11 +08:00
end
end
end
2016-02-12 23:52:43 +08:00
def module_contents
my_module = MyModule.find_by_id(params[:id])
return render_403 unless my_module.experiment.project == @project
2016-02-12 23:52:43 +08:00
respond_to do |format|
if my_module.blank?
format.json { render json: {}, status: :not_found }
else
elements = generate_module_contents_json(my_module)
if elements_empty? elements
format.json { render json: {}, status: :no_content }
else
2017-03-08 21:14:03 +08:00
format.json do
2016-02-12 23:52:43 +08:00
render json: {
status: :ok,
elements: elements
}
2017-03-08 21:14:03 +08:00
end
2016-02-12 23:52:43 +08:00
end
end
end
end
def step_contents
step = Step.find_by_id(params[:id])
return render_403 unless step.my_module.experiment.project == @project
respond_to do |format|
if step.blank?
format.json { render json: {}, status: :not_found }
else
elements = generate_step_contents_json(step)
if elements_empty? elements
format.json { render json: {}, status: :no_content }
else
format.json {
render json: {
status: :ok,
elements: elements
}
}
end
end
end
end
def result_contents
result = Result.find_by_id(params[:id])
return render_403 unless result.my_module.experiment.project == @project
respond_to do |format|
if result.blank?
format.json { render json: {}, status: :not_found }
else
elements = generate_result_contents_json(result)
if elements_empty? elements
format.json { render json: {}, status: :no_content }
else
format.json {
render json: {
status: :ok,
elements: elements
}
}
end
end
end
end
def available_repositories
render json: { results: @available_repositories }, status: :ok
end
def document_preview
render json: { html: render_to_string(
partial: 'reports/content_document_preview.html.erb',
locals: {
report: @report,
report_type: params[:report_type]
}
) }
end
2016-02-12 23:52:43 +08:00
private
include StringUtility
AvailableRepository = Struct.new(:id, :name)
2016-02-12 23:52:43 +08:00
def load_vars
@report = current_team.reports.find_by(id: params[:id])
2017-03-08 21:14:03 +08:00
render_404 unless @report
2016-02-12 23:52:43 +08:00
end
def load_vars_nested
@project = current_team.projects.find_by(id: params[:project_id])
2017-03-08 21:14:03 +08:00
render_404 unless @project
render_403 unless can_read_project?(@project)
2016-02-12 23:52:43 +08:00
end
def check_manage_permissions
render_403 unless can_manage_reports?(@project.team)
end
def load_visible_projects
render_404 unless current_team
@visible_projects = Project.viewable_by_user(
current_user, current_team
).select(:id, :name)
2016-02-12 23:52:43 +08:00
end
def load_available_repositories
@available_repositories = []
repositories = Repository.active
.accessible_by_teams(current_team)
.name_like(search_params[:q])
.limit(Constants::SEARCH_LIMIT)
.select(:id, :name, :team_id, :permission_level)
repositories.each do |repository|
next unless can_manage_repository_rows?(current_user, repository)
@available_repositories.push(AvailableRepository.new(repository.id,
ellipsize(repository.name, 75, 50)))
end
end
2016-02-12 23:52:43 +08:00
def report_params
2017-03-08 21:14:03 +08:00
params.require(:report)
.permit(:name, :description, :grouped_by, :report_contents)
2016-02-12 23:52:43 +08:00
end
def search_params
params.permit(:q)
end
def save_PDF_params
params.permit(:repository_id,
:respository_column_id,
:repository_item_id,
:html)
end
2019-03-14 02:05:29 +08:00
2019-03-21 04:34:47 +08:00
def log_activity(type_of, report = @report)
2019-03-14 02:05:29 +08:00
Activities::CreateActivityService
.call(activity_type: type_of,
owner: current_user,
2019-03-21 04:34:47 +08:00
subject: report,
team: report.team,
project: report.project,
message_items: { report: report.id })
2019-03-14 02:05:29 +08:00
end
2016-07-21 19:11:15 +08:00
end