Skip to content

Commit

Permalink
Merge from docusealco/wip
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexBTurchyn authored Nov 25, 2024
2 parents 0c2abf2 + 8e212e4 commit fa2d86b
Show file tree
Hide file tree
Showing 76 changed files with 1,789 additions and 324 deletions.
4 changes: 2 additions & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ RSpec/NestedGroups:
Max: 6

RSpec/MultipleExpectations:
Max: 20
Max: 25

RSpec/ExampleLength:
Max: 40
Max: 50

RSpec/MultipleMemoizedHelpers:
Max: 9
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/account_configs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class AccountConfigsController < ApplicationController
AccountConfig::FLATTEN_RESULT_PDF_KEY,
AccountConfig::WITH_SIGNATURE_ID,
AccountConfig::COMBINE_PDF_RESULT_KEY,
AccountConfig::REQUIRE_SIGNING_REASON_KEY
AccountConfig::REQUIRE_SIGNING_REASON_KEY,
AccountConfig::DOCUMENT_FILENAME_FORMAT_KEY
].freeze

InvalidKey = Class.new(StandardError)
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class ApplicationController < ActionController::Base

helper_method :button_title,
:current_account,
:form_link_host,
:svg_icon

impersonates :user, with: ->(uuid) { User.find_by(uuid:) }
Expand Down Expand Up @@ -105,6 +106,10 @@ def svg_icon(icon_name, class: '')
render_to_string(partial: "icons/#{icon_name}", locals: { class: })
end

def form_link_host
Docuseal.default_url_options[:host]
end

def maybe_redirect_com
return if request.domain != 'docuseal.co'

Expand Down
2 changes: 2 additions & 0 deletions app/controllers/esign_settings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ def to_key
end
end

prepend_before_action :maybe_redirect_com, only: %i[show]

before_action :load_encrypted_config
authorize_resource :encrypted_config, parent: false, only: %i[new create]
authorize_resource :encrypted_config, only: %i[update destroy show]
Expand Down
9 changes: 8 additions & 1 deletion app/controllers/submissions_archived_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ def index
.or(@submissions.where.not(templates: { archived_at: nil }))
.preload(:created_by_user, template: :author)
@submissions = Submissions.search(@submissions, params[:q], search_template: true)
@submissions = Submissions::Filter.call(@submissions, current_user, params)

@pagy, @submissions = pagy(@submissions.preload(:submitters).order(id: :desc))
@submissions = if params[:completed_at_from].present? || params[:completed_at_to].present?
@submissions.order(Submitter.arel_table[:completed_at].maximum.desc)
else
@submissions.order(id: :desc)
end

@pagy, @submissions = pagy(@submissions.preload(submitters: :start_form_submission_events))
end
end
2 changes: 2 additions & 0 deletions app/controllers/submissions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class SubmissionsController < ApplicationController

load_and_authorize_resource :submission, only: %i[show destroy]

prepend_before_action :maybe_redirect_com, only: %i[show]

def show
@submission = Submissions.preload_with_pages(@submission)

Expand Down
9 changes: 8 additions & 1 deletion app/controllers/submissions_dashboard_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ def index
.preload(:created_by_user, template: :author)

@submissions = Submissions.search(@submissions, params[:q], search_template: true)
@submissions = Submissions::Filter.call(@submissions, current_user, params)

@submissions = @submissions.pending if params[:status] == 'pending'
@submissions = @submissions.completed if params[:status] == 'completed'

@pagy, @submissions = pagy(@submissions.preload(submitters: :start_form_submission_events).order(id: :desc))
@submissions = if params[:completed_at_from].present? || params[:completed_at_to].present?
@submissions.order(Submitter.arel_table[:completed_at].maximum.desc)
else
@submissions.order(id: :desc)
end

@pagy, @submissions = pagy(@submissions.preload(submitters: :start_form_submission_events))
end
end
18 changes: 16 additions & 2 deletions app/controllers/submissions_download_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,15 @@ def current_user_submitter?(submitter)
end

def build_urls(submitter)
filename_format = AccountConfig.find_or_initialize_by(account_id: submitter.account_id,
key: AccountConfig::DOCUMENT_FILENAME_FORMAT_KEY)&.value

Submitters.select_attachments_for_download(submitter).map do |attachment|
ActiveStorage::Blob.proxy_url(attachment.blob, expires_at: FILES_TTL.from_now.to_i)
ActiveStorage::Blob.proxy_url(
attachment.blob,
expires_at: FILES_TTL.from_now.to_i,
filename: Submitters.build_document_filename(submitter, attachment.blob, filename_format)
)
end
end

Expand All @@ -65,6 +72,13 @@ def build_combined_url(submitter)
attachment = submitter.submission.combined_document_attachment
attachment ||= Submissions::GenerateCombinedAttachment.call(submitter)

