From ce31ebde1e257c4a7a90504a7e92bb46b5223546 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Mon, 11 Nov 2024 19:19:06 +0200 Subject: [PATCH 01/32] add delay --- lib/submissions.rb | 10 ++++++---- lib/submitters.rb | 10 +++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/submissions.rb b/lib/submissions.rb index 1c35b0c2..1e7f9e44 100644 --- a/lib/submissions.rb +++ b/lib/submissions.rb @@ -88,17 +88,19 @@ module Submissions ) end - def send_signature_requests(submissions) - submissions.each do |submission| + def send_signature_requests(submissions, delay: nil) + submissions.each_with_index do |submission, index| + delay_seconds = (delay + index).seconds if delay + submitters = submission.submitters.reject(&:completed_at?) if submission.submitters_order_preserved? first_submitter = submission.template_submitters.filter_map { |s| submitters.find { |e| e.uuid == s['uuid'] } }.first - Submitters.send_signature_requests([first_submitter]) if first_submitter + Submitters.send_signature_requests([first_submitter], delay_seconds:) if first_submitter else - Submitters.send_signature_requests(submitters) + Submitters.send_signature_requests(submitters, delay_seconds:) end end end diff --git a/lib/submitters.rb b/lib/submitters.rb index 18b2d151..19a44d4c 100644 --- a/lib/submitters.rb +++ b/lib/submitters.rb @@ -94,12 +94,16 @@ module Submitters preferences end - def send_signature_requests(submitters) - submitters.each do |submitter| + def send_signature_requests(submitters, delay_seconds: nil) + submitters.each_with_index do |submitter, index| next if submitter.email.blank? next if submitter.preferences['send_email'] == false - SendSubmitterInvitationEmailJob.perform_async('submitter_id' => submitter.id) + if delay_seconds + SendSubmitterInvitationEmailJob.perform_in((delay_seconds + index).seconds, 'submitter_id' => submitter.id) + else + SendSubmitterInvitationEmailJob.perform_async('submitter_id' => submitter.id) + end end end From 27901063ed4dc4cbabfe0949fee0d9fa6dec3420 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Tue, 12 Nov 2024 17:11:09 +0200 Subject: [PATCH 02/32] fix preview --- app/javascript/template_builder/builder.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue index e3e17dbe..56abedaf 100644 --- a/app/javascript/template_builder/builder.vue +++ b/app/javascript/template_builder/builder.vue @@ -1342,7 +1342,9 @@ export default { } this.$nextTick(() => { - this.$refs.previews.scrollTop = this.$refs.previews.scrollHeight + if (this.$refs.previews) { + this.$refs.previews.scrollTop = this.$refs.previews.scrollHeight + } this.scrollIntoDocument(data.schema[0]) }) From 0e2fd8ee4ff7e1103a73f370e23af5d47d3fa19e Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Wed, 13 Nov 2024 17:53:55 +0200 Subject: [PATCH 03/32] use email host --- app/controllers/submit_form_controller.rb | 2 -- lib/replace_email_variables.rb | 11 ++++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/controllers/submit_form_controller.rb b/app/controllers/submit_form_controller.rb index 642c3119..621849eb 100644 --- a/app/controllers/submit_form_controller.rb +++ b/app/controllers/submit_form_controller.rb @@ -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 diff --git a/lib/replace_email_variables.rb b/lib/replace_email_variables.rb index f403b82c..572fd0a4 100644 --- a/lib/replace_email_variables.rb +++ b/lib/replace_email_variables.rb @@ -19,6 +19,8 @@ module ReplaceEmailVariables DOCUMENTS_LINKS = /\{+documents\.links\}+/i DOCUMENTS_LINK = /\{+documents\.link\}+/i + EMAIL_HOST = ENV.fetch('EMAIL_HOST', nil) + module_function # rubocop:disable Metrics @@ -64,10 +66,17 @@ module ReplaceEmailVariables def build_submitter_link(submitter, tracking_event_type) if tracking_event_type == 'click_email' + url_options = + if EMAIL_HOST.present? + { host: EMAIL_HOST, protocol: ENV['FORCE_SSL'].present? ? 'https' : 'http' } + else + Docuseal.default_url_options + end + Rails.application.routes.url_helpers.submit_form_url( slug: submitter.slug, t: SubmissionEvents.build_tracking_param(submitter, 'click_email'), - **Docuseal.default_url_options + **url_options ) else Rails.application.routes.url_helpers.submit_form_url( From 8ddd4ee916a5073ce8277648f0c672accad6bf0f Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Wed, 13 Nov 2024 18:53:26 +0200 Subject: [PATCH 04/32] adjust duration --- app/controllers/submitters_send_email_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/submitters_send_email_controller.rb b/app/controllers/submitters_send_email_controller.rb index 910a4d69..f3eb3187 100644 --- a/app/controllers/submitters_send_email_controller.rb +++ b/app/controllers/submitters_send_email_controller.rb @@ -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), From 21bf5ed9f784df3f84198c70b3d467fde4efa138 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Thu, 14 Nov 2024 14:38:28 +0200 Subject: [PATCH 05/32] fix fields message --- app/javascript/template_builder/builder.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue index 56abedaf..04c6dcaf 100644 --- a/app/javascript/template_builder/builder.vue +++ b/app/javascript/template_builder/builder.vue @@ -4,7 +4,7 @@ class="mx-auto pl-3 md:pl-4 h-full" > - <% unless @template.archived_at? %> + <% if !@template.archived_at? && !@template.account.archived_at? %> <%= form_for @submitter, url: start_form_path(@template.slug), data: { turbo_frame: :_top }, method: :put, html: { class: 'space-y-4' } do |f| %>
<%= f.label :email, t('email'), class: 'label' %> From b035123ff9be5422d4731ffbdf095e40fb55a110 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Sat, 16 Nov 2024 16:13:30 +0200 Subject: [PATCH 13/32] disable email var --- app/views/submissions/_send_email.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/submissions/_send_email.html.erb b/app/views/submissions/_send_email.html.erb index b9638b49..9b78c07a 100644 --- a/app/views/submissions/_send_email.html.erb +++ b/app/views/submissions/_send_email.html.erb @@ -2,7 +2,7 @@ <% can_send_emails = Accounts.can_send_emails?(current_account) %>
<%= f.label :send_email, for: uuid = SecureRandom.uuid, class: 'flex items-center cursor-pointer' do %> - <%= f.check_box :send_email, id: uuid, class: 'base-checkbox', disabled: !can_send_emails, checked: can_send_emails && !local_assigns.key?(:resend_email) %> + <%= f.check_box :send_email, id: uuid, class: 'base-checkbox', disabled: !can_send_emails || local_assigns[:disable_email], checked: can_send_emails && !local_assigns.key?(:resend_email) && !local_assigns[:disable_email] %> <%= local_assigns[:resend_email] ? t('re_send_email') : t('send_email') %> <% end %>
From e52a721fc997d72d1ac284853af87279a3912c89 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Sat, 16 Nov 2024 18:19:25 +0200 Subject: [PATCH 14/32] fix typo --- app/views/submissions/_send_email.html.erb | 2 +- config/locales/i18n.yml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/views/submissions/_send_email.html.erb b/app/views/submissions/_send_email.html.erb index 9b78c07a..9031c8e4 100644 --- a/app/views/submissions/_send_email.html.erb +++ b/app/views/submissions/_send_email.html.erb @@ -26,7 +26,7 @@ <%= t('configure_smtp_settings_in_order_to_send_emails_') %>
- <%= t('go_to_smtp_setting') %> + <%= t('go_to_smtp_settings') %>

diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml index 12b896aa..788bf704 100644 --- a/config/locales/i18n.yml +++ b/config/locales/i18n.yml @@ -344,7 +344,7 @@ en: &en edit_message: Edit message smtp_not_configured: SMTP not Configured configure_smtp_settings_in_order_to_send_emails_: 'Configure SMTP settings in order to send emails:' - go_to_smtp_setting: Go to SMTP setting + go_to_smtp_settings: Go to SMTP settings save_as_default_template_message: Save as default template message re_send_sms: Re-send SMS send_sms: Send SMS @@ -993,7 +993,7 @@ es: &es edit_message: Editar mensaje smtp_not_configured: SMTP no configurado configure_smtp_settings_in_order_to_send_emails_: 'Configura los ajustes de SMTP para enviar correos electrónicos:' - go_to_smtp_setting: Ir a la configuración de SMTP + go_to_smtp_settings: Ir a la configuración de SMTP save_as_default_template_message: Guardar como mensaje de plantilla predeterminado re_send_sms: Reenviar SMS send_sms: Enviar SMS @@ -1642,7 +1642,7 @@ it: &it edit_message: Modifica messaggio smtp_not_configured: SMTP non configurato configure_smtp_settings_in_order_to_send_emails_: 'Configura le impostazioni SMTP per inviare email:' - go_to_smtp_setting: Vai alle impostazioni SMTP + go_to_smtp_settings: Vai alle impostazioni SMTP save_as_default_template_message: Salva come messaggio modello predefinito re_send_sms: Reinvio SMS send_sms: Invia SMS @@ -2292,7 +2292,7 @@ fr: &fr edit_message: Modifier le message smtp_not_configured: SMTP non configuré configure_smtp_settings_in_order_to_send_emails_: 'Configurez les paramètres SMTP pour envoyer des e-mails:' - go_to_smtp_setting: Aller aux paramètres SMTP + go_to_smtp_settings: Aller aux paramètres SMTP save_as_default_template_message: Enregistrer comme modèle de message par défaut re_send_sms: Renvoyer le SMS send_sms: Envoyer SMS @@ -2941,7 +2941,7 @@ pt: &pt edit_message: Editar mensagem smtp_not_configured: SMTP não configurado configure_smtp_settings_in_order_to_send_emails_: 'Configure as configurações de SMTP para enviar e-mails:' - go_to_smtp_setting: Ir para a configuração de SMTP + go_to_smtp_settings: Ir para a configuração de SMTP save_as_default_template_message: Salvar como mensagem de modelo padrão re_send_sms: Reenviar SMS send_sms: Enviar SMS @@ -3590,7 +3590,7 @@ de: &de edit_message: Nachricht bearbeiten smtp_not_configured: SMTP nicht konfiguriert configure_smtp_settings_in_order_to_send_emails_: 'Konfiguriere die SMTP-Einstellungen, um E-Mails zu senden:' - go_to_smtp_setting: Zu den SMTP-Einstellungen gehen + go_to_smtp_settings: Zu den SMTP-Einstellungen gehen save_as_default_template_message: Als Standardvorlage speichern re_send_sms: SMS erneut senden send_sms: SMS senden From f2782bd84e5efc26baf437c5c495032e88026da7 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Sat, 16 Nov 2024 23:06:00 +0200 Subject: [PATCH 15/32] fix form show --- app/javascript/submission_form/form.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue index c2eb93e8..ab592887 100644 --- a/app/javascript/submission_form/form.vue +++ b/app/javascript/submission_form/form.vue @@ -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 : '']" /> Date: Sun, 17 Nov 2024 21:15:10 +0200 Subject: [PATCH 16/32] fix default number --- lib/submitters/submit_values.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/submitters/submit_values.rb b/lib/submitters/submit_values.rb index 40e96618..4e330b54 100644 --- a/lib/submitters/submit_values.rb +++ b/lib/submitters/submit_values.rb @@ -207,7 +207,7 @@ module Submitters end def replace_default_variables(value, attrs, submission, with_time: false) - return value if value.in?([true, false]) + return value if value.in?([true, false]) || value.is_a?(Numeric) return if value.blank? value.to_s.gsub(VARIABLE_REGEXP) do |e| From 599785b6d1df078fd6a79f6e01ed4a3c609f9d90 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Sun, 17 Nov 2024 21:29:20 +0200 Subject: [PATCH 17/32] fix number cast empty string --- lib/submitters/submit_values.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/submitters/submit_values.rb b/lib/submitters/submit_values.rb index 4e330b54..65ecad75 100644 --- a/lib/submitters/submit_values.rb +++ b/lib/submitters/submit_values.rb @@ -93,7 +93,11 @@ module Submitters if params[:cast_boolean] == 'true' v == 'true' elsif params[:cast_number] == 'true' - (v.to_f % 1).zero? ? v.to_i : v.to_f + if v == '' + nil + else + (v.to_f % 1).zero? ? v.to_i : v.to_f + end elsif params[:normalize_phone] == 'true' v.to_s.gsub(/[^0-9+]/, '') else From 5a48ab036036a05b457698660e6516b5b7f199e1 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Mon, 18 Nov 2024 21:08:32 +0200 Subject: [PATCH 18/32] configure form link --- app/controllers/application_controller.rb | 5 +++++ app/views/submissions/show.html.erb | 2 +- app/views/templates/_submission.html.erb | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index bf2df2d3..a48146ee 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -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:) } @@ -105,6 +106,10 @@ class ApplicationController < ActionController::Base 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' diff --git a/app/views/submissions/show.html.erb b/app/views/submissions/show.html.erb index 301e0e52..5723e891 100644 --- a/app/views/submissions/show.html.erb +++ b/app/views/submissions/show.html.erb @@ -59,7 +59,7 @@
<% end %> <% elsif @submission.submitters.to_a.size == 1 && !@submission.expired? && !@submission.submitters.to_a.first.declined_at? && !@submission.archived_at? %> - <%= render 'shared/clipboard_copy', text: submit_form_url(slug: @submission.submitters.to_a.first.slug), class: 'base-button', icon_class: 'w-6 h-6 text-white', copy_title: t('copy_share_link'), copied_title: t('copied_to_clipboard') %> + <%= render 'shared/clipboard_copy', text: submit_form_url(slug: @submission.submitters.to_a.first.slug, host: form_link_host), class: 'base-button', icon_class: 'w-6 h-6 text-white', copy_title: t('copy_share_link'), copied_title: t('copied_to_clipboard') %> <% end %>
diff --git a/app/views/templates/_submission.html.erb b/app/views/templates/_submission.html.erb index 8ae256d5..ad0d490b 100644 --- a/app/views/templates/_submission.html.erb +++ b/app/views/templates/_submission.html.erb @@ -92,7 +92,7 @@ <% else %>
- <%= render 'shared/clipboard_copy', text: submit_form_url(slug: submitter.slug), class: 'btn btn-sm btn-neutral text-white md:w-36 flex z-[1]', icon_class: 'w-6 h-6 text-white', copy_title: t('copy_link').length < 10 ? t('copy_link') : t('copy'), copy_title_md: t('copy'), copied_title_md: t('copied') %> + <%= render 'shared/clipboard_copy', text: submit_form_url(slug: submitter.slug, host: form_link_host), class: 'btn btn-sm btn-neutral text-white md:w-36 flex z-[1]', icon_class: 'w-6 h-6 text-white', copy_title: t('copy_link').length < 10 ? t('copy_link') : t('copy'), copy_title_md: t('copy'), copied_title_md: t('copied') %>
<% end %> <% end %> @@ -176,7 +176,7 @@ <% else %> - <%= render 'shared/clipboard_copy', text: submit_form_url(slug: submitter.slug), class: 'absolute md:relative top-0 right-0 btn btn-xs text-xs btn-neutral text-white w-28 md:w-36 flex z-[1]', icon_class: 'w-4 h-4 text-white', copy_title: t('copy_link'), copy_title_md: t('copy_link').length < 10 ? t('copy_link') : t('copy'), copied_title_md: t('copied') %> + <%= render 'shared/clipboard_copy', text: submit_form_url(slug: submitter.slug, host: form_link_host), class: 'absolute md:relative top-0 right-0 btn btn-xs text-xs btn-neutral text-white w-28 md:w-36 flex z-[1]', icon_class: 'w-4 h-4 text-white', copy_title: t('copy_link'), copy_title_md: t('copy_link').length < 10 ? t('copy_link') : t('copy'), copied_title_md: t('copied') %> <% end %> <% end %> From 6d5c6e086dec2c8e64c747d979103379d4aa5941 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Tue, 19 Nov 2024 00:05:41 +0200 Subject: [PATCH 19/32] use email host --- app/views/submitter_mailer/invitation_email.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/submitter_mailer/invitation_email.html.erb b/app/views/submitter_mailer/invitation_email.html.erb index d5987306..968ec02b 100644 --- a/app/views/submitter_mailer/invitation_email.html.erb +++ b/app/views/submitter_mailer/invitation_email.html.erb @@ -7,7 +7,7 @@ <% else %>

