From 1e57c1ace72c393b5f4ec845d5e5a0cea3622112 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Wed, 17 Apr 2024 16:08:58 +0300 Subject: [PATCH] add template preferences --- app/controllers/submissions_controller.rb | 9 ++ .../templates_preferences_controller.rb | 22 ++++ app/javascript/application.js | 2 + app/javascript/elements/toggle_on_submit.js | 35 ++++++ app/jobs/process_submitter_completion_job.rb | 1 + app/mailers/submitter_mailer.rb | 4 +- app/models/template.rb | 3 + .../icons/_adjustments_horizontal.html.erb | 12 +++ app/views/icons/_settings.html.erb | 5 + app/views/layouts/application.html.erb | 1 + app/views/shared/_turbo_drawer.html.erb | 22 ++++ app/views/submissions/_send_email.html.erb | 8 +- app/views/templates/_embedding.html.erb | 77 +++++++++++++- app/views/templates/_title.html.erb | 6 +- app/views/templates_preferences/show.html.erb | 100 ++++++++++++++++++ config/routes.rb | 1 + ...0416170023_add_preferences_to_templates.rb | 15 +++ db/schema.rb | 3 +- 18 files changed, 317 insertions(+), 9 deletions(-) create mode 100644 app/controllers/templates_preferences_controller.rb create mode 100644 app/javascript/elements/toggle_on_submit.js create mode 100644 app/views/icons/_adjustments_horizontal.html.erb create mode 100644 app/views/icons/_settings.html.erb create mode 100644 app/views/shared/_turbo_drawer.html.erb create mode 100644 app/views/templates_preferences/show.html.erb create mode 100644 db/migrate/20240416170023_add_preferences_to_templates.rb diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index b68f32ae..5257da04 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -19,6 +19,8 @@ class SubmissionsController < ApplicationController def create authorize!(:create, Submission) + save_template_message(@template, params) if params[:save_message] == '1' + if params[:is_custom_message] != '1' params.delete(:subject) params.delete(:body) @@ -57,6 +59,13 @@ class SubmissionsController < ApplicationController private + def save_template_message(template, params) + template.preferences['request_email_subject'] = params[:subject] if params[:subject].present? + template.preferences['request_email_body'] = params[:body] if params[:body].present? + + template.save! + end + def submissions_params params.permit(submission: { submitters: [%i[uuid email phone name]] }) end diff --git a/app/controllers/templates_preferences_controller.rb b/app/controllers/templates_preferences_controller.rb new file mode 100644 index 00000000..48737fc1 --- /dev/null +++ b/app/controllers/templates_preferences_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class TemplatesPreferencesController < ApplicationController + load_and_authorize_resource :template + + def show; end + + def create + authorize!(:update, @template) + + @template.preferences = @template.preferences.merge(template_params[:preferences]) + @template.save! + + head :ok + end + + private + + def template_params + params.require(:template).permit(preferences: %i[bcc_completed request_email_subject request_email_body]) + end +end diff --git a/app/javascript/application.js b/app/javascript/application.js index b28d0bb2..5056863d 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -23,6 +23,7 @@ import SignatureForm from './elements/signature_form' import SubmitForm from './elements/submit_form' import PromptPassword from './elements/prompt_password' import EmailsTextarea from './elements/emails_textarea' +import ToggleOnSubmit from './elements/toggle_on_submit' import * as TurboInstantClick from './lib/turbo_instant_click' @@ -58,6 +59,7 @@ window.customElements.define('submit-form', SubmitForm) window.customElements.define('prompt-password', PromptPassword) window.customElements.define('emails-textarea', EmailsTextarea) window.customElements.define('toggle-cookies', ToggleCookies) +window.customElements.define('toggle-on-submit', ToggleOnSubmit) document.addEventListener('turbo:before-fetch-request', encodeMethodIntoRequestBody) document.addEventListener('turbo:submit-end', async (event) => { diff --git a/app/javascript/elements/toggle_on_submit.js b/app/javascript/elements/toggle_on_submit.js new file mode 100644 index 00000000..8cbc213f --- /dev/null +++ b/app/javascript/elements/toggle_on_submit.js @@ -0,0 +1,35 @@ +export default class extends HTMLElement { + connectedCallback () { + document.addEventListener('turbo:submit-end', this.onSubmitEnd) + + this.form.addEventListener('submit', this.onSubmit) + } + + disconnectedCallback () { + document.removeEventListener('turbo:submit-end', this.onSubmitEnd) + + this.form.removeEventListener('submit', this.onSubmit) + } + + onSubmit = () => { + this.element.classList.add('invisible') + } + + onSubmitEnd = (event) => { + if (event.target === this.form) { + const resp = event.detail?.formSubmission?.result?.fetchResponse?.response + + if (resp?.status / 100 === 2) { + this.element.classList.remove('invisible') + } + } + } + + get element () { + return document.getElementById(this.dataset.elementId) + } + + get form () { + return this.closest('form') + } +} diff --git a/app/jobs/process_submitter_completion_job.rb b/app/jobs/process_submitter_completion_job.rb index cf22112a..1f2b740d 100644 --- a/app/jobs/process_submitter_completion_job.rb +++ b/app/jobs/process_submitter_completion_job.rb @@ -34,6 +34,7 @@ class ProcessSubmitterCompletionJob < ApplicationJob end bcc = submission.preferences['bcc_completed'].presence || + submission.template.preferences['bcc_completed'].presence || submission.account.account_configs .find_by(key: AccountConfig::BCC_EMAILS)&.value diff --git a/app/mailers/submitter_mailer.rb b/app/mailers/submitter_mailer.rb index 545aa226..5ad6a868 100644 --- a/app/mailers/submitter_mailer.rb +++ b/app/mailers/submitter_mailer.rb @@ -14,8 +14,8 @@ class SubmitterMailer < ApplicationMailer @email_message = submitter.account.email_messages.find_by(uuid: submitter.preferences['email_message_uuid']) end - @body = @email_message&.body.presence - @subject = @email_message&.subject.presence + @body = @email_message&.body.presence || @submitter.template.preferences['request_email_body'].presence + @subject = @email_message&.subject.presence || @submitter.template.preferences['request_email_subject'].presence @email_config = AccountConfigs.find_for_account(@current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY) diff --git a/app/models/template.rb b/app/models/template.rb index 2e499030..bfa21fae 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -8,6 +8,7 @@ # archived_at :datetime # fields :text not null # name :string not null +# preferences :text not null # schema :text not null # slug :string not null # source :text not null @@ -41,12 +42,14 @@ class Template < ApplicationRecord before_validation :maybe_set_default_folder, on: :create + attribute :preferences, :string, default: -> { {} } attribute :fields, :string, default: -> { [] } attribute :schema, :string, default: -> { [] } attribute :submitters, :string, default: -> { [{ name: DEFAULT_SUBMITTER_NAME, uuid: SecureRandom.uuid }] } attribute :slug, :string, default: -> { SecureRandom.base58(14) } attribute :source, :string, default: 'native' + serialize :preferences, coder: JSON serialize :fields, coder: JSON serialize :schema, coder: JSON serialize :submitters, coder: JSON diff --git a/app/views/icons/_adjustments_horizontal.html.erb b/app/views/icons/_adjustments_horizontal.html.erb new file mode 100644 index 00000000..f7821c54 --- /dev/null +++ b/app/views/icons/_adjustments_horizontal.html.erb @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/app/views/icons/_settings.html.erb b/app/views/icons/_settings.html.erb new file mode 100644 index 00000000..54d301e7 --- /dev/null +++ b/app/views/icons/_settings.html.erb @@ -0,0 +1,5 @@ + + + + + diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 4dd73600..9f7f527b 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -12,6 +12,7 @@ + <%= render 'shared/navbar' %> <% if flash.present? %><%= render 'shared/flash' %><% end %>
diff --git a/app/views/shared/_turbo_drawer.html.erb b/app/views/shared/_turbo_drawer.html.erb new file mode 100644 index 00000000..251b5136 --- /dev/null +++ b/app/views/shared/_turbo_drawer.html.erb @@ -0,0 +1,22 @@ + + +
+
+ <% if local_assigns[:title] %> +
+ + <%= local_assigns[:title] %> + + × +
+ <% else %> + + × + + <% end %> +
+ <%= yield %> +
+
+
+
diff --git a/app/views/submissions/_send_email.html.erb b/app/views/submissions/_send_email.html.erb index a537bcd4..04f352fa 100644 --- a/app/views/submissions/_send_email.html.erb +++ b/app/views/submissions/_send_email.html.erb @@ -35,7 +35,7 @@
<%= f.label :subject, class: 'label' %> - <%= f.text_field :subject, value: config.value['subject'], required: true, class: '!text-sm base-input w-full', dir: 'auto' %> + <%= f.text_field :subject, value: @template.preferences['request_email_subject'].presence || config.value['subject'], required: true, class: '!text-sm base-input w-full', dir: 'auto' %>
@@ -45,8 +45,12 @@
- <%= f.text_area :body, value: config.value['body'], required: true, class: 'base-textarea w-full', rows: 10, dir: 'auto' %> + <%= f.text_area :body, value: @template.preferences['request_email_body'].presence || config.value['body'], required: true, class: 'base-textarea w-full', rows: 10, dir: 'auto' %> +
<%= render 'message_fields' %>
diff --git a/app/views/templates/_embedding.html.erb b/app/views/templates/_embedding.html.erb index af6df88c..8b9e30ed 100644 --- a/app/views/templates/_embedding.html.erb +++ b/app/views/templates/_embedding.html.erb @@ -1,4 +1,4 @@ - +
  • @@ -33,6 +33,23 @@ Vue
  • +
  • + + +
@@ -173,3 +190,61 @@ export default {
+ diff --git a/app/views/templates/_title.html.erb b/app/views/templates/_title.html.erb index 8bf4c7fa..2394a143 100644 --- a/app/views/templates/_title.html.erb +++ b/app/views/templates/_title.html.erb @@ -38,10 +38,10 @@ <% if !template.archived_at? %>
<% if can?(:update, template) && (Docuseal.multitenant? || current_account.testing? || current_account.id == 1) %> -
- <%= link_to template_code_modal_path(template), class: 'btn btn-ghost btn-sm flex-1 hidden md:flex', data: { turbo_frame: :modal } do %> +
+ <%= link_to template_preferences_path(template), class: 'btn border border-base-200 bg-base-200 hover:bg-base-300 hover:border-base-300 btn-sm flex-1 hidden md:flex', data: { turbo_frame: :drawer } do %> - <%= svg_icon('code', class: 'w-6 h-6') %> + <%= svg_icon('adjustments_horizontal', class: 'w-6 h-6') %> <% end %>
diff --git a/app/views/templates_preferences/show.html.erb b/app/views/templates_preferences/show.html.erb new file mode 100644 index 00000000..6d1861a1 --- /dev/null +++ b/app/views/templates_preferences/show.html.erb @@ -0,0 +1,100 @@ +<%= render 'shared/turbo_drawer', title: 'Preferences', close_after_submit: false do %> + <% options = [['General', 'general'], ['API and Embedding', 'api']] %> + +
+ <% options.each_with_index do |(label, value), index| %> + + <%= radio_button_tag 'option', value, value == 'general', class: 'peer hidden', data: { action: 'change:toggle-visible#trigger' } %> + + + <% end %> +
+
+
+ <%= form_for @template, url: template_preferences_path(@template), method: :post, html: { autocomplete: 'off', class: 'mt-1' } do |f| %> + + <%= f.fields_for :preferences, Struct.new(:request_email_subject, :request_email_body).new(*(@template.preferences.values_at('request_email_subject', 'request_email_body').compact_blank.presence || AccountConfigs.find_or_initialize_for_key(current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY).value.values_at('subject', 'body'))) do |ff| %> +
+ <%= ff.label :request_email_subject, 'Email subject', class: 'label' %> + <%= ff.text_field :request_email_subject, required: true, class: 'base-input', dir: 'auto' %> +
+
+
+ <%= ff.label :request_email_body, 'Email body', class: 'label' %> + + <%= svg_icon('info_circle', class: 'w-4 h-4') %> + +
+ + <%= ff.text_area :request_email_body, required: true, class: 'base-input w-full py-2', dir: 'auto' %> + +
+ <% end %> +
+ <%= f.button button_title(title: 'Save', disabled_with: 'Saving'), class: 'base-button' %> +
+ +
+
+ <% end %> + <%= form_for @template, url: template_preferences_path(@template), method: :post, html: { autocomplete: 'off', class: 'mt-2' } do |f| %> + + <%= f.fields_for :preferences, Struct.new(:bcc_completed).new(@template.preferences['bcc_completed']) do |ff| %> +
+ <%= ff.label :bcc_completed, class: 'label' do %> + + + Completed documents BCC address + + + <% end %> + <%= ff.email_field :bcc_completed, autocomplete: 'off', class: 'base-input' %> +
+ <% end %> +
+ <%= f.button button_title(title: 'Save', disabled_with: 'Updating'), class: 'base-button' %> +
+ +
+
+ <% end %> + <%= render 'templates_code_modal/preferences' %> +
+ +<% end %> diff --git a/config/routes.rb b/config/routes.rb index 237d6e84..b7ba10af 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -76,6 +76,7 @@ Rails.application.routes.draw do resource :folder, only: %i[edit update], controller: 'templates_folders' resource :preview, only: %i[show], controller: 'templates_preview' resource :code_modal, only: %i[show], controller: 'templates_code_modal' + resource :preferences, only: %i[show create], controller: 'templates_preferences' resources :submissions_export, only: %i[index new] end resources :preview_document_page, only: %i[show], path: '/preview/:signed_uuid' diff --git a/db/migrate/20240416170023_add_preferences_to_templates.rb b/db/migrate/20240416170023_add_preferences_to_templates.rb new file mode 100644 index 00000000..80241038 --- /dev/null +++ b/db/migrate/20240416170023_add_preferences_to_templates.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddPreferencesToTemplates < ActiveRecord::Migration[7.1] + class MigrationTemplate < ApplicationRecord + self.table_name = 'templates' + end + + def change + add_column :templates, :preferences, :text + + MigrationTemplate.where(preferences: nil).update_all(preferences: '{}') + + change_column_null :templates, :preferences, false + end +end diff --git a/db/schema.rb b/db/schema.rb index 4804ce0b..6c663ed6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_04_05_165329) do +ActiveRecord::Schema[7.1].define(version: 2024_04_16_170023) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -222,6 +222,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_04_05_165329) do t.text "source", null: false t.bigint "folder_id", null: false t.string "external_id" + t.text "preferences", null: false t.index ["account_id"], name: "index_templates_on_account_id" t.index ["author_id"], name: "index_templates_on_author_id" t.index ["folder_id"], name: "index_templates_on_folder_id"