ActiveStorage::Blob.proxy_url(attachment.blob, expires_at: FILES_TTL.from_now.to_i)
filename_format = AccountConfig.find_or_initialize_by(account_id: submitter.account_id,
key: AccountConfig::DOCUMENT_FILENAME_FORMAT_KEY)&.value

ActiveStorage::Blob.proxy_url(
attachment.blob,
expires_at: FILES_TTL.from_now.to_i,
filename: Submitters.build_document_filename(submitter, attachment.blob, filename_format)
)
end
end
17 changes: 17 additions & 0 deletions app/controllers/submissions_filters_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class SubmissionsFiltersController < ApplicationController
ALLOWED_NAMES = %w[
author
completed_at
created_at
].freeze

skip_authorization_check

def show
return head :not_found unless ALLOWED_NAMES.include?(params[:name])

render params[:name]
end
end
4 changes: 2 additions & 2 deletions app/controllers/submissions_preview_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class SubmissionsPreviewController < ApplicationController
skip_before_action :authenticate_user!
skip_authorization_check

before_action :maybe_redirect_com, only: %i[show completed]
prepend_before_action :maybe_redirect_com, only: %i[show completed]

TTL = 40.minutes

Expand All @@ -20,7 +20,7 @@ def show

@submission ||= Submission.find_by!(slug: params[:slug])

if !@submission.submitters.all?(&:completed_at?) && current_user.blank?
if @submission.account.archived_at? || (!@submission.submitters.all?(&:completed_at?) && current_user.blank?)
raise ActionController::RoutingError, I18n.t('not_found')
end

Expand Down
16 changes: 11 additions & 5 deletions app/controllers/submit_form_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ class SubmitFormController < ApplicationController
skip_before_action :authenticate_user!
skip_authorization_check

before_action :maybe_redirect_com, only: %i[show completed]

CONFIG_KEYS = [].freeze

def show
Expand All @@ -17,7 +15,9 @@ def show
submission = @submitter.submission

return redirect_to submit_form_completed_path(@submitter.slug) if @submitter.completed_at?
return render :archived if submission.template.archived_at? || submission.archived_at?
return render :archived if submission.template.archived_at? ||
submission.archived_at? ||
@submitter.account.archived_at?
return render :expired if submission.expired?
return render :declined if @submitter.declined_at?
return render :awaiting if submission.template.preferences['submitters_order'] == 'preserved' &&
Expand All @@ -27,8 +27,7 @@ def show

Submitters::MaybeUpdateDefaultValues.call(@submitter, current_user)

@attachments_index = ActiveStorage::Attachment.where(record: submission.submitters, name: :attachments)
.preload(:blob).index_by(&:uuid)
@attachments_index = build_attachments_index(submission)

@form_configs = Submitters::FormConfigs.call(@submitter, CONFIG_KEYS)

Expand Down Expand Up @@ -80,4 +79,11 @@ def completed
end

def success; end

private

def build_attachments_index(submission)
ActiveStorage::Attachment.where(record: submission.submitters, name: :attachments)
.preload(:blob).index_by(&:uuid)
end
end
2 changes: 1 addition & 1 deletion app/controllers/submitters_send_email_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class SubmittersSendEmailController < ApplicationController
def create
if Docuseal.multitenant? && SubmissionEvent.exists?(submitter: @submitter,
event_type: 'send_email',
created_at: 24.hours.ago..Time.current)
created_at: 10.hours.ago..Time.current)
Rollbar.warning("Already sent: #{@submitter.id}") if defined?(Rollbar)

