Merge from docusealco/wip
This commit is contained in:
@@ -34,6 +34,8 @@ module Api
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
rescue HexaPDF::MalformedPDFError
|
||||||
|
render json: { error: 'Malformed PDF' }, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class ApplicationController < ActionController::Base
|
|||||||
redirect_to request.referer, alert: 'Too many requests', status: :too_many_requests
|
redirect_to request.referer, alert: 'Too many requests', status: :too_many_requests
|
||||||
end
|
end
|
||||||
|
|
||||||
if Rails.env.production?
|
if Rails.env.production? || Rails.env.test?
|
||||||
rescue_from CanCan::AccessDenied do |e|
|
rescue_from CanCan::AccessDenied do |e|
|
||||||
Rollbar.warning(e) if defined?(Rollbar)
|
Rollbar.warning(e) if defined?(Rollbar)
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ class SendSubmissionEmailController < ApplicationController
|
|||||||
|
|
||||||
SEND_DURATION = 30.minutes
|
SEND_DURATION = 30.minutes
|
||||||
|
|
||||||
def success; end
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@submitter =
|
@submitter =
|
||||||
if params[:template_slug]
|
if params[:template_slug]
|
||||||
@@ -31,7 +29,7 @@ class SendSubmissionEmailController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
respond_to do |f|
|
respond_to do |f|
|
||||||
f.html { redirect_to success_send_submission_email_index_path }
|
f.html { render :success }
|
||||||
f.json { head :ok }
|
f.json { head :ok }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ class SubmissionsPreviewController < ApplicationController
|
|||||||
|
|
||||||
def completed
|
def completed
|
||||||
@submission = Submission.find_by!(slug: params[:submissions_preview_slug])
|
@submission = Submission.find_by!(slug: params[:submissions_preview_slug])
|
||||||
|
@template = @submission.template
|
||||||
|
|
||||||
render :completed, layout: 'form'
|
render :completed, layout: 'form'
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -28,8 +28,10 @@ class TemplatesPreferencesController < ApplicationController
|
|||||||
submitters_order
|
submitters_order
|
||||||
completed_notification_email_subject completed_notification_email_body
|
completed_notification_email_subject completed_notification_email_body
|
||||||
completed_notification_email_enabled completed_notification_email_attach_audit] +
|
completed_notification_email_enabled completed_notification_email_attach_audit] +
|
||||||
[completed_message: %i[title body]]
|
[completed_message: %i[title body],
|
||||||
|
submitters: [%i[uuid request_email_subject request_email_body]]]
|
||||||
).tap do |attrs|
|
).tap do |attrs|
|
||||||
|
attrs[:preferences].delete(:submitters) if params[:request_email_per_submitter] != '1'
|
||||||
attrs[:preferences] = attrs[:preferences].transform_values do |value|
|
attrs[:preferences] = attrs[:preferences].transform_values do |value|
|
||||||
if %w[true false].include?(value)
|
if %w[true false].include?(value)
|
||||||
value == 'true'
|
value == 'true'
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ export default class extends HTMLElement {
|
|||||||
this.resize()
|
this.resize()
|
||||||
|
|
||||||
this.textarea.addEventListener('input', () => this.resize())
|
this.textarea.addEventListener('input', () => this.resize())
|
||||||
|
|
||||||
|
this.observeVisibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
resize () {
|
resize () {
|
||||||
@@ -11,6 +13,28 @@ export default class extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
observeVisibility () {
|
||||||
|
this.observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
this.resize()
|
||||||
|
this.observer.unobserve(this.textarea)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
threshold: 0.1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
this.observer.observe(this.textarea)
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback () {
|
||||||
|
this.observer.unobserve(this.textarea)
|
||||||
|
}
|
||||||
|
|
||||||
get textarea () {
|
get textarea () {
|
||||||
return this.querySelector('textarea')
|
return this.querySelector('textarea')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
class="field-area flex absolute lg:text-base -outline-offset-1"
|
class="field-area flex absolute lg:text-base -outline-offset-1"
|
||||||
dir="auto"
|
dir="auto"
|
||||||
:style="computedStyle"
|
:style="computedStyle"
|
||||||
:class="{ 'font-serif': field.preferences?.font === 'Times', 'text-[1.6vw] lg:text-base': !textOverflowChars, 'text-[1.0vw] lg:text-xs': textOverflowChars, 'cursor-default': !submittable, 'border border-red-100 bg-red-100 cursor-pointer': submittable, 'border border-red-100': !isActive && submittable, 'bg-opacity-80': !isActive && !isValueSet && submittable, 'field-area-active outline-red-500 outline-dashed outline-2 z-10': isActive && submittable, 'bg-opacity-40': (isActive || isValueSet) && submittable }"
|
:class="{ 'font-mono': field.preferences?.font === 'Courier', 'font-serif': field.preferences?.font === 'Times', 'text-[1.6vw] lg:text-base': !textOverflowChars, 'text-[1.0vw] lg:text-xs': textOverflowChars, 'cursor-default': !submittable, 'border border-red-100 bg-red-100 cursor-pointer': submittable, 'border border-red-100': !isActive && submittable, 'bg-opacity-80': !isActive && !isValueSet && submittable, 'field-area-active outline-red-500 outline-dashed outline-2 z-10': isActive && submittable, 'bg-opacity-40': (isActive || isValueSet) && submittable }"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="(!withFieldPlaceholder || !field.name || field.type === 'cells') && !isActive && !isValueSet && field.type !== 'checkbox' && submittable && !area.option_uuid"
|
v-if="(!withFieldPlaceholder || !field.name || field.type === 'cells') && !isActive && !isValueSet && field.type !== 'checkbox' && submittable && !area.option_uuid"
|
||||||
|
|||||||
@@ -100,7 +100,8 @@
|
|||||||
<button
|
<button
|
||||||
v-if="!isCompleted"
|
v-if="!isCompleted"
|
||||||
id="minimize_form_button"
|
id="minimize_form_button"
|
||||||
class="absolute right-0 mr-2 mt-2 top-0 hidden md:block"
|
class="absolute right-0 top-0"
|
||||||
|
:class="currentField?.description?.length > 100 ? 'mr-1 mt-1 md:mr-2 md:mt-2': 'mr-2 mt-2 hidden md:block'"
|
||||||
:title="t('minimize')"
|
:title="t('minimize')"
|
||||||
@click.prevent="minimizeForm"
|
@click.prevent="minimizeForm"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1401,7 +1401,6 @@ export default {
|
|||||||
const lastArea = field.areas[field.areas.length - 1]
|
const lastArea = field.areas[field.areas.length - 1]
|
||||||
|
|
||||||
if (lastArea) {
|
if (lastArea) {
|
||||||
fieldArea.x -= lastArea.w / 2
|
|
||||||
fieldArea.w = lastArea.w
|
fieldArea.w = lastArea.w
|
||||||
fieldArea.h = lastArea.h
|
fieldArea.h = lastArea.h
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,20 @@ class SubmitterMailer < ApplicationMailer
|
|||||||
@email_message = submitter.account.email_messages.find_by(uuid: submitter.preferences['email_message_uuid'])
|
@email_message = submitter.account.email_messages.find_by(uuid: submitter.preferences['email_message_uuid'])
|
||||||
end
|
end
|
||||||
|
|
||||||
@body = @email_message&.body.presence || @submitter.template.preferences['request_email_body'].presence
|
template_submitters_index =
|
||||||
@subject = @email_message&.subject.presence || @submitter.template.preferences['request_email_subject'].presence
|
if @email_message.blank?
|
||||||
|
build_submitter_preferences_index(@submitter)
|
||||||
|
else
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
|
||||||
|
@body = @email_message&.body.presence ||
|
||||||
|
template_submitters_index.dig(@submitter.uuid, 'request_email_body').presence ||
|
||||||
|
@submitter.template.preferences['request_email_body'].presence
|
||||||
|
|
||||||
|
@subject = @email_message&.subject.presence ||
|
||||||
|
template_submitters_index.dig(@submitter.uuid, 'request_email_subject').presence ||
|
||||||
|
@submitter.template.preferences['request_email_subject'].presence
|
||||||
|
|
||||||
@email_config = AccountConfigs.find_for_account(@current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY)
|
@email_config = AccountConfigs.find_for_account(@current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY)
|
||||||
|
|
||||||
@@ -24,14 +36,7 @@ class SubmitterMailer < ApplicationMailer
|
|||||||
reply_to = build_submitter_reply_to(@submitter)
|
reply_to = build_submitter_reply_to(@submitter)
|
||||||
|
|
||||||
I18n.with_locale(@current_account.locale) do
|
I18n.with_locale(@current_account.locale) do
|
||||||
subject =
|
subject = build_invite_subject(@subject, @email_config, submitter)
|
||||||
if @email_config || @subject
|
|
||||||
ReplaceEmailVariables.call(@subject || @email_config.value['subject'], submitter:)
|
|
||||||
elsif @submitter.with_signature_fields?
|
|
||||||
I18n.t(:you_are_invited_to_sign_a_document)
|
|
||||||
else
|
|
||||||
I18n.t(:you_are_invited_to_submit_a_form)
|
|
||||||
end
|
|
||||||
|
|
||||||
mail(
|
mail(
|
||||||
to: @submitter.friendly_name,
|
to: @submitter.friendly_name,
|
||||||
@@ -196,6 +201,20 @@ class SubmitterMailer < ApplicationMailer
|
|||||||
user.role == 'integration' ? user.friendly_name.sub(/\+\w+@/, '@') : user.friendly_name
|
user.role == 'integration' ? user.friendly_name.sub(/\+\w+@/, '@') : user.friendly_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def build_invite_subject(subject, email_config, submitter)
|
||||||
|
if email_config || subject
|
||||||
|
ReplaceEmailVariables.call(subject || email_config.value['subject'], submitter:)
|
||||||
|
elsif submitter.with_signature_fields?
|
||||||
|
I18n.t(:you_are_invited_to_sign_a_document)
|
||||||
|
else
|
||||||
|
I18n.t(:you_are_invited_to_submit_a_form)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_submitter_preferences_index(submitter)
|
||||||
|
submitter.template.preferences['submitters'].to_a.index_by { |e| e['uuid'] }
|
||||||
|
end
|
||||||
|
|
||||||
def add_attachments_with_size_limit(submitter, storage_attachments, current_size, filename_format = nil)
|
def add_attachments_with_size_limit(submitter, storage_attachments, current_size, filename_format = nil)
|
||||||
total_size = current_size
|
total_size = current_size
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="<%= local_assigns[:class] %>" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" width="24" height="24" stroke-width="2">
|
||||||
|
<path d="M3 9l9 6l9 -6l-9 -6l-9 6"></path>
|
||||||
|
<path d="M21 9v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10"></path>
|
||||||
|
<path d="M3 19l6 -6"></path>
|
||||||
|
<path d="M15 13l6 6"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 401 B |
@@ -2,7 +2,7 @@
|
|||||||
<div class="space-y-6 mx-auto">
|
<div class="space-y-6 mx-auto">
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
<%= render 'start_form/docuseal_logo' %>
|
<%= render 'start_form/banner' %>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center text-4xl font-bold">
|
<div class="text-center text-4xl font-bold">
|
||||||
<%= t('email_has_been_sent') %>
|
<%= t('email_has_been_sent') %>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<% submitter_preferences_index = template.preferences['submitters'].to_a.index_by { |e| e['uuid'] } %>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<% can_send_emails = Accounts.can_send_emails?(current_account) %>
|
<% can_send_emails = Accounts.can_send_emails?(current_account) %>
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
@@ -36,10 +37,18 @@
|
|||||||
<% config = AccountConfigs.find_or_initialize_for_key(current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY) %>
|
<% config = AccountConfigs.find_or_initialize_for_key(current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY) %>
|
||||||
<div id="message_field" class="card card-compact bg-base-300/40 hidden">
|
<div id="message_field" class="card card-compact bg-base-300/40 hidden">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="form-control space-y-2">
|
<%= tag.input id: 'request_email_per_submitter', value: '1', name: 'request_email_per_submitter', class: 'peer', type: 'checkbox', hidden: true, checked: local_assigns[:message_per_submitter] != false && template.preferences['submitters'].to_a.size > 1 %>
|
||||||
|
<div class="peer-checked:hidden form-control space-y-2">
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<%= f.label :subject, t('subject'), class: 'label' %>
|
<div class="flex justify-between">
|
||||||
<%= f.text_field :subject, value: local_assigns[:submitter_email_message]&.subject.presence || template.preferences['request_email_subject'].presence || config.value['subject'], required: true, class: '!text-sm base-input w-full', dir: 'auto' %>
|
<%= f.label :subject, t('subject'), class: 'label' %>
|
||||||
|
<% if template.submitters.size > 1 && template.submitters.size < 5 && local_assigns[:message_per_submitter] != false %>
|
||||||
|
<label for="request_email_per_submitter" class="label underline">
|
||||||
|
<%= t('edit_per_party') %>
|
||||||
|
</label>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<%= f.text_field :subject, value: local_assigns[:submitter_email_message]&.subject.presence || submitter_preferences_index.dig(local_assigns[:submitter]&.uuid, 'request_email_subject').presence || template.preferences['request_email_subject'].presence || config.value['subject'], required: true, class: '!text-sm base-input w-full', dir: 'auto' %>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@@ -49,7 +58,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<autoresize-textarea>
|
<autoresize-textarea>
|
||||||
<%= f.text_area :body, value: local_assigns[:submitter_email_message]&.body.presence || template.preferences['request_email_body'].presence || config.value['body'], required: true, class: 'base-textarea w-full', rows: 10, dir: 'auto' %>
|
<%= f.text_area :body, value: local_assigns[:submitter_email_message]&.body.presence || submitter_preferences_index.dig(local_assigns[:submitter]&.uuid, 'request_email_body').presence || template.preferences['request_email_body'].presence || config.value['body'], required: true, class: 'base-textarea w-full', rows: 10, dir: 'auto' %>
|
||||||
</autoresize-textarea>
|
</autoresize-textarea>
|
||||||
<% unless local_assigns.fetch(:disable_save_as_default_template_option, false) %>
|
<% unless local_assigns.fetch(:disable_save_as_default_template_option, false) %>
|
||||||
<label for="<%= uuid = SecureRandom.uuid %>" class="flex items-center cursor-pointer">
|
<label for="<%= uuid = SecureRandom.uuid %>" class="flex items-center cursor-pointer">
|
||||||
@@ -60,5 +69,43 @@
|
|||||||
</div>
|
</div>
|
||||||
<%= render 'submissions/message_fields' %>
|
<%= render 'submissions/message_fields' %>
|
||||||
</div>
|
</div>
|
||||||
|
<% if template.submitters.size > 1 && template.submitters.size < 5 && local_assigns[:message_per_submitter] != false %>
|
||||||
|
<div class="hidden peer-checked:block form-control space-y-2">
|
||||||
|
<% options = template.submitters.map { |e| [e['name'], "request_email_#{e['uuid']}"] } %>
|
||||||
|
<toggle-visible data-element-ids="<%= options.map(&:last).to_json %>" class="flex relative px-1">
|
||||||
|
<ul class="tabs w-full flex flex-nowrap">
|
||||||
|
<% options.each_with_index do |(label, val), index| %>
|
||||||
|
<div class="w-full">
|
||||||
|
<%= f.radio_button :selected, val, checked: index.zero?, id: "#{val}_radio", data: { action: 'click:toggle-visible#trigger' }, class: 'hidden peer' %>
|
||||||
|
<%= f.label :selected, label, value: val, for: "#{val}_radio", class: 'tab w-full tab-lifted peer-checked:tab-active !bg-transparent' %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</toggle-visible>
|
||||||
|
<% template.submitters.each_with_index do |submitter, index| %>
|
||||||
|
<%= fields_for :submitter_preferences, nil, index: submitter['uuid'] do |ff| %>
|
||||||
|
<div id="request_email_<%= submitter['uuid'] %>" class="<%= 'hidden' if index != 0 %>">
|
||||||
|
<div class="form-control">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<%= ff.label :subject, t('subject'), class: 'label' %>
|
||||||
|
</div>
|
||||||
|
<%= ff.text_field :subject, value: local_assigns[:submitter_email_message]&.subject.presence || submitter_preferences_index.dig(submitter['uuid'], 'request_email_subject').presence || template.preferences['request_email_subject'].presence || config.value['subject'], required: true, class: '!text-sm base-input w-full', dir: 'auto' %>
|
||||||
|
</div>
|
||||||
|
<div class="form-control">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= ff.label :message, t('body'), class: 'label' %>
|
||||||
|
<span class="tooltip tooltip-right" data-tip="<%= t('use_following_placeholders_text_') %> <%= AccountConfig::DEFAULT_VALUES[AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY].call['body'].scan(/{.*?}/).join(', ') %>">
|
||||||
|
<%= svg_icon('info_circle', class: 'w-4 h-4') %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<autoresize-textarea>
|
||||||
|
<%= ff.text_area :body, value: local_assigns[:submitter_email_message]&.body.presence || submitter_preferences_index.dig(submitter['uuid'], 'request_email_body').presence || template.preferences['request_email_body'].presence || config.value['body'], required: true, class: 'base-textarea w-full', rows: 10, dir: 'auto' %>
|
||||||
|
</autoresize-textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<% align = field.dig('preferences', 'align') %>
|
<% align = field.dig('preferences', 'align') %>
|
||||||
<% color = field.dig('preferences', 'color') %>
|
<% color = field.dig('preferences', 'color') %>
|
||||||
<field-value dir="auto" class="flex absolute text-[1.6vw] lg:text-base <%= 'font-serif' if field.dig('preferences', 'font') == 'Times' %> <%= align == 'right' ? 'justify-end' : (align == 'center' ? 'justify-center' : '') %>" style="<%= "color: #{color}; " if color.present? %>width: <%= area['w'] * 100 %>%; height: <%= area['h'] * 100 %>%; left: <%= area['x'] * 100 %>%; top: <%= area['y'] * 100 %>%; <%= "font-size: clamp(4pt, 1.6vw, #{field['preferences']['font_size'].to_i * 1.23}pt); line-height: `clamp(6pt, 2.0vw, #{(field['preferences']['font_size'].to_i * 1.23) + 3}pt)`" if field.dig('preferences', 'font_size') %>">
|
<% font = field.dig('preferences', 'font') %>
|
||||||
|
<field-value dir="auto" class="flex absolute text-[1.6vw] lg:text-base <%= 'font-mono' if font == 'Courier' %> <%= 'font-serif' if font == 'Times' %> <%= align == 'right' ? 'justify-end' : (align == 'center' ? 'justify-center' : '') %>" style="<%= "color: #{color}; " if color.present? %>width: <%= area['w'] * 100 %>%; height: <%= area['h'] * 100 %>%; left: <%= area['x'] * 100 %>%; top: <%= area['y'] * 100 %>%; <%= "font-size: clamp(4pt, 1.6vw, #{field['preferences']['font_size'].to_i * 1.23}pt); line-height: `clamp(6pt, 2.0vw, #{(field['preferences']['font_size'].to_i * 1.23) + 3}pt)`" if field.dig('preferences', 'font_size') %>">
|
||||||
<% if field['type'] == 'signature' %>
|
<% if field['type'] == 'signature' %>
|
||||||
<div class="flex flex-col justify-between h-full overflow-hidden">
|
<div class="flex flex-col justify-between h-full overflow-hidden">
|
||||||
<div class="flex-grow flex overflow-hidden" style="min-height: 50%">
|
<div class="flex-grow flex overflow-hidden" style="min-height: 50%">
|
||||||
|
|||||||
@@ -232,7 +232,7 @@
|
|||||||
<% elsif field['type'] == 'date' %>
|
<% elsif field['type'] == 'date' %>
|
||||||
<%= TimeUtils.format_date_string(value, field.dig('preferences', 'format'), @submission.account.locale) %>
|
<%= TimeUtils.format_date_string(value, field.dig('preferences', 'format'), @submission.account.locale) %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<%= Array.wrap(value).join(', ') %>
|
<div class="whitespace-pre-wrap"><%= Array.wrap(value).join(', ') %></div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<% query_params = params.permit(:q).merge(filter_params) %>
|
<% query_params = params.permit(:q).merge(filter_params) %>
|
||||||
<% if icon = { 'declined' => 'x_circle', 'expired' => 'clock_cancel', 'partially_completed' => 'clock_edit' }[params[:status]] %>
|
<% if icon = { 'declined' => 'x_circle', 'expired' => 'clock_cancel', 'partially_completed' => 'clock_edit', 'sent' => 'send', 'opened' => 'mail_opened' }[params[:status]] %>
|
||||||
<div class="flex h-10 px-2 py-1 text-lg items-center justify-between border text-center text-neutral font-semibold rounded-xl w-full md:w-34 border-neutral-700">
|
<div class="flex h-10 px-2 py-1 text-lg items-center justify-between border text-center text-neutral font-semibold rounded-xl w-full md:w-34 border-neutral-700">
|
||||||
<%= link_to submissions_filter_path('status', query_params.merge(path: url_for, with_remove: true)), data: { turbo_frame: 'modal' }, class: 'flex items-center space-x-1 w-full pr-1 md:max-w-[140px]' do %>
|
<%= link_to submissions_filter_path('status', query_params.merge(path: url_for, with_remove: true)), data: { turbo_frame: 'modal' }, class: 'flex items-center space-x-1 w-full pr-1 md:max-w-[140px]' do %>
|
||||||
<%= svg_icon(icon, class: 'w-5 h-5 shrink-0') %>
|
<%= svg_icon(icon, class: 'w-5 h-5 shrink-0') %>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="flex flex-col md:flex-row gap-2 mt-5">
|
<div class="flex flex-col md:flex-row gap-2 mt-5">
|
||||||
<div class="form-control w-full">
|
<div class="form-control w-full">
|
||||||
<div id="status" class="radio-select grid grid-cols-2 gap-2 px-1">
|
<div id="status" class="radio-select grid grid-cols-2 gap-2 px-1">
|
||||||
<% ['', 'pending', 'completed', 'partially_completed', 'declined', 'expired'].each do |status| %>
|
<% ['', 'pending', 'completed', 'partially_completed', 'sent', 'opened', 'declined', 'expired'].each do |status| %>
|
||||||
<label class="radio-label cursor-pointer inline-flex items-center space-x-2">
|
<label class="radio-label cursor-pointer inline-flex items-center space-x-2">
|
||||||
<%= radio_button_tag 'status', status, params[:status] == status || (status == '' && params[:status].blank?), class: 'base-radio' %>
|
<%= radio_button_tag 'status', status, params[:status] == status || (status == '' && params[:status].blank?), class: 'base-radio' %>
|
||||||
<span><%= t(status.presence || 'all') %></span>
|
<span><%= t(status.presence || 'all') %></span>
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
<div class="max-w-md mx-auto px-2 mt-12 mb-4">
|
<div class="max-w-md mx-auto px-2 mt-12 mb-4">
|
||||||
<div class="space-y-6 mx-auto">
|
<div class="space-y-6 mx-auto">
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<% if Docuseal.multitenant? %>
|
<div class="flex items-center justify-center">
|
||||||
<div class="flex items-center justify-center">
|
<%= render 'start_form/banner' %>
|
||||||
<%= render 'start_form/docuseal_logo' %>
|
</div>
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<div class="flex items-center bg-base-200 rounded-xl p-4 mb-4">
|
<div class="flex items-center bg-base-200 rounded-xl p-4 mb-4">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="mr-3">
|
<div class="mr-3">
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</submitter-item>
|
</submitter-item>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<%= render 'submissions/send_email', f:, template: @submitter.template, submitter: @submitter, resend_email: @submitter.sent_at?, submitter_email_message: @submitter_email_message, disable_save_as_default_template_option: true %>
|
<%= render 'submissions/send_email', f:, template: @submitter.template, submitter: @submitter, resend_email: @submitter.sent_at?, submitter_email_message: @submitter_email_message, disable_save_as_default_template_option: true, message_per_submitter: false %>
|
||||||
<%= render 'submissions/send_sms', f:, resend_sms: @submitter.sent_at? %>
|
<%= render 'submissions/send_sms', f:, resend_sms: @submitter.sent_at? %>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control mt-4">
|
<div class="form-control mt-4">
|
||||||
|
|||||||
@@ -83,21 +83,71 @@
|
|||||||
<div class="collapse-content">
|
<div class="collapse-content">
|
||||||
<%= form_for @template, url: template_preferences_path(@template), method: :post, html: { autocomplete: 'off', class: 'mt-1' }, data: { close_on_submit: false } do |f| %>
|
<%= form_for @template, url: template_preferences_path(@template), method: :post, html: { autocomplete: 'off', class: 'mt-1' }, data: { close_on_submit: false } do |f| %>
|
||||||
<toggle-on-submit data-element-id="email_saved_alert1"></toggle-on-submit>
|
<toggle-on-submit data-element-id="email_saved_alert1"></toggle-on-submit>
|
||||||
<%= f.fields_for :preferences, Struct.new(:request_email_subject, :request_email_body).new(*(@template.preferences.values_at('request_email_subject', 'request_email_body').compact_blank.presence || AccountConfigs.find_or_initialize_for_key(current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY).value.values_at('subject', 'body'))) do |ff| %>
|
<%= tag.input id: 'request_email_per_submitter', value: '1', name: 'request_email_per_submitter', class: 'peer', type: 'checkbox', hidden: true, checked: @template.preferences['submitters'].to_a.size > 1 %>
|
||||||
<div class="form-control">
|
<div class="peer-checked:hidden">
|
||||||
<%= ff.label :request_email_subject, t('email_subject'), class: 'label' %>
|
<%= f.fields_for :preferences, Struct.new(:request_email_subject, :request_email_body).new(*(@template.preferences.values_at('request_email_subject', 'request_email_body').compact_blank.presence || AccountConfigs.find_or_initialize_for_key(current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY).value.values_at('subject', 'body'))) do |ff| %>
|
||||||
<%= ff.text_field :request_email_subject, required: true, class: 'base-input', dir: 'auto' %>
|
<div class="form-control">
|
||||||
</div>
|
<div class="flex justify-between">
|
||||||
<div class="form-control">
|
<%= ff.label :request_email_subject, t('email_subject'), class: 'label' %>
|
||||||
<div class="flex items-center">
|
<% if @template.submitters.size > 1 && @template.submitters.size < 5 %>
|
||||||
<%= ff.label :request_email_body, t('email_body'), class: 'label' %>
|
<label for="request_email_per_submitter" class="label underline">
|
||||||
<span class="tooltip tooltip-right" data-tip="<%= t('use_following_placeholders_text_') %> <%= AccountConfig::DEFAULT_VALUES[AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY].call['body'].scan(/{.*?}/).join(', ') %>">
|
<%= t('edit_per_party') %>
|
||||||
<%= svg_icon('info_circle', class: 'w-4 h-4') %>
|
</label>
|
||||||
</span>
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<%= ff.text_field :request_email_subject, required: true, class: 'base-input', dir: 'auto' %>
|
||||||
</div>
|
</div>
|
||||||
<autoresize-textarea>
|
<div class="form-control">
|
||||||
<%= ff.text_area :request_email_body, required: true, class: 'base-input w-full py-2', dir: 'auto' %>
|
<div class="flex items-center">
|
||||||
</autoresize-textarea>
|
<%= ff.label :request_email_body, t('email_body'), class: 'label' %>
|
||||||
|
<span class="tooltip tooltip-right" data-tip="<%= t('use_following_placeholders_text_') %> <%= AccountConfig::DEFAULT_VALUES[AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY].call['body'].scan(/{.*?}/).join(', ') %>">
|
||||||
|
<%= svg_icon('info_circle', class: 'w-4 h-4') %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<autoresize-textarea>
|
||||||
|
<%= ff.text_area :request_email_body, required: true, class: 'base-input w-full py-2', dir: 'auto' %>
|
||||||
|
</autoresize-textarea>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% if @template.submitters.size > 1 && @template.submitters.size < 5 %>
|
||||||
|
<div class="hidden peer-checked:block">
|
||||||
|
<% options = @template.submitters.map { |e| [e['name'], "request_email_#{e['uuid']}"] } %>
|
||||||
|
<toggle-visible data-element-ids="<%= options.map(&:last).to_json %>" class="flex relative px-1">
|
||||||
|
<ul class="tabs w-full flex flex-nowrap mb-2">
|
||||||
|
<% options.each_with_index do |(label, val), index| %>
|
||||||
|
<div class="w-full">
|
||||||
|
<%= f.radio_button :selected, val, checked: index.zero?, id: "#{val}_radio", data: { action: 'click:toggle-visible#trigger' }, class: 'hidden peer' %>
|
||||||
|
<%= f.label :selected, label, value: val, for: "#{val}_radio", class: 'tab w-full tab-lifted peer-checked:tab-active' %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</toggle-visible>
|
||||||
|
<%= f.fields_for :preferences do |ff| %>
|
||||||
|
<% @template.submitters.each_with_index do |submitter, index| %>
|
||||||
|
<div id="request_email_<%= submitter['uuid'] %>" class="<%= 'hidden' if index != 0 %>">
|
||||||
|
<% submitter_preferences = f.object.preferences['submitters'].to_a.find { |e| e['uuid'] == submitter['uuid'] } || {} %>
|
||||||
|
<%= ff.fields_for :submitters, Struct.new(:request_email_subject, :request_email_body).new(*(submitter_preferences.values_at('request_email_subject', 'request_email_body').compact_blank.presence || @template.preferences.values_at('request_email_subject', 'request_email_body').compact_blank.presence || AccountConfigs.find_or_initialize_for_key(current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY).value.values_at('subject', 'body'))), index: nil do |fff| %>
|
||||||
|
<%= fff.hidden_field :uuid, value: submitter['uuid'] %>
|
||||||
|
<div class="form-control">
|
||||||
|
<%= fff.label :request_email_subject, t('email_subject'), class: 'label' %>
|
||||||
|
<%= fff.text_field :request_email_subject, required: true, class: 'base-input', dir: 'auto' %>
|
||||||
|
</div>
|
||||||
|
<div class="form-control">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= fff.label :request_email_body, t('email_body'), class: 'label' %>
|
||||||
|
<span class="tooltip tooltip-right" data-tip="<%= t('use_following_placeholders_text_') %> <%= AccountConfig::DEFAULT_VALUES[AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY].call['body'].scan(/{.*?}/).join(', ') %>">
|
||||||
|
<%= svg_icon('info_circle', class: 'w-4 h-4') %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<autoresize-textarea>
|
||||||
|
<%= fff.text_area :request_email_body, required: true, class: 'base-input w-full py-2', dir: 'auto' %>
|
||||||
|
</autoresize-textarea>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<div class="form-control pt-2">
|
<div class="form-control pt-2">
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ en: &en
|
|||||||
language_ko: 한국어
|
language_ko: 한국어
|
||||||
hi_there: Hi there
|
hi_there: Hi there
|
||||||
thanks: Thanks
|
thanks: Thanks
|
||||||
|
edit_per_party: Edit per party
|
||||||
reply_to: Reply to
|
reply_to: Reply to
|
||||||
pending_by_me: Pending by me
|
pending_by_me: Pending by me
|
||||||
partially_completed: Partially completed
|
partially_completed: Partially completed
|
||||||
@@ -732,6 +733,7 @@ en: &en
|
|||||||
read: Read your data
|
read: Read your data
|
||||||
|
|
||||||
es: &es
|
es: &es
|
||||||
|
edit_per_party: Editar por parte
|
||||||
signed: Firmado
|
signed: Firmado
|
||||||
reply_to: Responder a
|
reply_to: Responder a
|
||||||
partially_completed: Parcialmente completado
|
partially_completed: Parcialmente completado
|
||||||
@@ -1446,6 +1448,7 @@ es: &es
|
|||||||
read: Leer tus datos
|
read: Leer tus datos
|
||||||
|
|
||||||
it: &it
|
it: &it
|
||||||
|
edit_per_party: Modifica per partito
|
||||||
signed: Firmato
|
signed: Firmato
|
||||||
reply_to: Rispondi a
|
reply_to: Rispondi a
|
||||||
pending_by_me: In sospeso da me
|
pending_by_me: In sospeso da me
|
||||||
@@ -2159,6 +2162,7 @@ it: &it
|
|||||||
read: Leggi i tuoi dati
|
read: Leggi i tuoi dati
|
||||||
|
|
||||||
fr: &fr
|
fr: &fr
|
||||||
|
edit_per_party: Éditer par partie
|
||||||
signed: Signé
|
signed: Signé
|
||||||
reply_to: Répondre à
|
reply_to: Répondre à
|
||||||
partially_completed: Partiellement complété
|
partially_completed: Partiellement complété
|
||||||
@@ -2874,6 +2878,7 @@ fr: &fr
|
|||||||
read: Lire vos données
|
read: Lire vos données
|
||||||
|
|
||||||
pt: &pt
|
pt: &pt
|
||||||
|
edit_per_party: Edita por festa
|
||||||
signed: Assinado
|
signed: Assinado
|
||||||
reply_to: Responder a
|
reply_to: Responder a
|
||||||
partially_completed: Parcialmente concluído
|
partially_completed: Parcialmente concluído
|
||||||
@@ -3588,6 +3593,7 @@ pt: &pt
|
|||||||
read: Ler seus dados
|
read: Ler seus dados
|
||||||
|
|
||||||
de: &de
|
de: &de
|
||||||
|
edit_per_party: Bearbeiten pro Partei
|
||||||
signed: Unterschrieben
|
signed: Unterschrieben
|
||||||
reply_to: Antworten auf
|
reply_to: Antworten auf
|
||||||
partially_completed: Teilweise abgeschlossen
|
partially_completed: Teilweise abgeschlossen
|
||||||
|
|||||||
+1
-3
@@ -145,9 +145,7 @@ Rails.application.routes.draw do
|
|||||||
get :completed
|
get :completed
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :send_submission_email, only: %i[create] do
|
resources :send_submission_email, only: %i[create]
|
||||||
get :success, on: :collection
|
|
||||||
end
|
|
||||||
|
|
||||||
resources :submitters, only: %i[], param: 'slug' do
|
resources :submitters, only: %i[], param: 'slug' do
|
||||||
resources :download, only: %i[index], controller: 'submissions_download'
|
resources :download, only: %i[index], controller: 'submissions_download'
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ module PdfIcons
|
|||||||
StringIO.new(logo_new_data)
|
StringIO.new(logo_new_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stamp_logo_io
|
||||||
|
StringIO.new(stamp_logo_data)
|
||||||
|
end
|
||||||
|
|
||||||
def check_data
|
def check_data
|
||||||
@check_data ||= PATH.join('check.png').read
|
@check_data ||= PATH.join('check.png').read
|
||||||
end
|
end
|
||||||
@@ -39,4 +43,8 @@ module PdfIcons
|
|||||||
def logo_new_data
|
def logo_new_data
|
||||||
@logo_new_data ||= PATH.join('logo_new.png').read
|
@logo_new_data ||= PATH.join('logo_new.png').read
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stamp_logo_data
|
||||||
|
@stamp_logo_data ||= PATH.join('stamp-logo.png').read
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@@ -36,8 +36,8 @@ module Submissions
|
|||||||
|
|
||||||
is_order_sent = submitters_order == 'random' || index.zero?
|
is_order_sent = submitters_order == 'random' || index.zero?
|
||||||
|
|
||||||
build_submitter(submission:, attrs: submitter_attrs, uuid:,
|
build_submitter(submission:, attrs: submitter_attrs,
|
||||||
is_order_sent:, user:,
|
uuid:, is_order_sent:, user:, params:,
|
||||||
preferences: preferences.merge(submission_preferences))
|
preferences: preferences.merge(submission_preferences))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -69,6 +69,16 @@ module Submissions
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def submitter_message_preferences(uuid, params)
|
||||||
|
return {} if params[:request_email_per_submitter] != '1'
|
||||||
|
return {} if params[:is_custom_message] != '1'
|
||||||
|
|
||||||
|
{
|
||||||
|
'subject' => params.dig('submitter_preferences', uuid, 'subject'),
|
||||||
|
'body' => params.dig('submitter_preferences', uuid, 'body')
|
||||||
|
}.compact_blank
|
||||||
|
end
|
||||||
|
|
||||||
def maybe_set_template_fields(submission, submitters_attrs, default_submitter_uuid: nil)
|
def maybe_set_template_fields(submission, submitters_attrs, default_submitter_uuid: nil)
|
||||||
template_fields = (submission.template_fields || submission.template.fields).deep_dup
|
template_fields = (submission.template_fields || submission.template.fields).deep_dup
|
||||||
|
|
||||||
@@ -175,9 +185,10 @@ module Submissions
|
|||||||
uuid || template.submitters[index]&.dig('uuid')
|
uuid || template.submitters[index]&.dig('uuid')
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_submitter(submission:, attrs:, uuid:, is_order_sent:, user:, preferences:)
|
def build_submitter(submission:, attrs:, uuid:, is_order_sent:, user:, preferences:, params:)
|
||||||
email = Submissions.normalize_email(attrs[:email])
|
email = Submissions.normalize_email(attrs[:email])
|
||||||
submitter_preferences = Submitters.normalize_preferences(submission.account, user, attrs)
|
submitter_preferences = Submitters.normalize_preferences(submission.account, user,
|
||||||
|
attrs.merge(submitter_message_preferences(uuid, params)))
|
||||||
values = attrs[:values] || {}
|
values = attrs[:values] || {}
|
||||||
|
|
||||||
phone_field_uuid = find_phone_field(submission, values)&.dig('uuid')
|
phone_field_uuid = find_phone_field(submission, values)&.dig('uuid')
|
||||||
|
|||||||
+36
-21
@@ -37,30 +37,45 @@ module Submissions
|
|||||||
submissions.where(created_by_user_id: user&.id || -1)
|
submissions.where(created_by_user_id: user&.id || -1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# rubocop:disable Metrics/MethodLength
|
||||||
def filter_by_status(submissions, filters)
|
def filter_by_status(submissions, filters)
|
||||||
submissions = submissions.pending if filters[:status] == 'pending'
|
case filters[:status]
|
||||||
submissions = submissions.completed if filters[:status] == 'completed'
|
when 'pending'
|
||||||
submissions = submissions.declined if filters[:status] == 'declined'
|
submissions.pending
|
||||||
submissions = submissions.expired if filters[:status] == 'expired'
|
when 'completed'
|
||||||
|
submissions.completed
|
||||||
if filters[:status] == 'partially_completed'
|
when 'declined'
|
||||||
submissions =
|
submissions.declined
|
||||||
submissions.joins(:submitters)
|
when 'expired'
|
||||||
.group(:id)
|
submissions.expired
|
||||||
.having(Arel::Nodes::NamedFunction.new(
|
when 'sent'
|
||||||
'COUNT', [Arel::Nodes::NamedFunction.new('NULLIF',
|
submissions.joins(:submitters)
|
||||||
[Submitter.arel_table[:completed_at].eq(nil),
|
.where(submitters: { opened_at: nil, completed_at: nil, declined_at: nil })
|
||||||
Arel::Nodes.build_quoted(false)])]
|
.where.not(submitters: { sent_at: nil })
|
||||||
).gt(0))
|
.group(:id)
|
||||||
.having(Arel::Nodes::NamedFunction.new(
|
when 'opened'
|
||||||
'COUNT', [Arel::Nodes::NamedFunction.new('NULLIF',
|
submissions.joins(:submitters)
|
||||||
[Submitter.arel_table[:completed_at].not_eq(nil),
|
.where(submitters: { completed_at: nil, declined_at: nil })
|
||||||
Arel::Nodes.build_quoted(false)])]
|
.where.not(submitters: { opened_at: nil })
|
||||||
).gt(0))
|
.group(:id)
|
||||||
|
when 'partially_completed'
|
||||||
|
submissions.joins(:submitters)
|
||||||
|
.group(:id)
|
||||||
|
.having(Arel::Nodes::NamedFunction.new(
|
||||||
|
'COUNT', [Arel::Nodes::NamedFunction.new('NULLIF',
|
||||||
|
[Submitter.arel_table[:completed_at].eq(nil),
|
||||||
|
Arel::Nodes.build_quoted(false)])]
|
||||||
|
).gt(0))
|
||||||
|
.having(Arel::Nodes::NamedFunction.new(
|
||||||
|
'COUNT', [Arel::Nodes::NamedFunction.new('NULLIF',
|
||||||
|
[Submitter.arel_table[:completed_at].not_eq(nil),
|
||||||
|
Arel::Nodes.build_quoted(false)])]
|
||||||
|
).gt(0))
|
||||||
|
else
|
||||||
|
submissions
|
||||||
end
|
end
|
||||||
|
|
||||||
submissions
|
|
||||||
end
|
end
|
||||||
|
# rubocop:enable Metrics/MethodLength
|
||||||
|
|
||||||
def filter_by_created_at(submissions, filters)
|
def filter_by_created_at(submissions, filters)
|
||||||
submissions = submissions.where(created_at: filters[:created_at_from]..) if filters[:created_at_from].present?
|
submissions = submissions.where(created_at: filters[:created_at_from]..) if filters[:created_at_from].present?
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ module Submissions
|
|||||||
TEXT_TOP_MARGIN = 1
|
TEXT_TOP_MARGIN = 1
|
||||||
MAX_PAGE_ROTATE = 20
|
MAX_PAGE_ROTATE = 20
|
||||||
|
|
||||||
|
COURIER_FONT = 'Courier'
|
||||||
|
|
||||||
A4_SIZE = [595, 842].freeze
|
A4_SIZE = [595, 842].freeze
|
||||||
|
|
||||||
TESTING_FOOTER = 'Testing Document - NOT LEGALLY BINDING'
|
TESTING_FOOTER = 'Testing Document - NOT LEGALLY BINDING'
|
||||||
@@ -188,7 +190,8 @@ module Submissions
|
|||||||
|
|
||||||
fill_color = field.dig('preferences', 'color').presence
|
fill_color = field.dig('preferences', 'color').presence
|
||||||
|
|
||||||
font = pdf.fonts.add(field.dig('preferences', 'font').presence || FONT_NAME)
|
font_name = field.dig('preferences', 'font').presence || FONT_NAME
|
||||||
|
font = pdf.fonts.add(font_name)
|
||||||
|
|
||||||
value = submitter.values[field['uuid']]
|
value = submitter.values[field['uuid']]
|
||||||
value = field['default_value'] if field['type'] == 'heading'
|
value = field['default_value'] if field['type'] == 'heading'
|
||||||
@@ -435,18 +438,19 @@ module Submissions
|
|||||||
|
|
||||||
value = TextUtils.maybe_rtl_reverse(Array.wrap(value).join(', '))
|
value = TextUtils.maybe_rtl_reverse(Array.wrap(value).join(', '))
|
||||||
|
|
||||||
text = HexaPDF::Layout::TextFragment.create(value, font:,
|
text_params = { font:, fill_color:, font_size: }
|
||||||
fill_color:,
|
text_params[:line_height] = text_params[:font_size] * 1.6 if font_name == COURIER_FONT
|
||||||
font_size:)
|
|
||||||
|
text = HexaPDF::Layout::TextFragment.create(value, **text_params)
|
||||||
|
|
||||||
lines = layouter.fit([text], area['w'] * width, height).lines
|
lines = layouter.fit([text], area['w'] * width, height).lines
|
||||||
box_height = lines.sum(&:height)
|
box_height = lines.sum(&:height)
|
||||||
|
|
||||||
if preferences_font_size.blank? && box_height > (area['h'] * height) + 1
|
if preferences_font_size.blank? && box_height > (area['h'] * height) + 1
|
||||||
text = HexaPDF::Layout::TextFragment.create(value,
|
text_params[:font_size] = (font_size / 1.4).to_i
|
||||||
font:,
|
text_params[:line_height] = text_params[:font_size] * 1.6 if font_name == COURIER_FONT
|
||||||
fill_color:,
|
|
||||||
font_size: (font_size / 1.4).to_i)
|
text = HexaPDF::Layout::TextFragment.create(value, **text_params)
|
||||||
|
|
||||||
lines = layouter.fit([text], field['type'].in?(%w[date number]) ? width : area['w'] * width, height).lines
|
lines = layouter.fit([text], field['type'].in?(%w[date number]) ? width : area['w'] * width, height).lines
|
||||||
|
|
||||||
@@ -454,10 +458,10 @@ module Submissions
|
|||||||
end
|
end
|
||||||
|
|
||||||
if preferences_font_size.blank? && box_height > (area['h'] * height) + 1
|
if preferences_font_size.blank? && box_height > (area['h'] * height) + 1
|
||||||
text = HexaPDF::Layout::TextFragment.create(value,
|
text_params[:font_size] = (font_size / 1.9).to_i
|
||||||
font:,
|
text_params[:line_height] = text_params[:font_size] * 1.6 if font_name == COURIER_FONT
|
||||||
fill_color:,
|
|
||||||
font_size: (font_size / 1.9).to_i)
|
text = HexaPDF::Layout::TextFragment.create(value, **text_params)
|
||||||
|
|
||||||
lines = layouter.fit([text], field['type'].in?(%w[date number]) ? width : area['w'] * width, height).lines
|
lines = layouter.fit([text], field['type'].in?(%w[date number]) ? width : area['w'] * width, height).lines
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ module Submitters
|
|||||||
end
|
end
|
||||||
|
|
||||||
def load_logo(_submitter)
|
def load_logo(_submitter)
|
||||||
PdfIcons.logo_io
|
PdfIcons.stamp_logo_io
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user