Compare commits

..
18 Commits
Author SHA1 Message Date
Pete Matsyburka f9ae79dd5b add go to last 2024-04-13 17:41:49 +03:00
Pete Matsyburka cadb78ca35 check on email events 2024-04-13 12:37:48 +03:00
Pete Matsyburka 36a6b7ff1d fix typo 2024-04-13 11:35:04 +03:00
Pete Matsyburka efee46f113 add bulk source 2024-04-12 17:20:00 +03:00
Pete Matsyburka b6639738c3 adjust dockerfile 2024-04-11 22:52:12 +03:00
Alex Turchyn aab07c5f49 add icons 2024-04-11 22:52:11 +03:00
Pete Matsyburka 33c0784bc6 add folder name to submission resp 2024-04-11 16:36:53 +03:00
Pete Matsyburka 6f5ebfc8a6 fix preview completed 2024-04-11 02:45:38 +03:00
Pete Matsyburka 811091ff14 adjust text signature size 2024-04-10 22:24:19 +03:00
Pete Matsyburka 6666f39928 add redacted param 2024-04-10 19:56:35 +03:00
Pete Matsyburka f67db9fe5f add field uuid param 2024-04-10 13:30:27 +03:00
Pete Matsyburka 45f002803e adjust padding 2024-04-10 10:55:51 +03:00
Pete Matsyburka 8c19f90e88 remove debug 2024-04-10 00:44:36 +03:00
Pete Matsyburka a8f5d5cea7 fix typo 2024-04-09 19:08:05 +03:00
Pete Matsyburka 6788071eec add webhook event preferences 2024-04-09 18:11:58 +03:00
Pete Matsyburka 0c690b3033 custom submit button 2024-04-09 01:54:39 +03:00
Pete Matsyburka dcb963b623 add autoscrollFields prop 2024-04-08 18:37:10 +03:00
Pete Matsyburka 04e30dbdd6 add submitter update params 2024-04-08 10:51:18 +03:00
37 changed files with 209 additions and 53 deletions

No files matched your search

