add notifications settings

pull/112/head
Alex Turchyn 2 years ago
parent 41d3eaf582
commit 2f74caf16a

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class EmailSettingsController < ApplicationController class EmailSmtpSettingsController < ApplicationController
before_action :load_encrypted_config before_action :load_encrypted_config
authorize_resource :encrypted_config, only: :index authorize_resource :encrypted_config, only: :index
authorize_resource :encrypted_config, parent: false, only: :create authorize_resource :encrypted_config, parent: false, only: :create

@ -0,0 +1,46 @@
# frozen_string_literal: true
class NotificationsSettingsController < ApplicationController
before_action :load_bcc_config, only: :index
before_action :load_reminder_config, only: :index
authorize_resource :bcc_config, only: :index
authorize_resource :reminder_config, only: :index
before_action :build_account_config, only: :create
authorize_resource :account_config, only: :create
def index; end
def create
if @account_config.save
redirect_back fallback_location: settings_notifications_path, notice: 'Changes have been saved'
else
redirect_back fallback_location: settings_notifications_path, alert: 'Unable to save'
end
end
private
def build_account_config
@account_config =
AccountConfig.find_or_initialize_by(account: current_account, key: email_config_params[:key])
@account_config.assign_attributes(email_config_params)
end
def load_bcc_config
@bcc_config =
AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::BCC_EMAILS)
end
def load_reminder_config
@reminder_config =
AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::SUBMITTER_REMAILERS)
end
def email_config_params
params.require(:account_config).permit!.tap do |attrs|
attrs[:key] = nil unless attrs[:key].in?([AccountConfig::BCC_EMAILS, AccountConfig::SUBMITTER_REMAILERS])
end
end
end

@ -26,7 +26,8 @@ class ProcessSubmitterCompletionJob < ApplicationJob
user = submitter.submission.created_by_user || submitter.template.author user = submitter.submission.created_by_user || submitter.template.author
if submitter.template.account.users.exists?(id: user.id) if submitter.template.account.users.exists?(id: user.id)
bcc = submitter.submission.template.account.account_configs.find_by(key: 'bcc_emails')&.value bcc = submitter.submission.template.account.account_configs
.find_by(key: AccountConfig::BCC_EMAILS)&.value
SubmitterMailer.completed_email(submitter, user, bcc:).deliver_later! SubmitterMailer.completed_email(submitter, user, bcc:).deliver_later!
end end

