From d6474f0e6e3d9d3f7a6f623a3d535e07226ec091 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Tue, 8 Oct 2024 14:14:24 +0300 Subject: [PATCH] adjust submitter edit --- app/controllers/submissions_controller.rb | 7 + .../submissions_dashboard_controller.rb | 2 +- app/controllers/submitters_controller.rb | 47 ++++--- app/controllers/templates_controller.rb | 2 +- app/models/submitter.rb | 2 + app/views/submissions/show.html.erb | 6 +- app/views/submitters/edit.html.erb | 8 +- app/views/templates/_submission.html.erb | 130 ++++++++---------- 8 files changed, 104 insertions(+), 100 deletions(-) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 515dda43..6f92a874 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -9,6 +9,13 @@ class SubmissionsController < ApplicationController def show @submission = Submissions.preload_with_pages(@submission) + unless @submission.submitters.all?(&:completed_at?) + ActiveRecord::Associations::Preloader.new( + records: [@submission], + associations: [submitters: :start_form_submission_events] + ).call + end + render :show, layout: 'plain' end diff --git a/app/controllers/submissions_dashboard_controller.rb b/app/controllers/submissions_dashboard_controller.rb index 784df4fd..aa17b5c4 100644 --- a/app/controllers/submissions_dashboard_controller.rb +++ b/app/controllers/submissions_dashboard_controller.rb @@ -15,6 +15,6 @@ class SubmissionsDashboardController < ApplicationController @submissions = @submissions.pending if params[:status] == 'pending' @submissions = @submissions.completed if params[:status] == 'completed' - @pagy, @submissions = pagy(@submissions.preload(submitters: :submission_events).order(id: :desc)) + @pagy, @submissions = pagy(@submissions.preload(submitters: :start_form_submission_events).order(id: :desc)) end end diff --git a/app/controllers/submitters_controller.rb b/app/controllers/submitters_controller.rb index 225f473a..9d2ff813 100644 --- a/app/controllers/submitters_controller.rb +++ b/app/controllers/submitters_controller.rb @@ -6,9 +6,7 @@ class SubmittersController < ApplicationController def edit @submitter_email_message = if @submitter.preferences['email_message_uuid'].present? - @submitter.account - .email_messages - .find_by(uuid: @submitter.preferences['email_message_uuid']) + @submitter.account.email_messages.find_by(uuid: @submitter.preferences['email_message_uuid']) end end @@ -29,13 +27,16 @@ class SubmittersController < ApplicationController params.delete(:body) end - assign_preferences(@submitter, params) + submitter_preferences = Submitters.normalize_preferences(@submitter.account, current_user, params) + + if submitter_preferences.key?('email_message_uuid') + submitter.preferences['email_message_uuid'] = submitter_preferences['email_message_uuid'] + end + assign_submitter_attrs(@submitter, submitter_params) if @submitter.save - if @submitter.preferences['send_email'] || @submitter.preferences['send_sms'] - Submitters.send_signature_requests([@submitter]) - end + maybe_resend_email_sms(@submitter, params) redirect_back fallback_location: submission_path(submission), notice: I18n.t('changes_have_been_saved') else @@ -45,28 +46,30 @@ class SubmittersController < ApplicationController private - def assign_submitter_attrs(submitter, attrs) - submitter.phone = attrs[:phone].to_s.gsub(/[^0-9+]/, '') if attrs.key?(:phone) + def maybe_resend_email_sms(submitter, params) + if params[:send_email] == '1' && submitter.email.present? + is_sent_recently = Docuseal.multitenant? && + EmailEvent.exists?(email: submitter.email, + tag: 'submitter_invitation', + emailable: submitter, + event_type: 'send', + created_at: 4.hours.ago..Time.current) - submitter.email = Submissions.normalize_email(attrs[:email]) if attrs.key?(:email) + SendSubmitterInvitationEmailJob.perform_async('submitter_id' => submitter.id) unless is_sent_recently + end - submitter.name = attrs[:name] if attrs.key?(:name) + return if submitter.phone.blank? + return unless params[:send_sms] == '1' - submitter + SendSubmitterInvitationSmsJob.perform_async('submitter_id' => submitter.id) end - def assign_preferences(submitter, attrs) - submitter_preferences = Submitters.normalize_preferences(submitter.account, current_user, attrs) - - if submitter_preferences.key?('send_email') - submitter.preferences['send_email'] = submitter_preferences['send_email'] - end + def assign_submitter_attrs(submitter, attrs) + submitter.phone = attrs[:phone].to_s.gsub(/[^0-9+]/, '') if attrs.key?(:phone) - submitter.preferences['send_sms'] = submitter_preferences['send_sms'] if submitter_preferences.key?('send_sms') + submitter.email = Submissions.normalize_email(attrs[:email]) if attrs.key?(:email) - if submitter_preferences.key?('email_message_uuid') - submitter.preferences['email_message_uuid'] = submitter_preferences['email_message_uuid'] - end + submitter.name = attrs[:name] if attrs.key?(:name) submitter end diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb index 2705fa94..d5c06ace 100644 --- a/app/controllers/templates_controller.rb +++ b/app/controllers/templates_controller.rb @@ -15,7 +15,7 @@ class TemplatesController < ApplicationController submissions = submissions.pending if params[:status] == 'pending' submissions = submissions.completed if params[:status] == 'completed' - @pagy, @submissions = pagy(submissions.preload(submitters: :submission_events).order(id: :desc)) + @pagy, @submissions = pagy(submissions.preload(submitters: :start_form_submission_events).order(id: :desc)) rescue ActiveRecord::RecordNotFound redirect_to root_path end diff --git a/app/models/submitter.rb b/app/models/submitter.rb index e155a14e..de80d3e6 100644 --- a/app/models/submitter.rb +++ b/app/models/submitter.rb @@ -56,6 +56,8 @@ class Submitter < ApplicationRecord has_many :document_generation_events, dependent: :destroy has_many :submission_events, dependent: :destroy + has_many :start_form_submission_events, -> { where(event_type: :start_form) }, + class_name: 'SubmissionEvent', dependent: :destroy, inverse_of: :submitter scope :completed, -> { where.not(completed_at: nil) } diff --git a/app/views/submissions/show.html.erb b/app/views/submissions/show.html.erb index d5a22ca7..66dda492 100644 --- a/app/views/submissions/show.html.erb +++ b/app/views/submissions/show.html.erb @@ -115,10 +115,10 @@ <%= (@submission.template_submitters || @submission.template.submitters).find { |e| e['uuid'] == submitter&.uuid }&.dig('name') || "#{(index + 1).ordinalize} Submitter" %> - <% if can?(:update, submitter) && !submitter.submission_events.exists?(event_type: 'start_form') && !@submission.archived_at? && !@submission.expired? %> + <% if signed_in? && can?(:update, submitter) && !submitter.completed_at? && !submitter.declined_at? && !@submission.archived_at? && !@submission.expired? && !submitter.start_form_submission_events.any? %> - <%= link_to edit_submitter_path(submitter), class: 'shrink-0 text-neutral-600 md:text-neutral-400 md:group-hover:text-neutral-600', data: { turbo_frame: 'modal' } do %> - <%= svg_icon('pencil', class: 'w-5 h-5 stroke-2') %> + <%= link_to edit_submitter_path(submitter), class: 'shrink-0 inline md:hidden md:group-hover:inline', data: { turbo_frame: 'modal' } do %> + <%= svg_icon('pencil', class: 'w-5 h-5') %> <% end %> <% end %> diff --git a/app/views/submitters/edit.html.erb b/app/views/submitters/edit.html.erb index c4d58b36..c3a0e9a8 100644 --- a/app/views/submitters/edit.html.erb +++ b/app/views/submitters/edit.html.erb @@ -1,12 +1,12 @@ <%= render 'shared/turbo_modal_large', title: t('edit_recipient') do %>
- <%= form_for '', url: submitter_path(@submitter), method: :patch, html: { class: 'space-y-4', autocomplete: 'off' }, data: { turbo_frame: :_top } do |f| %> -
+ <%= form_for '', url: submitter_path(@submitter), method: :patch, html: { autocomplete: 'off' }, data: { turbo_frame: :_top } do |f| %> +
<%= text_field_tag 'submitter[name]', @submitter.name, autocomplete: 'off', class: 'base-input !h-10 w-full', placeholder: "#{t('name')} (#{t('optional')})", dir: 'auto' %> -
+
<%= email_field_tag 'submitter[email]', @submitter.email, autocomplete: 'off', class: 'base-input !h-10 mt-1.5 w-full', placeholder: "#{t('email')} (#{t('optional')})" %> @@ -20,7 +20,7 @@ <%= render 'submissions/send_email', f:, template: @submitter.template, submitter: @submitter, resend_email: @submitter.sent_at?, submitter_email_message: @submitter_email_message, disable_save_as_default_template_option: true %> <%= render 'submissions/send_sms', f:, resend_sms: @submitter.sent_at? %>
-
+
<%= f.button button_title(title: t('update_recipient'), disabled_with: t('updating')), class: 'base-button' %>
<% end %> diff --git a/app/views/templates/_submission.html.erb b/app/views/templates/_submission.html.erb index 4ac672e5..01f17a76 100644 --- a/app/views/templates/_submission.html.erb +++ b/app/views/templates/_submission.html.erb @@ -27,7 +27,6 @@ <% end %>
- <% submitters = (submission.template_submitters || submission.template.submitters).filter_map { |item| submission.submitters.find { |e| e.uuid == item['uuid'] } } %> <% is_submission_completed = submitters.all?(&:completed_at?) && submitters.size.positive? %> <% if submitters.size == 1 %> @@ -42,20 +41,20 @@
<% else %> - + <% end %> - + <%= submitter.name || submitter.email || submitter.phone %> - <% if can?(:update, submitter) && !submitter.submission_events.any? { |e| e.event_type == 'start_form' } && !submission.archived_at? && !submission.expired? %> - - <%= link_to edit_submitter_path(submitter), class: 'text-neutral-600 shrink-0', data: { turbo_frame: 'modal' } do %> - <%= svg_icon('pencil', class: 'w-5 h-5 stroke-2') %> + <% if can?(:update, submitter) && !submitter.start_form_submission_events.any? && !submission.archived_at? && !submission.expired? %> + + <%= link_to edit_submitter_path(submitter), class: 'shrink-0', data: { turbo_frame: 'modal' } do %> + <%= svg_icon('pencil', class: 'w-5 h-5') %> <% end %> <% end %> @@ -65,8 +64,8 @@
<% if submitter.completed_at? %> -
- -
+
+
<% elsif !submission.archived_at? && !template.archived_at? && !submission.expired? && !submitter.declined_at? %> <% if current_user.email == submitter.email %> - + <% if t('sign_now').length < 12 %> <%= svg_icon('writing_sign', class: 'w-4 h-4 stroke-2') %> @@ -91,23 +90,23 @@ <% else %>
- <%= render 'shared/clipboard_copy', text: submit_form_url(slug: submitter.slug), class: 'btn btn-sm btn-neutral text-white md:w-36 flex', 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), 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 %> -
+ <% if !submission.archived_at? && !template.archived_at? && can?(:destroy, submission) %> - <%= button_to button_title(title: nil, disabled_with: t(:archive).first(4), icon: svg_icon('archive', class: 'w-6 h-6')), submission_path(submission), class: 'btn btn-outline btn-sm w-full md:w-fit', form: { class: 'flex' }, title: t('archive'), method: :delete, onclick: 'event.stopPropagation()' %> + <%= button_to button_title(title: nil, disabled_with: t(:archive).first(4), icon: svg_icon('archive', class: 'w-6 h-6')), submission_path(submission), class: 'btn btn-outline btn-sm w-full md:w-fit', form: { class: 'flex' }, title: t('archive'), method: :delete %> <% end %> <% if local_assigns[:archived] && can?(:destroy, submission) %> - <%= button_to button_title(title: nil, disabled_with: t(:remove).first(3), icon: svg_icon('trash', class: 'w-6 h-6')), submission_path(submission, permanently: true), class: 'btn btn-outline btn-sm w-full md:w-fit', form: { class: 'flex' }, title: t('remove'), method: :delete, data: { turbo_confirm: t('submission_deletion_is_irreversible_and_will_permanently_remove_all_associated_signed_documents_with_it_are_you_sure_') }, onclick: 'event.stopPropagation()' %> + <%= button_to button_title(title: nil, disabled_with: t(:remove).first(3), icon: svg_icon('trash', class: 'w-6 h-6')), submission_path(submission, permanently: true), class: 'btn btn-outline btn-sm w-full md:w-fit', form: { class: 'flex' }, title: t('remove'), method: :delete, data: { turbo_confirm: t('submission_deletion_is_irreversible_and_will_permanently_remove_all_associated_signed_documents_with_it_are_you_sure_') } %> <% end %>
@@ -116,11 +115,11 @@
<% if is_submission_completed %> <% latest_submitter = submitters.select(&:completed_at?).max_by(&:completed_at) %> - + <% elsif submission.expired? %>
@@ -133,55 +132,49 @@
<% if !is_submission_completed && !submission.expired? %> - + <% end %> - + <%= submitter.name || submitter.email || submitter.phone %> - <% if can?(:update, submitter) && !submitter.submission_events.any? { |e| e.event_type == 'start_form' } && !submission.archived_at? && !submission.expired? %> - - <%= link_to edit_submitter_path(submitter), class: 'text-neutral-600 shrink-0', data: { turbo_frame: 'modal' } do %> - <%= svg_icon('pencil', class: 'w-5 h-5 stroke-2') %> + <% if can?(:update, submitter) && !submitter.start_form_submission_events.any? && !submission.archived_at? && !submission.expired? %> + + <%= link_to edit_submitter_path(submitter), class: 'shrink-0', data: { turbo_frame: 'modal' } do %> + <%= svg_icon('pencil', class: 'w-5 h-5') %> <% end %> <% end %> <% if submitter.completed_at? && !is_submission_completed %> -
- -
+ + + <%= svg_icon('download', class: 'w-4 h-4 stroke-2') %> + <%= t('download') %> + + + <% elsif !template.archived_at? && !submission.archived_at? && !is_submission_completed && !submission.expired? && !submitter.declined_at? %>
<% if current_user.email == submitter.email %> -
- -
+ + + <% if t('sign_now').length < 12 %> + <%= svg_icon('writing_sign', class: 'w-4 h-4 stroke-2') %> + <% end %> + <%= t('sign_now') %> + + <% 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', 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), 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 %> @@ -194,38 +187,37 @@ <% if is_submission_completed %> <% latest_submitter = submitters.select(&:completed_at?).max_by(&:completed_at) %>
-
- -
+
+ + + <%= svg_icon('download', class: 'w-5 h-5 stroke-2') %> + <%= t('download') %> + + + +
<% end %> -
+ <% if !submission.archived_at? && !template.archived_at? %> - <%= button_to button_title(title: nil, disabled_with: t(:archive).first(4), icon: svg_icon('archive', class: 'w-6 h-6')), submission_path(submission), class: 'btn btn-outline btn-sm w-full md:w-fit', form: { class: 'flex' }, title: t('archive'), method: :delete, onclick: 'event.stopPropagation()' %> + <%= button_to button_title(title: nil, disabled_with: t(:archive).first(4), icon: svg_icon('archive', class: 'w-6 h-6')), submission_path(submission), class: 'btn btn-outline btn-sm w-full md:w-fit', form: { class: 'flex' }, title: t('archive'), method: :delete %> <% end %> <% if local_assigns[:archived] && can?(:destroy, submission) %> - <%= button_to button_title(title: nil, disabled_with: t(:remove).first(3), icon: svg_icon('trash', class: 'w-6 h-6')), submission_path(submission, permanently: true), class: 'btn btn-outline btn-sm w-full md:w-fit', form: { class: 'flex' }, title: t('remove'), method: :delete, data: { turbo_confirm: t('submission_deletion_is_irreversible_and_will_permanently_remove_all_associated_signed_documents_with_it_are_you_sure_') }, onclick: 'event.stopPropagation()' %> + <%= button_to button_title(title: nil, disabled_with: t(:remove).first(3), icon: svg_icon('trash', class: 'w-6 h-6')), submission_path(submission, permanently: true), class: 'btn btn-outline btn-sm w-full md:w-fit', form: { class: 'flex' }, title: t('remove'), method: :delete, data: { turbo_confirm: t('submission_deletion_is_irreversible_and_will_permanently_remove_all_associated_signed_documents_with_it_are_you_sure_') } %> <% end %>
<% end %> +