initial commit
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
class ApiBaseController < ActionController::API
|
||||
include ActiveStorage::SetCurrent
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
private
|
||||
|
||||
def current_account
|
||||
current_user&.account
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
class AttachmentsController < ApiBaseController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def create
|
||||
submission = Submission.find_by!(slug: params[:submission_slug])
|
||||
blob = ActiveStorage::Blob.find_signed(params[:blob_signed_id])
|
||||
|
||||
attachment = ActiveStorage::Attachment.create!(
|
||||
blob:,
|
||||
name: params[:name],
|
||||
record: submission
|
||||
)
|
||||
|
||||
render json: attachment.as_json(only: %i[uuid], methods: %i[url filename content_type])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
class FlowsController < ApiBaseController
|
||||
def update
|
||||
@flow = current_account.flows.find(params[:id])
|
||||
|
||||
@flow.update!(flow_params)
|
||||
|
||||
render :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def flow_params
|
||||
params.require(:flow).permit(:name,
|
||||
schema: [%i[attachment_uuid name]],
|
||||
fields: [[:uuid, :name, :type, :required,
|
||||
{ options: [], areas: [%i[x y w h attachment_uuid page]] }]])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
class FlowsDocumentsController < ApiBaseController
|
||||
def create
|
||||
@flow = current_account.flows.find(params[:flow_id])
|
||||
|
||||
documents =
|
||||
params[:blobs].map do |blob|
|
||||
blob = ActiveStorage::Blob.find_signed(blob[:signed_id])
|
||||
|
||||
document = @flow.documents.create!(blob:)
|
||||
|
||||
Flows::ProcessDocument.call(document)
|
||||
end
|
||||
|
||||
schema = documents.map do |doc|
|
||||
{ attachment_uuid: doc.uuid, name: doc.filename.base }
|
||||
end
|
||||
|
||||
render json: {
|
||||
schema:,
|
||||
documents: documents.as_json(
|
||||
include: {
|
||||
preview_images: { methods: %i[url metadata filename] }
|
||||
}
|
||||
)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
include ActiveStorage::SetCurrent
|
||||
|
||||
before_action :maybe_redirect_to_setup, unless: :signed_in?
|
||||
before_action :authenticate_user!, unless: :devise_controller?
|
||||
|
||||
helper_method :button_title,
|
||||
:current_account
|
||||
|
||||
private
|
||||
|
||||
def current_account
|
||||
current_user&.account
|
||||
end
|
||||
|
||||
def maybe_redirect_to_setup
|
||||
redirect_to setup_index_path unless User.exists?
|
||||
end
|
||||
|
||||
def button_title(title = 'Submit', disabled_with = 'Submitting...')
|
||||
render_to_string(partial: 'shared/button_title', locals: { title:, disabled_with: })
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DashboardController < ApplicationController
|
||||
def index
|
||||
@flows = current_account.flows.active
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class EmailSettingsController < ApplicationController
|
||||
before_action :load_encrypted_config
|
||||
|
||||
def index; end
|
||||
|
||||
def create
|
||||
if @encrypted_config.update(storage_configs)
|
||||
redirect_to settings_email_index_path, notice: 'Changes have been saved'
|
||||
else
|
||||
render :index, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_encrypted_config
|
||||
@encrypted_config =
|
||||
EncryptedConfig.find_or_initialize_by(account: current_account, key: EncryptedConfig::EMAIL_SMTP_KEY)
|
||||
end
|
||||
|
||||
def storage_configs
|
||||
params.require(:encrypted_config).permit(value: {}).tap do |e|
|
||||
e[:value].compact_blank!
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class FlowsController < ApplicationController
|
||||
def show
|
||||
@flow = current_account.flows.preload(documents_attachments: { preview_images_attachments: :blob })
|
||||
.find(params[:id])
|
||||
end
|
||||
|
||||
def new
|
||||
@flow = current_account.flows.new
|
||||
end
|
||||
|
||||
def create
|
||||
@flow = current_account.flows.new(flow_params)
|
||||
@flow.author = current_user
|
||||
|
||||
if @flow.save
|
||||
redirect_to flow_path(@flow)
|
||||
else
|
||||
render turbo_stream: turbo_stream.replace(:modal, template: 'flows/new'), status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@flow = current_account.flows.find(params[:id])
|
||||
@flow.update!(deleted_at: Time.current)
|
||||
|
||||
redirect_to settings_users_path, notice: 'Flow has been archived.'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def flow_params
|
||||
params.require(:flow).permit(:name, :schema)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class InvitationsController < Devise::PasswordsController
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class RegistrationsController < Devise::RegistrationsController
|
||||
private
|
||||
|
||||
def build_resource(_hash = {})
|
||||
account = Account.new(account_params)
|
||||
|
||||
self.resource = account.users.new(user_params)
|
||||
end
|
||||
|
||||
def user_params
|
||||
return {} if params[:user].blank?
|
||||
|
||||
params.require(:user).permit(:first_name, :last_name, :email, :password)
|
||||
end
|
||||
|
||||
def account_params
|
||||
return {} if params[:account].blank?
|
||||
|
||||
params.require(:account).permit(:name)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SendSubmissionEmailController < ApplicationController
|
||||
layout 'flow'
|
||||
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def success; end
|
||||
|
||||
def create
|
||||
@submission = if params[:flow_slug]
|
||||
Submission.joins(:flow).find_by!(email: params[:email], flow: { slug: params[:flow_slug] })
|
||||
else
|
||||
Submission.find_by!(slug: params[:submission_slug])
|
||||
end
|
||||
|
||||
SubmissionMailer.copy_to_submitter(@submission).deliver_later!
|
||||
|
||||
redirect_to success_send_submission_email_index_path
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SetupController < ApplicationController
|
||||
skip_before_action :maybe_redirect_to_setup
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
before_action :redirect_to_root_if_signed, if: :signed_in?
|
||||
before_action :ensure_first_user_not_created!
|
||||
|
||||
def index
|
||||
@account = Account.new(account_params)
|
||||
@user = @account.users.new(user_params)
|
||||
end
|
||||
|
||||
def create
|
||||
@account = Account.new(account_params)
|
||||
@user = @account.users.new(user_params)
|
||||
|
||||
if @user.save
|
||||
sign_in(@user)
|
||||
|
||||
redirect_to root_path
|
||||
else
|
||||
render :index, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_params
|
||||
return {} unless params[:user]
|
||||
|
||||
params.require(:user).permit(:first_name, :last_name, :email, :password)
|
||||
end
|
||||
|
||||
def account_params
|
||||
return {} unless params[:account]
|
||||
|
||||
params.require(:account).permit(:name)
|
||||
end
|
||||
|
||||
def redirect_to_root_if_signed
|
||||
redirect_to root_path, notice: 'You are already signed in'
|
||||
end
|
||||
|
||||
def ensure_first_user_not_created!
|
||||
redirect_to new_user_session_path, notice: 'Please sign in.' if User.exists?
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class StartFlowController < ApplicationController
|
||||
layout 'flow'
|
||||
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
before_action :load_flow
|
||||
|
||||
def show
|
||||
@submission = @flow.submissions.new
|
||||
end
|
||||
|
||||
def update
|
||||
@submission = @flow.submissions.find_or_initialize_by(
|
||||
deleted_at: nil, **submission_params
|
||||
)
|
||||
|
||||
if @submission.completed_at?
|
||||
redirect_to start_flow_completed_path(@flow.slug, email: submission_params[:email])
|
||||
else
|
||||
@submission.assign_attributes(
|
||||
opened_at: Time.current,
|
||||
ip: request.remote_ip,
|
||||
ua: request.user_agent
|
||||
)
|
||||
|
||||
if @submission.save
|
||||
redirect_to submit_flow_path(@submission.slug)
|
||||
else
|
||||
render :show
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def completed
|
||||
@submission = @flow.submissions.find_by(email: params[:email])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def submission_params
|
||||
params.require(:submission).permit(:email)
|
||||
end
|
||||
|
||||
def load_flow
|
||||
slug = params[:slug] || params[:start_flow_slug]
|
||||
|
||||
@flow = Flow.find_by!(slug:)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class StorageSettingsController < ApplicationController
|
||||
before_action :load_encrypted_config
|
||||
|
||||
def index; end
|
||||
|
||||
def create
|
||||
if @encrypted_config.update(storage_configs)
|
||||
LoadActiveStorageConfigs.reload
|
||||
|
||||
redirect_to settings_storage_index_path, notice: 'Changes have been saved'
|
||||
else
|
||||
render :index, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_encrypted_config
|
||||
@encrypted_config =
|
||||
EncryptedConfig.find_or_initialize_by(account: current_account, key: EncryptedConfig::FILES_STORAGE_KEY)
|
||||
end
|
||||
|
||||
def storage_configs
|
||||
params.require(:encrypted_config).permit(value: {}).tap do |e|
|
||||
e[:value].compact_blank!
|
||||
|
||||
e.dig(:value, :configs)&.compact_blank!
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,50 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SubmissionsController < ApplicationController
|
||||
before_action :load_flow, only: %i[index new create]
|
||||
|
||||
def index
|
||||
@submissions = @flow.submissions.active
|
||||
end
|
||||
|
||||
def show
|
||||
@submission =
|
||||
Submission.joins(:flow).where(flow: { account_id: current_account.id })
|
||||
.preload(flow: { documents_attachments: { preview_images_attachments: :blob } })
|
||||
.find(params[:id])
|
||||
end
|
||||
|
||||
def new; end
|
||||
|
||||
def create
|
||||
emails = params[:emails].to_s.scan(User::EMAIL_REGEXP)
|
||||
|
||||
submissions =
|
||||
emails.map do |email|
|
||||
submission = @flow.submissions.create!(email:, sent_at: params[:send_email] == '1' ? Time.current : nil)
|
||||
|
||||
if params[:send_email] == '1'
|
||||
SubmissionMailer.invitation_email(submission, message: params[:message]).deliver_later!
|
||||
end
|
||||
|
||||
submission
|
||||
end
|
||||
|
||||
redirect_to flow_submissions_path(@flow), notice: "#{submissions.size} recepients added"
|
||||
end
|
||||
|
||||
def destroy
|
||||
submission = Submission.joins(:flow).where(flow: { account_id: current_account.id })
|
||||
.find(params[:id])
|
||||
|
||||
submission.update!(deleted_at: Time.current)
|
||||
|
||||
redirect_to flow_submissions_path(submission.flow), notice: 'Submission has been archieved'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_flow
|
||||
@flow = current_account.flows.find(params[:flow_id])
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SubmissionsDownloadController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def index
|
||||
submission = Submission.find_by(slug: params[:submission_slug])
|
||||
|
||||
Submissions::GenerateResultAttachments.call(submission)
|
||||
|
||||
redirect_to submission.archive.url, allow_other_host: true
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SubmitFlowController < ApplicationController
|
||||
layout 'flow'
|
||||
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
@submission = Submission.preload(flow: { documents_attachments: { preview_images_attachments: :blob } })
|
||||
.find_by!(slug: params[:slug])
|
||||
|
||||
return redirect_to submit_flow_completed_path(@submission.slug) if @submission.completed_at?
|
||||
end
|
||||
|
||||
def update
|
||||
submission = Submission.find_by!(slug: params[:slug])
|
||||
submission.values.merge!(params[:values].to_unsafe_h)
|
||||
submission.completed_at = Time.current if params[:completed] == 'true'
|
||||
|
||||
submission.save
|
||||
|
||||
head :ok
|
||||
end
|
||||
|
||||
def completed
|
||||
@submission = Submission.find_by!(slug: params[:submit_flow_slug])
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class UsersController < ApplicationController
|
||||
before_action :load_user, only: %i[edit update destroy]
|
||||
|
||||
def index
|
||||
@users = current_account.users.active.order(id: :desc)
|
||||
end
|
||||
|
||||
def new
|
||||
@user = current_account.users.new
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
def create
|
||||
@user = current_account.users.find_by(email: user_params[:email])&.tap do |user|
|
||||
user.assign_attributes(user_params)
|
||||
user.deleted_at = nil
|
||||
end
|
||||
|
||||
@user ||= current_account.users.new(user_params)
|
||||
|
||||
if @user.save
|
||||
UserMailer.invitation_email(@user).deliver_later!
|
||||
|
||||
redirect_to settings_users_path, notice: 'User has been invited.'
|
||||
else
|
||||
render turbo_stream: turbo_stream.replace(:modal, template: 'users/new'), status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @user.update(user_params.compact_blank)
|
||||
redirect_to settings_users_path, notice: 'User has been updated.'
|
||||
else
|
||||
render turbo_stream: turbo_stream.replace(:modal, template: 'users/edit'), status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@user.update!(deleted_at: Time.current)
|
||||
|
||||
redirect_to settings_users_path, notice: 'User has been removed.'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_user
|
||||
@user = current_account.users.find(params[:id])
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:email, :first_name, :last_name, :password)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user