migrate emails text editor to new interface

This commit is contained in:
kara Diaby 2020-08-25 11:40:24 +02:00
parent a51d6046dc
commit ae61c279af
17 changed files with 154 additions and 166 deletions

View file

@ -5,32 +5,11 @@
//
// = require trix
// We need to override trix.csss image gallery styles to accommodate the
// <action-text-attachment> element we wrap around attachments. Otherwise,
// images in galleries will be squished by the max-width: 33%; rule.
.trix-content {
.attachment-gallery {
> action-text-attachment,
> .attachment {
flex: 1 0 33%;
padding: 0 0.5em;
max-width: 33%;
}
&.attachment-gallery--2,
&.attachment-gallery--4 {
> action-text-attachment,
> .attachment {
flex-basis: 50%;
max-width: 50%;
}
}
}
action-text-attachment {
.attachment {
padding: 0 !important;
max-width: 100% !important;
}
}
.trix-button-group.trix-button-group--file-tools {
display: none;
}
trix-editor {
min-height: 10em;
background-color: #FFFFFF;
}

View file

@ -1,42 +0,0 @@
class Admin::MailTemplatesController < AdminController
before_action :retrieve_procedure
def index
@mail_templates = mail_templates
end
def edit
@mail_template = find_mail_template_by_slug(params[:id])
end
def update
mail_template = find_mail_template_by_slug(params[:id])
mail_template.update(update_params)
flash.notice = "Email mis à jour"
redirect_to edit_admin_procedure_mail_template_path(mail_template.procedure_id, params[:id])
end
private
def mail_templates
[
@procedure.initiated_mail_template,
@procedure.received_mail_template,
@procedure.closed_mail_template,
@procedure.refused_mail_template,
@procedure.without_continuation_mail_template
]
end
def find_mail_template_by_slug(slug)
mail_templates.find { |template| template.class.const_get(:SLUG) == slug }
end
def update_params
{
procedure_id: params[:procedure_id],
subject: params[:mail_template][:subject],
body: params[:mail_template][:body]
}
end
end

View file

@ -6,6 +6,24 @@ module NewAdministrateur
@mail_templates = mail_templates
end
def edit
@procedure = procedure
@mail_template = find_mail_template_by_slug(params[:id])
end
def update
@procedure = procedure
mail_template = find_mail_template_by_slug(params[:id])
if mail_template.update(update_params)
flash.notice = "Email mis à jour"
else
flash.alert = mail_template.errors.full_messages
end
redirect_to edit_admin_procedure_mail_template_path(mail_template.procedure_id, params[:id])
end
def preview
mail_template = find_mail_template_by_slug(params[:id])
dossier = Dossier.new(id: '1', procedure: procedure)
@ -13,7 +31,7 @@ module NewAdministrateur
@dossier = dossier
@logo_url = procedure.logo_url
@service = procedure.service
@rendered_template = sanitize(mail_template.body)
@rendered_template = sanitize(mail_template.rich_body.body.to_html)
@actions = mail_template.actions_for_dossier(dossier)
render(template: 'notification_mailer/send_notification', layout: 'mailers/notifications_layout')
@ -38,5 +56,14 @@ module NewAdministrateur
def find_mail_template_by_slug(slug)
mail_templates.find { |template| template.class.const_get(:SLUG) == slug }
end
def update_params
mail_template_id = params[:id]
{
procedure_id: params[:procedure_id],
subject: params["mails_#{mail_template_id}"] ? params["mails_#{mail_template_id}"][:subject] : params["mails_#{mail_template_id}_mail"][:subject],
body: params["mails_#{mail_template_id}"] ? params["mails_#{mail_template_id}"][:rich_body] : params["mails_#{mail_template_id}_mail"][:rich_body]
}
end
end
end

View file

@ -1,6 +1,7 @@
import '../shared/polyfills';
import Rails from '@rails/ujs';
import * as ActiveStorage from '@rails/activestorage';
import 'trix';
import '@rails/actiontext';
import 'whatwg-fetch'; // window.fetch polyfill
import ReactRailsUJS from 'react_ujs';

View file

@ -33,8 +33,9 @@ module MailTemplateConcern
module ClassMethods
def default_for_procedure(procedure)
template_name = default_template_name_for_procedure(procedure)
body = ActionController::Base.new.render_to_string(template: template_name)
new(subject: const_get(:DEFAULT_SUBJECT), body: body, procedure: procedure)
rich_body = ActionController::Base.new.render_to_string(template: template_name)
trix_rich_body = rich_body.gsub(/(?<!^|[.-])(?<!<\/strong>)\n/, '')
new(subject: const_get(:DEFAULT_SUBJECT), rich_body: trix_rich_body, procedure: procedure)
end
def default_template_name_for_procedure(procedure)

View file

@ -474,7 +474,7 @@ class Procedure < ApplicationRecord
def closed_mail_template_attestation_inconsistency_state
# As an optimization, dont check the predefined templates (they are presumed correct)
if closed_mail.present?
tag_present = closed_mail.body.include?("--lien attestation--")
tag_present = closed_mail.body.to_s.include?("--lien attestation--")
if attestation_template&.activated? && !tag_present
:missing_tag
elsif !attestation_template&.activated? && tag_present

View file

@ -1,40 +0,0 @@
- if params[:id] == 'closed_mail'
= render partial: 'admin/closed_mail_template_attestation_inconsistency_alert'
.white-back
%h3
= @mail_template.class.const_get(:DISPLAYED_NAME)
= form_for @mail_template,
as: 'mail_template',
url: admin_procedure_mail_template_path(@procedure, @mail_template.class.const_get(:SLUG)),
method: :put do |f|
.row
.col-md-6
.form-group.string.optional.mail_template_subject
= f.label :subject, "Objet de l'email", class: 'control-label string optional'
= f.text_field :subject, class: 'form-control string optional'
.form-group.text.optional.mail_template_body
= f.label :body, "Corps de l'email", class: 'control-label string optional'
= f.text_area :body, class: 'wysihtml5 form-control text optional'
.text-right
= link_to "Annuler", admin_procedure_mail_templates_path(@procedure), class: "btn btn-default"
= f.submit 'Mettre à jour', class: "btn btn-default btn-success"
= link_to "Prévisualiser", preview_admin_procedure_mail_template_path(@procedure, @mail_template.class.const_get(:SLUG)), class: "btn btn-primary", target: "_blank"
.row
.col-md-12
%table.table
%tr
%th.col-md-3
Balise
%th
Description
- @mail_template.tags.each do |tag|
%tr
%td
%code{ style: "white-space: pre-wrap;" }
= "--#{tag[:libelle]}--"
%td
= tag[:description]

View file

@ -1,14 +0,0 @@
= render partial: 'admin/closed_mail_template_attestation_inconsistency_alert'
#custom-mails
.wrapper
%h1 E-mails personnalisables
%table.table
%tr
%th{ colspan: 2 }
Type d'email
- @mail_templates.each do |mail_template|
%tr
%td
= mail_template.class.const_get(:DISPLAYED_NAME)
%td.text-right
= link_to "Personnaliser l'e-mail", edit_admin_procedure_mail_template_path(@procedure, mail_template.class.const_get(:SLUG))

View file

@ -0,0 +1 @@
%iframe{ src: preview_admin_procedure_mail_template_path, width: '100%', height: '650px' }

View file

@ -0,0 +1,47 @@
= f.label :subject do
Objet de l'email
%span.mandatory *
= f.text_field :subject, required: true
= f.label :body do
Corps de l'email
%span.mandatory *
= f.rich_text_area :rich_body, required: true, class: "mb-4"
#tags-table
%h2.add-tag-title
Insérer une balise
%p.notice
Copiez-collez les balises ci-dessous pour afficher automatiquement linformation souhaitée.
.head
.tag Balise
.description Description
.items
- @mail_template.tags.each do |tag|
.item
%code.tag
= "--#{tag[:libelle]}--"
.description
= tag[:description]
-# Disable accepting dropped images and traduce toolbar tooltips
:javascript
addEventListener('trix-file-accept', function(e) { e.preventDefault(); });
addEventListener("trix-initialize", function(e) {
document.querySelector('button[data-trix-attribute="bold"]').setAttribute('title', 'Gras');
document.querySelector('button[data-trix-attribute="italic"]').setAttribute('title', 'Italique');
document.querySelector('button[data-trix-attribute="strike"]').setAttribute('title', 'Barrer');
document.querySelector('button[data-trix-attribute="href"]').setAttribute('title', 'Créer lien');
document.querySelector('button[data-trix-attribute="heading1"]').setAttribute('title', 'Titre');
document.querySelector('button[data-trix-attribute="quote"]').setAttribute('title', 'Citation');
document.querySelector('button[data-trix-attribute="bullet"]').setAttribute('title', 'Liste à puce');
document.querySelector('button[data-trix-attribute="number"]').setAttribute('title', 'Liste numérotée');
document.querySelector('button[data-trix-action="increaseNestingLevel"]').setAttribute('title', 'Indenter');
document.querySelector('button[data-trix-action="decreaseNestingLevel"]').setAttribute('title', 'Désindenter');
document.querySelector('button[data-trix-action="undo"]').setAttribute('title', 'Annuler la modification');
document.querySelector('button[data-trix-action="redo"]').setAttribute('title', 'Appliquer à nouveau la modification');
document.querySelector('.trix-button.trix-button--dialog[data-trix-method="setAttribute"]').value = "Créer lien";
document.querySelector('.trix-button.trix-button--dialog[data-trix-method="removeAttribute"]').value = "Effacer lien";
})

View file

@ -0,0 +1,33 @@
- if params[:id] == 'closed_mail'
= render partial: 'admin/closed_mail_template_attestation_inconsistency_alert'
= render partial: 'new_administrateur/breadcrumbs',
locals: { steps: [link_to('Démarches', admin_procedures_path),
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
link_to("Emails", admin_procedure_mail_templates_path(@procedure)),
@mail_template.class.const_get(:DISPLAYED_NAME)] }
.procedure-form
.procedure-form__columns.container
= form_for @mail_template,
url: admin_procedure_mail_template_path(@procedure, @mail_template.class.const_get(:SLUG)),
method: :put,
html: { class: 'form procedure-form__column--form' } do |f|
%h1.page-title= @mail_template.class.const_get(:DISPLAYED_NAME)
= render partial: 'form', locals: { f: f }
.procedure-form__actions.sticky--bottom
.actions-right
= f.submit 'Enregistrer', class: 'button primary send'
.procedure-form__column--preview
.procedure-form__preview.sticky--top
%h3
.procedure-form__preview-title
Aperçu
.notice
Cet aperçu est mis à jour après chaque sauvegarde.
.procedure-preview
= render partial: 'apercu', locals: { procedure: @procedure }

View file

@ -8,6 +8,10 @@
.flex.justify-between
%div
.card-title= mail_template.class.const_get(:DISPLAYED_NAME)
%p.notice= mail_template.class.const_get(:DISPLAYED_NAME) === 'Accusé de réception' ? 'Personnalisé' : 'Modèle standard'
- if mail_template.updated_at.blank?
%p.notice= mail_template.class.const_get(:DISPLAYED_NAME) === 'Accusé de réception' ? 'Personnalisé' : 'Modèle standard'
- else
%span.badge.baseline modifié le #{mail_template.updated_at.strftime('%d-%m-%Y')}
%div
= link_to 'Modifier', edit_admin_procedure_mail_template_path(@procedure, mail_template.class.const_get(:SLUG)), class: 'button'

View file

@ -189,8 +189,6 @@ Rails.application.routes.draw do
delete :delete_notice
end
resources :mail_templates, only: [:edit, :update]
put 'archive' => 'procedures#archive', as: :archive
get 'publish_validate' => 'procedures#publish_validate', as: :publish_validate
put 'publish' => 'procedures#publish', as: :publish
@ -373,6 +371,8 @@ Rails.application.routes.draw do
patch 'update_jeton'
end
resources :mail_templates, only: [:edit, :update]
resources :groupe_instructeurs, only: [:index, :show, :create, :update, :destroy] do
member do
post 'add_instructeur'

View file

@ -1,31 +0,0 @@
describe Admin::MailTemplatesController, type: :controller do
let(:procedure) { create :procedure }
let(:initiated_mail) { Mails::InitiatedMail.default_for_procedure(procedure) }
before do
sign_in(procedure.administrateurs.first.user)
end
describe 'PATCH update' do
let(:mail_subject) { 'plop modif' }
let(:mail_body) { 'plip modif' }
before :each do
patch :update,
params: {
procedure_id: procedure.id,
id: initiated_mail.class.const_get(:SLUG),
mail_template: { subject: mail_subject, body: mail_body }
}
end
it { expect(response).to redirect_to edit_admin_procedure_mail_template_path(procedure, initiated_mail.class.const_get(:SLUG)) }
context 'the mail template' do
subject { procedure.reload; procedure.initiated_mail_template }
it { expect(subject.subject).to eq(mail_subject) }
it { expect(subject.body).to eq(mail_body) }
end
end
end

View file

@ -42,4 +42,27 @@ describe NewAdministrateur::MailTemplatesController, type: :controller do
expect(response.body).to include(procedure.service.telephone)
end
end
describe 'PATCH update' do
let(:mail_subject) { 'Mise à jour de votre démarche' }
let(:mail_body) { '<div>Une mise à jour a été effectuée sur votre démarche n° --demarche-id--.</div>' }
before :each do
patch :update,
params: {
procedure_id: procedure.id,
id: initiated_mail.class.const_get(:SLUG),
mails_initiated_mail: { subject: mail_subject, rich_body: mail_body }
}
end
it { expect(response).to redirect_to edit_admin_procedure_mail_template_path(procedure, initiated_mail.class.const_get(:SLUG)) }
context 'the mail template' do
subject { procedure.reload; procedure.initiated_mail_template }
it { expect(subject.subject).to eq(mail_subject) }
it { expect(subject.body).to eq(mail_body) }
end
end
end

View file

@ -42,7 +42,7 @@ describe Procedure do
describe 'closed mail template body' do
let(:procedure) { create(:procedure) }
subject { procedure.closed_mail_template.body }
subject { procedure.closed_mail_template.rich_body.body.to_html }
context 'for procedures without an attestation' do
it { is_expected.not_to include('lien attestation') }

View file

@ -1,10 +1,10 @@
describe 'admin/mail_templates/edit.html.haml', type: :view do
describe 'new_administrateur/mail_templates/edit.html.haml', type: :view do
let(:procedure) { create(:procedure) }
let(:mail_template) { create(:received_mail, procedure: procedure) }
let(:all_tags) { mail_template.tags }
before do
allow(view).to receive(:admin_procedure_mail_template_path).and_return("/toto")
allow(view).to receive(:admin_procedure_mail_templates_path).and_return("/toto")
allow(view).to receive(:admin_procedure_mail_templates_path).and_return("/toto")
assign(:mail_template, mail_template)
@ -13,6 +13,5 @@ describe 'admin/mail_templates/edit.html.haml', type: :view do
context "Champs are listed in the page" do
it { expect(all_tags).to include(include({ libelle: 'numéro du dossier' })) }
it { expect(render).to include("numéro du dossier") }
end
end