commit
2550dce8b0
15 changed files with 142 additions and 47 deletions
|
@ -254,7 +254,8 @@ module Instructeurs
|
|||
private
|
||||
|
||||
def assign_to_params
|
||||
params.require(:assign_to).permit(:instant_email_message_notifications_enabled, :daily_email_notifications_enabled, :weekly_email_notifications_enabled)
|
||||
params.require(:assign_to)
|
||||
.permit(:instant_email_dossier_notifications_enabled, :instant_email_message_notifications_enabled, :daily_email_notifications_enabled, :weekly_email_notifications_enabled)
|
||||
end
|
||||
|
||||
def assign_exports
|
||||
|
|
|
@ -153,6 +153,9 @@ module Users
|
|||
if passage_en_construction? && errors.blank?
|
||||
@dossier.en_construction!
|
||||
NotificationMailer.send_initiated_notification(@dossier).deliver_later
|
||||
@dossier.procedure.instructeurs.with_instant_email_dossier_notifications.each do |instructeur|
|
||||
DossierMailer.notify_new_dossier_depose_to_instructeur(@dossier, instructeur.email).deliver_later
|
||||
end
|
||||
return redirect_to(merci_dossier_path(@dossier))
|
||||
elsif errors.present?
|
||||
flash.now.alert = errors
|
||||
|
|
22
app/javascript/shared/activestorage/errors.js
Normal file
22
app/javascript/shared/activestorage/errors.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Convert an error message returned by DirectUpload to a proper error object.
|
||||
//
|
||||
// This function has two goals:
|
||||
// 1. Remove the file name from the DirectUpload error message
|
||||
// (because the filename confuses Sentry error grouping)
|
||||
// 2. Create each kind of error on a different line
|
||||
// (so that Sentry knows they are different kind of errors, from
|
||||
// the line they were created.)
|
||||
export default function errorFromDirectUploadMessage(message) {
|
||||
let matches = message.match(/ Status: [0-9]{1,3}/);
|
||||
let status = (matches && matches[0]) || '';
|
||||
|
||||
if (message.includes('Error creating')) {
|
||||
return new Error('Error creating file.' + status);
|
||||
} else if (message.includes('Error storing')) {
|
||||
return new Error('Error storing file.' + status);
|
||||
} else if (message.includes('Error reading')) {
|
||||
return new Error('Error reading file.' + status);
|
||||
} else {
|
||||
return new Error(message);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import ProgressBar from './progress-bar';
|
||||
import errorFromDirectUploadMessage from './errors';
|
||||
import { fire } from '@utils';
|
||||
|
||||
const INITIALIZE_EVENT = 'direct-upload:initialize';
|
||||
|
@ -40,17 +41,22 @@ addUploadEventListener(PROGRESS_EVENT, ({ detail: { id, progress } }) => {
|
|||
});
|
||||
|
||||
addUploadEventListener(ERROR_EVENT, event => {
|
||||
let id = event.detail.id;
|
||||
let errorMsg = event.detail.error;
|
||||
|
||||
// Display an error message
|
||||
alert(
|
||||
`Nous sommes désolés, une erreur s’est produite lors de l’envoi du fichier.
|
||||
|
||||
(${event.detail.error})`
|
||||
(${errorMsg})`
|
||||
);
|
||||
// Prevent ActiveStorage from displaying its own error message
|
||||
event.preventDefault();
|
||||
|
||||
ProgressBar.error(event.detail.id, event.detail.error);
|
||||
fire(document, 'sentry:capture-exception', new Error(event.detail.error));
|
||||
ProgressBar.error(id, errorMsg);
|
||||
|
||||
let error = errorFromDirectUploadMessage(errorMsg);
|
||||
fire(document, 'sentry:capture-exception', error);
|
||||
});
|
||||
|
||||
addUploadEventListener(END_EVENT, ({ detail: { id } }) => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { DirectUpload } from '@rails/activestorage';
|
||||
import ProgressBar from './progress-bar';
|
||||
import errorFromDirectUploadMessage from './errors';
|
||||
|
||||
/**
|
||||
Uploader class is a delegate for DirectUpload instance
|
||||
|
@ -18,7 +19,8 @@ export default class Uploader {
|
|||
this.directUpload.create((errorMsg, attributes) => {
|
||||
if (errorMsg) {
|
||||
this.progressBar.error(errorMsg);
|
||||
reject(new Error(errorMsg));
|
||||
let error = errorFromDirectUploadMessage(errorMsg);
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(attributes.signed_id);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,12 @@ class DossierMailer < ApplicationMailer
|
|||
mail(from: NO_REPLY_EMAIL, to: instructeur_email, subject: @subject)
|
||||
end
|
||||
|
||||
def notify_new_dossier_depose_to_instructeur(dossier, instructeur_email)
|
||||
@dossier = dossier
|
||||
@subject = default_i18n_subject(dossier_id: dossier.id, libelle_demarche: dossier.procedure.libelle)
|
||||
mail(from: NO_REPLY_EMAIL, to: instructeur_email, subject: @subject)
|
||||
end
|
||||
|
||||
def notify_revert_to_instruction(dossier)
|
||||
@dossier = dossier
|
||||
@service = dossier.procedure.service
|
||||
|
|
|
@ -23,6 +23,10 @@ class Instructeur < ApplicationRecord
|
|||
includes(:assign_to).where(assign_tos: { instant_email_message_notifications_enabled: true })
|
||||
}
|
||||
|
||||
scope :with_instant_email_dossier_notifications, -> {
|
||||
includes(:assign_to).where(assign_tos: { instant_email_dossier_notifications_enabled: true })
|
||||
}
|
||||
|
||||
default_scope { eager_load(:user) }
|
||||
|
||||
def self.by_email(email)
|
||||
|
|
|
@ -26,6 +26,7 @@ class Procedure < ApplicationRecord
|
|||
has_many :administrateurs_procedures
|
||||
has_many :administrateurs, through: :administrateurs_procedures, after_remove: -> (procedure, _admin) { procedure.validate! }
|
||||
has_many :groupe_instructeurs, dependent: :destroy
|
||||
has_many :instructeurs, through: :groupe_instructeurs
|
||||
|
||||
has_many :dossiers, through: :groupe_instructeurs, dependent: :restrict_with_exception
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
- content_for(:title, "#{@subject}")
|
||||
|
||||
%p
|
||||
Bonjour,
|
||||
|
||||
%p
|
||||
= t('.body', dossier_id: @dossier.id, libelle_demarche: @dossier.procedure.libelle)
|
||||
%p= link_to("Consulter le dossier n°#{@dossier.id}", instructeur_dossier_url(procedure_id: @dossier.procedure.id, dossier_id: @dossier.id))
|
||||
|
||||
= render partial: "layouts/mailers/signature"
|
|
@ -11,6 +11,22 @@
|
|||
.explication
|
||||
Configurez sur cette page les notifications que vous souhaitez recevoir par email pour cette démarche.
|
||||
|
||||
= form.label :email_notification, "Recevoir une notification à chaque dossier déposé"
|
||||
|
||||
%p.notice
|
||||
Cet email vous signale le dépôt d'un nouveau dossier.
|
||||
%p.notice
|
||||
Il est envoyé à chaque fois qu'un usager dépose un dossier.
|
||||
|
||||
.radios
|
||||
%label
|
||||
= form.radio_button :instant_email_dossier_notifications_enabled, true
|
||||
Oui
|
||||
|
||||
%label
|
||||
= form.radio_button :instant_email_dossier_notifications_enabled, false
|
||||
Non
|
||||
|
||||
= form.label :email_notification, "Recevoir une notification à chaque message déposé"
|
||||
|
||||
%p.notice
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
fr:
|
||||
dossier_mailer:
|
||||
notify_new_dossier_depose_to_instructeur:
|
||||
subject: Nouveau dossier déposé pour la démarche %{libelle_demarche}
|
||||
body: Un nouveau dossier a été déposé (n° %{dossier_id}) pour la démarche %{libelle_demarche}
|
|
@ -0,0 +1,5 @@
|
|||
class AddInstantEmailDossierNotificationsToAssignTos < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :assign_tos, :instant_email_dossier_notifications_enabled, :boolean, default: false, null: false
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_04_07_135256) do
|
||||
ActiveRecord::Schema.define(version: 2020_04_09_075320) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -104,6 +104,7 @@ ActiveRecord::Schema.define(version: 2020_04_07_135256) do
|
|||
t.boolean "weekly_email_notifications_enabled", default: true, null: false
|
||||
t.boolean "daily_email_notifications_enabled", default: false, null: false
|
||||
t.boolean "instant_email_message_notifications_enabled", default: false, null: false
|
||||
t.boolean "instant_email_dossier_notifications_enabled", default: false, null: false
|
||||
t.index ["groupe_instructeur_id", "instructeur_id"], name: "unique_couple_groupe_instructeur_instructeur", unique: true
|
||||
t.index ["groupe_instructeur_id"], name: "index_assign_tos_on_groupe_instructeur_id"
|
||||
t.index ["instructeur_id", "procedure_id"], name: "index_assign_tos_on_instructeur_id_and_procedure_id", unique: true
|
||||
|
|
|
@ -421,6 +421,24 @@ describe Users::DossiersController, type: :controller do
|
|||
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
|
||||
end
|
||||
|
||||
context 'with instructeurs ok to be notified instantly' do
|
||||
let!(:instructeur_with_instant_email_dossier) { create(:instructeur) }
|
||||
let!(:instructeur_without_instant_email_dossier) { create(:instructeur) }
|
||||
|
||||
before do
|
||||
allow(DossierMailer).to receive(:notify_new_dossier_depose_to_instructeur).and_return(double(deliver_later: nil))
|
||||
create(:assign_to, instructeur: instructeur_with_instant_email_dossier, procedure: dossier.procedure, instant_email_dossier_notifications_enabled: true, groupe_instructeur: dossier.procedure.defaut_groupe_instructeur)
|
||||
create(:assign_to, instructeur: instructeur_without_instant_email_dossier, procedure: dossier.procedure, instant_email_dossier_notifications_enabled: false, groupe_instructeur: dossier.procedure.defaut_groupe_instructeur)
|
||||
end
|
||||
|
||||
it "sends notification mail to instructeurs" do
|
||||
subject
|
||||
|
||||
expect(DossierMailer).to have_received(:notify_new_dossier_depose_to_instructeur).once.with(dossier, instructeur_with_instant_email_dossier.email)
|
||||
expect(DossierMailer).not_to have_received(:notify_new_dossier_depose_to_instructeur).with(dossier, instructeur_without_instant_email_dossier.email)
|
||||
end
|
||||
end
|
||||
|
||||
context "on an closed procedure" do
|
||||
before { dossier.procedure.close! }
|
||||
|
||||
|
|
77
yarn.lock
77
yarn.lock
|
@ -1087,55 +1087,55 @@
|
|||
webpack-sources "^1.4.3"
|
||||
|
||||
"@sentry/browser@^5.11.2":
|
||||
version "5.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.11.2.tgz#f0b19bd97e9f09a20e9f93a9835339ed9ab1f5a4"
|
||||
integrity sha512-ls6ARX5m+23ld8OsuoPnR+kehjR5ketYWRcDYlmJDX2VOq5K4EzprujAo8waDB0o5a92yLXQ0ZSoK/zzAV2VoA==
|
||||
version "5.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.15.4.tgz#5a7e7bad088556665ed8e69bceb0e18784e4f6c7"
|
||||
integrity sha512-l/auT1HtZM3KxjCGQHYO/K51ygnlcuOrM+7Ga8gUUbU9ZXDYw6jRi0+Af9aqXKmdDw1naNxr7OCSy6NBrLWVZw==
|
||||
dependencies:
|
||||
"@sentry/core" "5.11.2"
|
||||
"@sentry/types" "5.11.0"
|
||||
"@sentry/utils" "5.11.1"
|
||||
"@sentry/core" "5.15.4"
|
||||
"@sentry/types" "5.15.4"
|
||||
"@sentry/utils" "5.15.4"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/core@5.11.2":
|
||||
version "5.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.11.2.tgz#f2d9d37940d291dbcb9a9e4a012f76919474bdf6"
|
||||
integrity sha512-IFCXGy7ebqIq/Kb8RVryCo/SjwhPcrfBmOjkicr4+DxN1UybLre2N3p9bejQMPIteOfDVHlySLYeipjTf+mxZw==
|
||||
"@sentry/core@5.15.4":
|
||||
version "5.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.15.4.tgz#08b617e093a636168be5aebad141d1f744217085"
|
||||
integrity sha512-9KP4NM4SqfV5NixpvAymC7Nvp36Zj4dU2fowmxiq7OIbzTxGXDhwuN/t0Uh8xiqlkpkQqSECZ1OjSFXrBldetQ==
|
||||
dependencies:
|
||||
"@sentry/hub" "5.11.2"
|
||||
"@sentry/minimal" "5.11.2"
|
||||
"@sentry/types" "5.11.0"
|
||||
"@sentry/utils" "5.11.1"
|
||||
"@sentry/hub" "5.15.4"
|
||||
"@sentry/minimal" "5.15.4"
|
||||
"@sentry/types" "5.15.4"
|
||||
"@sentry/utils" "5.15.4"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/hub@5.11.2":
|
||||
version "5.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.11.2.tgz#a3b7ec27cd4cea2cddd75c372fbf1b4bc04c6aae"
|
||||
integrity sha512-5BiDin6ZPsaiTm29rCC41MAjP1vOaKniqfjtXHVPm7FeOBA2bpHm95ncjLkshKGJTPfPZHXTpX/1IZsHrfGVEA==
|
||||
"@sentry/hub@5.15.4":
|
||||
version "5.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.15.4.tgz#cb64473725a60eec63b0be58ed1143eaaf894bee"
|
||||
integrity sha512-1XJ1SVqadkbUT4zLS0TVIVl99si7oHizLmghR8LMFl5wOkGEgehHSoOydQkIAX2C7sJmaF5TZ47ORBHgkqclUg==
|
||||
dependencies:
|
||||
"@sentry/types" "5.11.0"
|
||||
"@sentry/utils" "5.11.1"
|
||||
"@sentry/types" "5.15.4"
|
||||
"@sentry/utils" "5.15.4"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/minimal@5.11.2":
|
||||
version "5.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.11.2.tgz#ae417699342266ecd109a97e53cd9519c0893b21"
|
||||
integrity sha512-oNuJuz3EZhVtamzABmPdr6lcYo06XHLWb2LvgnoNaYcMD1ExUSvhepOSyZ2h5STCMbmVgGVfXBNPV9RUTp8GZg==
|
||||
"@sentry/minimal@5.15.4":
|
||||
version "5.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.15.4.tgz#113f01fefb86b7830994c3dfa7ad4889ba7b2003"
|
||||
integrity sha512-GL4GZ3drS9ge+wmxkHBAMEwulaE7DMvAEfKQPDAjg2p3MfcCMhAYfuY4jJByAC9rg9OwBGGehz7UmhWMFjE0tw==
|
||||
dependencies:
|
||||
"@sentry/hub" "5.11.2"
|
||||
"@sentry/types" "5.11.0"
|
||||
"@sentry/hub" "5.15.4"
|
||||
"@sentry/types" "5.15.4"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/types@5.11.0":
|
||||
version "5.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.11.0.tgz#40f0f3174362928e033ddd9725d55e7c5cb7c5b6"
|
||||
integrity sha512-1Uhycpmeo1ZK2GLvrtwZhTwIodJHcyIS6bn+t4IMkN9MFoo6ktbAfhvexBDW/IDtdLlCGJbfm8nIZerxy0QUpg==
|
||||
"@sentry/types@5.15.4":
|
||||
version "5.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.15.4.tgz#37f30e35b06e8e12ad1101f1beec3e9b88ca1aab"
|
||||
integrity sha512-quPHPpeAuwID48HLPmqBiyXE3xEiZLZ5D3CEbU3c3YuvvAg8qmfOOTI6z4Z3Eedi7flvYpnx3n7N3dXIEz30Eg==
|
||||
|
||||
"@sentry/utils@5.11.1":
|
||||
version "5.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.11.1.tgz#aa19fcc234cf632257b2281261651d2fac967607"
|
||||
integrity sha512-O0Zl4R2JJh8cTkQ8ZL2cDqGCmQdpA5VeXpuBbEl1v78LQPkBDISi35wH4mKmLwMsLBtTVpx2UeUHBj0KO5aLlA==
|
||||
"@sentry/utils@5.15.4":
|
||||
version "5.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.15.4.tgz#02865ab3c9b745656cea0ab183767ec26c96f6e6"
|
||||
integrity sha512-lO8SLBjrUDGADl0LOkd55R5oL510d/1SaI08/IBHZCxCUwI4TiYo5EPECq8mrj3XGfgCyq9osw33bymRlIDuSQ==
|
||||
dependencies:
|
||||
"@sentry/types" "5.11.0"
|
||||
"@sentry/types" "5.15.4"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@turf/area@^6.0.1":
|
||||
|
@ -9105,16 +9105,11 @@ ts-pnp@^1.1.6:
|
|||
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
|
||||
integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==
|
||||
|
||||
tslib@^1.9.0:
|
||||
tslib@^1.9.0, tslib@^1.9.3:
|
||||
version "1.11.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
|
||||
integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
|
||||
|
||||
tslib@^1.9.3:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
||||
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
|
||||
|
||||
tty-browserify@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
|
||||
|
|
Loading…
Reference in a new issue