@ -24,6 +24,8 @@ class AccountConfig < ApplicationRecord
SUBMITTER_INVITATION_EMAIL_KEY = 'submitter_invitation_email' SUBMITTER_INVITATION_EMAIL_KEY = 'submitter_invitation_email'
SUBMITTER_COMPLETED_EMAIL_KEY = 'submitter_completed_email' SUBMITTER_COMPLETED_EMAIL_KEY = 'submitter_completed_email'
SUBMITTER_DOCUMENTS_COPY_EMAIL_KEY = 'submitter_documents_copy_email' SUBMITTER_DOCUMENTS_COPY_EMAIL_KEY = 'submitter_documents_copy_email'
BCC_EMAILS = 'bcc_emails'
SUBMITTER_REMAILERS = 'submitter_reminders'
DEFAULT_VALUES = { DEFAULT_VALUES = {
SUBMITTER_INVITATION_EMAIL_KEY => { SUBMITTER_INVITATION_EMAIL_KEY => {

@ -25,6 +25,7 @@
# #
class SubmissionEvent < ApplicationRecord class SubmissionEvent < ApplicationRecord
belongs_to :submission belongs_to :submission
has_one :account, through: :submission
belongs_to :submitter, optional: true belongs_to :submitter, optional: true
attribute :data, :string, default: -> { {} } attribute :data, :string, default: -> { {} }
@ -36,6 +37,7 @@ class SubmissionEvent < ApplicationRecord
enum :event_type, { enum :event_type, {
send_email: 'send_email', send_email: 'send_email',
send_reminder_email: 'send_reminder_email',
send_sms: 'send_sms', send_sms: 'send_sms',
open_email: 'open_email', open_email: 'open_email',
click_email: 'click_email', click_email: 'click_email',

@ -0,0 +1,19 @@
<%= form_for config, url: settings_notifications_path, method: :post, html: { autocomplete: 'off', class: 'space-y-4' } do |f| %>
<%= f.hidden_field :key %>
<div class="form-control">
<%= f.label :value, class: 'label' do %>
<span class="flex items-center space-x-1">
<span>
Completed documents BCC address
</span>
<span class="tooltip" data-tip="Send email copy with completed documents to a specified BCC address.">
<%= svg_icon('info_circle', class: 'w-4 h-4') %>
</span>
</span>
<% end %>
<%= f.email_field :value, autocomplete: 'off', class: 'base-input' %>
</div>
<div class="form-control pt-2">
<%= f.button button_title(title: 'Save', disabled_with: 'Updating'), class: 'base-button' %>
</div>
<% end %>

@ -0,0 +1 @@
<%= render 'reminder_placeholder' %>

@ -0,0 +1,29 @@
<%= form_for config, url: settings_notifications_path, method: :post, html: { autocomplete: 'off', class: 'space-y-4' } do |f| %>
<%= f.hidden_field :key %>
<div class="form-control">
<% record = Struct.new(:first_duration, :second_duration, :third_duration).new(*(f.object.value || {}).values_at('first_duration', 'second_duration', 'third_duration')) %>
<div class="flex space-x-4">
<div class="w-full">
<%= f.fields_for :value, record do |ff| %>
<%= ff.label :first_duration, 'First reminder in', class: 'label' %>
<%= ff.select :first_duration, AccountConfigs::REMINDER_DURATIONS.invert, { include_blank: 'None' }, class: 'base-select' %>
<% end %>
</div>
<div class="w-full">
<%= f.fields_for :value, record do |ff| %>
<%= ff.label :second_duration, 'Second reminder in', class: 'label' %>
<%= ff.select :second_duration, AccountConfigs::REMINDER_DURATIONS.invert, { include_blank: 'None' }, class: 'base-select' %>
<% end %>
</div>
<div class="w-full">
<%= f.fields_for :value, record do |ff| %>
<%= ff.label :third_duration, 'Third reminder in', class: 'label' %>
<%= ff.select :third_duration, AccountConfigs::REMINDER_DURATIONS.invert, { include_blank: 'None' }, class: 'base-select' %>
<% end %>
</div>
</div>
</div>
<div class="form-control pt-4">
<%= f.button button_title(title: 'Save', disabled_with: 'Updating'), class: 'base-button' %>
</div>
<% end %>

@ -0,0 +1,11 @@
<div class="alert my-4">
<%= svg_icon('info_circle', class: 'w-6 h-6') %>
<div>
<p class="font-bold">Unlock with DocuSeal Pro</p>
<p>
Send automatic email reminders to your recipients.
<br>
<a class="link font-medium" target="_blank" href="<%= "#{Docuseal::CONSOLE_URL}/#{Docuseal.multitenant? ? 'plans' : 'on_premise'}" %>">Learn More</a>
</p>
</div>
</div>

@ -0,0 +1,14 @@
<div class="flex flex-wrap space-y-4 md:flex-nowrap md:space-y-0">
<%= render 'shared/settings_nav' %>
<div class="flex-grow max-w-xl mx-auto">
<h1 class="text-4xl font-bold mb-4">Email Notifications</h1>
<%= render 'email_stats' %>
<%= render 'bcc_form', config: @bcc_config %>
<div class="flex justify-between items-end mb-4 mt-8">
<h2 class="text-3xl font-bold">Signature Email Reminders</h2>
</div>
<%= render 'reminder_banner' %>
<%= render 'reminder_form', config: @reminder_config %>
</div>
<div class="w-0 md:w-52"></div>
</div>

@ -26,6 +26,11 @@
</li> </li>
<% end %> <% end %>
<% end %> <% end %>
<% if can?(:read, AccountConfig) %>
<li>
<%= link_to 'Notifications', settings_notifications_path, class: 'text-base hover:bg-base-300' %>
</li>
<% end %>
<% if can?(:read, EncryptedConfig.new(key: EncryptedConfig::ESIGN_CERTS_KEY, account: current_account)) %> <% if can?(:read, EncryptedConfig.new(key: EncryptedConfig::ESIGN_CERTS_KEY, account: current_account)) %>
<li> <li>
<%= link_to 'E-Signature', settings_esign_path, class: 'text-base hover:bg-base-300' %> <%= link_to 'E-Signature', settings_esign_path, class: 'text-base hover:bg-base-300' %>

@ -1,9 +1,12 @@
<div class="form-control"> <div class="form-control">
<% is_smtp_configured = Accounts.can_send_emails?(current_account) %> <% is_smtp_configured = Accounts.can_send_emails?(current_account) %>
<div class="flex justify-between">
<%= f.label :send_email, for: uuid = SecureRandom.uuid, class: 'flex items-center cursor-pointer' do %> <%= 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: !is_smtp_configured, checked: is_smtp_configured %> <%= f.check_box :send_email, id: uuid, class: 'base-checkbox', disabled: !is_smtp_configured, checked: is_smtp_configured %>
<span class="label">Send emails</span> <span class="label">Send emails</span>
<% end %> <% end %>
<%= render 'email_stats' %>
</div>
<% unless is_smtp_configured %> <% unless is_smtp_configured %>
<div class="alert my-4"> <div class="alert my-4">
<%= svg_icon('info_circle', class: 'w-6 h-6') %> <%= svg_icon('info_circle', class: 'w-6 h-6') %>

@ -78,9 +78,10 @@ Rails.application.routes.draw do
scope '/settings', as: :settings do scope '/settings', as: :settings do
unless Docuseal.multitenant? unless Docuseal.multitenant?
resources :storage, only: %i[index create], controller: 'storage_settings' resources :storage, only: %i[index create], controller: 'storage_settings'
resources :email, only: %i[index create], controller: 'email_settings' resources :email, only: %i[index create], controller: 'email_smtp_settings'
resources :sms, only: %i[index], controller: 'sms_settings' resources :sms, only: %i[index], controller: 'sms_settings'
end end
resources :notifications, only: %i[index create], controller: 'notifications_settings'
resource :esign, only: %i[show create new update destroy], controller: 'esign_settings' resource :esign, only: %i[show create new update destroy], controller: 'esign_settings'
resources :users, only: %i[index] resources :users, only: %i[index]
resource :personalization, only: %i[show create], controller: 'personalization_settings' resource :personalization, only: %i[show create], controller: 'personalization_settings'

@ -1,6 +1,7 @@
queues: queues:
- [default, 1] - [default, 1]
- [mailers, 1] - [mailers, 1]
- [recurrent, 1]
production: production:
:concurrency: 15 :concurrency: 15

@ -1,6 +1,19 @@
# frozen_string_literal: true # frozen_string_literal: true
module AccountConfigs module AccountConfigs
REMINDER_DURATIONS = {
'one_hour' => '1 hour',
'two_hours' => '2 hours',
'four_hours' => '4 hours',
'eight_hours' => '8 hours',
'twelve_hours' => '12 hours',
'twenty_four_hours' => '24 hours',
'two_days' => '2 days',
'four_days' => '4 days',
'eight_days' => '8 days',
'fifteen_days' => '15 days'
}.freeze
module_function module_function
def find_or_initialize_for_key(account, key) def find_or_initialize_for_key(account, key)

@ -5,6 +5,7 @@ module SubmissionEvents
EVENT_NAMES = { EVENT_NAMES = {
send_email: 'Email sent', send_email: 'Email sent',
send_reminder_email: 'Reminder email sent',
send_sms: 'SMS sent', send_sms: 'SMS sent',
open_email: 'Email opened', open_email: 'Email opened',
click_email: 'Email link clicked', click_email: 'Email link clicked',

Loading…
Cancel
Save