scinote-web/app/controllers/forms_controller.rb

274 lines
7.6 KiB
Ruby

# frozen_string_literal: true
class FormsController < ApplicationController
include InputSanitizeHelper
before_action :check_forms_enabled
before_action :load_forms, only: %i(index actions_toolbar)
before_action :load_form, only: %i(show update publish unpublish export_form_responses duplicate)
before_action :set_breadcrumbs_items, only: %i(index show)
before_action :check_manage_permissions, only: :update
before_action :check_create_permissions, only: :create
def index
respond_to do |format|
format.html
format.json do
forms_list = Lists::FormsService.new(@forms, params, user: current_user).call
render json: forms_list,
each_serializer: Lists::FormSerializer,
user: current_user,
meta: pagination_dict(forms_list)
end
end
end
def show
respond_to do |format|
format.json { render json: @form, serializer: FormSerializer, include: %i(form_fields), user: current_user }
format.html
end
end
def create
ActiveRecord::Base.transaction do
@form = Form.new(
name: I18n.t('forms.default_name'),
team: current_team,
created_by: current_user,
last_modified_by: current_user
)
if @form.save
log_activity(@form, :form_created)
render json: @form, serializer: FormSerializer, user: current_user
else
render json: { error: @form.errors.full_messages }, status: :unprocessable_entity
end
end
end
def update
ActiveRecord::Base.transaction do
if @form.update(form_params.merge({ last_modified_by: current_user }))
log_activity(@form, :form_name_changed)
render json: @form, serializer: FormSerializer, user: current_user
else
render json: { error: @form.errors.full_messages }, status: :unprocessable_entity
end
end
end
def published_forms
forms = current_team.forms.active.readable_by_user(current_user).published.order(name: :asc)
forms = forms.where('forms.name ILIKE ?', "%#{params[:query]}%") if params[:query].present?
forms = forms.page(params[:page])
render json: {
data: forms.map { |f| [f.id, f.name] },
paginated: true,
next_page: forms.next_page
}
end
def latest_attached_forms
forms = current_team.forms.active.readable_by_user(current_user).published
.joins(:form_responses)
.where(form_responses: { created_by: current_user })
.select('forms.id, forms.name, MAX(form_responses.created_at) AS last_response_at')
.group('forms.id')
.order('last_response_at DESC')
.limit(5)
render json: {
data: forms
}
end
def publish
render_403 and return unless can_publish_form?(@form)
ActiveRecord::Base.transaction do
@form.update!(
published_by: current_user,
published_on: DateTime.now
)
log_activity(@form, :form_published, { version_number: 1 })
render json: @form, serializer: FormSerializer, user: current_user
end
end
def unpublish
render_403 and return unless can_unpublish_form?(@form)
ActiveRecord::Base.transaction do
@form.update!(
published_by: nil,
published_on: nil
)
log_activity(@form, :form_unpublished)
render json: @form, serializer: FormSerializer, user: current_user
end
end
def archive
forms = current_team.forms.active.where(id: params[:form_ids])
return render_404 if forms.blank?
return render_403 unless forms.all? { |f| can_archive_form?(f) }
counter = 0
forms.each do |form|
form.transaction do
form.archive!(current_user)
log_activity(form, :form_archived)
counter += 1
rescue StandardError => e
Rails.logger.error e.message
raise ActiveRecord::Rollback
end
end
if counter.positive?
render json: { message: t('forms.archived.success_flash', number: counter) }
else
render json: { message: t('forms.archived.error_flash') }, status: :unprocessable_entity
end
end
def restore
forms = current_team.forms.archived.where(id: params[:form_ids])
return render_404 if forms.blank?
return render_403 unless forms.all? { |f| can_restore_form?(f) }
counter = 0
forms.each do |form|
form.transaction do
form.restore!(current_user)
log_activity(form, :form_restored)
counter += 1
rescue StandardError => e
Rails.logger.error e.message
raise ActiveRecord::Rollback
end
end
if counter.positive?
render json: { message: t('forms.restored.success_flash', number: counter) }
else
render json: { message: t('forms.restored.error_flash') }, status: :unprocessable_entity
end
end
def duplicate
ActiveRecord::Base.transaction do
new_form = @form.duplicate!(current_user)
log_activity(new_form, :form_duplicated, { form_old: @form.id })
render json: { message: t('forms.duplicated.success_flash', name: escape_input(@form.name)) }
rescue ActiveRecord::RecordInvalid
render json: { error: new_form.errors.full_messages }, status: :unprocessable_entity
raise ActiveRecord::Rollback
rescue StandardError => e
render json: { message: I18n.t('errors.general') }, status: :unprocessable_entity
Rails.logger.error e.message
raise ActiveRecord::Rollback
end
end
def export_form_responses
FormResponsesZipExportJob.perform_later(
user_id: current_user.id,
params: {
form_id: @form.id
}
)
Activities::CreateActivityService.call(
activity_type: :export_form_responses,
owner: current_user,
subject: @form,
team: @form.team,
message_items: {
form: @form.id
}
)
render json: { message: t('zip_export.export_request_success') }
end
def actions_toolbar
selected_forms = @forms.where(id: JSON.parse(params[:items]).pluck('id'))
render json: {
actions:
Toolbars::FormsService.new(
selected_forms,
current_user
).actions
}
end
private
def set_breadcrumbs_items
archived = params[:view_mode] == 'archived' || @form&.archived?
@breadcrumbs_items = []
@breadcrumbs_items.push(
{ label: t('breadcrumbs.forms'), url: forms_path(view_mode: archived ? 'archived' : nil) }
)
if @form
@breadcrumbs_items.push(
{ label: @form.name, url: form_path(@form) }
)
end
@breadcrumbs_items.each do |item|
item[:label] = "#{t('labels.archived')} #{item[:label]}" if archived
end
end
def load_forms
# Team owners see all forms in the team
@forms = current_team.forms
@forms = @forms.readable_by_user(current_user) unless can_manage_team?(current_team)
end
def load_form
@form = current_team.forms.readable_by_user(current_user).find_by(id: params[:id])
render_404 unless @form
end
def check_create_permissions
render_403 unless can_create_forms?(current_team)
end
def check_manage_permissions
render_403 unless @form && can_manage_form_draft?(@form)
end
def form_params
params.require(:form).permit(:name, :description)
end
def check_forms_enabled
render :promo unless Form.forms_enabled?
end
def log_activity(form, type_of, message_items = {})
Activities::CreateActivityService
.call(activity_type: type_of,
owner: current_user,
team: form.team,
subject: form,
message_items: {
form: form.id,
user: current_user.id
}.merge(message_items))
end
end