+4 -4
View File
@@ -23,10 +23,10 @@ RUN yarn install --network-timeout 1000000
COPY ./bin/shakapacker ./bin/shakapacker
COPY ./config/webpack ./config/webpack
COPY ./config/shakapacker.yml ./config/shakapacker.yml
COPY ./postcss.config.js ./postcss.config.js ./
COPY ./tailwind.config.js ./tailwind.config.js ./
COPY ./tailwind.form.config.js ./tailwind.form.config.js ./
COPY ./tailwind.application.config.js ./tailwind.application.config.js ./
COPY ./postcss.config.js ./postcss.config.js
COPY ./tailwind.config.js ./tailwind.config.js
COPY ./tailwind.form.config.js ./tailwind.form.config.js
COPY ./tailwind.application.config.js ./tailwind.application.config.js
COPY ./app/javascript ./app/javascript
COPY ./app/views ./app/views
+10 -6
View File
@@ -17,7 +17,8 @@ module Api
submissions = submissions.joins(template: :folder).where(folder: { name: params[:template_folder] })
end
submissions = paginate(submissions.preload(:created_by_user, :template, :submitters,
submissions = paginate(submissions.preload(:created_by_user, :submitters,
template: :folder,
audit_trail_attachment: :blob))
render json: {
@@ -102,6 +103,8 @@ module Api
def destroy
@submission.update!(archived_at: Time.current)
SendSubmissionArchivedWebhookRequestJob.perform_later(@submission)
render json: @submission.as_json(only: %i[id], methods: %i[archived_at])
end
@@ -153,7 +156,8 @@ module Api
completed_at opened_at sent_at
created_at updated_at external_id metadata],
methods: %i[status application_key] },
template: { only: %i[id name created_at updated_at] },
template: { only: %i[id name external_id created_at updated_at],
methods: %i[folder_name] },
created_by_user: { only: %i[id email first_name last_name] }
}
}
@@ -161,14 +165,14 @@ module Api
def submissions_params
permitted_attrs = [
:send_email, :send_sms, :bcc_completed, :completed_redirect_url, :reply_to,
:send_email, :send_sms, :bcc_completed, :completed_redirect_url, :reply_to, :go_to_last,
{
message: %i[subject body],
submitters: [[:send_email, :send_sms, :completed_redirect_url, :uuid, :name, :email, :role,
:completed, :phone, :application_key, :external_id, :reply_to,
:completed, :phone, :application_key, :external_id, :reply_to, :go_to_last,
{ metadata: {}, values: {}, readonly_fields: [], message: %i[subject body],
fields: [:name, :default_value, :title, :description,
:readonly, :validation_pattern, :invalid_message,
fields: [:name, :uuid, :default_value, :title, :description,
:readonly, :redacted, :validation_pattern, :invalid_message,
{ default_value: [] }] }]]
}
]
+11 -3
View File
@@ -73,10 +73,10 @@ module Api
submitter_params = params.key?(:submitter) ? params.require(:submitter) : params
submitter_params.permit(
:send_email, :send_sms, :uuid, :name, :email, :role,
:completed, :phone, :application_key, :external_id,
:send_email, :send_sms, :reply_to, :completed_redirect_url, :uuid, :name, :email, :role,
:completed, :phone, :application_key, :external_id, :go_to_last,
{ metadata: {}, values: {}, readonly_fields: [], message: %i[subject body],
fields: [[:name, :default_value, :readonly, :validation_pattern, :invalid_message,
fields: [[:name, :uuid, :default_value, :readonly, :redacted, :validation_pattern, :invalid_message,
{ default_value: [] }]] }
)
end
@@ -125,6 +125,14 @@ module Api
end
submitter.preferences['send_sms'] = submitter_preferences['send_sms'] if submitter_preferences.key?('send_sms')
submitter.preferences['reply_to'] = submitter_preferences['reply_to'] if submitter_preferences.key?('reply_to')
if submitter_preferences.key?('go_to_last')
submitter.preferences['go_to_last'] = submitter_preferences['go_to_last']
end
if submitter_preferences.key?('completed_redirect_url')
submitter.preferences['completed_redirect_url'] = submitter_preferences['completed_redirect_url']
end
return unless submitter_preferences.key?('email_message_uuid')
@@ -35,12 +35,12 @@ class NotificationsSettingsController < ApplicationController
def load_reminder_config
@reminder_config =
AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::SUBMITTER_REMAILERS)
AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::SUBMITTER_REMINDERS)
end
def email_config_params
params.require(:account_config).permit!.tap do |attrs|
attrs[:key] = nil unless attrs[:key].in?([AccountConfig::BCC_EMAILS, AccountConfig::SUBMITTER_REMAILERS])
attrs[:key] = nil unless attrs[:key].in?([AccountConfig::BCC_EMAILS, AccountConfig::SUBMITTER_REMINDERS])
end
end
end
@@ -50,6 +50,8 @@ class SubmissionsController < ApplicationController
def destroy
@submission.update!(archived_at: Time.current)
SendSubmissionArchivedWebhookRequestJob.perform_later(@submission)
redirect_back(fallback_location: template_path(@submission.template), notice: 'Submission has been archived')
end
@@ -0,0 +1,33 @@
# frozen_string_literal: true
class WebhookPreferencesController < ApplicationController
EVENTS = %w[
form.viewed
form.started
form.completed
submission.archived
].freeze
before_action :load_account_config
authorize_resource :account_config, parent: false
def create
@account_config.value[account_config_params[:event]] = account_config_params[:value] == '1'
@account_config.save!
head :ok
end
private
def load_account_config
@account_config =
current_account.account_configs.find_or_initialize_by(key: AccountConfig::WEBHOOK_PREFERENCES_KEY)
@account_config.value ||= {}
end
def account_config_params
params.permit(:event, :value)
end
end
+1 -1
View File
@@ -19,7 +19,7 @@
</label>
<button
class="btn btn-outline btn-sm !normal-case font-normal"
@click.prevent="setCurrentDate"
@click.prevent="[setCurrentDate(), $emit('focus')]"
>
<IconCalendarCheck :width="16" />
{{ t('set_today') }}
+8 -3
View File
@@ -544,6 +544,11 @@ export default {
required: false,
default: false
},
autoscrollFields: {
type: Boolean,
required: false,
default: true
},
showFieldNames: {
type: Boolean,
required: false,
@@ -900,9 +905,9 @@ export default {
if (scrollToArea) {
this.scrollIntoField(step[0])
}
this.$refs.form.querySelector('input[type="date"], input[type="number"], input[type="text"], select')?.focus()
this.$refs.form.querySelector('input[type="date"], input[type="number"], input[type="text"], select')?.focus()
}
if (clickUpload && !this.values[this.currentField.uuid] && ['file', 'image'].includes(this.currentField.type)) {
this.$refs.form.querySelector('input[type="file"]')?.click()
@@ -976,7 +981,7 @@ export default {
const nextStep = (isLastStep && emptyRequiredField) || this.stepFields[this.currentStep + 1]
if (nextStep) {
this.goToStep(nextStep, true)
this.goToStep(nextStep, this.autoscrollFields)
if (emptyRequiredField === nextStep) {
this.showFillAllRequiredFields = true
+2 -2
View File
@@ -24,7 +24,7 @@ const en = {
appears_on: 'Appears on',
page: 'Page',
select_your_option: 'Select your option',
complete_hightlighted_checkboxes_and_click: 'Complete hightlighted checkboxes and click',
complete_hightlighted_checkboxes_and_click: 'Complete highlighted checkboxes and click',
submit: 'submit',
next: 'next',
click_to_upload: 'Click to upload',
@@ -42,7 +42,7 @@ const en = {
please_check_the_box_to_continue: 'Please check the box to continue',
open_source_documents_software: 'open source documents software',
verified_phone_number: 'Verify Phone Number',
use_international_format: 'Use internatioanl format: +1xxx',
use_international_format: 'Use international format: +1xxx',
six_digits_code: '6-digit code',
change_phone_number: 'Change phone number',
sending: 'Sending...',
@@ -193,8 +193,6 @@ export default {
this.$refs.canvas.getContext('2d').scale(scale, scale)
}
this.$refs.textInput?.focus()
})
if (this.$refs.canvas) {
+1 -1
View File
@@ -16,7 +16,7 @@ class ProcessSubmitterCompletionJob < ApplicationJob
enqueue_completed_emails(submitter)
end
return if Accounts.load_webhook_configs(submitter.account).blank?
return if Accounts.load_webhook_url(submitter.account).blank?
SendFormCompletedWebhookRequestJob.perform_later(submitter)
end
@@ -7,16 +7,20 @@ class SendFormCompletedWebhookRequestJob < ApplicationJob
def perform(submitter, params = {})
attempt = params[:attempt].to_i
config = Accounts.load_webhook_configs(submitter.submission.account)
url = Accounts.load_webhook_url(submitter.submission.account)
return if config.blank? || config.value.blank?
return if url.blank?
preferences = Accounts.load_webhook_preferences(submitter.submission.account)
return if preferences['form.completed'] == false
Submissions::EnsureResultGenerated.call(submitter)
ActiveStorage::Current.url_options = Docuseal.default_url_options
resp = begin
Faraday.post(config.value,
Faraday.post(url,
{
event_type: 'form.completed',
timestamp: Time.current,
@@ -7,14 +7,18 @@ class SendFormStartedWebhookRequestJob < ApplicationJob
def perform(submitter, params = {})
attempt = params[:attempt].to_i
config = Accounts.load_webhook_configs(submitter.submission.account)
url = Accounts.load_webhook_url(submitter.submission.account)
return if config.blank? || config.value.blank?
return if url.blank?
preferences = Accounts.load_webhook_preferences(submitter.submission.account)
return if preferences['form.started'] == false
ActiveStorage::Current.url_options = Docuseal.default_url_options
resp = begin
Faraday.post(config.value,
Faraday.post(url,
{
event_type: 'form.started',
timestamp: Time.current,
@@ -7,14 +7,18 @@ class SendFormViewedWebhookRequestJob < ApplicationJob
def perform(submitter, params = {})
attempt = params[:attempt].to_i
config = Accounts.load_webhook_configs(submitter.submission.account)
url = Accounts.load_webhook_url(submitter.submission.account)
return if config.blank? || config.value.blank?
return if url.blank?
preferences = Accounts.load_webhook_preferences(submitter.submission.account)
return if preferences['form.viewed'] == false
ActiveStorage::Current.url_options = Docuseal.default_url_options
resp = begin
Faraday.post(config.value,
Faraday.post(url,
{
event_type: 'form.viewed',
timestamp: Time.current,
@@ -0,0 +1,40 @@
# frozen_string_literal: true
class SendSubmissionArchivedWebhookRequestJob < ApplicationJob
USER_AGENT = 'DocuSeal.co Webhook'
MAX_ATTEMPTS = 10
def perform(submission, params = {})
attempt = params[:attempt].to_i
url = Accounts.load_webhook_url(submission.account)
return if url.blank?
preferences = Accounts.load_webhook_preferences(submission.account)
return if preferences['submission.archived'].blank?
resp = begin
Faraday.post(url,
{
event_type: 'submission.archived',
timestamp: Time.current,
data: submission.as_json(only: %i[id archived_at])
}.to_json,
'Content-Type' => 'application/json',
'User-Agent' => USER_AGENT)
rescue Faraday::Error
nil
end
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
(!Docuseal.multitenant? || submitter.account.account_configs.exists?(key: :plan))
SendSubmissionArchivedWebhookRequestJob.set(wait: (2**attempt).minutes)
.perform_later(submitter, {
attempt: attempt + 1,
last_status: resp&.status.to_i
})
end
end
end
@@ -4,7 +4,7 @@ class SendSubmitterInvitationEmailJob < ApplicationJob
def perform(params = {})
submitter = Submitter.find(params['submitter_id'])
if submitter.submission.source == 'invite' && !Accounts.can_send_emails?(submitter.account)
if submitter.submission.source == 'invite' && !Accounts.can_send_emails?(submitter.account, on_events: true)
Rollbar.error("Skip email: #{submitter.id}") if defined?(Rollbar)
return
+2 -1
View File
@@ -28,11 +28,12 @@ class AccountConfig < ApplicationRecord
FORCE_MFA = 'force_mfa'
ALLOW_TYPED_SIGNATURE = 'allow_typed_signature'
ALLOW_TO_RESUBMIT = 'allow_to_resubmit'
SUBMITTER_REMAILERS = 'submitter_reminders'
SUBMITTER_REMINDERS = 'submitter_reminders'
FORM_COMPLETED_BUTTON_KEY = 'form_completed_button'
FORM_COMPLETED_MESSAGE_KEY = 'form_completed_message'
FORM_WITH_CONFETTI_KEY = 'form_with_confetti'
ESIGNING_PREFERENCE_KEY = 'esigning_preference'
WEBHOOK_PREFERENCES_KEY = 'webhook_preferences'
DEFAULT_VALUES = {
SUBMITTER_INVITATION_EMAIL_KEY => {
+1
View File
@@ -63,6 +63,7 @@ class Submission < ApplicationRecord
enum :source, {
invite: 'invite',
bulk: 'bulk',
api: 'api',
embed: 'embed',
link: 'link'
+2
View File
@@ -62,6 +62,8 @@ class Template < ApplicationRecord
scope :active, -> { where(archived_at: nil) }
scope :archived, -> { where.not(archived_at: nil) }
delegate :name, to: :folder, prefix: true
def application_key
external_id
end
@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" class="<%= local_assigns[:class] %>" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M12 3a9 9 0 1 0 0 18a9 9 0 0 0 0 -18" />
<path d="M16 12l-4 -4" />
<path d="M16 12h-8" />
<path d="M12 16l4 -4" />
</svg>

After

Width:  |  Height:  |  Size: 415 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" class="<%= local_assigns[:class] %>" aria-hidden="true" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
</svg>

After

Width:  |  Height:  |  Size: 338 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" class="<%= local_assigns[:class] %>" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M6.06004 6.00016C6.21678 5.55461 6.52614 5.1789 6.93334 4.93958C7.34055 4.70027 7.8193 4.61279 8.28483 4.69264C8.75035 4.77249 9.17259 5.01451 9.47676 5.37585C9.78093 5.73718 9.94741 6.19451 9.94671 6.66683C9.94671 8.00016 7.94671 8.66683 7.94671 8.66683M8.00004 11.3335H8.00671M14.6667 8.00016C14.6667 11.6821 11.6819 14.6668 8.00004 14.6668C4.31814 14.6668 1.33337 11.6821 1.33337 8.00016C1.33337 4.31826 4.31814 1.3335 8.00004 1.3335C11.6819 1.3335 14.6667 4.31826 14.6667 8.00016Z" stroke="currentColor" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round" />
</svg>

After

Width:  |  Height:  |  Size: 730 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" class="<%= local_assigns[:class] %>" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M6 6v6a3 3 0 0 0 3 3h10l-4 -4m0 8l4 -4" />
</svg>

After

Width:  |  Height:  |  Size: 337 B

+3 -1
View File
@@ -48,6 +48,8 @@
<%= render('submitters_order', f:, template:) if Accounts.can_send_emails?(current_account) %>
</div>
<div class="form-control">
<%= f.button button_title(title: 'Add Recipients'), class: 'base-button' %>
<%= content_for(:submit_button) || capture do %>
<%= f.button button_title(title: 'Add Recipients'), class: 'base-button' %>
<% end %>
</div>
<% end %>
@@ -13,8 +13,8 @@
</div>
<div>
<p dir="auto" class="text-lg font-bold mb-1"><%= @submission.template.name %></p>
<% if submitter = @submission.submitters.map(&:completed_at).max %>
<p dir="auto" class="text-sm"><%= t('signed_on_time', time: l(submitter.to_date, format: :long)) %></p>
<% if completed_at = @submission.submitters.map(&:completed_at).compact.max %>
<p dir="auto" class="text-sm"><%= t('signed_on_time', time: l(completed_at.to_date, format: :long)) %></p>
<% end %>
</div>
</div>
@@ -1,4 +1,4 @@
<% data_attachments = attachments_index.values.select { |e| e.record_id == submitter.id }.to_json(only: %i[uuid], methods: %i[url filename content_type]) %>
<% data_fields = (submitter.submission.template_fields || submitter.submission.template.fields).select { |f| f['submitter_uuid'] == submitter.uuid }.to_json %>
<% configs = Submitters::FormConfigs.call(submitter) %>
<submission-form data-is-demo="<%= Docuseal.demo? %>" data-with-confetti="<%= configs[:with_confetti] %>" data-completed-redirect-url="<%= submitter.preferences['completed_redirect_url'] %>" data-completed-message="<%= configs[:completed_message].to_json %>" data-completed-button="<%= configs[:completed_button].to_json %>" data-go-to-last="<%= submitter.opened_at? %>" data-submitter="<%= submitter.to_json(only: %i[uuid slug name phone email]) %>" data-can-send-email="<%= Accounts.can_send_emails?(submitter.submission.account) %>" data-attachments="<%= data_attachments %>" data-fields="<%= data_fields %>" data-values="<%= submitter.values.to_json %>" data-with-typed-signature="<%= configs[:with_typed_signature] %>"></submission-form>
<submission-form data-is-demo="<%= Docuseal.demo? %>" data-with-confetti="<%= configs[:with_confetti] %>" data-completed-redirect-url="<%= submitter.preferences['completed_redirect_url'] %>" data-completed-message="<%= configs[:completed_message].to_json %>" data-completed-button="<%= configs[:completed_button].to_json %>" data-go-to-last="<%= submitter.preferences['go_to_last'].presence || submitter.opened_at? %>" data-submitter="<%= submitter.to_json(only: %i[uuid slug name phone email]) %>" data-can-send-email="<%= Accounts.can_send_emails?(submitter.submission.account) %>" data-attachments="<%= data_attachments %>" data-fields="<%= data_fields %>" data-values="<%= submitter.values.to_json %>" data-with-typed-signature="<%= configs[:with_typed_signature] %>"></submission-form>
+1
View File
@@ -24,6 +24,7 @@
<% value = values[field['uuid']].presence || (field['default_value'].present? ? Submitters::SubmitValues.template_default_value_for_submitter(field['default_value'], @submitter.submission.submitters.find { |e| e.uuid == field['submitter_uuid'] }, with_time: false) : nil) %>
<% next if value.blank? %>
<% next if !field['readonly'] && field['submitter_uuid'] == @submitter.uuid %>
<% next if field['redacted'] && field['submitter_uuid'] != @submitter.uuid %>
<% next if value == '{{date}}' && field['submitter_uuid'] != @submitter.uuid %>
<% next if field.dig('preferences', 'formula') && field['submitter_uuid'] == @submitter.uuid %>
<%= render 'submissions/value', area:, field:, attachments_index:, value:, locale: @submitter.account.locale, timezone: @submitter.account.timezone %>
+17
View File
@@ -14,6 +14,23 @@
<%= f.button button_title(title: 'Save', disabled_with: 'Saving'), class: 'base-button w-full md:w-32' %>
</div>
<% end %>
<% preference = current_account.account_configs.find_by(key: AccountConfig::WEBHOOK_PREFERENCES_KEY)&.value || {} %>
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 mt-2 gap-y-2">
<% WebhookPreferencesController::EVENTS.each do |event| %>
<%= form_for '', url: webhook_preferences_path, method: :post do |f| %>
<%= f.hidden_field :event, value: event %>
<% uuid = SecureRandom.uuid %>
<div class="flex">
<label for="<%= uuid %>" class="flex items-center space-x-2">
<%= f.check_box :value, class: 'base-checkbox', checked: preference[event] || (!preference.key?(event) && event.starts_with?('form.')), onchange: 'this.form.requestSubmit()', id: uuid %>
<span>
<%= event %>
</span>
</label>
</div>
<% end %>
<% end %>
</div>
</div>
</div>
<% submitter = current_account.submitters.where.not(completed_at: nil).order(:id).last %>
+1
View File
@@ -59,6 +59,7 @@ Rails.application.routes.draw do
resources :testing_api_settings, only: %i[index]
resources :submitters_autocomplete, only: %i[index]
resources :template_folders_autocomplete, only: %i[index]
resources :webhook_preferences, only: %i[create]
resource :templates_upload, only: %i[create]
authenticated do
resource :templates_upload, only: %i[show], path: 'new'
+13 -3
View File
@@ -67,14 +67,24 @@ module Accounts
new_template
end
def load_webhook_configs(account)
def load_webhook_url(account)
configs = account.encrypted_configs.find_by(key: EncryptedConfig::WEBHOOK_URL_KEY)
unless Docuseal.multitenant?
configs ||= Account.order(:id).first.encrypted_configs.find_by(key: EncryptedConfig::WEBHOOK_URL_KEY)
end
configs
configs&.value.presence
end
def load_webhook_preferences(account)
configs = account.account_configs.find_by(key: AccountConfig::WEBHOOK_PREFERENCES_KEY)
unless Docuseal.multitenant?
configs ||= Account.order(:id).first.account_configs.find_by(key: AccountConfig::WEBHOOK_PREFERENCES_KEY)
end
configs&.value.presence || {}
end
def load_signing_pkcs(account)
@@ -108,7 +118,7 @@ module Accounts
end.presence
end
def can_send_emails?(_account)
def can_send_emails?(_account, **_params)
return true if Docuseal.multitenant?
return true if ENV['SMTP_ADDRESS'].present?
+1 -1
View File
@@ -87,7 +87,7 @@ module Params
type(submitter_params, :fields, Array)
in_path_each(submitter_params, :fields) do |field_params|
required(field_params, :name)
required(field_params, %i[name uuid])
type(field_params, :name, String)
type(field_params, :validation_pattern, String)
+6 -1
View File
@@ -102,7 +102,11 @@ module Submissions
next if f['submitter_uuid'] != submitter_uuid
field_configs = fields.find do |e|
e['name'].to_s.casecmp(f['name'].to_s).zero? || e['name'] == f['name'].to_s.parameterize.underscore
if e['name'].present?
e['name'].to_s.casecmp(f['name'].to_s).zero? || e['name'] == f['name'].to_s.parameterize.underscore
else
e['uuid'] == f['uuid']
end
end
next if field_configs.blank?
@@ -115,6 +119,7 @@ module Submissions
field['title'] = attrs['title'] if attrs['title'].present?
field['description'] = attrs['description'] if attrs['description'].present?
field['readonly'] = attrs['readonly'] if attrs.key?('readonly')
field['redacted'] = attrs['redacted'] if attrs.key?('redacted')
field['required'] = attrs['required'] if attrs.key?('required')
if attrs.key?('default_value') && !field['type'].in?(%w[signature image initials file])
+1 -1
View File
@@ -22,7 +22,7 @@ module Submissions
default_values = submitter_params[:values] || {}
submitter_params[:fields]&.each do |f|
default_values[f[:name]] = f[:default_value] if f.key?(:default_value)
default_values[f[:name].presence || f[:uuid]] = f[:default_value] if f.key?(:default_value)
end
return submitter_params if default_values.blank?
+1
View File
@@ -62,6 +62,7 @@ module Submitters
preferences['send_sms'] = params['send_sms'].in?(TRUE_VALUES) if params.key?('send_sms')
preferences['bcc_completed'] = params['bcc_completed'] if params.key?('bcc_completed')
preferences['reply_to'] = params['reply_to'] if params.key?('reply_to')
preferences['go_to_last'] = params['go_to_last'] if params.key?('go_to_last')
preferences['completed_redirect_url'] = params['completed_redirect_url'] if params.key?('completed_redirect_url')
preferences
+2 -2
View File
@@ -118,12 +118,12 @@ module Submitters
blob =
if value.match?(%r{\Ahttps?://})
find_or_create_blob_from_url(account, value)
elsif type.in?(%w[signature initials]) && value.length < 50
elsif type.in?(%w[signature initials]) && value.length < 60
find_or_create_blob_from_text(account, value, type)
elsif (data = Base64.decode64(value)) && Marcel::MimeType.for(data).include?('image')
find_or_create_blob_from_base64(account, data, type)
else
raise InvalidDefaultValue, "Invalid value, url, base64 or text < 50 chars is expected: #{value.first(50)}..."
raise InvalidDefaultValue, "Invalid value, url, base64 or text < 60 chars is expected: #{value.first(200)}..."
end
attachment = for_submitter.attachments.find_by(blob_id: blob.id) if for_submitter
+1 -3
View File
@@ -10,15 +10,13 @@ module Templates
module_function
def call(template, params)
res = Array.wrap(params[:files].presence || params[:file]).map do |file|
Array.wrap(params[:files].presence || params[:file]).map do |file|
if file.content_type.exclude?('image') && file.content_type != PDF_CONTENT_TYPE
next handle_file_types(template, file, params)
end
handle_pdf_or_image(template, file, file.read, params)
end
Rails.logger.debug res
res
end
def handle_pdf_or_image(template, file, document_data = nil, params = {})
+1 -3
View File
@@ -6,12 +6,10 @@ module Templates
def call(template, schema_documents = template.schema_documents, preview_image_attachments = [])
json = template.as_json(
methods: %i[application_key],
methods: %i[application_key folder_name],
include: { author: { only: %i[id email first_name last_name] } }
)
json[:folder_name] = template.folder.name
json[:documents] = template.schema.map do |item|
attachment = schema_documents.find { |e| e.uuid == item['attachment_uuid'] }