<%= t('hi_there') %>,

<%= I18n.t(@submitter.with_signature_fields? ? :you_have_been_invited_to_sign_the_name : :you_have_been_invited_to_submit_the_name_form, name: @submitter.submission.template.name) %>

-

<%= link_to I18n.t(@submitter.with_signature_fields? ? :review_and_sign : :review_and_submit), submit_form_url(slug: @submitter.slug, t: SubmissionEvents.build_tracking_param(@submitter, 'click_email')) %>

+

<%= link_to I18n.t(@submitter.with_signature_fields? ? :review_and_sign : :review_and_submit), submit_form_url(slug: @submitter.slug, t: SubmissionEvents.build_tracking_param(@submitter, 'click_email'), host: ENV.fetch('EMAIL_HOST', Docuseal.default_url_options[:host])) %>

<%= t('please_contact_us_by_replying_to_this_email_if_you_didn_t_request_this') %>

<%= t('thanks') %>,
<%= @current_account.name %> From 18d60f5522e3741dd41df5c57cd45558f968a6a3 Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Sun, 17 Nov 2024 15:57:10 +0200 Subject: [PATCH 20/32] add signing form specs --- .rubocop.yml | 4 +- app/javascript/submission_form/date_step.vue | 1 + app/javascript/submission_form/dropzone.vue | 1 + app/javascript/submission_form/i18n.js | 65 +- app/javascript/submission_form/phone_step.vue | 6 +- app/javascript/template_builder/i18n.js | 6 - spec/factories/submitters.rb | 1 - spec/factories/templates.rb | 280 +++++++- spec/fixtures/sample-image.png | Bin 0 -> 132313 bytes spec/rails_helper.rb | 2 + spec/requests/templates_spec.rb | 28 +- spec/signing_form_helper.rb | 34 + spec/system/signing_form_spec.rb | 598 ++++++++++++++++++ spec/system/submit_form_spec.rb | 87 --- spec/system/template_spec.rb | 2 +- 15 files changed, 956 insertions(+), 159 deletions(-) create mode 100644 spec/fixtures/sample-image.png create mode 100644 spec/signing_form_helper.rb create mode 100644 spec/system/signing_form_spec.rb delete mode 100644 spec/system/submit_form_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index 4265d3ab..499a63e6 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -60,10 +60,10 @@ RSpec/NestedGroups: Max: 6 RSpec/MultipleExpectations: - Max: 20 + Max: 25 RSpec/ExampleLength: - Max: 40 + Max: 50 RSpec/MultipleMemoizedHelpers: Max: 9 diff --git a/app/javascript/submission_form/date_step.vue b/app/javascript/submission_form/date_step.vue index fcd9cc0c..7984ac09 100644 --- a/app/javascript/submission_form/date_step.vue +++ b/app/javascript/submission_form/date_step.vue @@ -37,6 +37,7 @@

-
+
{{ selectedCountry.flag }} +{{ selectedCountry.dial }}
<% end %> + <% Submissions::Filter::ALLOWED_PARAMS.each do |key| %> + <% if params[key].present? %> + + <% end %> + <% end %> <% if params[:q].present? %>
diff --git a/app/views/submissions_archived/index.html.erb b/app/views/submissions_archived/index.html.erb index 846a044d..8a5216c1 100644 --- a/app/views/submissions_archived/index.html.erb +++ b/app/views/submissions_archived/index.html.erb @@ -1,22 +1,31 @@ +<% filter_params = params.permit(Submissions::Filter::ALLOWED_PARAMS).compact_blank %>
<%= link_to root_path do %> ← <%= t('back_to_active') %> <% end %>
-
-
-

<%= t('submissions') %> <%= t('archived') %>

+
+
+
+

<%= t('submissions') %> <%= t('archived') %>

