From 905e0b22ed538cbb4de7b9ee578235f59db58a01 Mon Sep 17 00:00:00 2001 From: Joseph Benguira Date: Thu, 21 Sep 2023 02:03:05 +0300 Subject: [PATCH 001/127] Added Elestio as a deployment option Hello, I'm Joseph Benguira, Founder of Elest.io I'm suggesting to add Elestio as a deployment option near the other one-click options in your list. FYI I'm also trying to contact you through Linkedin to check if you are interested in a revenue sharing partnership (we will share with you part of profits generated on Elestio) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2eab1042..0c16c8d3 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,8 @@ DocuSeal is an open source platform that provides secure and efficient digital d | [Deploy on Heroku](https://heroku.com/deploy?template=https://github.com/docusealco/docuseal-heroku) | [Deploy on Railway](https://railway.app/template/IGoDnc?referralCode=ruU7JR)| |**DigitalOcean**|**Render**| | [Deploy on DigitalOcean](https://cloud.digitalocean.com/apps/new?repo=https://github.com/docusealco/docuseal-digitalocean/tree/master&refcode=421d50f53990) | [Deploy to Render](https://render.com/deploy?repo=https://github.com/docusealco/docuseal-render) -|**Koyeb**| | -| [Deploy on Koyeb](https://app.koyeb.com/deploy?name=docuseal&type=docker&image=docker.io/docuseal/docuseal&env[PORT]=8000&env[DATABASE_URL]=CHANGE_ME&env[SECRET_KEY_BASE]=CHANGE_ME&ports=8000;http;/) | | +|**Koyeb**|**Elestio**| +| [Deploy on Koyeb](https://app.koyeb.com/deploy?name=docuseal&type=docker&image=docker.io/docuseal/docuseal&env[PORT]=8000&env[DATABASE_URL]=CHANGE_ME&env[SECRET_KEY_BASE]=CHANGE_ME&ports=8000;http;/) | [Deploy on Elestio](https://dash.elest.io/deploy?soft=DocuSeal&id=339) | #### Docker From dc02964d9b81b2555da00d49fff5a23bb275696a Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Tue, 19 Sep 2023 19:33:34 +0300 Subject: [PATCH 002/127] ensure template account is set --- app/controllers/templates_uploads_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/templates_uploads_controller.rb b/app/controllers/templates_uploads_controller.rb index fd57f577..1a111dee 100644 --- a/app/controllers/templates_uploads_controller.rb +++ b/app/controllers/templates_uploads_controller.rb @@ -4,6 +4,7 @@ class TemplatesUploadsController < ApplicationController load_and_authorize_resource :template, parent: false def create + @template.account = current_account @template.author = current_user @template.name = File.basename(params[:files].first.original_filename, '.*') From ee350324e5def607f3818e20a8b78960afe2e52e Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Wed, 20 Sep 2023 00:13:14 +0300 Subject: [PATCH 003/127] add initials field --- app/javascript/application.scss | 17 ++ app/javascript/submission_form/area.vue | 16 +- app/javascript/submission_form/form.vue | 20 +- app/javascript/submission_form/i18n.js | 63 +++++ .../submission_form/initials_step.vue | 245 ++++++++++++++++++ .../submission_form/signature_step.vue | 28 +- app/javascript/template_builder/builder.vue | 11 +- app/javascript/template_builder/field.vue | 33 ++- .../template_builder/field_type.vue | 8 +- app/javascript/template_builder/fields.vue | 2 +- app/views/submissions/_value.html.erb | 2 +- app/views/submissions/show.html.erb | 4 +- lib/submissions/generate_audit_trail.rb | 4 +- .../generate_result_attachments.rb | 2 +- 14 files changed, 426 insertions(+), 29 deletions(-) create mode 100644 app/javascript/submission_form/initials_step.vue diff --git a/app/javascript/application.scss b/app/javascript/application.scss index 4cb86b4f..e731dfc5 100644 --- a/app/javascript/application.scss +++ b/app/javascript/application.scss @@ -74,3 +74,20 @@ button[disabled] .enabled { .base-select { @apply select base-input w-full font-normal; } + +.tooltip-bottom-end:before { + transform: translateX(-95%); + top: var(--tooltip-offset); + left: 100%; + right: auto; + bottom: auto; +} + +.tooltip-bottom-end:after { + transform: translateX(-25%); + border-color: transparent transparent var(--tooltip-color) transparent; + top: var(--tooltip-tail-offset); + left: 50%; + right: auto; + bottom: auto; +} diff --git a/app/javascript/submission_form/area.vue b/app/javascript/submission_form/area.vue index 7f057bab..96eef249 100644 --- a/app/javascript/submission_form/area.vue +++ b/app/javascript/submission_form/area.vue @@ -47,6 +47,11 @@ class="object-contain mx-auto" :src="signature.url" > +
diff --git a/app/javascript/submission_form/signature_step.vue b/app/javascript/submission_form/signature_step.vue index ff2269c5..9806a417 100644 --- a/app/javascript/submission_form/signature_step.vue +++ b/app/javascript/submission_form/signature_step.vue @@ -3,7 +3,7 @@
+ >{{ field.name || t('signature') }}
- Redraw + {{ t('redraw') }}
diff --git a/app/views/shared/_navbar.html.erb b/app/views/shared/_navbar.html.erb index 889c9bbc..74db7f2d 100644 --- a/app/views/shared/_navbar.html.erb +++ b/app/views/shared/_navbar.html.erb @@ -8,7 +8,12 @@ <% if signed_in? %>
<% if Docuseal.demo? %> - <%= render 'shared/github_button' %> + + Sign Up + + <% else %>
<% if can?(:manage, EncryptedConfig) && !can?(:manage, :tenants) %> diff --git a/lib/accounts.rb b/lib/accounts.rb index 504fb005..1a73c459 100644 --- a/lib/accounts.rb +++ b/lib/accounts.rb @@ -8,6 +8,7 @@ module Accounts new_user = account.users.first.dup + new_user.uuid = SecureRandom.uuid new_user.account = new_account new_user.encrypted_password = SecureRandom.hex new_user.email = "#{SecureRandom.hex}@docuseal.co" @@ -18,12 +19,14 @@ module Accounts new_template.account = new_account new_template.slug = SecureRandom.base58(14) + new_template.deleted_at = nil new_template.save! Templates::CloneAttachments.call(template: new_template, original_template: template) end new_user.save!(validate: false) + new_account.templates.update_all(folder_id: new_account.default_template_folder.id) new_account end From c621166b45c393c4a492189bd71de1f9b5b2f65d Mon Sep 17 00:00:00 2001 From: DocuSeal Date: Sat, 14 Oct 2023 22:31:32 +0300 Subject: [PATCH 061/127] use full name form company name if missing --- app/controllers/registrations_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index bca21d22..ca07f304 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -43,7 +43,7 @@ class RegistrationsController < Devise::RegistrationsController self.resource = account.users.new(user_params) - account.name ||= "#{resource.full_name}'s Company" if params[:action] == 'create' + account.name ||= resource.full_name if params[:action] == 'create' end def user_params From 60b32fec9464b685e9196b5d2ea0d5641fb6b69b Mon Sep 17 00:00:00 2001 From: DocuSeal Date: Sun, 15 Oct 2023 00:58:03 +0300 Subject: [PATCH 062/127] adjust sign up header buttons --- app/views/shared/_navbar.html.erb | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/app/views/shared/_navbar.html.erb b/app/views/shared/_navbar.html.erb index 74db7f2d..589ad6ac 100644 --- a/app/views/shared/_navbar.html.erb +++ b/app/views/shared/_navbar.html.erb @@ -63,18 +63,19 @@
<% else %> -
- <%= link_to new_user_session_path, class: 'font-medium text-lg' do %> - - <%= svg_icon('login', class: 'w-6 h-6') %> - Sign in - +
+ <% if request.path != new_user_session_path %> + <%= link_to new_user_session_path, class: 'font-medium text-lg' do %> + + <%= svg_icon('login', class: 'w-6 h-6') %> + Sign in + + <% end %> <% end %> - <% if Docuseal.multitenant? %> - <%= link_to registration_path, class: 'font-medium text-lg hidden md:inline' do %> + <% if Docuseal.multitenant? && !request.path.in?([registration_path, new_registration_path])%> + <%= link_to registration_path, class: 'btn btn-neutral btn-sm btn-outline' do %> - <%= svg_icon('user_plus', class: 'w-6 h-6') %> - Try for Free + Create free Account <% end %> <% end %> From 6dc21e66e1cd0d4eed732e3a92044c5535eee88f Mon Sep 17 00:00:00 2001 From: DocuSeal Date: Sun, 15 Oct 2023 21:41:47 +0300 Subject: [PATCH 063/127] return to required fields --- app/javascript/submission_form/form.vue | 45 ++++++++++++++++++++----- app/javascript/submission_form/i18n.js | 9 +++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue index f231e3d4..d84a9ea5 100644 --- a/app/javascript/submission_form/form.vue +++ b/app/javascript/submission_form/form.vue @@ -297,6 +297,7 @@
+
+ {{ t('please_fill_all_required_fields') }} +
@@ -457,9 +464,11 @@ export default { return { isCompleted: false, isFormVisible: true, + showFillAllRequiredFields: false, currentStep: 0, isSubmitting: false, submittedValues: {}, + isSecondWalkthrough: false, recalculateButtonDisabledKey: '' } }, @@ -514,10 +523,20 @@ export default { this.submittedValues = JSON.parse(JSON.stringify(this.values)) if (this.goToLast) { - this.currentStep = Math.min( - this.stepFields.indexOf([...this.stepFields].reverse().find((fields) => fields.some((f) => !!this.values[f.uuid]))) + 1, - this.stepFields.length - 1 - ) + const requiredEmptyStepIndex = this.stepFields.indexOf(this.stepFields.find((fields) => fields.some((f) => f.required && !this.values[f.uuid]))) + const lastFilledStepIndex = this.stepFields.indexOf([...this.stepFields].reverse().find((fields) => fields.some((f) => !!this.values[f.uuid]))) + 1 + + const indexesList = [this.stepFields.length - 1] + + if (requiredEmptyStepIndex !== -1) { + indexesList.push(requiredEmptyStepIndex) + } + + if (lastFilledStepIndex !== -1) { + indexesList.push(lastFilledStepIndex) + } + + this.currentStep = Math.min(...indexesList) } if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) { @@ -608,6 +627,7 @@ export default { }, goToStep (step, scrollToArea = false, clickUpload = false) { this.currentStep = this.stepFields.indexOf(step) + this.showFillAllRequiredFields = false this.$nextTick(() => { this.recalculateButtonDisabledKey = Math.random() @@ -642,12 +662,13 @@ export default { stepPromise().then(async () => { const emptyRequiredField = this.stepFields.find((fields, index) => { - return index < this.currentStep && fields[0].required && (fields[0].type === 'phone' || !this.allowToSkip) && !this.submittedValues[fields[0].uuid] + return index < this.currentStep && fields[0].required && (fields[0].type === 'phone' || !this.allowToSkip || !this.isSecondWalkthrough) && !this.submittedValues[fields[0].uuid] }) const formData = new FormData(this.$refs.form) + const isLastStep = this.currentStep === this.stepFields.length - 1 - if (this.currentStep === this.stepFields.length - 1 && !emptyRequiredField) { + if (isLastStep && !emptyRequiredField) { formData.append('completed', 'true') } @@ -662,10 +683,18 @@ export default { this.submittedValues[this.currentField.uuid] = this.values[this.currentField.uuid] - const nextStep = emptyRequiredField || this.stepFields[this.currentStep + 1] + if (isLastStep) { + this.isSecondWalkthrough = true + } + + const nextStep = (isLastStep && emptyRequiredField) || this.stepFields[this.currentStep + 1] if (nextStep) { this.goToStep(nextStep, true) + + if (emptyRequiredField === nextStep) { + this.showFillAllRequiredFields = true + } } else { this.isCompleted = true } diff --git a/app/javascript/submission_form/i18n.js b/app/javascript/submission_form/i18n.js index 5b57ed7b..3db20ffd 100644 --- a/app/javascript/submission_form/i18n.js +++ b/app/javascript/submission_form/i18n.js @@ -29,6 +29,7 @@ const en = { sending: 'Sending...', resend_code: 'Re-send code', verification_code_has_been_resent: 'Verification code has been re-sent via SMS', + please_fill_all_required_fields: 'Please fill all required fields', email_has_been_sent: 'Email has been sent' } @@ -63,6 +64,7 @@ const es = { sending: 'Enviando...', resend_code: 'Reenviar código', verification_code_has_been_resent: 'El código de verificación ha sido reenviado por SMS', + please_fill_all_required_fields: 'Por favor, complete todos los campos obligatorios', email_has_been_sent: 'El correo electrónico ha sido enviado' } @@ -97,6 +99,7 @@ const it = { sending: 'Invio in corso...', resend_code: 'Rinvia codice', verification_code_has_been_resent: 'Il codice di verifica è stato rinviato tramite SMS', + please_fill_all_required_fields: 'Si prega di compilare tutti i campi obbligatori', email_has_been_sent: "L'email è stata inviata" } @@ -131,6 +134,7 @@ const de = { sending: 'Senden...', resend_code: 'Code erneut senden', verification_code_has_been_resent: 'Die Verifizierungscode wurde erneut per SMS gesendet', + please_fill_all_required_fields: 'Bitte füllen Sie alle erforderlichen Felder aus', email_has_been_sent: 'Die E-Mail wurde gesendet' } @@ -165,6 +169,7 @@ const fr = { sending: 'Envoi en cours...', resend_code: 'Renvoyer le code', verification_code_has_been_resent: 'Le code de vérification a été renvoyé par SMS', + please_fill_all_required_fields: 'Veuillez remplir tous les champs obligatoires', email_has_been_sent: "L'email a été envoyé" } @@ -199,6 +204,7 @@ const pl = { sending: 'Wysyłanie...', resend_code: 'Ponownie wyślij kod', verification_code_has_been_resent: 'Kod weryfikacyjny został ponownie wysłany', + please_fill_all_required_fields: 'Proszę wypełnić wszystkie wymagane pola', email_has_been_sent: 'E-mail został wysłany' } @@ -233,6 +239,7 @@ const uk = { sending: 'Надсилаю...', resend_code: 'Повторно відправити код', verification_code_has_been_resent: 'Код підтвердження був повторно надісланий', + please_fill_all_required_fields: "Будь ласка, заповніть всі обов'язкові поля", email_has_been_sent: 'Електронний лист був відправлений' } @@ -267,6 +274,7 @@ const cs = { sending: 'Odesílání...', resend_code: 'Znovu odeslat kód', verification_code_has_been_resent: 'Ověřovací kód byl znovu odeslán', + please_fill_all_required_fields: 'Prosím vyplňte všechny povinné položky', email_has_been_sent: 'E-mail byl odeslán' } @@ -301,6 +309,7 @@ const pt = { sending: 'Enviando...', resend_code: 'Reenviar código', verification_code_has_been_resent: 'O código de verificação foi reenviado via SMS', + please_fill_all_required_fields: 'Por favor, preencha todos os campos obrigatórios', email_has_been_sent: 'Email enviado' } From 698031cfc0aa673077ce8a186dbf9582d9849951 Mon Sep 17 00:00:00 2001 From: DocuSeal Date: Sun, 15 Oct 2023 22:59:32 +0300 Subject: [PATCH 064/127] add current date button --- app/javascript/submission_form/form.vue | 36 ++++++++++++++++--------- app/javascript/submission_form/i18n.js | 18 +++++++++++++ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue index d84a9ea5..0671bb2d 100644 --- a/app/javascript/submission_form/form.vue +++ b/app/javascript/submission_form/form.vue @@ -86,17 +86,21 @@
- -
+
+ + +
Date: Mon, 16 Oct 2023 00:41:14 +0300 Subject: [PATCH 065/127] add ability to toggle textarea --- app/javascript/form.scss | 4 + app/javascript/submission_form/area.vue | 7 +- app/javascript/submission_form/form.vue | 32 ++--- app/javascript/submission_form/i18n.js | 9 ++ app/javascript/submission_form/text_step.vue | 111 ++++++++++++++++++ app/views/shared/_search_input.html.erb | 8 +- app/views/submissions/_value.html.erb | 4 +- .../generate_result_attachments.rb | 4 +- 8 files changed, 142 insertions(+), 37 deletions(-) create mode 100644 app/javascript/submission_form/text_step.vue diff --git a/app/javascript/form.scss b/app/javascript/form.scss index a9bac997..c6686829 100644 --- a/app/javascript/form.scss +++ b/app/javascript/form.scss @@ -47,6 +47,10 @@ select:required:invalid { @apply border-base-content/20; } +.base-textarea { + @apply textarea textarea-bordered bg-white rounded-3xl; +} + .btn { @apply no-animation; } diff --git a/app/javascript/submission_form/area.vue b/app/javascript/submission_form/area.vue index 96eef249..f0a56a43 100644 --- a/app/javascript/submission_form/area.vue +++ b/app/javascript/submission_form/area.vue @@ -110,9 +110,10 @@ {{ formattedDate }} - - {{ modelValue }} - + {{ modelValue }}
diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue index 0671bb2d..b6255055 100644 --- a/app/javascript/submission_form/form.vue +++ b/app/javascript/submission_form/form.vue @@ -58,32 +58,12 @@ >
- -
-
- -
@@ -363,6 +343,7 @@ import InitialsStep from './initials_step' import AttachmentStep from './attachment_step' import MultiSelectStep from './multi_select_step' import PhoneStep from './phone_step' +import TextStep from './text_step' import FormCompleted from './completed' import { IconInnerShadowTop, IconArrowsDiagonal, IconArrowsDiagonalMinimize2, IconCalendarCheck } from '@tabler/icons-vue' import { t } from './i18n' @@ -378,6 +359,7 @@ export default { MultiSelectStep, IconInnerShadowTop, IconArrowsDiagonal, + TextStep, PhoneStep, IconCalendarCheck, IconArrowsDiagonalMinimize2, diff --git a/app/javascript/submission_form/i18n.js b/app/javascript/submission_form/i18n.js index fec800ab..05e7339d 100644 --- a/app/javascript/submission_form/i18n.js +++ b/app/javascript/submission_form/i18n.js @@ -31,6 +31,7 @@ const en = { verification_code_has_been_resent: 'Verification code has been re-sent via SMS', please_fill_all_required_fields: 'Please fill all required fields', set_today: 'Set Today', + toggle_multiline_text: 'Toggle Multiline Text', date: 'Date', email_has_been_sent: 'Email has been sent' } @@ -69,6 +70,7 @@ const es = { please_fill_all_required_fields: 'Por favor, complete todos los campos obligatorios', set_today: 'Establecer Hoy', date: 'Fecha', + toggle_multiline_text: 'Alternar Texto Multilínea', email_has_been_sent: 'El correo electrónico ha sido enviado' } @@ -106,6 +108,7 @@ const it = { please_fill_all_required_fields: 'Si prega di compilare tutti i campi obbligatori', set_today: 'Imposta Oggi', date: 'Data', + toggle_multiline_text: 'Attiva Testo Multilinea', email_has_been_sent: "L'email è stata inviata" } @@ -143,6 +146,7 @@ const de = { please_fill_all_required_fields: 'Bitte füllen Sie alle erforderlichen Felder aus', set_today: 'Heute einstellen', date: 'Datum', + toggle_multiline_text: 'Mehrzeiligen Text umschalten', email_has_been_sent: 'Die E-Mail wurde gesendet' } @@ -180,6 +184,7 @@ const fr = { please_fill_all_required_fields: 'Veuillez remplir tous les champs obligatoires', set_today: "Définir Aujourd'hui", date: 'Date', + toggle_multiline_text: 'Basculer le Texte Multiligne', email_has_been_sent: "L'email a été envoyé" } @@ -217,6 +222,7 @@ const pl = { please_fill_all_required_fields: 'Proszę wypełnić wszystkie wymagane pola', set_today: 'Ustaw Dziś', date: 'Data', + toggle_multiline_text: 'Przełącz Tekst Wielolinijkowy', email_has_been_sent: 'E-mail został wysłany' } @@ -254,6 +260,7 @@ const uk = { please_fill_all_required_fields: "Будь ласка, заповніть всі обов'язкові поля", set_today: 'Задати Сьогодні', date: 'Дата', + toggle_multiline_text: 'Перемкнути Багаторядковий Текст', email_has_been_sent: 'Електронний лист був відправлений' } @@ -291,6 +298,7 @@ const cs = { please_fill_all_required_fields: 'Prosím vyplňte všechny povinné položky', set_today: 'Nastavit Dnes', date: 'Datum', + toggle_multiline_text: 'Přepnout Víceřádkový Text', email_has_been_sent: 'E-mail byl odeslán' } @@ -328,6 +336,7 @@ const pt = { please_fill_all_required_fields: 'Por favor, preencha todos os campos obrigatórios', set_today: 'Definir Hoje', date: 'Data', + toggle_multiline_text: 'Alternar Texto Multilinha', email_has_been_sent: 'Email enviado' } diff --git a/app/javascript/submission_form/text_step.vue b/app/javascript/submission_form/text_step.vue new file mode 100644 index 00000000..19c54a69 --- /dev/null +++ b/app/javascript/submission_form/text_step.vue @@ -0,0 +1,111 @@ +