From 8d953f210fb700cefc63cf9d308af04e38e86b6c Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Mon, 10 Feb 2025 22:27:28 +0200 Subject: [PATCH 01/16] add attachment count attribute to template factory --- spec/factories/templates.rb | 616 ++++++++++++++++++------------------ 1 file changed, 313 insertions(+), 303 deletions(-) diff --git a/spec/factories/templates.rb b/spec/factories/templates.rb index 0f737512..8f619353 100644 --- a/spec/factories/templates.rb +++ b/spec/factories/templates.rb @@ -9,6 +9,7 @@ FactoryBot.define do transient do submitter_count { 1 } + attachment_count { 1 } only_field_types do %w[text date checkbox radio signature number multiple select initials image file stamp cells phone payment] end @@ -16,20 +17,6 @@ FactoryBot.define do end after(:create) do |template, ev| - blob = ActiveStorage::Blob.create_and_upload!( - io: Rails.root.join('spec/fixtures/sample-document.pdf').open, - filename: 'sample-document.pdf', - content_type: 'application/pdf' - ) - attachment = ActiveStorage::Attachment.create!( - blob:, - name: :documents, - record: template - ) - - Templates::ProcessDocument.call(attachment, attachment.download) - - template.schema = [{ attachment_uuid: attachment.uuid, name: 'sample-document' }] number_words = %w[first second third fourth fifth sixth seventh eighth ninth tenth] template.submitters = Array.new(ev.submitter_count) do |i| @@ -39,296 +26,319 @@ FactoryBot.define do } end - template.fields = template.submitters.reduce([]) do |fields, submitter| - fields += [ - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'First Name', - 'type' => 'text', - 'required' => true, - 'preferences' => {}, - 'areas' => [ - { - 'x' => 0.09273546006944444, - 'y' => 0.1099851117387033, - 'w' => 0.2701497395833333, - 'h' => 0.0372705365913556, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Birthday', - 'type' => 'date', - 'required' => true, - 'preferences' => { 'format' => 'DD/MM/YYYY' }, - 'areas' => [ - { - 'x' => 0.09166666666666666, - 'y' => 0.1762778204144282, - 'w' => 0.2763888888888889, - 'h' => 0.0359029261474578, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Do you agree?', - 'type' => 'checkbox', - 'required' => true, - 'preferences' => {}, - 'areas' => [ - { - 'x' => 0.09051106770833334, - 'y' => 0.227587027259332, - 'w' => 0.2784450954861111, - 'h' => 0.04113074042239687, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'First child', - 'type' => 'radio', - 'required' => true, - 'preferences' => {}, - 'options' => [ - { 'value' => 'Girl', 'uuid' => SecureRandom.uuid }, - { 'value' => 'Boy', 'uuid' => SecureRandom.uuid } - ], - 'areas' => [ - { - 'x' => 0.09027777777777778, - 'y' => 0.3020184190330008, - 'w' => 0.2, - 'h' => 0.02857142857142857, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Signature', - 'type' => 'signature', - 'required' => true, - 'preferences' => {}, - 'areas' => [ - { - 'x' => 0.08611111111111111, - 'y' => 0.3487183422870299, - 'w' => 0.2, - 'h' => 0.0707269155206287, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'House number', - 'type' => 'number', - 'required' => true, - 'preferences' => {}, - 'areas' => [ - { - 'x' => 0.08333333333333333, - 'y' => 0.4582041442824252, - 'w' => 0.2, - 'h' => 0.02857142857142857, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Colors', - 'type' => 'multiple', - 'required' => true, - 'preferences' => {}, - 'options' => [ - { 'value' => 'Red', 'uuid' => SecureRandom.uuid }, - { 'value' => 'Green', 'uuid' => SecureRandom.uuid }, - { 'value' => 'Blue', 'uuid' => SecureRandom.uuid } - ], - 'areas' => [ - { - 'x' => 0.45, - 'y' => 0.1133998465080583, - 'w' => 0.2, - 'h' => 0.02857142857142857, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Gender', - 'type' => 'select', - 'required' => true, - 'preferences' => {}, - 'options' => [ - { 'value' => 'Male', 'uuid' => SecureRandom.uuid }, - { 'value' => 'Female', 'uuid' => SecureRandom.uuid } - ], - 'areas' => [ - { - 'x' => 0.4513888888888889, - 'y' => 0.1752954719877206, - 'w' => 0.2, - 'h' => 0.02857142857142857, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Initials', - 'type' => 'initials', - 'required' => true, - 'preferences' => {}, - 'areas' => [ - { - 'x' => 0.4486111111111111, - 'y' => 0.2273599386032233, - 'w' => 0.1, - 'h' => 0.02857142857142857, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Avatar', - 'type' => 'image', - 'required' => true, - 'preferences' => {}, - 'areas' => [ - { - 'x' => 0.7180555555555556, - 'y' => 0.1129547198772064, - 'w' => 0.2, - 'h' => 0.1414538310412574, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Attachment', - 'type' => 'file', - 'required' => true, - 'preferences' => {}, - 'areas' => [ - { - 'x' => 0.7166666666666667, - 'y' => 0.3020107444359171, - 'w' => 0.2, - 'h' => 0.02857142857142857, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Stamp', - 'type' => 'stamp', - 'required' => true, - 'readonly' => true, - 'preferences' => {}, - 'areas' => [ - { - 'x' => 0.7166666666666667, - 'y' => 0.3771910974673829, - 'w' => 0.2, - 'h' => 0.0707269155206287, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Cell code', - 'type' => 'cells', - 'required' => true, - 'preferences' => {}, - 'areas' => [ - { - 'x' => 0.4472222222222222, - 'y' => 0.3530851880276286, - 'w' => 0.2, - 'h' => 0.02857142857142857, - 'cell_w' => 0.04, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Payment', - 'type' => 'payment', - 'required' => true, - 'preferences' => { 'currency' => 'EUR', 'price' => 1000 }, - 'areas' => [ - { - 'x' => 0.4486111111111111, - 'y' => 0.43168073676132, - 'w' => 0.2, - 'h' => 0.02857142857142857, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - }, - { - 'uuid' => SecureRandom.uuid, - 'submitter_uuid' => submitter['uuid'], - 'name' => 'Mobile Phone', - 'type' => 'phone', - 'required' => true, - 'preferences' => {}, - 'areas' => [ - { - 'x' => 0.44443359375, - 'y' => 0.3010283960092095, - 'w' => 0.2, - 'h' => 0.02857142857142857, - 'attachment_uuid' => attachment.uuid, - 'page' => 0 - } - ] - } - ].select { |f| ev.only_field_types.include?(f['type']) && ev.except_field_types.exclude?(f['type']) } + ev.attachment_count.times do |i| + attachment_index = i + 1 if i > 0 + field_index = "(#{attachment_index})" if attachment_index + + blob = ActiveStorage::Blob.create_and_upload!( + io: Rails.root.join('spec/fixtures/sample-document.pdf').open, + filename: 'sample-document.pdf', + content_type: 'application/pdf' + ) + attachment = ActiveStorage::Attachment.create!( + blob:, + name: :documents, + record: template + ) + + Templates::ProcessDocument.call(attachment, attachment.download) + + template.schema << { + attachment_uuid: attachment.uuid, + name: ['sample-document', attachment_index].compact.join('-') + } + + template.fields += template.submitters.reduce([]) do |fields, submitter| + fields += [ + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['First Name', field_index].compact.join(' '), + 'type' => 'text', + 'required' => true, + 'preferences' => {}, + 'areas' => [ + { + 'x' => 0.09273546006944444, + 'y' => 0.1099851117387033, + 'w' => 0.2701497395833333, + 'h' => 0.0372705365913556, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Birthday', field_index].compact.join(' '), + 'type' => 'date', + 'required' => true, + 'preferences' => { 'format' => 'DD/MM/YYYY' }, + 'areas' => [ + { + 'x' => 0.09166666666666666, + 'y' => 0.1762778204144282, + 'w' => 0.2763888888888889, + 'h' => 0.0359029261474578, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Do you agree?', field_index].compact.join(' '), + 'type' => 'checkbox', + 'required' => true, + 'preferences' => {}, + 'areas' => [ + { + 'x' => 0.09051106770833334, + 'y' => 0.227587027259332, + 'w' => 0.2784450954861111, + 'h' => 0.04113074042239687, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['First child', field_index].compact.join(' '), + 'type' => 'radio', + 'required' => true, + 'preferences' => {}, + 'options' => [ + { 'value' => 'Girl', 'uuid' => SecureRandom.uuid }, + { 'value' => 'Boy', 'uuid' => SecureRandom.uuid } + ], + 'areas' => [ + { + 'x' => 0.09027777777777778, + 'y' => 0.3020184190330008, + 'w' => 0.2, + 'h' => 0.02857142857142857, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Signature', field_index].compact.join(' '), + 'type' => 'signature', + 'required' => true, + 'preferences' => {}, + 'areas' => [ + { + 'x' => 0.08611111111111111, + 'y' => 0.3487183422870299, + 'w' => 0.2, + 'h' => 0.0707269155206287, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['House number', field_index].compact.join(' '), + 'type' => 'number', + 'required' => true, + 'preferences' => {}, + 'areas' => [ + { + 'x' => 0.08333333333333333, + 'y' => 0.4582041442824252, + 'w' => 0.2, + 'h' => 0.02857142857142857, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Colors', field_index].compact.join(' '), + 'type' => 'multiple', + 'required' => true, + 'preferences' => {}, + 'options' => [ + { 'value' => 'Red', 'uuid' => SecureRandom.uuid }, + { 'value' => 'Green', 'uuid' => SecureRandom.uuid }, + { 'value' => 'Blue', 'uuid' => SecureRandom.uuid } + ], + 'areas' => [ + { + 'x' => 0.45, + 'y' => 0.1133998465080583, + 'w' => 0.2, + 'h' => 0.02857142857142857, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Gender', field_index].compact.join(' '), + 'type' => 'select', + 'required' => true, + 'preferences' => {}, + 'options' => [ + { 'value' => 'Male', 'uuid' => SecureRandom.uuid }, + { 'value' => 'Female', 'uuid' => SecureRandom.uuid } + ], + 'areas' => [ + { + 'x' => 0.4513888888888889, + 'y' => 0.1752954719877206, + 'w' => 0.2, + 'h' => 0.02857142857142857, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Initials', field_index].compact.join(' '), + 'type' => 'initials', + 'required' => true, + 'preferences' => {}, + 'areas' => [ + { + 'x' => 0.4486111111111111, + 'y' => 0.2273599386032233, + 'w' => 0.1, + 'h' => 0.02857142857142857, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Avatar', field_index].compact.join(' '), + 'type' => 'image', + 'required' => true, + 'preferences' => {}, + 'areas' => [ + { + 'x' => 0.7180555555555556, + 'y' => 0.1129547198772064, + 'w' => 0.2, + 'h' => 0.1414538310412574, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Attachment', field_index].compact.join(' '), + 'type' => 'file', + 'required' => true, + 'preferences' => {}, + 'areas' => [ + { + 'x' => 0.7166666666666667, + 'y' => 0.3020107444359171, + 'w' => 0.2, + 'h' => 0.02857142857142857, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Stamp', field_index].compact.join(' '), + 'type' => 'stamp', + 'required' => true, + 'readonly' => true, + 'preferences' => {}, + 'areas' => [ + { + 'x' => 0.7166666666666667, + 'y' => 0.3771910974673829, + 'w' => 0.2, + 'h' => 0.0707269155206287, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Cell code', field_index].compact.join(' '), + 'type' => 'cells', + 'required' => true, + 'preferences' => {}, + 'areas' => [ + { + 'x' => 0.4472222222222222, + 'y' => 0.3530851880276286, + 'w' => 0.2, + 'h' => 0.02857142857142857, + 'cell_w' => 0.04, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Payment', field_index].compact.join(' '), + 'type' => 'payment', + 'required' => true, + 'preferences' => { 'currency' => 'EUR', 'price' => 1000 }, + 'areas' => [ + { + 'x' => 0.4486111111111111, + 'y' => 0.43168073676132, + 'w' => 0.2, + 'h' => 0.02857142857142857, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + }, + { + 'uuid' => SecureRandom.uuid, + 'submitter_uuid' => submitter['uuid'], + 'name' => ['Mobile Phone', field_index].compact.join(' '), + 'type' => 'phone', + 'required' => true, + 'preferences' => {}, + 'areas' => [ + { + 'x' => 0.44443359375, + 'y' => 0.3010283960092095, + 'w' => 0.2, + 'h' => 0.02857142857142857, + 'attachment_uuid' => attachment.uuid, + 'page' => 0 + } + ] + } + ].select { |f| ev.only_field_types.include?(f['type']) && ev.except_field_types.exclude?(f['type']) } - fields + fields + end end template.save! From a31567442161506b15ca416a639bc735a1d0cb3f Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Tue, 11 Feb 2025 11:17:27 +0200 Subject: [PATCH 02/16] update gem --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index da75225a..b40d07db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -327,7 +327,7 @@ GEM mysql2 (0.5.6) net-http-persistent (4.0.5) connection_pool (~> 2.2) - net-imap (0.5.3) + net-imap (0.5.6) date net-protocol net-pop (0.1.2) From e406620044044a18eae9d531c3b176ee528d3505 Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Tue, 11 Feb 2025 22:23:51 +0200 Subject: [PATCH 03/16] add 'Event Log' modal --- .../submission_events_controller.rb | 64 +++++++++++++++++++ app/views/icons/_2fa.html.erb | 6 ++ app/views/icons/_circle_dot.html.erb | 5 ++ app/views/icons/_hand_click.html.erb | 10 +++ app/views/icons/_logs.html.erb | 11 ++++ app/views/icons/_phone_check.html.erb | 4 ++ app/views/icons/_player_play.html.erb | 3 + app/views/submission_events/index.html.erb | 38 +++++++++++ app/views/submissions/show.html.erb | 5 ++ config/locales/i18n.yml | 54 ++++++++++++++++ config/routes.rb | 1 + 11 files changed, 201 insertions(+) create mode 100644 app/controllers/submission_events_controller.rb create mode 100644 app/views/icons/_2fa.html.erb create mode 100644 app/views/icons/_circle_dot.html.erb create mode 100644 app/views/icons/_hand_click.html.erb create mode 100644 app/views/icons/_logs.html.erb create mode 100644 app/views/icons/_phone_check.html.erb create mode 100644 app/views/icons/_player_play.html.erb create mode 100644 app/views/submission_events/index.html.erb diff --git a/app/controllers/submission_events_controller.rb b/app/controllers/submission_events_controller.rb new file mode 100644 index 00000000..044b9319 --- /dev/null +++ b/app/controllers/submission_events_controller.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +class SubmissionEventsController < ApplicationController + SUBMISSION_EVENT_ICONS = { + 'view_form' => 'eye', + 'start_form' => 'player_play', + 'complete_form' => 'check', + 'send_email' => 'mail_forward', + 'click_email' => 'hand_click', + 'api_complete_form' => 'check', + 'send_reminder_email' => 'mail_forward', + 'send_2fa_sms' => '2fa', + 'send_sms' => 'send', + 'phone_verified' => 'phone_check', + 'click_sms' => 'hand_click', + 'decline_form' => 'x', + 'start_verification' => 'player_play', + 'complete_verification' => 'check', + 'invite_party' => 'user_plus' + }.freeze + + load_and_authorize_resource :submission + + # rubocop:disable Metrics + def index + submitters = @submission.submitters + submitters_uuids = (@submission.template_submitters || @submission.template.submitters).pluck('uuid') + + @events_data = @submission.submission_events.sort_by(&:event_timestamp).map do |event| + submitter = submitters.find { |e| e.id == event.submitter_id } + submitter_name = + if event.event_type.include?('sms') || event.event_type.include?('phone') + event.data['phone'] || submitter.phone + else + submitter.name || submitter.email || submitter.phone + end + + text = + if event.event_type == 'complete_verification' + helpers.t('submission_event_names.complete_verification_by_html', provider: event.data['method'], + submitter_name:) + elsif event.event_type == 'invite_party' && + (invited_submitter = submitters.find { |e| e.uuid == event.data['uuid'] }) && + (name = submission.template_submitters.find { |e| e['uuid'] == event.data['uuid'] }&.dig('name')) + invited_submitter_name = [invited_submitter.name || invited_submitter.email || invited_submitter.phone, + name].join(' ') + helpers.t('submission_event_names.invite_party_by_html', invited_submitter_name:, + submitter_name:) + elsif event.event_type.include?('send_') + helpers.t("submission_event_names.#{event.event_type}_to_html", submitter_name:) + else + helpers.t("submission_event_names.#{event.event_type}_by_html", submitter_name:) + end + + { + timestamp: event.event_timestamp.in_time_zone(current_account.timezone), + event_type: event.event_type, + submitter_index: submitters_uuids.index(submitter.uuid), + text: + } + end + end + # rubocop:enable Metrics +end diff --git a/app/views/icons/_2fa.html.erb b/app/views/icons/_2fa.html.erb new file mode 100644 index 00000000..5dfebef1 --- /dev/null +++ b/app/views/icons/_2fa.html.erb @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/views/icons/_circle_dot.html.erb b/app/views/icons/_circle_dot.html.erb new file mode 100644 index 00000000..b6b36b41 --- /dev/null +++ b/app/views/icons/_circle_dot.html.erb @@ -0,0 +1,5 @@ + + + + + diff --git a/app/views/icons/_hand_click.html.erb b/app/views/icons/_hand_click.html.erb new file mode 100644 index 00000000..016556b9 --- /dev/null +++ b/app/views/icons/_hand_click.html.erb @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/app/views/icons/_logs.html.erb b/app/views/icons/_logs.html.erb new file mode 100644 index 00000000..88ecf439 --- /dev/null +++ b/app/views/icons/_logs.html.erb @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/views/icons/_phone_check.html.erb b/app/views/icons/_phone_check.html.erb new file mode 100644 index 00000000..8b57c41e --- /dev/null +++ b/app/views/icons/_phone_check.html.erb @@ -0,0 +1,4 @@ + + + + diff --git a/app/views/icons/_player_play.html.erb b/app/views/icons/_player_play.html.erb new file mode 100644 index 00000000..947124b3 --- /dev/null +++ b/app/views/icons/_player_play.html.erb @@ -0,0 +1,3 @@ + + + diff --git a/app/views/submission_events/index.html.erb b/app/views/submission_events/index.html.erb new file mode 100644 index 00000000..00392cbf --- /dev/null +++ b/app/views/submission_events/index.html.erb @@ -0,0 +1,38 @@ +<% event_colors = %w[bg-red-200 bg-sky-200 bg-emerald-200 bg-yellow-300 bg-purple-200 bg-pink-200 bg-cyan-200 bg-orange-200 bg-lime-200 bg-indigo-200] %> +<%= render 'shared/turbo_modal_large', title: t('event_log') do %> +
+
    +
  1. + + <%= svg_icon('file_text', class: 'w-3.5 h-3.5') %> + +

    + <%= l(@submission.created_at.in_time_zone(current_account.timezone), format: :long, locale: current_account.locale) %> +

    +

    + <% if @submission.source == 'invite' %> + <%= t('submission_created_by_email_invite_html', email: @submission.created_by_user.email) %> + <% elsif @submission.created_by_user %> + <%= t('submission_created_by_email_via_source_html', email: @submission.created_by_user.email, source: t("submission_sources.#{@submission.source}")) %> + <% else %> + <%= t('submission_created_via_source_html', source: t("submission_sources.#{@submission.source}")) %> + <% end %> +

    +
  2. + <% @events_data.each do |row| %> + <% bg_class = event_colors[row[:submitter_index] % event_colors.length] %> +
  3. + + <%= svg_icon(SubmissionEventsController::SUBMISSION_EVENT_ICONS.fetch(row[:event_type], 'circle_dot'), class: 'w-3.5 h-3.5') %> + +

    + <%= l(row[:timestamp], format: :long, locale: current_account.locale) %> +

    +

    + <%= row[:text] %> +

    +
  4. + <% end %> +
+
+<% end %> diff --git a/app/views/submissions/show.html.erb b/app/views/submissions/show.html.erb index fff9f56f..3256ad36 100644 --- a/app/views/submissions/show.html.erb +++ b/app/views/submissions/show.html.erb @@ -19,6 +19,11 @@ <%= svg_icon('external_link', class: 'w-6 h-6') %> + <% else %> + <%= link_to submission_events_path(@submission), class: 'white-button', data: { turbo_frame: :modal } do %> + <%= svg_icon('logs', class: 'w-6 h-6') %> + + <% end %> <% end %> <% if last_submitter %> <% if is_all_completed || !is_combined_enabled %> diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml index 924d46fd..44d04f02 100644 --- a/config/locales/i18n.yml +++ b/config/locales/i18n.yml @@ -695,6 +695,15 @@ en: &en overdue_payment: Overdue Payment your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Your Pro Plan has been suspended due to unpaid invoices. You can update your payment details to settle the invoice and continue using DocuSeal or cancel your subscription. manage_subscription: Manage Subscription + submission_created_by_email_invite_html: 'Submission created by %{email} invite' + submission_created_by_email_via_source_html: 'Submission created by %{email} via %{source}' + submission_created_via_source_html: 'Submission created via %{source}' + submission_sources: + api: API + bulk: Bulk Send + embed: Embedding + invie: Invite + link: Link submission_event_names: send_email_to_html: 'Email sent to %{submitter_name}' send_reminder_email_to_html: 'Reminder email sent to %{submitter_name}' @@ -1410,6 +1419,15 @@ es: &es overdue_payment: Pago Atrasado your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Tu plan Pro ha sido suspendido debido a facturas impagas. Puedes actualizar tus datos de pago para liquidar la factura y seguir usando DocuSeal o cancelar tu suscripción. manage_subscription: Gestionar Suscripción + submission_created_by_email_invite_html: 'Envío creado por invitación de %{email}' + submission_created_by_email_via_source_html: 'Envío creado por %{email} a través de %{source}' + submission_created_via_source_html: 'Envío creado a través de %{source}' + submission_sources: + api: API + bulk: Envío masivo + embed: Integración + invite: Invitación + link: Enlace submission_event_names: send_email_to_html: 'Correo electrónico enviado a %{submitter_name}' send_reminder_email_to_html: 'Correo de recordatorio enviado a %{submitter_name}' @@ -2124,6 +2142,15 @@ it: &it overdue_payment: Pagamento Scaduto your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Il tuo piano Pro è stato sospeso a causa di fatture non pagate. Puoi aggiornare i tuoi dati di pagamento per saldare la fattura e continuare a utilizzare DocuSeal o annullare l'abbonamento. manage_subscription: Gestisci Abbonamento + submission_created_by_email_invite_html: 'Invio creato tramite invito di %{email}' + submission_created_by_email_via_source_html: 'Invio creato da %{email} tramite %{source}' + submission_created_via_source_html: 'Invio creato tramite %{source}' + submission_sources: + api: API + bulk: Invio massivo + embed: Incorporamento + invite: Invito + link: Link submission_event_names: send_email_to_html: 'E-mail inviato a %{submitter_name}' send_reminder_email_to_html: 'E-mail di promemoria inviato a %{submitter_name}' @@ -2840,6 +2867,15 @@ fr: &fr overdue_payment: Paiement En Retard your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Votre plan Pro a été suspendu en raison de factures impayées. Vous pouvez mettre à jour vos informations de paiement pour régler la facture et continuer à utiliser DocuSeal ou annuler votre abonnement. manage_subscription: Gérer l'Abonnement + submission_created_by_email_invite_html: "Soumission créée par l'invitation de %{email}" + submission_created_by_email_via_source_html: 'Soumission créée par %{email} via %{source}' + submission_created_via_source_html: 'Soumission créée via %{source}' + submission_sources: + api: API + bulk: Envoi en masse + embed: Intégration + invite: Invitation + link: Lien submission_event_names: send_email_to_html: 'E-mail envoyé à %{submitter_name}' send_reminder_email_to_html: 'E-mail de rappel envoyé à %{submitter_name}' @@ -3555,6 +3591,15 @@ pt: &pt overdue_payment: Pagamento Atrasado your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Seu plano Pro foi suspenso devido a faturas não pagas. Você pode atualizar seus dados de pagamento para quitar a fatura e continuar usando o DocuSeal ou cancelar sua assinatura. manage_subscription: Gerenciar Assinatura + submission_created_by_email_invite_html: 'Envio criado por convite de %{email}' + submission_created_by_email_via_source_html: 'Envio criado por %{email} via %{source}' + submission_created_via_source_html: 'Envio criado via %{source}' + submission_sources: + api: API + bulk: Envio em massa + embed: Incorporação + invite: Convite + link: Link submission_event_names: send_email_to_html: 'E-mail enviado para %{submitter_name}' send_reminder_email_to_html: 'E-mail de lembrete enviado para %{submitter_name}' @@ -4270,6 +4315,15 @@ de: &de overdue_payment: Überfällige Zahlung your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Ihr Pro-Plan wurde aufgrund unbezahlter Rechnungen ausgesetzt. Sie können Ihre Zahlungsdaten aktualisieren, um die Rechnung zu begleichen und DocuSeal weiterhin zu nutzen, oder Ihr Abonnement kündigen. manage_subscription: Abonnement Verwalten + submission_created_by_email_invite_html: 'Übermittlung erstellt durch Einladung von %{email}' + submission_created_by_email_via_source_html: 'Übermittlung erstellt durch %{email} über %{source}' + submission_created_via_source_html: 'Übermittlung erstellt über %{source}' + submission_sources: + api: API + bulk: Massenversand + embed: Einbettung + invite: Einladung + link: Link submission_event_names: send_email_to_html: 'E-Mail gesendet an %{submitter_name}' send_reminder_email_to_html: 'Erinnerungs-E-Mail gesendet an %{submitter_name}' diff --git a/config/routes.rb b/config/routes.rb index d4d792c6..7e24097b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -72,6 +72,7 @@ Rails.application.routes.draw do resources :submissions, only: %i[index], controller: 'submissions_dashboard' resources :submissions, only: %i[show destroy] do resources :unarchive, only: %i[create], controller: 'submissions_unarchive' + resources :events, only: %i[index], controller: 'submission_events' end resources :submitters, only: %i[edit update] resources :console_redirect, only: %i[index] From 8d685d1f73dbbf04a1b4ef52a2c5cee05e1bf22b Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Tue, 11 Feb 2025 22:37:47 +0200 Subject: [PATCH 04/16] adjust event log --- .../submission_events_controller.rb | 3 ++- app/views/submission_events/index.html.erb | 22 +++++++++---------- config/locales/i18n.yml | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/app/controllers/submission_events_controller.rb b/app/controllers/submission_events_controller.rb index 044b9319..e493bd95 100644 --- a/app/controllers/submission_events_controller.rb +++ b/app/controllers/submission_events_controller.rb @@ -24,9 +24,10 @@ class SubmissionEventsController < ApplicationController # rubocop:disable Metrics def index submitters = @submission.submitters + submitters_uuids = (@submission.template_submitters || @submission.template.submitters).pluck('uuid') - @events_data = @submission.submission_events.sort_by(&:event_timestamp).map do |event| + @events_data = @submission.submission_events.order(:event_timestamp).map do |event| submitter = submitters.find { |e| e.id == event.submitter_id } submitter_name = if event.event_type.include?('sms') || event.event_type.include?('phone') diff --git a/app/views/submission_events/index.html.erb b/app/views/submission_events/index.html.erb index 00392cbf..31f184fe 100644 --- a/app/views/submission_events/index.html.erb +++ b/app/views/submission_events/index.html.erb @@ -1,15 +1,15 @@ -<% event_colors = %w[bg-red-200 bg-sky-200 bg-emerald-200 bg-yellow-300 bg-purple-200 bg-pink-200 bg-cyan-200 bg-orange-200 bg-lime-200 bg-indigo-200] %> +<% event_colors = %w[bg-red-200 bg-sky-200 bg-emerald-200 bg-yellow-200 bg-purple-200 bg-pink-200 bg-cyan-200 bg-orange-200 bg-lime-200 bg-indigo-200] %> <%= render 'shared/turbo_modal_large', title: t('event_log') do %>
-
    -
  1. - +
      +
    1. + <%= svg_icon('file_text', class: 'w-3.5 h-3.5') %> -

      +

      <%= l(@submission.created_at.in_time_zone(current_account.timezone), format: :long, locale: current_account.locale) %>

      -

      +

      <% if @submission.source == 'invite' %> <%= t('submission_created_by_email_invite_html', email: @submission.created_by_user.email) %> <% elsif @submission.created_by_user %> @@ -21,14 +21,14 @@

    2. <% @events_data.each do |row| %> <% bg_class = event_colors[row[:submitter_index] % event_colors.length] %> -
    3. - - <%= svg_icon(SubmissionEventsController::SUBMISSION_EVENT_ICONS.fetch(row[:event_type], 'circle_dot'), class: 'w-3.5 h-3.5') %> +
    4. + + <%= svg_icon(SubmissionEventsController::SUBMISSION_EVENT_ICONS.fetch(row[:event_type], 'circle_dot'), class: 'w-4 h-4') %> -

      +

      <%= l(row[:timestamp], format: :long, locale: current_account.locale) %>

      -

      +

      <%= row[:text] %>

    5. diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml index 44d04f02..6f5a3ec7 100644 --- a/config/locales/i18n.yml +++ b/config/locales/i18n.yml @@ -695,7 +695,7 @@ en: &en overdue_payment: Overdue Payment your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Your Pro Plan has been suspended due to unpaid invoices. You can update your payment details to settle the invoice and continue using DocuSeal or cancel your subscription. manage_subscription: Manage Subscription - submission_created_by_email_invite_html: 'Submission created by %{email} invite' + submission_created_by_email_invite_html: 'Submission created by %{email}' submission_created_by_email_via_source_html: 'Submission created by %{email} via %{source}' submission_created_via_source_html: 'Submission created via %{source}' submission_sources: From d9d969cb790ed72cd8bf065eb03e07318fc5b099 Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Wed, 12 Feb 2025 14:28:35 +0200 Subject: [PATCH 05/16] add translations --- app/views/submission_events/index.html.erb | 2 +- app/views/users/_seats_info.html.erb | 0 app/views/users/index.html.erb | 1 + config/locales/i18n.yml | 24 ++++++++++++++++------ 4 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 app/views/users/_seats_info.html.erb diff --git a/app/views/submission_events/index.html.erb b/app/views/submission_events/index.html.erb index 31f184fe..6d89ff27 100644 --- a/app/views/submission_events/index.html.erb +++ b/app/views/submission_events/index.html.erb @@ -11,7 +11,7 @@

      <% if @submission.source == 'invite' %> - <%= t('submission_created_by_email_invite_html', email: @submission.created_by_user.email) %> + <%= t('submission_created_by_email_html', email: @submission.created_by_user.email) %> <% elsif @submission.created_by_user %> <%= t('submission_created_by_email_via_source_html', email: @submission.created_by_user.email, source: t("submission_sources.#{@submission.source}")) %> <% else %> diff --git a/app/views/users/_seats_info.html.erb b/app/views/users/_seats_info.html.erb new file mode 100644 index 00000000..e69de29b diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index a37a59c0..a9ddd3c3 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -25,6 +25,7 @@ <% end %>

+ <%= render 'users/seats_info' %>
diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml index 6f5a3ec7..e39a0ce4 100644 --- a/config/locales/i18n.yml +++ b/config/locales/i18n.yml @@ -695,9 +695,11 @@ en: &en overdue_payment: Overdue Payment your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Your Pro Plan has been suspended due to unpaid invoices. You can update your payment details to settle the invoice and continue using DocuSeal or cancel your subscription. manage_subscription: Manage Subscription - submission_created_by_email_invite_html: 'Submission created by %{email}' + submission_created_by_email_html: 'Submission created by %{email}' submission_created_by_email_via_source_html: 'Submission created by %{email} via %{source}' submission_created_via_source_html: 'Submission created via %{source}' + pro_user_seats_used: Pro user seats used + manage_plan: Manage plan submission_sources: api: API bulk: Bulk Send @@ -1419,9 +1421,11 @@ es: &es overdue_payment: Pago Atrasado your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Tu plan Pro ha sido suspendido debido a facturas impagas. Puedes actualizar tus datos de pago para liquidar la factura y seguir usando DocuSeal o cancelar tu suscripción. manage_subscription: Gestionar Suscripción - submission_created_by_email_invite_html: 'Envío creado por invitación de %{email}' + submission_created_by_email_html: 'Envío creado por %{email}' submission_created_by_email_via_source_html: 'Envío creado por %{email} a través de %{source}' submission_created_via_source_html: 'Envío creado a través de %{source}' + pro_user_seats_used: Plazas de usuario Pro en uso + manage_plan: Gestionar plan submission_sources: api: API bulk: Envío masivo @@ -2142,9 +2146,11 @@ it: &it overdue_payment: Pagamento Scaduto your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Il tuo piano Pro è stato sospeso a causa di fatture non pagate. Puoi aggiornare i tuoi dati di pagamento per saldare la fattura e continuare a utilizzare DocuSeal o annullare l'abbonamento. manage_subscription: Gestisci Abbonamento - submission_created_by_email_invite_html: 'Invio creato tramite invito di %{email}' + submission_created_by_email_html: 'Invio creato da %{email}' submission_created_by_email_via_source_html: 'Invio creato da %{email} tramite %{source}' submission_created_via_source_html: 'Invio creato tramite %{source}' + pro_user_seats_used: Posti utente Pro in uso + manage_plan: Gestisci piano submission_sources: api: API bulk: Invio massivo @@ -2867,9 +2873,11 @@ fr: &fr overdue_payment: Paiement En Retard your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Votre plan Pro a été suspendu en raison de factures impayées. Vous pouvez mettre à jour vos informations de paiement pour régler la facture et continuer à utiliser DocuSeal ou annuler votre abonnement. manage_subscription: Gérer l'Abonnement - submission_created_by_email_invite_html: "Soumission créée par l'invitation de %{email}" + submission_created_by_email_html: 'Soumission créée par %{email}' submission_created_by_email_via_source_html: 'Soumission créée par %{email} via %{source}' submission_created_via_source_html: 'Soumission créée via %{source}' + pro_user_seats_used: Places utilisateur Pro en cours d'utilisation + manage_plan: Gérer le plan submission_sources: api: API bulk: Envoi en masse @@ -3591,9 +3599,11 @@ pt: &pt overdue_payment: Pagamento Atrasado your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Seu plano Pro foi suspenso devido a faturas não pagas. Você pode atualizar seus dados de pagamento para quitar a fatura e continuar usando o DocuSeal ou cancelar sua assinatura. manage_subscription: Gerenciar Assinatura - submission_created_by_email_invite_html: 'Envio criado por convite de %{email}' + submission_created_by_email_html: 'Envio criado por %{email}' submission_created_by_email_via_source_html: 'Envio criado por %{email} via %{source}' submission_created_via_source_html: 'Envio criado via %{source}' + pro_user_seats_used: Lugares de usuário Pro em uso + manage_plan: Gerenciar plano submission_sources: api: API bulk: Envio em massa @@ -4315,9 +4325,11 @@ de: &de overdue_payment: Überfällige Zahlung your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Ihr Pro-Plan wurde aufgrund unbezahlter Rechnungen ausgesetzt. Sie können Ihre Zahlungsdaten aktualisieren, um die Rechnung zu begleichen und DocuSeal weiterhin zu nutzen, oder Ihr Abonnement kündigen. manage_subscription: Abonnement Verwalten - submission_created_by_email_invite_html: 'Übermittlung erstellt durch Einladung von %{email}' + submission_created_by_email_html: 'Übermittlung erstellt von %{email}' submission_created_by_email_via_source_html: 'Übermittlung erstellt durch %{email} über %{source}' submission_created_via_source_html: 'Übermittlung erstellt über %{source}' + pro_user_seats_used: Verwendete Pro-Benutzerplätze + manage_plan: Plan verwalten submission_sources: api: API bulk: Massenversand From 0c72f58ab0e9001f71197b2a9e35e2c7d87bc85f Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Wed, 12 Feb 2025 12:58:18 +0200 Subject: [PATCH 06/16] fix combined --- lib/submissions/generate_combined_attachment.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/submissions/generate_combined_attachment.rb b/lib/submissions/generate_combined_attachment.rb index e5dfc892..cdc5673e 100644 --- a/lib/submissions/generate_combined_attachment.rb +++ b/lib/submissions/generate_combined_attachment.rb @@ -23,9 +23,15 @@ module Submissions **Submissions::GenerateResultAttachments.build_signing_params(submitter, pkcs, tsa_url) } - pdf.sign(io, **sign_params) + begin + pdf.sign(io, write_options: { validate: false }, **sign_params) + rescue HexaPDF::MalformedPDFError => e + Rollbar.error(e) if defined?(Rollbar) + + pdf.sign(io, write_options: { validate: false, incremental: false }, **sign_params) + end else - pdf.write(io) + pdf.write(io, incremental: true, validate: false) end Submissions::GenerateResultAttachments.maybe_enable_ltv(io, sign_params) From 2e2c0e087d7b2cbc113f31fd46278f5e95c37c22 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Wed, 12 Feb 2025 19:49:50 +0200 Subject: [PATCH 07/16] skip missing font --- lib/submissions/generate_result_attachments.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/submissions/generate_result_attachments.rb b/lib/submissions/generate_result_attachments.rb index a5941863..3039ac19 100644 --- a/lib/submissions/generate_result_attachments.rb +++ b/lib/submissions/generate_result_attachments.rb @@ -23,6 +23,7 @@ module Submissions A4_SIZE = [595, 842].freeze TESTING_FOOTER = 'Testing Document - NOT LEGALLY BINDING' + DEFAULT_FONTS = %w[Times Helvetica Courier].freeze MISSING_GLYPH_REPLACE = { '▪' => '-', @@ -190,7 +191,8 @@ module Submissions fill_color = field.dig('preferences', 'color').presence - font_name = field.dig('preferences', 'font').presence || FONT_NAME + font_name = field.dig('preferences', 'font') + font_name = FONT_NAME unless font_name.in?(DEFAULT_FONTS) font = pdf.fonts.add(font_name) value = submitter.values[field['uuid']] From 1da72e3e7a5ff49a76baf3b3e3c26bbc322b72e5 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Wed, 12 Feb 2025 21:31:56 +0200 Subject: [PATCH 08/16] update gem --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index b40d07db..de6e71b3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -386,7 +386,7 @@ GEM puma (6.5.0) nio4r (~> 2.0) racc (1.8.1) - rack (3.1.8) + rack (3.1.10) rack-proxy (0.7.7) rack rack-session (2.0.0) From f91f02f786286dd435e5b183cfdcea92dbdea45d Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Thu, 13 Feb 2025 00:07:43 +0200 Subject: [PATCH 09/16] remove seats info --- app/views/users/_seats_info.html.erb | 0 app/views/users/index.html.erb | 1 - 2 files changed, 1 deletion(-) delete mode 100644 app/views/users/_seats_info.html.erb diff --git a/app/views/users/_seats_info.html.erb b/app/views/users/_seats_info.html.erb deleted file mode 100644 index e69de29b..00000000 diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index a9ddd3c3..a37a59c0 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -25,7 +25,6 @@ <% end %> - <%= render 'users/seats_info' %>
From 9f4f868246cc896351441835e41c6ee2911bdb24 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Thu, 13 Feb 2025 13:19:33 +0200 Subject: [PATCH 10/16] use erb_lint --- .erb-lint.yml => .erb_lint.yml | 0 .github/workflows/ci.yml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename .erb-lint.yml => .erb_lint.yml (100%) diff --git a/.erb-lint.yml b/.erb_lint.yml similarity index 100% rename from .erb-lint.yml rename to .erb_lint.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55d7a256..1a28aa8e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: bundle config path vendor/bundle bundle install --jobs 4 --retry 4 - name: Run Erblint - run: bundle exec erblint ./app + run: bundle exec erb_lint ./app eslint: name: ESLint From bfb2db07a55353936dad244ce2dff7ae3f7ca17c Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Thu, 13 Feb 2025 16:46:39 +0200 Subject: [PATCH 11/16] fix events modal --- app/controllers/submission_events_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/submission_events_controller.rb b/app/controllers/submission_events_controller.rb index e493bd95..d922d389 100644 --- a/app/controllers/submission_events_controller.rb +++ b/app/controllers/submission_events_controller.rb @@ -42,7 +42,7 @@ class SubmissionEventsController < ApplicationController submitter_name:) elsif event.event_type == 'invite_party' && (invited_submitter = submitters.find { |e| e.uuid == event.data['uuid'] }) && - (name = submission.template_submitters.find { |e| e['uuid'] == event.data['uuid'] }&.dig('name')) + (name = @submission.template_submitters.find { |e| e['uuid'] == event.data['uuid'] }&.dig('name')) invited_submitter_name = [invited_submitter.name || invited_submitter.email || invited_submitter.phone, name].join(' ') helpers.t('submission_event_names.invite_party_by_html', invited_submitter_name:, From 496cc855f6e48e9b3fd948b92727d2e5667a3bed Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Fri, 14 Feb 2025 10:37:56 +0200 Subject: [PATCH 12/16] refactor --- .../submission_events_controller.rb | 42 +------------------ app/views/submission_events/index.html.erb | 23 +++++++--- 2 files changed, 18 insertions(+), 47 deletions(-) diff --git a/app/controllers/submission_events_controller.rb b/app/controllers/submission_events_controller.rb index d922d389..9dbd57ed 100644 --- a/app/controllers/submission_events_controller.rb +++ b/app/controllers/submission_events_controller.rb @@ -21,45 +21,5 @@ class SubmissionEventsController < ApplicationController load_and_authorize_resource :submission - # rubocop:disable Metrics - def index - submitters = @submission.submitters - - submitters_uuids = (@submission.template_submitters || @submission.template.submitters).pluck('uuid') - - @events_data = @submission.submission_events.order(:event_timestamp).map do |event| - submitter = submitters.find { |e| e.id == event.submitter_id } - submitter_name = - if event.event_type.include?('sms') || event.event_type.include?('phone') - event.data['phone'] || submitter.phone - else - submitter.name || submitter.email || submitter.phone - end - - text = - if event.event_type == 'complete_verification' - helpers.t('submission_event_names.complete_verification_by_html', provider: event.data['method'], - submitter_name:) - elsif event.event_type == 'invite_party' && - (invited_submitter = submitters.find { |e| e.uuid == event.data['uuid'] }) && - (name = @submission.template_submitters.find { |e| e['uuid'] == event.data['uuid'] }&.dig('name')) - invited_submitter_name = [invited_submitter.name || invited_submitter.email || invited_submitter.phone, - name].join(' ') - helpers.t('submission_event_names.invite_party_by_html', invited_submitter_name:, - submitter_name:) - elsif event.event_type.include?('send_') - helpers.t("submission_event_names.#{event.event_type}_to_html", submitter_name:) - else - helpers.t("submission_event_names.#{event.event_type}_by_html", submitter_name:) - end - - { - timestamp: event.event_timestamp.in_time_zone(current_account.timezone), - event_type: event.event_type, - submitter_index: submitters_uuids.index(submitter.uuid), - text: - } - end - end - # rubocop:enable Metrics + def index; end end diff --git a/app/views/submission_events/index.html.erb b/app/views/submission_events/index.html.erb index 6d89ff27..4b318cfb 100644 --- a/app/views/submission_events/index.html.erb +++ b/app/views/submission_events/index.html.erb @@ -1,10 +1,11 @@ <% event_colors = %w[bg-red-200 bg-sky-200 bg-emerald-200 bg-yellow-200 bg-purple-200 bg-pink-200 bg-cyan-200 bg-orange-200 bg-lime-200 bg-indigo-200] %> +<% submitters_uuids = (@submission.template_submitters || @submission.template.submitters).pluck('uuid') %> <%= render 'shared/turbo_modal_large', title: t('event_log') do %>
  1. - <%= svg_icon('file_text', class: 'w-3.5 h-3.5') %> + <%= svg_icon('file_text', class: 'w-4 h-4') %>

    <%= l(@submission.created_at.in_time_zone(current_account.timezone), format: :long, locale: current_account.locale) %> @@ -19,17 +20,27 @@ <% end %>

  2. - <% @events_data.each do |row| %> - <% bg_class = event_colors[row[:submitter_index] % event_colors.length] %> + <% @submission.submission_events.order(:event_timestamp).each do |event| %> + <% submitter = @submission.submitters.find { |e| e.id == event.submitter_id } %> + <% bg_class = event_colors[submitters_uuids.index(submitter.uuid) % event_colors.length] %> + <% submitter_name = event.event_type.include?('sms') || event.event_type.include?('phone') ? (event.data['phone'] || submitter.phone) : (submitter.name || submitter.email || submitter.phone) %>
  3. - <%= svg_icon(SubmissionEventsController::SUBMISSION_EVENT_ICONS.fetch(row[:event_type], 'circle_dot'), class: 'w-4 h-4') %> + <%= svg_icon(SubmissionEventsController::SUBMISSION_EVENT_ICONS.fetch(event.event_type, 'circle_dot'), class: 'w-4 h-4') %>

    - <%= l(row[:timestamp], format: :long, locale: current_account.locale) %> + <%= l(event.event_timestamp.in_time_zone(current_account.timezone), format: :long, locale: current_account.locale) %>

    - <%= row[:text] %> + <% if event.event_type == 'complete_verification' %> + <%= t('submission_event_names.complete_verification_by_html', provider: event.data['method'], submitter_name:) %> + <% elsif event.event_type == 'invite_party' && (invited_submitter = @submission.submitters.find { |e| e.uuid == event.data['uuid'] }) && (name = @submission.template_submitters.find { |e| e['uuid'] == event.data['uuid'] }&.dig('name')) %> + <%= t('submission_event_names.invite_party_by_html', invited_submitter_name: [invited_submitter.name || invited_submitter.email || invited_submitter.phone, name].join(' '), submitter_name:) %> + <% elsif event.event_type.include?('send_') %> + <%= t("submission_event_names.#{event.event_type}_to_html", submitter_name:) %> + <% else %> + <%= t("submission_event_names.#{event.event_type}_by_html", submitter_name:) %> + <% end %>

  4. <% end %> From cfc4e001bae28baa2a0e872febfa21b2dae8ef7a Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Fri, 14 Feb 2025 12:33:49 +0200 Subject: [PATCH 13/16] refactor annots --- app/views/submit_form/_annotations.html.erb | 1 + app/views/submit_form/show.html.erb | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 app/views/submit_form/_annotations.html.erb diff --git a/app/views/submit_form/_annotations.html.erb b/app/views/submit_form/_annotations.html.erb new file mode 100644 index 00000000..f4fbaaff --- /dev/null +++ b/app/views/submit_form/_annotations.html.erb @@ -0,0 +1 @@ +<%= render partial: 'submissions/annotation', collection: annots, as: :annot %> diff --git a/app/views/submit_form/show.html.erb b/app/views/submit_form/show.html.erb index 28f94fef..02967492 100644 --- a/app/views/submit_form/show.html.erb +++ b/app/views/submit_form/show.html.erb @@ -47,8 +47,8 @@
    - <% document_annots_index[index]&.each do |annot| %> - <%= render 'submissions/annotation', annot: %> + <% if annots = document_annots_index[index] %> + <%= render 'submit_form/annotations', annots: %> <% end %> <% fields_index.dig(document.uuid, index)&.each do |(area, field)| %> <% value = values[field['uuid']].presence || (field['default_value'].present? ? Submitters::SubmitValues.template_default_value_for_submitter(field['default_value'], @submitter.submission.submitters.find { |e| e.uuid == field['submitter_uuid'] }, with_time: false) : nil) %> From a823a6ac56facbfdfb3a584b9e090021295edae8 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Fri, 14 Feb 2025 13:57:40 +0200 Subject: [PATCH 14/16] fix template clone --- lib/templates/clone.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/templates/clone.rb b/lib/templates/clone.rb index cd1118a3..6210354d 100644 --- a/lib/templates/clone.rb +++ b/lib/templates/clone.rb @@ -32,6 +32,7 @@ module Templates template end + # rubocop:disable Metrics, Style/CombinableLoops def update_submitters_and_fields_and_schema(cloned_submitters, cloned_fields, cloned_schema) submitter_uuids_replacements = {} field_uuids_replacements = {} @@ -43,6 +44,20 @@ module Templates submitter['uuid'] = new_submitter_uuid end + cloned_submitters.each do |submitter| + if submitter['optional_invite_by_uuid'].present? + submitter['optional_invite_by_uuid'] = submitter_uuids_replacements[submitter['optional_invite_by_uuid']] + end + + if submitter['invite_by_uuid'].present? + submitter['invite_by_uuid'] = submitter_uuids_replacements[submitter['invite_by_uuid']] + end + + if submitter['linked_to_uuid'].present? + submitter['linked_to_uuid'] = submitter_uuids_replacements[submitter['linked_to_uuid']] + end + end + cloned_fields.each do |field| new_field_uuid = SecureRandom.uuid @@ -75,5 +90,6 @@ module Templates [cloned_submitters, cloned_fields, cloned_schema] end + # rubocop:enable Metrics, Style/CombinableLoops end end From 14e2dbe1aa08d8ef6e0d219d4f991a14557058f6 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Fri, 14 Feb 2025 17:43:28 +0200 Subject: [PATCH 15/16] detailed party email form --- app/views/submissions/_send_email.html.erb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/submissions/_send_email.html.erb b/app/views/submissions/_send_email.html.erb index ae6f9bc1..43617218 100644 --- a/app/views/submissions/_send_email.html.erb +++ b/app/views/submissions/_send_email.html.erb @@ -37,13 +37,13 @@ <% config = AccountConfigs.find_or_initialize_for_key(current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY) %>