diff --git a/app/controllers/api/api_base_controller.rb b/app/controllers/api/api_base_controller.rb index 57e3d216..d85692bc 100644 --- a/app/controllers/api/api_base_controller.rb +++ b/app/controllers/api/api_base_controller.rb @@ -3,6 +3,12 @@ module Api class ApiBaseController < ActionController::API include ActiveStorage::SetCurrent + include Pagy::Backend + + DEFAULT_LIMIT = 10 + MAX_LIMIT = 100 + + wrap_parameters false before_action :authenticate_user! check_authorization @@ -17,6 +23,16 @@ module Api private + def paginate(relation) + result = relation.order(id: :desc) + .limit([params[:limit] || DEFAULT_LIMIT, MAX_LIMIT].min) + + result = result.where('id < ?', params[:after]) if params[:after].present? + result = result.where('id > ?', params[:before]) if params[:before].present? + + result + end + def current_account current_user&.account end diff --git a/app/controllers/api/submissions_controller.rb b/app/controllers/api/submissions_controller.rb index 30b85625..14abd825 100644 --- a/app/controllers/api/submissions_controller.rb +++ b/app/controllers/api/submissions_controller.rb @@ -2,12 +2,52 @@ module Api class SubmissionsController < ApiBaseController - load_and_authorize_resource :template + load_and_authorize_resource :template, only: :create + load_and_authorize_resource :submission, only: %i[show index] - before_action do + before_action only: :create do authorize!(:create, Submission) end + def index + submissions = Submissions.search(@submissions, params[:q]) + submissions = submissions.where(template_id: params[:template_id]) if params[:template_id].present? + + submissions = paginate(submissions.preload(:created_by_user, :template, :submitters)) + + render json: { + data: submissions.as_json(serialize_params), + pagination: { + count: submissions.size, + next: submissions.last&.id, + prev: submissions.first&.id + } + } + end + + def show + serialized_subbmitters = + @submission.submitters.preload(documents_attachments: :blob, attachments_attachments: :blob).map do |submitter| + Submissions::EnsureResultGenerated.call(submitter) if submitter.completed_at? + + Submitters::SerializeForApi.call(submitter) + end + + json = @submission.as_json( + serialize_params.deep_merge( + include: { + submission_events: { + only: %i[id submitter_id event_type event_timestamp] + } + } + ) + ) + + json[:submitters] = serialized_subbmitters + + render json: + end + def create is_send_email = !params[:send_email].in?(['false', false]) @@ -42,8 +82,28 @@ module Api render json: { error: e.message }, status: :unprocessable_entity end + def destroy + @submission.update!(deleted_at: Time.current) + + render json: @submission.as_json(only: %i[id deleted_at]) + end + private + def serialize_params + { + only: %i[id source submitters_order created_at updated_at], + include: { + submitters: { only: %i[id slug uuid name email phone + completed_at opened_at sent_at + created_at updated_at], + methods: %i[status] }, + template: { only: %i[id name created_at updated_at] }, + created_by_user: { only: %i[id email first_name last_name] } + } + } + end + def submissions_params params.permit(submission: [{ submitters: [[:uuid, :name, :email, :role, :completed, :phone, { values: {} }]] diff --git a/app/controllers/api/submitters_controller.rb b/app/controllers/api/submitters_controller.rb new file mode 100644 index 00000000..03a21fdd --- /dev/null +++ b/app/controllers/api/submitters_controller.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Api + class SubmittersController < ApiBaseController + load_and_authorize_resource :submitter + + def show + Submissions::EnsureResultGenerated.call(@submitter) if @submitter.completed_at? + + render json: Submitters::SerializeForApi.call(@submitter, with_template: true, with_events: true) + end + end +end diff --git a/app/controllers/api/templates_controller.rb b/app/controllers/api/templates_controller.rb index ef4a1e33..98815000 100644 --- a/app/controllers/api/templates_controller.rb +++ b/app/controllers/api/templates_controller.rb @@ -5,22 +5,51 @@ module Api load_and_authorize_resource :template def index - render json: @templates + templates = Templates.search(@templates, params[:q]) + + templates = params[:archived] ? templates.archived : templates.active + + templates = paginate(templates.preload(:author, documents_attachments: :blob)) + + render json: { + data: templates.as_json(serialize_params), + pagination: { + count: templates.size, + next: templates.last&.id, + prev: templates.first&.id + } + } end def show - render json: @template.as_json(include: { author: { only: %i[id email first_name last_name] }, - documents: { only: %i[id uuid], methods: %i[url filename] } }) + render json: @template.as_json(serialize_params) end def update + if (folder_name = params.dig(:template, :folder_name)) + @template.folder = TemplateFolders.find_or_create_by_name(current_user, folder_name) + end + @template.update!(template_params) - render :ok + render json: @template.as_json(only: %i[id updated_at]) + end + + def destroy + @template.update!(deleted_at: Time.current) + + render json: @template.as_json(only: %i[id deleted_at]) end private + def serialize_params + { + include: { author: { only: %i[id email first_name last_name] }, + documents: { only: %i[id uuid], methods: %i[url filename] } } + } + end + def template_params params.require(:template).permit(:name, schema: [%i[attachment_uuid name]], diff --git a/app/models/template.rb b/app/models/template.rb index 2168689d..e1d4fbb9 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -58,6 +58,7 @@ class Template < ApplicationRecord has_many :submissions, dependent: :destroy scope :active, -> { where(deleted_at: nil) } + scope :archived, -> { where.not(deleted_at: nil) } private diff --git a/app/views/api_settings/index.html.erb b/app/views/api_settings/index.html.erb index e8530140..aff07684 100644 --- a/app/views/api_settings/index.html.erb +++ b/app/views/api_settings/index.html.erb @@ -16,7 +16,7 @@