diff --git a/.gitignore b/.gitignore
index be639edb..012a440f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,4 @@ yarn-debug.log*
/ee
dump.rdb
.aider*
+.kilocode/*
\ No newline at end of file
diff --git a/app/controllers/api/templates_controller.rb b/app/controllers/api/templates_controller.rb
index d087b980..aed33d35 100644
--- a/app/controllers/api/templates_controller.rb
+++ b/app/controllers/api/templates_controller.rb
@@ -90,66 +90,20 @@ module Api
end
def pdf
- template = Template.new
- template.account = current_account
- template.author = current_user
- template.folder = TemplateFolders.find_or_create_by_name(current_user, params[:folder_name])
- template.name = params[:name] || 'Untitled Template'
- template.external_id = params[:external_id] if params[:external_id].present?
- template.source = :api
-
- # Set submitters if provided
- if params[:submitters].present?
- template.submitters = params[:submitters]
- end
-
- # Set fields if provided
- if params[:fields].present?
- # We'll set fields after documents are processed to ensure correct attachment_uuid mapping
- fields_from_request = params[:fields]
- end
+ template = build_template
+ fields_from_request = params[:fields] if params[:fields].present?
template.save!
begin
documents = process_documents(template, params[:documents])
+ schema = build_schema(documents)
- schema = documents.map { |doc| { attachment_uuid: doc.uuid, name: doc.filename.base } }
-
- if template.fields.blank?
- if fields_from_request.present?
- # Map the fields to use the correct attachment_uuid from the processed documents
- mapped_fields = fields_from_request.map do |field|
- field_copy = field.dup
- if field_copy['areas'].present?
- field_copy['areas'] = field_copy['areas'].map do |area|
- area_copy = area.dup
- # Use the first document's UUID since we're processing one document at a time
- area_copy['attachment_uuid'] = documents.first.uuid if documents.any?
- area_copy
- end
- end
- field_copy
- end
- template.fields = mapped_fields
- else
- template.fields = Templates::ProcessDocument.normalize_attachment_fields(template, documents)
- schema.each { |item| item['pending_fields'] = true } if template.fields.present?
- end
- end
+ set_template_fields(template, fields_from_request, documents, schema) if template.fields.blank?
template.update!(schema: schema)
- enqueue_template_created_webhooks(template)
-
- SearchEntries.enqueue_reindex(template)
-
- # Get the documents for serialization
- template_documents = template.documents.where(uuid: documents.map(&:uuid))
-
- result = Templates::SerializeForApi.call(template, template_documents)
-
- render json: result
+ finalize_template_creation(template, documents)
rescue StandardError => e
template.destroy!
raise e
@@ -166,20 +120,16 @@ module Api
def process_documents(template, documents_params)
return [] if documents_params.blank?
- documents_params.map.with_index do |doc_param, index|
- expected_length = (doc_param[:file].length / 4.0 * 3).ceil
+ documents_params.map.with_index do |doc_param, _index|
+ (doc_param[:file].length / 4.0 * 3).ceil
# Validate base64 string
- unless doc_param[:file].match?(/\A[A-Za-z0-9+\/]*={0,2}\z/)
- raise ArgumentError, "Invalid base64 string format"
- end
+ raise ArgumentError, 'Invalid base64 string format' unless doc_param[:file].match?(%r{\A[A-Za-z0-9+/]*={0,2}\z})
# Decode base64 file data
file_data = Base64.decode64(doc_param[:file])
# Check if the decoded data looks like a PDF
- if file_data.size >= 4
- pdf_header = file_data[0..3]
- end
+ file_data[0..3] if file_data.size >= 4
# Create a temporary file-like object
file = Tempfile.new(['document', '.pdf'])
@@ -199,6 +149,55 @@ module Api
end
end
+ def build_template
+ template = Template.new
+ template.account = current_account
+ template.author = current_user
+ template.folder = TemplateFolders.find_or_create_by_name(current_user, params[:folder_name])
+ template.name = params[:name] || 'Untitled Template'
+ template.external_id = params[:external_id] if params[:external_id].present?
+ template.source = :api
+ template.submitters = params[:submitters] if params[:submitters].present?
+ template
+ end
+
+ def build_schema(documents)
+ documents.map { |doc| { attachment_uuid: doc.uuid, name: doc.filename.base } }
+ end
+
+ def set_template_fields(template, fields_from_request, documents, schema)
+ if fields_from_request.present?
+ template.fields = map_request_fields_to_documents(fields_from_request, documents)
+ else
+ template.fields = Templates::ProcessDocument.normalize_attachment_fields(template, documents)
+ schema.each { |item| item['pending_fields'] = true } if template.fields.present?
+ end
+ end
+
+ def map_request_fields_to_documents(fields_from_request, documents)
+ fields_from_request.map do |field|
+ field_copy = field.dup
+ if field_copy['areas'].present?
+ field_copy['areas'] = field_copy['areas'].map do |area|
+ area_copy = area.dup
+ area_copy['attachment_uuid'] = documents.first.uuid if documents.any?
+ area_copy
+ end
+ end
+ field_copy
+ end
+ end
+
+ def finalize_template_creation(template, documents)
+ enqueue_template_created_webhooks(template)
+ SearchEntries.enqueue_reindex(template)
+
+ template_documents = template.documents.where(uuid: documents.map(&:uuid))
+ result = Templates::SerializeForApi.call(template, template_documents)
+
+ render json: result
+ end
+
def enqueue_template_created_webhooks(template)
WebhookUrls.for_account_id(template.account_id, 'template.created').each do |webhook_url|
SendTemplateCreatedWebhookRequestJob.perform_async('template_id' => template.id,
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index ac32132a..92bf197c 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -111,6 +111,7 @@ class ApplicationController < ActionController::Base
def ensure_demo_user_signed_in
return true if signed_in?
+
user = find_or_create_demo_user
sign_in(user)
true
diff --git a/app/controllers/export_controller.rb b/app/controllers/export_controller.rb
index cf2c1da2..3c5403b9 100644
--- a/app/controllers/export_controller.rb
+++ b/app/controllers/export_controller.rb
@@ -30,5 +30,4 @@ class ExportController < ApplicationController
redirect_to submission, alert: service.error_message
end
end
-
end
diff --git a/app/controllers/templates_dashboard_controller.rb b/app/controllers/templates_dashboard_controller.rb
index 49ddb738..6cb553c1 100644
--- a/app/controllers/templates_dashboard_controller.rb
+++ b/app/controllers/templates_dashboard_controller.rb
@@ -72,9 +72,7 @@ class TemplatesDashboardController < ApplicationController
# Templates.search(current_user, rel, params[:q])
templates = templates.active
- templates = Templates.search(current_user, templates, params[:q])
-
- templates
+ Templates.search(current_user, templates, params[:q])
end
def sort_template_folders(template_folders, current_user, order)
diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue
index 9d5a705d..d60d9e5d 100644
--- a/app/javascript/template_builder/builder.vue
+++ b/app/javascript/template_builder/builder.vue
@@ -57,99 +57,20 @@
:class="{ sticky: withStickySubmitters || isBreakpointLg }"
:style="{ backgroundColor }"
>
-
-
-
+
diff --git a/app/javascript/template_builder/fields.vue b/app/javascript/template_builder/fields.vue
index e657ba3e..9a6efc0d 100644
--- a/app/javascript/template_builder/fields.vue
+++ b/app/javascript/template_builder/fields.vue
@@ -112,7 +112,7 @@
:key="type"
>