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 11, 2024
2 parents 50acff2 + 8ecaa4f commit 0c2abf2
Show file tree
Hide file tree
Showing 38 changed files with 528 additions and 172 deletions.
4 changes: 2 additions & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ Metrics/AbcSize:
- spec/**/*

Metrics/ModuleLength:
Max: 500
Max: 1000

Metrics/ClassLength:
Max: 500
Max: 1000

RSpec/NestedGroups:
Max: 6
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/webhook_secret_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ def update
webhook_secret_params[:key] => webhook_secret_params[:value]
}.compact_blank)

redirect_back(fallback_location: settings_webhooks_path, notice: I18n.t('webhook_secret_has_been_saved'))
redirect_back(fallback_location: settings_webhook_path(@webhook_url),
notice: I18n.t('webhook_secret_has_been_saved'))
end

private
Expand Down
43 changes: 34 additions & 9 deletions app/controllers/webhook_settings_controller.rb
Original file line number Diff line number Diff line change
@@ -1,22 +1,47 @@
# frozen_string_literal: true

class WebhookSettingsController < ApplicationController
before_action :load_webhook_url
authorize_resource :webhook_url, parent: false
load_and_authorize_resource :webhook_url, parent: false, only: %i[index show new create update destroy]
load_and_authorize_resource :webhook_url, only: %i[resend], id_param: :webhook_id

def index
@webhook_urls = @webhook_urls.order(id: :desc)
@webhook_url = @webhook_urls.first_or_initialize

render @webhook_urls.size > 1 ? 'index' : 'show'
end

def show; end

def create
@webhook_url.assign_attributes(webhook_params)
def new; end

@webhook_url.url.present? ? @webhook_url.save! : @webhook_url.delete
def create
@webhook_url.save!

redirect_back(fallback_location: settings_webhooks_path, notice: I18n.t('webhook_url_has_been_saved'))
redirect_to settings_webhooks_path, notice: I18n.t('webhook_url_has_been_saved')
end

def update
@webhook_url.update!(update_params)

redirect_back(fallback_location: settings_webhook_path(@webhook_url),
notice: I18n.t('webhook_url_has_been_updated'))
end

def destroy
@webhook_url.destroy!

redirect_to settings_webhooks_path, notice: I18n.t('webhook_url_has_been_deleted')
end

def resend
submitter = current_account.submitters.where.not(completed_at: nil).order(:id).last

if submitter.blank? || @webhook_url.blank?
return redirect_back(fallback_location: settings_webhooks_path,
alert: I18n.t('unable_to_resend_webhook_request'))
end

SendFormCompletedWebhookRequestJob.perform_async('submitter_id' => submitter.id,
'webhook_url_id' => @webhook_url.id)

Expand All @@ -25,11 +50,11 @@ def update

private

def load_webhook_url
@webhook_url = current_account.webhook_urls.first_or_initialize
def create_params
params.require(:webhook_url).permit(:url, events: []).reverse_merge(events: [])
end