return redirect_back(fallback_location: submission_path(@submitter.submission),
Expand Down
9 changes: 8 additions & 1 deletion app/controllers/templates_archived_submissions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@ class TemplatesArchivedSubmissionsController < ApplicationController
def index
@submissions = @submissions.where.not(archived_at: nil)
@submissions = Submissions.search(@submissions, params[:q], search_values: true)
@submissions = Submissions::Filter.call(@submissions, current_user, params)

@pagy, @submissions = pagy(@submissions.preload(:submitters).order(id: :desc))
@submissions = if params[:completed_at_from].present? || params[:completed_at_to].present?
@submissions.order(Submitter.arel_table[:completed_at].maximum.desc)
else
@submissions.order(id: :desc)
end

@pagy, @submissions = pagy(@submissions.preload(submitters: :start_form_submission_events))
rescue ActiveRecord::RecordNotFound
redirect_to root_path
end
Expand Down
9 changes: 8 additions & 1 deletion app/controllers/templates_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,20 @@ def show
submissions = @template.submissions.accessible_by(current_ability)
submissions = submissions.active if @template.archived_at.blank?
submissions = Submissions.search(submissions, params[:q], search_values: true)
submissions = Submissions::Filter.call(submissions, current_user, params)

@base_submissions = submissions

submissions = submissions.pending if params[:status] == 'pending'
submissions = submissions.completed if params[:status] == 'completed'

@pagy, @submissions = pagy(submissions.preload(submitters: :start_form_submission_events).order(id: :desc))
submissions = if params[:completed_at_from].present? || params[:completed_at_to].present?
submissions.order(Submitter.arel_table[:completed_at].maximum.desc)
else
submissions.order(id: :desc)
end

@pagy, @submissions = pagy(submissions.preload(submitters: :start_form_submission_events))
rescue ActiveRecord::RecordNotFound
redirect_to root_path
end
Expand Down
2 changes: 2 additions & 0 deletions app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import ToggleAttribute from './elements/toggle_attribute'
import LinkedInput from './elements/linked_input'
import CheckboxGroup from './elements/checkbox_group'
import MaskedInput from './elements/masked_input'
import SetDateButton from './elements/set_date_button'

import * as TurboInstantClick from './lib/turbo_instant_click'

Expand Down Expand Up @@ -97,6 +98,7 @@ safeRegisterElement('toggle-attribute', ToggleAttribute)
safeRegisterElement('linked-input', LinkedInput)
safeRegisterElement('checkbox-group', CheckboxGroup)
safeRegisterElement('masked-input', MaskedInput)
safeRegisterElement('set-date-button', SetDateButton)

safeRegisterElement('template-builder', class extends HTMLElement {
connectedCallback () {
Expand Down
20 changes: 20 additions & 0 deletions app/javascript/elements/set_date_button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default class extends HTMLElement {
connectedCallback () {
this.button.addEventListener('click', () => {
this.fromInput.value = this.dataset.fromValue || ''
this.toInput.value = this.dataset.toValue || ''
})
}

get button () {
return this.querySelector('button')
}

get fromInput () {
return document.getElementById(this.dataset.fromId)
}

get toInput () {
return document.getElementById(this.dataset.toId)
}
}
1 change: 1 addition & 0 deletions app/javascript/submission_form/date_step.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<AppearsOn :field="field" />
<div class="text-center">
<input
:id="field.uuid"
ref="input"
v-model="value"
class="base-input !text-2xl text-center w-full"
Expand Down
1 change: 1 addition & 0 deletions app/javascript/submission_form/dropzone.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<div
id="dropzone"
class="flex h-32 w-full"
@dragover.prevent
@drop.prevent="onDropFiles"
Expand Down
20 changes: 14 additions & 6 deletions app/javascript/submission_form/form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
:with-label="!isAnonymousChecboxes && showFieldNames"
:current-step="currentStepFields"
:scroll-padding="scrollPadding"
@focus-step="[saveStep(), currentField.type !== 'checkbox' ? isFormVisible = true : '', goToStep($event, false, true)]"
@focus-step="[saveStep(), goToStep($event, false, true), currentField.type !== 'checkbox' ? isFormVisible = true : '']"
/>
<FieldAreas
:steps="readonlyConditionalFields.map((e) => [e])"
Expand Down Expand Up @@ -1039,10 +1039,14 @@ export default {
} else if (['not_empty', 'checked'].includes(c.action)) {
return acc && !isEmpty(this.values[c.field_uuid])
} else if (['equal', 'contains'].includes(c.action) && field) {
const option = field.options.find((o) => o.uuid === c.value)
const values = [this.values[c.field_uuid]].flat()
if (field.options) {
const option = field.options.find((o) => o.uuid === c.value)
const values = [this.values[c.field_uuid]].flat()
return acc && values.includes(this.optionValue(option, field.options.indexOf(option)))
return acc && values.includes(this.optionValue(option, field.options.indexOf(option)))
} else {
return acc && [this.values[c.field_uuid]].flat().includes(c.value)
}
} else if (['not_equal', 'does_not_contain'].includes(c.action) && field) {
const option = field.options.find((o) => o.uuid === c.value)
const values = [this.values[c.field_uuid]].flat()
Expand Down Expand Up @@ -1243,9 +1247,13 @@ export default {
if (response.status === 422 || response.status === 500) {
const data = await response.json()
const i18nError = data.error ? this.t(data.error.replace(/\s+/g, '_').toLowerCase()) : ''
if (data.error) {
const i18nKey = data.error.replace(/\s+/g, '_').toLowerCase()
alert(i18nError !== data.error ? i18nError : (data.error || this.t('value_is_invalid')))
alert(this.t(i18nKey) !== i18nKey ? this.t(i18nKey) : data.error)
} else {
alert(this.t('value_is_invalid'))
}
return Promise.reject(new Error(data.error))
}
Expand Down
Loading

0 comments on commit fa2d86b

Please sign in to comment.