+
+
+ <% if params[:q].present? || @pagy.pages > 1 || filter_params.present? %> + <%= render 'shared/search_input', placeholder: "#{t('search')}..." %> + <% end %> +
+
+
+ <%= render 'submissions_filters/applied_filters', filter_params: %> + <%= render 'submissions_filters/filter_button', filter_params: %>
- <% if params[:q].present? || @pagy.pages > 1 %> - <%= render 'shared/search_input', placeholder: "#{t('search')}..." %> - <% end %>
<% if @pagy.count > 0 %>
<%= render partial: 'templates/submission', collection: @submissions, locals: { with_template: true, archived: true } %>
-<% elsif params[:q].present? %> +<% elsif params[:q].present? || filter_params.present? %>
<%= t('submissions_not_found') %> diff --git a/app/views/submissions_dashboard/index.html.erb b/app/views/submissions_dashboard/index.html.erb index 040e2301..fc58043a 100644 --- a/app/views/submissions_dashboard/index.html.erb +++ b/app/views/submissions_dashboard/index.html.erb @@ -1,4 +1,5 @@ -<% is_show_tabs = @pagy.count >= 5 || params[:status].present? %> +<% filter_params = params.permit(Submissions::Filter::ALLOWED_PARAMS).compact_blank %> +<% is_show_tabs = @pagy.count >= 5 || params[:status].present? || filter_params.present? %> <% if Docuseal.demo? %><%= render 'shared/demo_alert' %><% end %>
@@ -10,7 +11,7 @@
- <% if params[:q].present? || @pagy.pages > 1 %> + <% if params[:q].present? || @pagy.pages > 1 || filter_params.present? %> <%= render 'shared/search_input' %> <% end %> <% if can?(:create, ::Template) %> @@ -32,25 +33,31 @@ <% end %> <% end %> <% if is_show_tabs %> -
- -
- <%= svg_icon('list', class: 'w-5 h-5') %> - <%= t('all') %> -
-
- -
- <%= svg_icon('clock', class: 'w-5 h-5') %> - <%= t('pending') %> -
-
- -
- <%= svg_icon('circle_check', class: 'w-5 h-5') %> - <%= t('completed') %> -
-
+ <% end %> <% if @pagy.count > 0 %> @@ -58,10 +65,10 @@ <%= render partial: 'templates/submission', collection: @submissions, locals: { with_template: true } %>
<% end %> -<% if params[:q].blank? && params[:status].blank? && @pagy.count < 5 %> +<% if params[:q].blank? && params[:status].blank? && filter_params.blank? && @pagy.count < 5 %> <%= render 'templates/dropzone' %> <% end %> -<% if @submissions.present? || params[:q].blank? %> +<% if @submissions.present? || (params[:q].blank? && filter_params.blank?) %> <% if @pagy.pages > 1 %> <%= render 'shared/pagination', pagy: @pagy, items_name: 'submissions', left_additional_html: view_archived_html %> <% else %> @@ -69,7 +76,7 @@ <%= view_archived_html %>
<% end %> -<% elsif params[:q].present? %> +<% elsif params[:q].present? || filter_params.present? %>
<%= t('submissions_not_found') %> diff --git a/app/views/submissions_filters/_applied_filters.html.erb b/app/views/submissions_filters/_applied_filters.html.erb new file mode 100644 index 00000000..ad988d71 --- /dev/null +++ b/app/views/submissions_filters/_applied_filters.html.erb @@ -0,0 +1,50 @@ +<% query_params = params.permit(:q, :status).merge(filter_params) %> +<% if query_params[:completed_at_from].present? || query_params[:completed_at_to].present? %> +
+ <%= link_to submissions_filter_path('completed_at', 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('calendar_check', class: 'w-5 h-5 shrink-0') %> + + <% if query_params[:completed_at_from] == query_params[:completed_at_to] %> + <%= l(Date.parse(query_params[:completed_at_from]), locale: current_account.locale) %> + <% else %> + <%= query_params[:completed_at_from].present? ? l(Date.parse(query_params[:completed_at_from]), locale: current_account.locale) : '∞' %> + - + <%= query_params[:completed_at_to].present? ? l(Date.parse(query_params[:completed_at_to]), locale: current_account.locale) : t('today') %> + <% end %> + + <% end %> + <%= link_to url_for(params.to_unsafe_h.except(:completed_at_from, :completed_at_to)), class: 'rounded-lg ml-1 hover:bg-base-content hover:text-white' do %> + <%= svg_icon('x', class: 'w-5 h-5') %> + <% end %> +
+<% end %> +<% if query_params[:created_at_from].present? || query_params[:created_at_to].present? %> +
+ <%= link_to submissions_filter_path('created_at', 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('calendar', class: 'w-5 h-5 shrink-0') %> + + <% if query_params[:created_at_from] == query_params[:created_at_to] %> + <%= l(Date.parse(query_params[:created_at_from]), locale: current_account.locale) %> + <% else %> + <%= query_params[:created_at_from].present? ? l(Date.parse(query_params[:created_at_from]), locale: current_account.locale) : '∞' %> + - + <%= query_params[:created_at_to].present? ? l(Date.parse(query_params[:created_at_to]), locale: current_account.locale) : t('today') %> + <% end %> + + <% end %> + <%= link_to url_for(params.to_unsafe_h.except(:created_at_to, :created_at_from)), class: 'rounded-lg ml-1 hover:bg-base-content hover:text-white' do %> + <%= svg_icon('x', class: 'w-5 h-5') %> + <% end %> +
+<% end %> +<% if params[:author].present? %> +
+ <%= link_to submissions_filter_path('author', 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('user', class: 'w-5 h-5 shrink-0') %> + <%= current_account.users.accessible_by(current_ability).where(account: current_account).find_by(email: params[:author])&.full_name || 'NA' %> + <% end %> + <%= link_to url_for(params.to_unsafe_h.except(:author)), class: 'rounded-lg ml-1 hover:bg-base-content hover:text-white' do %> + <%= svg_icon('x', class: 'w-5 h-5') %> + <% end %> +
+<% end %> diff --git a/app/views/submissions_filters/_date_buttons.html.erb b/app/views/submissions_filters/_date_buttons.html.erb new file mode 100644 index 00000000..3eb15e9c --- /dev/null +++ b/app/views/submissions_filters/_date_buttons.html.erb @@ -0,0 +1,39 @@ +<% current_time = Time.current.in_time_zone(current_account.timezone) %> +<% week_start = TimeUtils.timezone_abbr(current_account.timezone, current_time).in?(TimeUtils::US_TIMEZONES) ? :sunday : :monday %> +
+ + + + + + + + + + + + + + + + + + + + + +
diff --git a/app/views/submissions_filters/_filter_button.html.erb b/app/views/submissions_filters/_filter_button.html.erb new file mode 100644 index 00000000..cdf00fad --- /dev/null +++ b/app/views/submissions_filters/_filter_button.html.erb @@ -0,0 +1,27 @@ +<% query_params = params.permit(:q, :status).merge(filter_params) %> + diff --git a/app/views/submissions_filters/_filter_modal.html.erb b/app/views/submissions_filters/_filter_modal.html.erb new file mode 100644 index 00000000..04599244 --- /dev/null +++ b/app/views/submissions_filters/_filter_modal.html.erb @@ -0,0 +1,18 @@ +<%= render 'shared/turbo_modal', title: local_assigns[:title] do %> + <%= form_for '', url: params[:path], method: :get, data: { turbo_frame: :_top }, html: { autocomplete: :off } do |f| %> + <%= hidden_field_tag :status, params[:status] if params[:status].present? %> + <%= hidden_field_tag :q, params[:q] if params[:q].present? %> + <% local_assigns[:default_params].each do |key, value| %> + <%= hidden_field_tag(key, value) if value.present? %> + <% end %> + <%= yield %> +
+ <%= f.button button_title(title: t('apply'), disabled_with: t('applying')), name: nil, class: 'base-button' %> +
+ <% if params[:with_remove] %> +
+ <%= link_to t('remove_filter'), "#{params[:path]}?#{params.to_unsafe_h.slice(:q, :status).to_query}", class: 'link', data: { turbo_frame: :_top } %> +
+ <% end %> + <% end %> +<% end %> diff --git a/app/views/submissions_filters/author.html.erb b/app/views/submissions_filters/author.html.erb new file mode 100644 index 00000000..b9f3b27f --- /dev/null +++ b/app/views/submissions_filters/author.html.erb @@ -0,0 +1,7 @@ +<%= render 'filter_modal', title: t('author'), default_params: params.permit(*(Submissions::Filter::ALLOWED_PARAMS - ['author'])) do %> +
+
+ <%= select_tag :author, options_for_select(current_account.users.accessible_by(current_ability).where.not(role: :integration).where(account: current_account).map { |u| [u.full_name, u.email] }, params[:author].presence || current_user.email), required: true, class: 'base-select' %> +
+
+<% end %> diff --git a/app/views/submissions_filters/completed_at.html.erb b/app/views/submissions_filters/completed_at.html.erb new file mode 100644 index 00000000..0a0b6b6f --- /dev/null +++ b/app/views/submissions_filters/completed_at.html.erb @@ -0,0 +1,15 @@ +<%= render 'filter_modal', title: t('completed_at'), default_params: params.permit(*(Submissions::Filter::ALLOWED_PARAMS - %w[completed_at_to completed_at_from])) do %> +
+
+
+ <%= label_tag 'completed_at_from', t('from'), for: 'date_from', class: 'label text-sm' %> + <%= date_field_tag 'completed_at_from', params[:completed_at_from], id: 'date_from', class: 'base-input !h-10', autocomplete: 'off' %> +
+
+ <%= label_tag 'completed_at_to', t('to'), for: 'date_to', class: 'label text-sm' %> + <%= date_field_tag 'completed_at_to', params[:completed_at_to], id: 'date_to', class: 'base-input !h-10', autocomplete: 'off' %> +
+
+ <%= render 'date_buttons' %> +
+<% end %> diff --git a/app/views/submissions_filters/created_at.html.erb b/app/views/submissions_filters/created_at.html.erb new file mode 100644 index 00000000..2f089464 --- /dev/null +++ b/app/views/submissions_filters/created_at.html.erb @@ -0,0 +1,15 @@ +<%= render 'filter_modal', title: t('created_at'), default_params: params.permit(*(Submissions::Filter::ALLOWED_PARAMS - %w[created_at_to created_at_from])) do %> +
+
+
+ <%= label_tag 'created_at_from', t('from'), for: 'date_from', class: 'label text-sm' %> + <%= date_field_tag 'created_at_from', params[:created_at_from], id: 'date_from', class: 'base-input !h-10', autocomplete: 'off' %> +
+
+ <%= label_tag 'created_at_to', t('to'), for: 'date_to', class: 'label text-sm' %> + <%= date_field_tag 'created_at_to', params[:created_at_to], id: 'date_to', class: 'base-input !h-10', autocomplete: 'off' %> +
+
+ <%= render 'date_buttons' %> +
+<% end %> diff --git a/app/views/templates/filter.html.erb b/app/views/templates/filter.html.erb deleted file mode 100644 index 87d962f6..00000000 --- a/app/views/templates/filter.html.erb +++ /dev/null @@ -1,94 +0,0 @@ -<%= render 'shared/turbo_modal', title: t(params[:filter], default: '') do %> - <%= form_for @template, method: :get, data: { turbo_frame: :_top }, html: { autocomplete: :off } do |f| %> - <%= hidden_field_tag :status, params[:status] if params[:status].present? %> - <%= hidden_field_tag :q, params[:q] if params[:q].present? %> -
- <% if params[:filter] == 'author' %> - <%= hidden_field_tag 'created_at[from]', params.dig(:created_at, :from) if params.dig(:created_at, :from).present? %> - <%= hidden_field_tag 'created_at[to]', params.dig(:created_at, :to) if params.dig(:created_at, :to).present? %> - <%= hidden_field_tag 'completed_at[from]', params.dig(:completed_at, :from) if params.dig(:completed_at, :from).present? %> - <%= hidden_field_tag 'completed_at[to]', params.dig(:completed_at, :to) if params.dig(:completed_at, :to).present? %> -
- <%= select_tag :author, options_for_select(@creator_names), required: true, class: 'base-select' %> -
- <% elsif params[:filter] == 'created_at' %> - <%= hidden_field_tag 'author', params[:author] if params[:author].present? %> - <%= hidden_field_tag 'completed_at[from]', params.dig(:completed_at, :from) if params.dig(:completed_at, :from).present? %> - <%= hidden_field_tag 'completed_at[to]', params.dig(:completed_at, :to) if params.dig(:completed_at, :to).present? %> -
-
- <%= label_tag 'created_at[from]', t('from'), for: 'date_from', class: 'label text-sm' %> - <%= date_field_tag 'created_at[from]', params.dig(:created_at, :from), id: 'date_from', class: 'base-input !select-sm !h-10"', autocomplete: 'off' %> -
-
- <%= label_tag 'created_at[to]', t('to'), for: 'date_to', class: 'label text-sm' %> - <%= date_field_tag 'created_at[to]', params.dig(:created_at, :to), id: 'date_to', class: 'base-input !select-sm !h-10"', autocomplete: 'off' %> -
-
- <% elsif params[:filter] == 'completed_at' %> - <%= hidden_field_tag 'author', params[:author] if params[:author].present? %> - <%= hidden_field_tag 'created_at[from]', params.dig(:created_at, :from) if params.dig(:created_at, :from).present? %> - <%= hidden_field_tag 'created_at[to]', params.dig(:created_at, :to) if params.dig(:created_at, :to).present? %> -
-
- <%= label_tag 'completed_at[from]', t('from'), for: 'date_from', class: 'label text-sm' %> - <%= date_field_tag 'completed_at[from]', params.dig(:completed_at, :from), id: 'date_from', class: 'base-input !select-sm !h-10"', autocomplete: 'off' %> -
-
- <%= label_tag 'completed_at[to]', t('to'), for: 'date_to', class: 'label text-sm' %> - <%= date_field_tag 'completed_at[to]', params.dig(:completed_at, :to), id: 'date_to', class: 'base-input !select-sm !h-10"', autocomplete: 'off' %> -
-
- <% end %> -
- <% if %w[created_at completed_at].include?(params[:filter]) %> - <% current_time = Time.current.in_time_zone(current_account.timezone) %> -
- - - - - - - - - - - - - - - - - - -
- <% end %> -
- <%= f.button button_title(title: t('apply'), disabled_with: t('applying')), name: nil, class: 'base-button' %> -
- <% if params[:filter].present? && params[params[:filter]].present? %> -
- <%= link_to t('remove_condition'), template_path(params[:id], params.to_unsafe_h.except(:id, :filter, :action, :controller, params[:filter].to_sym)), class: 'link', data: { turbo: false } %> -
- <% end %> - <% end %> -<% end %> diff --git a/app/views/templates/show.html.erb b/app/views/templates/show.html.erb index 82728490..8e222df9 100644 --- a/app/views/templates/show.html.erb +++ b/app/views/templates/show.html.erb @@ -1,7 +1,7 @@ <%= render 'title', template: @template %> -<% is_filter_active = params.slice(:author, :created_at, :completed_at).to_unsafe_h.any?(&:present?) %> -<% is_show_tabs = @pagy.pages > 1 || params[:q].present? || params[:status].present? || is_filter_active %> -<% if !@pagy.count.zero? || params[:q].present? || params[:status].present? || is_filter_active %> +<% filter_params = params.permit(Submissions::Filter::ALLOWED_PARAMS).compact_blank %> +<% is_show_tabs = @pagy.pages > 1 || params[:q].present? || params[:status].present? || filter_params.present? %> +<% if !@pagy.count.zero? || params[:q].present? || params[:status].present? || filter_params.present? %>
@@ -10,7 +10,7 @@
- <% if params[:q].present? || params[:status].present? || is_filter_active || @pagy.pages > 1 %> + <% if params[:q].present? || params[:status].present? || filter_params.present? || @pagy.pages > 1 %> <%= render 'shared/search_input', title_selector: 'h2' %> <% end %> <%= link_to new_template_submissions_export_path(@template), class: 'hidden md:flex btn btn-ghost text-base', data: { turbo_frame: 'modal' } do %> @@ -36,7 +36,7 @@ <%= t('all') %>
- <%= params[:status].blank? ? @pagy.count : @base_submissions.count %> + <%= params[:status].blank? && filter_params.blank? ? @pagy.count : @base_submissions.unscope(:group, :order).count %>
@@ -45,7 +45,7 @@ <%= t('pending') %>
- <%= params[:status] == 'pending' ? @pagy.count : @base_submissions.pending.count %> + <%= params[:status] == 'pending' && filter_params.blank? ? @pagy.count : @base_submissions.pending.unscope(:group, :order).count %>
@@ -54,86 +54,13 @@ <%= t('completed') %>
- <%= params[:status] == 'completed' ? @pagy.count : @base_submissions.completed.count %> + <%= params[:status] == 'completed' && filter_params.blank? ? @pagy.count : @base_submissions.completed.unscope(:group, :order).count %>
- <% if completed_at_range.present? %> -
- <%= link_to filter_templates_path(params.to_unsafe_h.except(:controller, :action).merge(filter: 'completed_at')), data: { turbo_frame: 'modal' }, class: 'flex items-center space-x-1' do %> - <%= svg_icon('calendar_check', class: 'w-5 h-5 shrink-0') %> - - <% if completed_at_range.begin&.to_date == completed_at_range.end&.to_date %> - <%= l(completed_at_range.begin.to_date, locale: current_account.locale) %> - <% else %> - <%= completed_at_range.begin ? l(completed_at_range.begin.to_date, locale: current_account.locale) : '∞' %> - - - <%= completed_at_range.end ? l(completed_at_range.end.to_date, locale: current_account.locale) : t('today') %> - <% end %> - - <% end %> - <%= link_to url_for(params.to_unsafe_h.except(:completed_at)), class: 'rounded-lg ml-1 hover:bg-neutral-700 hover:text-white' do %> - <%= svg_icon('x', class: 'w-5 h-5') %> - <% end %> -
- <% end %> - <% if @created_at_range.present? %> -
- <%= link_to filter_templates_path(params.to_unsafe_h.except(:controller, :action).merge(filter: 'created_at')), data: { turbo_frame: 'modal' }, class: 'flex items-center space-x-1' do %> - <%= svg_icon('calendar', class: 'w-5 h-5 shrink-0') %> - - <% if created_at_range.begin&.to_date == created_at_range.end&.to_date %> - <%= l(created_at_range.begin.to_date, locale: current_account.locale) %> - <% else %> - <%= created_at_range.begin ? l(created_at_range.begin.to_date, locale: current_account.locale) : '∞' %> - - - <%= created_at_range.end ? l(created_at_range.end.to_date, locale: current_account.locale) : t('today') %> - <% end %> - - <% end %> - <%= link_to url_for(params.to_unsafe_h.except(:created_at)), class: 'rounded-lg ml-1 hover:bg-neutral-700 hover:text-white' do %> - <%= svg_icon('x', class: 'w-5 h-5') %> - <% end %> -
- <% end %> - <% if params[:author].present? %> -
- <%= link_to filter_templates_path(params.to_unsafe_h.except(:controller, :action).merge(filter: 'author')), data: { turbo_frame: 'modal' }, class: 'flex items-center space-x-1 w-full md:w-36' do %> - <%= svg_icon('user', class: 'w-5 h-5 shrink-0') %> - <%= params[:author] %> - <% end %> - <%= link_to url_for(params.to_unsafe_h.except(:author)), class: 'rounded-lg ml-1 hover:bg-neutral-700 hover:text-white' do %> - <%= svg_icon('x', class: 'w-5 h-5') %> - <% end %> -
- <% end %> - + <%= render 'submissions_filters/applied_filters', filter_params: %> + <%= render 'submissions_filters/filter_button', filter_params: %>
<% end %> @@ -148,7 +75,7 @@

<%= t('there_are_no_submissions') %>

- <% if @template.archived_at.blank? && params[:q].blank? %> + <% if @template.archived_at.blank? && params[:q].blank? && filter_params.blank? %>

<%= t('send_an_invitation_to_fill_and_complete_the_form') %>

@@ -169,7 +96,7 @@ <%= t('sign_it_yourself') %> <% end %> <% end %> - +
<% end %>
diff --git a/app/views/templates_archived_submissions/index.html.erb b/app/views/templates_archived_submissions/index.html.erb index 779b9e8e..eac39e1e 100644 --- a/app/views/templates_archived_submissions/index.html.erb +++ b/app/views/templates_archived_submissions/index.html.erb @@ -1,3 +1,5 @@ +<% filter_params = params.permit(Submissions::Filter::ALLOWED_PARAMS).compact_blank %> +<% with_filters = @pagy.pages > 1 || params[:q].present? || filter_params.present? %> <%= render 'templates/title', template: @template %>
<%= link_to template_path(@template) do %> @@ -5,23 +7,33 @@ <%= t('back_to_active') %> <% end %>
-
-
-

<%= t('submissions') %> <%= t('archived') %>

-
-
- <%= render 'shared/search_input' %> - <%= link_to new_template_submissions_export_path(@template), class: 'order-3 md:order-1 btn btn-ghost text-base', data: { turbo_frame: 'modal' } do %> - <%= svg_icon('download', class: 'w-6 h-6 stroke-2') %> - <%= t('export') %> - <% end %> +
+
+
+

<%= t('submissions') %> <%= t('archived') %>

+
+
+ <% if with_filters %> + <%= render 'shared/search_input' %> + <% end %> + <%= link_to new_template_submissions_export_path(@template), class: 'btn btn-ghost text-base', data: { turbo_frame: 'modal' } do %> + <%= svg_icon('download', class: 'w-6 h-6 stroke-2') %> + <%= t('export') %> + <% end %> +
+ <% if with_filters %> +
+ <%= render 'submissions_filters/applied_filters', filter_params: %> + <%= render 'submissions_filters/filter_button', filter_params: %> +
+ <% end %>
<% if @pagy.count > 0 %>
<%= render partial: 'templates/submission', collection: @submissions, locals: { template: @template, archived: true } %>
-<% elsif params[:q].present? %> +<% elsif params[:q].present? || filter_params.present? %>
<%= t('submissions_not_found') %> diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml index 6558454e..58869925 100644 --- a/config/locales/i18n.yml +++ b/config/locales/i18n.yml @@ -22,6 +22,7 @@ en: &en thanks: Thanks unarchive: Unarchive first_party: 'First Party' + remove_filter: Remove filter document_download_filename_format: Document download filename format document_name: Document Name docuseal_trusted_signature: DocuSeal Trusted Signature @@ -621,7 +622,7 @@ en: &en verified: Verified unverified: Unverified document: Document - completed_at: Completed At + completed_at: Completed at edit_recipient: Edit Recipient update_recipient: Update Recipient use_international_format_1xxx_: 'Use internatioanl format: +1xxx...' @@ -635,16 +636,16 @@ en: &en webhook_secret: Webhook Secret author: Author to: To - created_at: Created At - remove_condition: Remove condition + created_at: Created at apply: Apply applying: Applying today: Today - this_week: This Week - last_week: Last Week - this_month: This Month - last_month: Last Month - this_year: This Year + yesterday: Yesterday + this_week: This week + last_week: Last week + this_month: This month + last_month: Last month + this_year: This year submission_event_names: send_email_to_html: 'Email sent to %{submitter_name}' send_reminder_email_to_html: 'Reminder email sent to %{submitter_name}' @@ -681,6 +682,7 @@ en: &en read: Read your data es: &es + remove_filter: Eliminar filtro document_download_filename_format: Formato del nombre del archivo de descarga del documento document_name: Nombre del documento unarchive: Desarchivar @@ -1299,10 +1301,10 @@ es: &es author: Autor to: A created_at: Creado el - remove_condition: Eliminar condición apply: Aplicar applying: Aplicando today: Hoy + yesterday: Ayer this_week: Esta Semana last_week: La Semana Pasada this_month: Este Mes @@ -1344,6 +1346,7 @@ es: &es read: Leer tus datos it: &it + remove_filter: Rimuovi filtro document_download_filename_format: Formato del nome file scaricato document_name: Nome del Documento unarchive: Ripristina @@ -1962,10 +1965,10 @@ it: &it author: Autore to: A created_at: Creato il - remove_condition: Rimuovi condizione apply: Applica applying: Applicazione today: Oggi + yesterday: Ieri this_week: Questa Settimana last_week: Settimana Scorsa this_month: Questo Mese @@ -2007,6 +2010,7 @@ it: &it read: Leggi i tuoi dati fr: &fr + remove_filter: Supprimer le filtre document_download_filename_format: Format du nom de fichier du téléchargement de document document_name: Nom du document unarchive: Désarchiver @@ -2626,10 +2630,10 @@ fr: &fr author: Auteur to: À created_at: Créé le - remove_condition: Supprimer la condition apply: Appliquer applying: Application en cours today: "Aujourd'hui" + yesterday: Hier this_week: Cette Semaine last_week: La Semaine Dernière this_month: Ce Mois-ci @@ -2671,6 +2675,7 @@ fr: &fr read: Lire vos données pt: &pt + remove_filter: Remover filtro document_download_filename_format: Formato do nome do arquivo de download do documento document_name: Nome do documento unarchive: Desarquivar @@ -3289,10 +3294,10 @@ pt: &pt author: Autor to: Para created_at: Criado em - remove_condition: Remover condição apply: Aplicar applying: Aplicando today: Hoje + yesterday: Ontem this_week: Esta Semana last_week: Semana Passada this_month: Este Mês @@ -3334,6 +3339,7 @@ pt: &pt read: Ler seus dados de: &de + remove_filter: Filter entfernen document_download_filename_format: Format des Dateinamens beim Herunterladen von Dokumenten document_name: Dokumentname unarchive: Wiederherstellen @@ -3952,10 +3958,10 @@ de: &de author: Autor to: An created_at: Erstellt am - remove_condition: Bedingung entfernen apply: Anwenden applying: Anwenden today: Heute + yesterday: Gestern this_week: Diese Woche last_week: Letzte Woche this_month: Dieser Monat diff --git a/config/routes.rb b/config/routes.rb index c1835f6a..dd568316 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -90,8 +90,8 @@ Rails.application.routes.draw do resources :folders, only: %i[show edit update destroy], controller: 'template_folders' resources :template_sharings_testing, only: %i[create] resources :templates, only: %i[index], controller: 'templates_dashboard' + resources :submissions_filters, only: %i[show], param: 'name' resources :templates, only: %i[new create edit update show destroy] do - get :filter, on: :collection resource :debug, only: %i[show], controller: 'templates_debug' if Rails.env.development? resources :documents, only: %i[create], controller: 'template_documents' resources :restore, only: %i[create], controller: 'templates_restore' diff --git a/lib/submissions.rb b/lib/submissions.rb index 1e7f9e44..ab9d9887 100644 --- a/lib/submissions.rb +++ b/lib/submissions.rb @@ -26,7 +26,7 @@ module Submissions arel = arel.or(Template.arel_table[:name].lower.matches("%#{keyword.downcase}%")) end - submissions.joins(:submitters).where(arel).distinct + submissions.joins(:submitters).where(arel).group(:id) end def update_template_fields!(submission) diff --git a/lib/submissions/filter.rb b/lib/submissions/filter.rb new file mode 100644 index 00000000..f4a2271a --- /dev/null +++ b/lib/submissions/filter.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module Submissions + module Filter + ALLOWED_PARAMS = %w[ + author + completed_at_from + completed_at_to + created_at_from + created_at_to + ].freeze + + DATE_PARAMS = %w[ + completed_at_from + completed_at_to + created_at_from + created_at_to + ].freeze + + module_function + + def call(submissions, current_user, params) + filters = normalize_filter_params(params, current_user) + + if filters[:author].present? + user = current_user.account.users.find_by(email: filters[:author]) + submissions = submissions.where(created_by_user_id: user&.id || -1) + end + + submissions = submissions.where(created_at: filters[:created_at_from]..) if filters[:created_at_from].present? + + if filters[:created_at_to].present? + submissions = submissions.where(created_at: ..filters[:created_at_to].end_of_day) + end + + if filters[:completed_at_from].present? || filters[:completed_at_to].present? + completed_arel = Submitter.arel_table[:completed_at].maximum + submissions = submissions.completed.joins(:submitters).group(:id) + + if filters[:completed_at_from].present? + submissions = submissions.having(completed_arel.gteq(filters[:completed_at_from])) + end + + if filters[:completed_at_to].present? + submissions = submissions.having(completed_arel.lteq(filters[:completed_at_to].end_of_day)) + end + end + + submissions + end + + def normalize_filter_params(params, current_user) + tz = ActiveSupport::TimeZone[current_user.account.timezone] || Time.zone + + ALLOWED_PARAMS.each_with_object({}) do |key, acc| + next if params[key].blank? + + value = DATE_PARAMS.include?(key) ? tz.parse(params[key]) : params[key] + + acc[key.to_sym] = value + end + end + end +end diff --git a/lib/submissions/generate_audit_trail.rb b/lib/submissions/generate_audit_trail.rb index 96747e81..ab932be8 100644 --- a/lib/submissions/generate_audit_trail.rb +++ b/lib/submissions/generate_audit_trail.rb @@ -23,7 +23,7 @@ module Submissions RTL_REGEXP = TextUtils::RTL_REGEXP MAX_IMAGE_HEIGHT = 100 - US_TIMEZONES = %w[EST CST MST PST HST AKDT].freeze + US_TIMEZONES = TimeUtils::US_TIMEZONES module_function diff --git a/lib/time_utils.rb b/lib/time_utils.rb index 1f499195..9150b1b9 100644 --- a/lib/time_utils.rb +++ b/lib/time_utils.rb @@ -22,6 +22,8 @@ module TimeUtils DEFAULT_DATE_FORMAT_US = 'MM/DD/YYYY' DEFAULT_DATE_FORMAT = 'DD/MM/YYYY' + US_TIMEZONES = %w[EST CST MST PST HST AKDT].freeze + module_function def timezone_abbr(timezone, time = Time.current) diff --git a/spec/system/template_spec.rb b/spec/system/template_spec.rb index 2f017b05..0b512041 100644 --- a/spec/system/template_spec.rb +++ b/spec/system/template_spec.rb @@ -183,7 +183,7 @@ RSpec.describe 'Template' do end page.find('.dropdown', text: 'Filter').click - click_link 'Created At' + click_link 'Created at' within '#modal' do fill_in 'From', with: I18n.l(10.days.ago, format: '%Y-%m-%d') fill_in 'To', with: I18n.l(6.days.ago, format: '%Y-%m-%d') @@ -218,7 +218,7 @@ RSpec.describe 'Template' do end page.find('.dropdown', text: 'Filter').click - click_link 'Completed At' + click_link 'Completed at' within '#modal' do fill_in 'From', with: I18n.l(5.days.ago, format: '%Y-%m-%d') fill_in 'To', with: I18n.l(1.day.ago, format: '%Y-%m-%d') From 1ab0f1c90c21dfe17314e94db511b0d183d45be9 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Sat, 23 Nov 2024 22:14:07 +0200 Subject: [PATCH 30/32] fix form error message --- app/javascript/submission_form/form.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue index d6b471b2..ac1da8a6 100644 --- a/app/javascript/submission_form/form.vue +++ b/app/javascript/submission_form/form.vue @@ -1247,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)) } From a59c18f04b7a924246e5bd22f5423feaa22e9d06 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Sun, 24 Nov 2024 12:13:13 +0200 Subject: [PATCH 31/32] adjust filters ui --- app/views/submissions_dashboard/index.html.erb | 2 +- app/views/submissions_filters/_filter_button.html.erb | 4 ++-- app/views/submissions_filters/_filter_modal.html.erb | 2 +- app/views/templates/show.html.erb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/submissions_dashboard/index.html.erb b/app/views/submissions_dashboard/index.html.erb index fc58043a..5c9a733f 100644 --- a/app/views/submissions_dashboard/index.html.erb +++ b/app/views/submissions_dashboard/index.html.erb @@ -33,7 +33,7 @@ <% end %> <% end %> <% if is_show_tabs %> -
+
diff --git a/app/views/submissions_filters/_filter_button.html.erb b/app/views/submissions_filters/_filter_button.html.erb index cdf00fad..b840729d 100644 --- a/app/views/submissions_filters/_filter_button.html.erb +++ b/app/views/submissions_filters/_filter_button.html.erb @@ -1,9 +1,9 @@ <% query_params = params.permit(:q, :status).merge(filter_params) %> <% if params[:with_remove] %>
- <%= link_to t('remove_filter'), "#{params[:path]}?#{params.to_unsafe_h.slice(:q, :status).to_query}", class: 'link', data: { turbo_frame: :_top } %> + <%= link_to t('remove_filter'), "#{params[:path]}?#{params.to_unsafe_h.slice(:q, :status).merge(local_assigns[:default_params]).to_query}", class: 'link', data: { turbo_frame: :_top } %>
<% end %> <% end %> diff --git a/app/views/templates/show.html.erb b/app/views/templates/show.html.erb index 8e222df9..63729287 100644 --- a/app/views/templates/show.html.erb +++ b/app/views/templates/show.html.erb @@ -28,7 +28,7 @@
<% end %> <% if is_show_tabs %> -