diff --git a/app/controllers/submissions_preview_controller.rb b/app/controllers/submissions_preview_controller.rb
new file mode 100644
index 00000000..878dfe26
--- /dev/null
+++ b/app/controllers/submissions_preview_controller.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class SubmissionsPreviewController < ApplicationController
+ skip_before_action :authenticate_user!
+ skip_authorization_check
+
+ PRELOAD_ALL_PAGES_AMOUNT = 200
+
+ def show
+ @submission = Submission.find_by!(slug: params[:slug])
+
+ ActiveRecord::Associations::Preloader.new(
+ records: [@submission],
+ associations: [:template, { template_schema_documents: :blob }]
+ ).call
+
+ total_pages =
+ @submission.template_schema_documents.sum { |e| e.metadata.dig('pdf', 'number_of_pages').to_i }
+
+ if total_pages < PRELOAD_ALL_PAGES_AMOUNT
+ ActiveRecord::Associations::Preloader.new(
+ records: @submission.template_schema_documents,
+ associations: [:blob, { preview_images_attachments: :blob }]
+ ).call
+ end
+
+ render 'submissions/show', layout: 'plain'
+ end
+end
diff --git a/app/models/account_config.rb b/app/models/account_config.rb
index 9d7c6b21..b592cbca 100644
--- a/app/models/account_config.rb
+++ b/app/models/account_config.rb
@@ -49,7 +49,7 @@ class AccountConfig < ApplicationRecord
'body' => "Hi there,\n\n" \
"Please check the copy of your \"{{template.name}}\" submission in the email attachments.\n" \
"Alternatively, you can download your copy using:\n\n" \
- "{{documents.links}}\n\n" \
+ "{{documents.link}}\n\n" \
"Thanks,\n" \
'{{account.name}}'
}
diff --git a/app/models/submission.rb b/app/models/submission.rb
index 5ce02367..e240c774 100644
--- a/app/models/submission.rb
+++ b/app/models/submission.rb
@@ -6,6 +6,7 @@
#
# id :bigint not null, primary key
# deleted_at :datetime
+# slug :string not null
# source :text not null
# submitters_order :string not null
# template_fields :text
@@ -19,6 +20,7 @@
# Indexes
#
# index_submissions_on_created_by_user_id (created_by_user_id)
+# index_submissions_on_slug (slug) UNIQUE
# index_submissions_on_template_id (template_id)
#
# Foreign Keys
@@ -41,6 +43,8 @@ class Submission < ApplicationRecord
attribute :source, :string, default: 'link'
attribute :submitters_order, :string, default: 'random'
+ attribute :slug, :string, default: -> { SecureRandom.base58(14) }
+
has_one_attached :audit_trail
has_many :template_schema_documents,
diff --git a/app/views/submissions/show.html.erb b/app/views/submissions/show.html.erb
index ad198a43..ccb757da 100644
--- a/app/views/submissions/show.html.erb
+++ b/app/views/submissions/show.html.erb
@@ -61,7 +61,7 @@
<% fields_index.dig(document.uuid, index)&.each do |(area, field)| %>
<% value = values[field['uuid']] %>
<% next if value.blank? %>
- <%= render 'submissions/value', area:, field:, attachments_index:, value:, locale: current_account.locale %>
+ <%= render 'submissions/value', area:, field:, attachments_index:, value:, locale: @submission.template.account.locale %>
<% end %>
@@ -109,18 +109,18 @@
<%= svg_icon('writing', class: 'w-5 h-5') %>
- <%= submitter&.completed_at? ? l(submitter.completed_at.in_time_zone(current_account.timezone), format: :long, locale: current_account.locale) : 'Not completed yet' %>
+ <%= submitter&.completed_at? ? l(submitter.completed_at.in_time_zone(@submission.template.account.timezone), format: :long, locale: @submission.template.account.locale) : 'Not completed yet' %>
- <% if submitter && submitter.email && !submitter.completed_at && can?(:update, submitter) %>
+ <% if signed_in? && submitter && submitter.email && !submitter.completed_at && can?(:update, submitter) %>
<%= button_to button_title(title: submitter.sent_at? ? 'Re-send Email' : 'Send Email', disabled_with: 'Sending'), submitter_send_email_index_path(submitter_slug: submitter.slug), class: 'btn btn-sm btn-primary w-full' %>
<% end %>
- <% if submitter && submitter.phone && !submitter.completed_at && can?(:update, submitter) %>
+ <% if signed_in? && submitter && submitter.phone && !submitter.completed_at && can?(:update, submitter) %>
<%= render 'send_sms_button', submitter: %>
<% end %>
- <% if submitter && !submitter.completed_at? && can?(:create, submitter) %>
+ <% if signed_in? && submitter && !submitter.completed_at? && can?(:create, submitter) %>
Submit Form
@@ -160,7 +160,7 @@
<% elsif field['type'] == 'checkbox' %>
<%= svg_icon('check', class: 'w-6 h-6') %>
<% elsif field['type'] == 'date' %>
- <%= l(Date.parse(value), locale: current_account.locale, format: :long) %>
+ <%= l(Date.parse(value), locale: @submission.template.account.locale, format: :long) %>
<% else %>
<%= Array.wrap(value).join(', ') %>
<% end %>
diff --git a/app/views/submitter_mailer/documents_copy_email.html.erb b/app/views/submitter_mailer/documents_copy_email.html.erb
index 931d2aba..ac438e76 100644
--- a/app/views/submitter_mailer/documents_copy_email.html.erb
+++ b/app/views/submitter_mailer/documents_copy_email.html.erb
@@ -3,14 +3,10 @@
<% else %>
Hi there,
Please check the copy of your "<%= @submitter.submission.template.name %>" submission in the email attachments.
- Alternatively, you can download your copy using:
- <% @documents.each do |document| %>
-
- -
- <%= link_to document.filename.to_s, rails_blob_url(document) %>
-
-
- <% end %>
+ Alternatively, you can review and download your copy using:
+
+ <%= link_to @submitter.template.name, submissions_preview_url(@submitter.submission.slug) %>
+
Thanks,
<%= @current_account.name %>
diff --git a/config/routes.rb b/config/routes.rb
index d4fb5a91..cc6fb5c0 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -80,6 +80,8 @@ Rails.application.routes.draw do
get :completed
end
+ resources :submissions_preview, only: %i[show], path: 'e', param: 'slug'
+
resources :send_submission_email, only: %i[create] do
get :success, on: :collection
end
diff --git a/db/migrate/20231119222105_add_slug_to_submissions.rb b/db/migrate/20231119222105_add_slug_to_submissions.rb
new file mode 100644
index 00000000..53651def
--- /dev/null
+++ b/db/migrate/20231119222105_add_slug_to_submissions.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class AddSlugToSubmissions < ActiveRecord::Migration[7.0]
+ class MigrationSubmission < ApplicationRecord
+ self.table_name = 'submissions'
+ end
+
+ def up
+ add_column :submissions, :slug, :string
+
+ MigrationSubmission.where(slug: nil).find_each do |submission|
+ submission.update_columns(slug: SecureRandom.base58(14))
+ end
+
+ change_column_null :submissions, :slug, false
+
+ add_index :submissions, :slug, unique: true
+ end
+
+ def down
+ remove_column :submissions, :slug
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index ce043569..b01abe1f 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2023_11_12_224432) do
+ActiveRecord::Schema[7.0].define(version: 2023_11_19_222105) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -124,7 +124,9 @@ ActiveRecord::Schema[7.0].define(version: 2023_11_12_224432) do
t.text "template_submitters"
t.text "source", null: false
t.string "submitters_order", null: false
+ t.string "slug", null: false
t.index ["created_by_user_id"], name: "index_submissions_on_created_by_user_id"
+ t.index ["slug"], name: "index_submissions_on_slug", unique: true
t.index ["template_id"], name: "index_submissions_on_template_id"
end
diff --git a/lib/replace_email_variables.rb b/lib/replace_email_variables.rb
index 5c721cf8..a6035a5a 100644
--- a/lib/replace_email_variables.rb
+++ b/lib/replace_email_variables.rb
@@ -9,6 +9,7 @@ module ReplaceEmailVariables
SUBMISSION_LINK = '{{submission.link}}'
SUBMISSION_SUBMITTERS = '{{submission.submitters}}'
DOCUMENTS_LINKS = '{{documents.links}}'
+ DOCUMENTS_LINK = '{{documents.link}}'
module_function
@@ -26,6 +27,7 @@ module ReplaceEmailVariables
text = text.gsub(SUBMISSION_SUBMITTERS, build_submission_submitters(submitter.submission))
end
text = text.gsub(DOCUMENTS_LINKS, build_documents_links_text(submitter))
+ text = text.gsub(DOCUMENTS_LINK, build_documents_links_text(submitter))
text = text.gsub(ACCOUNT_NAME, submitter.template.account.name) if submitter.template
@@ -33,14 +35,9 @@ module ReplaceEmailVariables
end
def build_documents_links_text(submitter)
- Submitters.select_attachments_for_download(submitter).map do |document|
- link =
- Rails.application.routes.url_helpers.rails_blob_url(
- document, **Docuseal.default_url_options
- )
-
- "#{link}\n"
- end.join
+ Rails.application.routes.url_helpers.submissions_preview_url(
+ submitter.submission.slug, **Docuseal.default_url_options
+ )
end
def build_submitter_link(submitter, tracking_event_type)
diff --git a/lib/submissions/generate_audit_trail.rb b/lib/submissions/generate_audit_trail.rb
index dd84dbeb..1cdd8499 100644
--- a/lib/submissions/generate_audit_trail.rb
+++ b/lib/submissions/generate_audit_trail.rb
@@ -107,7 +107,7 @@ module Submissions
"\n",
{ text: 'Generated at: ', font: [FONT_BOLD_NAME, { variant: :bold }] },
"#{I18n.l(document.created_at.in_time_zone(account.timezone), format: :long, locale: account.locale)} " \
- "#{timezone_abbr(account.timezone, document.created_at)}"
+ "#{TimeUtils.timezone_abbr(account.timezone, document.created_at)}"
], line_spacing: 1.8
)
]
@@ -232,7 +232,7 @@ module Submissions
submitter = submission.submitters.find { |e| e.id == event.submitter_id }
[
"#{I18n.l(event.event_timestamp.in_time_zone(account.timezone), format: :long, locale: account.locale)} " \
- "#{timezone_abbr(account.timezone, event.event_timestamp)}",
+ "#{TimeUtils.timezone_abbr(account.timezone, event.event_timestamp)}",
composer.document.layout.formatted_text_box(
[
{ text: SubmissionEvents::EVENT_NAMES[event.event_type.to_sym],
@@ -268,14 +268,6 @@ module Submissions
)
end
- def timezone_abbr(timezone, time = Time.current)
- tz_info = TZInfo::Timezone.get(
- ActiveSupport::TimeZone::MAPPING[timezone] || timezone || 'UTC'
- )
-
- tz_info.abbreviation(time)
- end
-
def add_logo(column)
column.image(PdfIcons.logo_io, width: 40, height: 40, position: :float)
diff --git a/lib/time_utils.rb b/lib/time_utils.rb
new file mode 100644
index 00000000..c708ead5
--- /dev/null
+++ b/lib/time_utils.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module TimeUtils
+ module_function
+
+ def timezone_abbr(timezone, time = Time.current)
+ tz_info = TZInfo::Timezone.get(
+ ActiveSupport::TimeZone::MAPPING[timezone] || timezone || 'UTC'
+ )
+
+ tz_info.abbreviation(time)
+ end
+end
diff --git a/spec/system/submission_preview_spec.rb b/spec/system/submission_preview_spec.rb
new file mode 100644
index 00000000..aea89e3b
--- /dev/null
+++ b/spec/system/submission_preview_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Submission Preview' do
+ let(:account) { create(:account) }
+ let(:user) { create(:user, account:) }
+ let(:template) { create(:template, account:, author: user) }
+
+ context 'when not submitted' do
+ let(:submission) { create(:submission, template:, created_by_user: user) }
+ let(:submitters) { template.submitters.map { |s| create(:submitter, submission:, uuid: s['uuid']) } }
+
+ before do
+ visit submissions_preview_path(slug: submission.slug)
+ end
+
+ it 'completes the form' do
+ expect(page).to have_content('Not completed')
+ end
+ end
+end