diff --git a/app/controllers/administrateurs/attestation_template_v2s_controller.rb b/app/controllers/administrateurs/attestation_template_v2s_controller.rb index f5ace97c7..eb2c45743 100644 --- a/app/controllers/administrateurs/attestation_template_v2s_controller.rb +++ b/app/controllers/administrateurs/attestation_template_v2s_controller.rb @@ -77,6 +77,13 @@ module Administrateurs def update attestation_params = editor_params + + if @attestation_template.published? + @attestation_template = @attestation_template.dup + @attestation_template.state = :draft + @attestation_template.procedure = @procedure + end + logo_file = attestation_params.delete(:logo) signature_file = attestation_params.delete(:signature) @@ -88,11 +95,29 @@ module Administrateurs attestation_params[:signature] = uninterlace_png(signature_file) end - if !@attestation_template.update(attestation_params) - flash.alert = "Le modèle de l’attestation contient des erreurs et n'a pas pu être enregistré. Corriger les erreurs." - end + @attestation_template.assign_attributes(attestation_params) - render :update + if @attestation_template.invalid? + flash.alert = "L’attestation contient des erreurs et n'a pas pu être enregistrée. Corriger les erreurs." + else + # - draft just published + if @attestation_template.published? && should_edit_draft? + published = @procedure.attestation_templates.published + + @attestation_template.transaction do + were_published = published.destroy_all + @attestation_template.save! + flash.notice = were_published.any? ? "La nouvelle version de l’attestation a été publiée." : "L’attestation a été publiée." + end + + redirect_to edit_admin_procedure_attestation_template_v2_path(@procedure) + else + # - draft updated + # - or, attestation already published, without need for publication (draft procedure) + @attestation_template.save! + render :update + end + end end def create = update @@ -104,11 +129,12 @@ module Administrateurs end def retrieve_attestation_template - @attestation_template = @procedure.attestation_template_v2 || @procedure.build_attestation_template_v2(json_body: AttestationTemplate::TIPTAP_BODY_DEFAULT) + v2s = @procedure.attestation_templates_v2 + @attestation_template = v2s.find(&:draft?) || v2s.find(&:published?) || @procedure.build_attestation_template(version: 2, json_body: AttestationTemplate::TIPTAP_BODY_DEFAULT, state: :draft) end def editor_params - params.required(:attestation_template).permit(:official_layout, :label_logo, :label_direction, :tiptap_body, :footer, :logo, :signature, :activated) + params.required(:attestation_template).permit(:official_layout, :label_logo, :label_direction, :tiptap_body, :footer, :logo, :signature, :activated, :state) end end end diff --git a/app/controllers/administrateurs/procedures_controller.rb b/app/controllers/administrateurs/procedures_controller.rb index 1c68058ea..874290617 100644 --- a/app/controllers/administrateurs/procedures_controller.rb +++ b/app/controllers/administrateurs/procedures_controller.rb @@ -112,7 +112,7 @@ module Administrateurs revision_types_de_champ: { type_de_champ: { piece_justificative_template_attachment: :blob } } }, attestation_template_v1: [], - attestation_template_v2: [], + attestation_templates_v2: [], initiated_mail: [], received_mail: [], closed_mail: [], diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 818b3c982..db13205c8 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -50,7 +50,7 @@ class Procedure < ApplicationRecord has_one :module_api_carto, dependent: :destroy has_many :attestation_templates, dependent: :destroy has_one :attestation_template_v1, -> { AttestationTemplate.v1 }, dependent: :destroy, class_name: "AttestationTemplate", inverse_of: :procedure - has_one :attestation_template_v2, -> { AttestationTemplate.v2 }, dependent: :destroy, class_name: "AttestationTemplate", inverse_of: :procedure + has_many :attestation_templates_v2, -> { AttestationTemplate.v2 }, dependent: :destroy, class_name: "AttestationTemplate", inverse_of: :procedure has_one :attestation_template, -> { published }, dependent: :destroy, inverse_of: :procedure diff --git a/app/views/administrateurs/attestation_template_v2s/_fixed_footer.html.haml b/app/views/administrateurs/attestation_template_v2s/_fixed_footer.html.haml new file mode 100644 index 000000000..ec8f4d655 --- /dev/null +++ b/app/views/administrateurs/attestation_template_v2s/_fixed_footer.html.haml @@ -0,0 +1,18 @@ +.fr-container + .fr-grid-row.fr-grid-row--middle.fr-pb-3v + .fr-col-12.fr-col-md-4 + = link_to admin_procedure_path(id: procedure), class: 'fr-link' do + %span.fr-icon-arrow-left-line.fr-icon--sm + Revenir à l’écran de gestion + + .fr-col-12.fr-col-md-8.text-right + + - if attestation_template.published? + %p.fr-hint-text Cette attestation est actuellement délivrée aux usagers. + + %span#autosave-notice + + - if procedure.feature_enabled?(:attestation_v2) && attestation_template.draft? + %button.fr-btn.fr-ml-2w{ name: field_name(:attestation_template, :state), value: "published", + data: { 'disable-with': "Publication en cours…", controller: 'autosave-submit' } } + Publier diff --git a/app/views/administrateurs/attestation_template_v2s/edit.html.haml b/app/views/administrateurs/attestation_template_v2s/edit.html.haml index 8ef9c6cfc..8b0f3ecb1 100644 --- a/app/views/administrateurs/attestation_template_v2s/edit.html.haml +++ b/app/views/administrateurs/attestation_template_v2s/edit.html.haml @@ -19,11 +19,12 @@ tout en respectant la charte de l’état. Essayez-la et donnez-nous votre avis en nous envoyant un email à #{mail_to(Current.contact_email, subject: "Feedback attestation v2")}. %br - %strong Les attestations délivrées suivent encore l’ancien format : - l’activation des attestations basées sur ce format sera bientôt disponible. - %br + - if !@procedure.feature_enabled?(:attestation_v2) + %strong Les attestations délivrées suivent encore l’ancien format : + l’activation des attestations basées sur ce format sera bientôt disponible. + %br - = link_to("Suivez ce lien pour revenir aux attestations actuellement délivrées", edit_admin_procedure_attestation_template_path(@procedure)) + = link_to("Suivez ce lien pour revenir aux attestations actuellement délivrées", edit_admin_procedure_attestation_template_path(@procedure)) .fr-grid-row.fr-grid-row--gutters .fr-col-12.fr-col-lg-7 @@ -77,10 +78,10 @@ %button.fr-btn.fr-btn--secondary.fr-btn--sm{ type: 'button', title: label, class: icon == :hidden ? "hidden" : "fr-icon-#{icon}", data: { action: 'click->tiptap#menuButton', tiptap_target: 'button', tiptap_action: action } } = label - #editor.tiptap-editor{ data: { tiptap_target: 'editor' }, aria: { describedby: dom_id(f.object, "json-body-messages")} } + #editor.tiptap-editor{ data: { tiptap_target: 'editor' }, aria: { describedby: "attestation-template-json-body-messages"} } = f.hidden_field :tiptap_body, data: { tiptap_target: 'input' } - .fr-error-text{ id: dom_id(f.object, "json-body-messages"), class: class_names("hidden" => !f.object.errors.include?(:json_body)) } + .fr-error-text{ id: "attestation-template-json-body-messages", class: class_names("hidden" => !f.object.errors.include?(:json_body)) } - if f.object.errors.include?(:json_body) = render partial: "shared/errors_list", locals: { object: f.object, attribute: :json_body } @@ -118,20 +119,5 @@ Pour générer un aperçu fidèle avec tous les champs et les dates, créez-vous un dossier et acceptez-le : l’aperçu l’utilisera. .padded-fixed-footer - .fixed-footer - .fr-container - .fr-grid-row - .fr-col-12.fr-col-md-7 - %ul.fr-btns-group.fr-btns-group--inline-md - %li - = link_to admin_procedure_path(id: @procedure), class: 'fr-btn fr-btn--secondary' do - %span.fr-icon-arrow-go-back-line.fr-icon--sm.fr-mr-1v - Revenir à la démarche - - .fr-col-12.fr-col-md-5 - -# .fr-toggle - -# = f.check_box :activated, class: "fr-toggle-input", disabled: true, id: dom_id(@attestation_template, :activated) - -# %label.fr-toggle__label{ for: dom_id(@attestation_template, :activated), data: { fr_checked_label: "Attestation activée", fr_unchecked_label: "Attestation désactivée" } } - .text-right - %span#autosave-notice - %p.fr-hint-text L’activation de cette attestation sera bientôt disponible. + .fixed-footer#fixed_footer + = render partial: "fixed_footer", locals: { procedure: @procedure, attestation_template: @attestation_template } diff --git a/app/views/administrateurs/attestation_template_v2s/update.turbo_stream.haml b/app/views/administrateurs/attestation_template_v2s/update.turbo_stream.haml index 67ef140a1..69447ce28 100644 --- a/app/views/administrateurs/attestation_template_v2s/update.turbo_stream.haml +++ b/app/views/administrateurs/attestation_template_v2s/update.turbo_stream.haml @@ -1,3 +1,6 @@ +- if @attestation_template.previously_new_record? || @attestation_template.state_changed? + = turbo_stream.update "fixed_footer", render(partial: "fixed_footer", locals: { procedure: @procedure, attestation_template: @attestation_template }) + = turbo_stream.show 'autosave-notice' = turbo_stream.replace 'autosave-notice', render(partial: 'administrateurs/autosave_notice', locals: { success: !@attestation_template.changed? }) = turbo_stream.hide 'autosave-notice', delay: 15000 @@ -10,7 +13,7 @@ = turbo_stream.update dom_id(@attestation_template, :signature_attachment) do = render(Attachment::EditComponent.new(attached_file: @attestation_template.signature, direct_upload: false)) -- body_id = dom_id(@attestation_template, "json-body-messages") +- body_id = "attestation-template-json-body-messages" - if @attestation_template.errors.include?(:json_body) = turbo_stream.update body_id do = render partial: "shared/errors_list", locals: { object: @attestation_template, attribute: :json_body } diff --git a/spec/controllers/administrateurs/attestation_template_v2s_controller_spec.rb b/spec/controllers/administrateurs/attestation_template_v2s_controller_spec.rb index d04d7aa89..6541c0ddd 100644 --- a/spec/controllers/administrateurs/attestation_template_v2s_controller_spec.rb +++ b/spec/controllers/administrateurs/attestation_template_v2s_controller_spec.rb @@ -140,8 +140,9 @@ describe Administrateurs::AttestationTemplateV2sController, type: :controller do it "create template" do subject - attestation_template = procedure.reload.attestation_template + attestation_template = procedure.reload.attestation_templates.first + expect(attestation_template).to be_draft expect(attestation_template.official_layout).to eq(true) expect(attestation_template.label_logo).to eq("Ministère des specs") expect(attestation_template.label_direction).to eq("RSPEC") @@ -157,7 +158,7 @@ describe Administrateurs::AttestationTemplateV2sController, type: :controller do it "upload files" do subject - attestation_template = procedure.reload.attestation_template + attestation_template = procedure.reload.attestation_templates.first expect(attestation_template.logo.download).to eq(logo.read) expect(attestation_template.signature.download).to eq(signature.read) @@ -174,10 +175,16 @@ describe Administrateurs::AttestationTemplateV2sController, type: :controller do end context 'when attestation template is valid' do - it "update template" do - subject - attestation_template.reload + it "create a draft template" do + expect { subject }.to change { procedure.attestation_templates.count }.by(1) + # published remains inchanged + expect(attestation_template.reload).to be_published + expect(attestation_template.label_logo).to eq("Ministère des devs") + + attestation_template = procedure.attestation_templates.draft.first + + expect(attestation_template).to be_draft expect(attestation_template.official_layout).to eq(true) expect(attestation_template.label_logo).to eq("Ministère des specs") expect(attestation_template.label_direction).to eq("RSPEC") @@ -186,6 +193,7 @@ describe Administrateurs::AttestationTemplateV2sController, type: :controller do expect(attestation_template.tiptap_body).to eq(update_params[:tiptap_body]) expect(response.body).to include("Formulaire enregistré") + expect(response.body).to include("Publier") end context "with files" do @@ -193,7 +201,8 @@ describe Administrateurs::AttestationTemplateV2sController, type: :controller do it "upload files" do subject - attestation_template.reload + + attestation_template = procedure.attestation_templates.draft.first expect(attestation_template.logo.download).to eq(logo.read) expect(attestation_template.signature.download).to eq(signature.read) @@ -211,6 +220,17 @@ describe Administrateurs::AttestationTemplateV2sController, type: :controller do expect(response.body).to include('Supprimer cette balise') end end + + context "publishing a draft" do + let(:attestation_template) { build(:attestation_template, :draft, :v2) } + let(:update_params) { super().merge(state: :published) } + + it "publish and redirect with notice" do + subject + expect(attestation_template.reload).to be_published + expect(flash.notice).to eq("L’attestation a été publiée.") + end + end end end end diff --git a/spec/system/administrateurs/procedure_attestation_template_spec.rb b/spec/system/administrateurs/procedure_attestation_template_spec.rb index a54d2e4e3..f2be6e451 100644 --- a/spec/system/administrateurs/procedure_attestation_template_spec.rb +++ b/spec/system/administrateurs/procedure_attestation_template_spec.rb @@ -81,7 +81,7 @@ describe 'As an administrateur, I want to manage the procedure’s attestation', find("a").click end - expect(procedure.reload.attestation_template_v2).to be_nil + expect(procedure.reload.attestation_templates.v2).to be_empty expect(page).to have_css("label", text: "Logo additionnel") @@ -90,7 +90,7 @@ describe 'As an administrateur, I want to manage the procedure’s attestation', attestation = nil wait_until { - attestation = procedure.reload.attestation_template_v2 + attestation = procedure.reload.attestation_templates.v2.draft.first attestation.present? } expect(attestation.label_logo).to eq("System Test") @@ -130,6 +130,10 @@ describe 'As an administrateur, I want to manage the procedure’s attestation', fill_in "Contenu du pied de page", with: ["line1", "line2", "line3", "line4"].join("\n") expect(page).to have_field("Contenu du pied de page", with: "line1\nline2\nline3\nline4") + + click_on "Publier" + expect(page).to have_text("L’attestation a été publiée") + expect(attestation.reload).to be_published end context "tag in error" do @@ -137,7 +141,7 @@ describe 'As an administrateur, I want to manage the procedure’s attestation', tdc = procedure.active_revision.add_type_de_champ(type_champ: :integer_number, libelle: 'age') procedure.publish_revision! - attestation = procedure.build_attestation_template_v2(json_body: AttestationTemplate::TIPTAP_BODY_DEFAULT, label_logo: "test") + attestation = procedure.build_attestation_template(version: 2, json_body: AttestationTemplate::TIPTAP_BODY_DEFAULT, label_logo: "test") attestation.json_body["content"] << { type: :mention, attrs: { id: "tdc#{tdc.stable_id}", label: tdc.libelle } } attestation.save!