def webhook_params
def update_params
params.require(:webhook_url).permit(:url)
end
end
4 changes: 4 additions & 0 deletions app/javascript/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ window.customElements.define('draw-signature', class extends HTMLElement {

this.pad = new SignaturePad(this.canvas)

if (this.dataset.color) {
this.pad.penColor = this.dataset.color
}

this.pad.addEventListener('endStroke', () => {
this.updateSubmitButtonVisibility()
})
Expand Down
9 changes: 6 additions & 3 deletions app/javascript/submission_form/area.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
</template>
</div>
<div
v-if="isActive"
ref="scrollToElem"
class="absolute"
:style="{ top: scrollPadding }"
Expand Down Expand Up @@ -405,8 +404,12 @@ export default {
}
if (this.field.preferences?.font_size) {
style.fontSize = `clamp(4pt, 1.6vw, ${this.field.preferences.font_size}pt)`
style.lineHeight = `clamp(6pt, 2.0vw, ${parseInt(this.field.preferences.font_size) + 3}pt)`
style.fontSize = `clamp(4pt, 1.6vw, ${parseInt(this.field.preferences.font_size) * 1.23}pt)`
style.lineHeight = `clamp(6pt, 2.0vw, ${parseInt(this.field.preferences.font_size) * 1.23 + 3}pt)`
}
if (this.field.preferences?.color) {
style.color = this.field.preferences.color
}
return style
Expand Down
68 changes: 64 additions & 4 deletions app/javascript/submission_form/form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,44 @@
:fields="formulaFields"
:values="values"
/>
<Teleport
v-if="completeButtonToRef"
:to="completeButtonToRef"
>
<span
v-if="(emptyValueRequiredStep && ((stepFields.length - 1) !== currentStep || currentStepFields !== emptyValueRequiredStep)) || isCompleted"
class="tooltip-left"
:class="{ tooltip: !isCompleted }"
:data-tip="t('fill_all_required_fields_to_complete')"
>
<button
class="btn btn-sm btn-neutral text-white px-4 w-full flex justify-center btn-disabled pointer-events-auto"
@click="[isFormVisible = true, !isCompleted && goToStep(stepFields.indexOf(emptyValueRequiredStep), true, false)]"
>
{{ t('complete') }}
</button>
</span>
<button
v-else
id="complete_form_button"
class="btn btn-sm btn-neutral text-white px-4 w-full flex justify-center"
form="steps_form"
type="submit"
name="completed"
value="true"
:disabled="isSubmittingComplete"
>
<span class="flex items-center">
<IconInnerShadowTop
v-if="isSubmittingComplete"
class="mr-1 animate-spin w-5 h-5"
/>
<span>
{{ t('complete') }}
</span>
</span>
</button>
</Teleport>
<button
v-if="!isFormVisible"
id="expand_form_button"
Expand Down Expand Up @@ -74,6 +112,7 @@
>
<form
v-if="!isCompleted && !isInvite"
id="steps_form"
ref="form"
:action="submitPath"
method="post"
Expand Down Expand Up @@ -592,6 +631,11 @@ export default {
required: false,
default: false
},
completeButtonToRef: {
type: Object,
required: false,
default: null
},
attachments: {
type: Array,
required: false,
Expand Down Expand Up @@ -772,6 +816,7 @@ export default {
phoneVerifiedValues: {},
orientation: screen?.orientation?.type,
isSubmitting: false,
isSubmittingComplete: false,
submittedValues: {},
recalculateButtonDisabledKey: ''
}
Expand All @@ -780,6 +825,13 @@ export default {
isMobile () {
return /android|iphone|ipad/i.test(navigator.userAgent)
},
emptyValueRequiredStep () {
return this.stepFields.find((fields, index) => {
return fields.some((f) => {
return f.required && isEmpty(this.values[f.uuid])
})
})
},
submitButtonText () {
if (this.alwaysMinimize) {
return this.t('submit')
Expand Down Expand Up @@ -1146,9 +1198,15 @@ export default {
scrollIntoArea (area) {
return this.$refs.areas.scrollIntoArea(area)
},
async submitStep () {
async submitStep (e) {
this.isSubmitting = true
const forceComplete = e?.submitter?.getAttribute('name') === 'completed'
if (forceComplete) {
this.isSubmittingComplete = true
}
const submitStep = this.currentStep
const stepPromise = ['signature', 'phone', 'initials', 'payment'].includes(this.currentField.type)
Expand All @@ -1157,7 +1215,7 @@ export default {
stepPromise().then(async () => {
const emptyRequiredField = this.stepFields.find((fields, index) => {
if (index >= submitStep) {
if (forceComplete ? index === submitStep : index >= submitStep) {
return false
}
Expand All @@ -1167,7 +1225,7 @@ export default {
})
const formData = new FormData(this.$refs.form)
const isLastStep = submitStep === this.stepFields.length - 1
const isLastStep = (submitStep === this.stepFields.length - 1) || forceComplete
if (isLastStep && !emptyRequiredField && !this.inviteSubmitters.length) {
formData.append('completed', 'true')
Expand All @@ -1192,7 +1250,7 @@ export default {
return Promise.reject(new Error(data.error))
}
const nextStep = (isLastStep && emptyRequiredField) || this.stepFields[submitStep + 1]
const nextStep = (isLastStep && emptyRequiredField) || (forceComplete ? null : this.stepFields[submitStep + 1])
if (nextStep) {
if (this.alwaysMinimize) {
Expand All @@ -1213,6 +1271,7 @@ export default {
console.error(error)
}).finally(() => {
this.isSubmitting = false
this.isSubmittingComplete = false
})
}).catch(error => {
if (error?.message === 'Image too small') {
Expand All @@ -1222,6 +1281,7 @@ export default {
}
}).finally(() => {
this.isSubmitting = false
this.isSubmittingComplete = false
})
},
minimizeForm () {
Expand Down
13 changes: 13 additions & 0 deletions app/javascript/submission_form/i18n.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const en = {
complete: 'Complete',
fill_all_required_fields_to_complete: 'Fill all required fields to complete',
sign_and_complete: 'Sign and Complete',
text: 'Text',
by_clicking_you_agree_to_the: 'By clicking "{button}", you agree to the',
Expand Down Expand Up @@ -93,6 +94,7 @@ const en = {

const es = {
complete: 'Completar',
fill_all_required_fields_to_complete: 'Complete todos los campos requeridos para finalizar',
sign_and_complete: 'Firmar y Completar',
invite: 'Invitar',
email: 'Correo electrónico',
Expand Down Expand Up @@ -185,6 +187,7 @@ const es = {

const it = {
complete: 'Completa',
fill_all_required_fields_to_complete: 'Compila tutti i campi obbligatori per completare',
sign_and_complete: 'Firma e Completa',
invite: 'Invita',
email: 'Email',
Expand Down Expand Up @@ -277,6 +280,7 @@ const it = {

const de = {
complete: 'Abschließen',
fill_all_required_fields_to_complete: 'Alle erforderlichen Felder ausfüllen, um abzuschließen',
sign_and_complete: 'Signieren und Abschließen',
invite: 'Einladen',
email: 'E-Mail',
Expand Down Expand Up @@ -369,6 +373,7 @@ const de = {

const fr = {
complete: 'Terminer',
fill_all_required_fields_to_complete: 'Veuillez remplir tous les champs obligatoires pour compléter',
sign_and_complete: 'Signer et Terminer',
invite: 'Inviter',
email: 'Courriel',
Expand Down Expand Up @@ -461,6 +466,7 @@ const fr = {

const pl = {
complete: 'Zakończ',
fill_all_required_fields_to_complete: 'Uzupełnij wszystkie wymagane pola, aby zakończyć',
sign_and_complete: 'Podpisz i zakończ',
invite: 'Zaproś',
email: 'E-mail',
Expand Down Expand Up @@ -553,6 +559,7 @@ const pl = {

const uk = {
complete: 'Завершити',
fill_all_required_fields_to_complete: "Заповніть всі обов'язкові поля для завершення",
sign_and_complete: 'Підписати і завершити',
invite: 'Запросити',
email: 'Електронна пошта',
Expand Down Expand Up @@ -645,6 +652,7 @@ const uk = {

const cs = {
complete: 'Dokončit',
fill_all_required_fields_to_complete: 'Please complete all mandatory fields',
sign_and_complete: 'Podepsat a dokončit',
invite: 'Pozvat',
email: 'E-mail',
Expand Down Expand Up @@ -737,6 +745,7 @@ const cs = {

const pt = {
complete: 'Completar',
preencher_todos_os_campos_obrigatórios_para_concluir: 'Preencher todos os campos obrigatórios para concluir',
sign_and_complete: 'Assinar e Completar',
invite: 'Convidar',
email: 'E-mail',
Expand Down Expand Up @@ -829,6 +838,7 @@ const pt = {

const he = {
complete: 'השלם',
fill_all_required_fields_to_complete: 'נא למלא את כל השדות הנדרשים להשלמה',
sign_and_complete: 'חתום והשלם',
invite: 'הזמן',
email: 'דוא"ל',
Expand Down Expand Up @@ -922,6 +932,7 @@ const he = {

const nl = {
complete: 'Voltooien',
vul_alle_verplichte_velden_in_om_te_voltooien: 'Vul alle verplichte velden in om te voltooien',
sign_and_complete: 'Ondertekenen en voltooien',
invite: 'Uitnodigen',
email: 'E-mail',
Expand Down Expand Up @@ -1015,6 +1026,7 @@ const nl = {

const ar = {
complete: 'اكتمال',
fill_all_required_fields_to_complete: 'يرجى ملء جميع الحقول المطلوبة لإكمال',
sign_and_complete: 'التوقيع والاكتمال',
invite: 'دعوة',
email: 'البريد الإلكتروني',
Expand Down Expand Up @@ -1107,6 +1119,7 @@ const ar = {

const ko = {
complete: '완료',
fill_all_required_fields_to_complete: '모든 필수 필드를 작성하여 완료하세요',
sign_and_complete: '서명하고 완료하기',
invite: '초대하기',
email: '이메일',
Expand Down
4 changes: 4 additions & 0 deletions app/javascript/submission_form/initials_step.vue
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ export default {
if (this.$refs.canvas) {
this.pad = new SignaturePad(this.$refs.canvas)
if (this.field.preferences?.color) {
this.pad.penColor = this.field.preferences.color
}
this.pad.addEventListener('beginStroke', () => {
this.isInitialsStarted = true
Expand Down
4 changes: 4 additions & 0 deletions app/javascript/submission_form/signature_step.vue
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,10 @@ export default {
if (this.$refs.canvas) {
this.pad = new SignaturePad(this.$refs.canvas)
if (this.field.preferences?.color) {
this.pad.penColor = this.field.preferences.color
}
this.pad.addEventListener('endStroke', () => {
this.isSignatureStarted = true
Expand Down
Loading

0 comments on commit 0c2abf2

Please sign in to comment.