diff --git a/app/controllers/instructeurs/export_templates_controller.rb b/app/controllers/instructeurs/export_templates_controller.rb
index 453673b42..f78e3550c 100644
--- a/app/controllers/instructeurs/export_templates_controller.rb
+++ b/app/controllers/instructeurs/export_templates_controller.rb
@@ -15,7 +15,7 @@ module Instructeurs
@export_template = ExportTemplate.new(export_template_params)
if @export_template.save
- redirect_to [:exports, :instructeur, @procedure], notice: "Le modèle d'export #{@export_template.name} a bien été créé"
+ redirect_to [:export_templates, :instructeur, @procedure], notice: "Le modèle d'export #{@export_template.name} a bien été créé"
else
flash[:alert] = @export_template.errors.full_messages
render :new
diff --git a/app/controllers/instructeurs/procedures_controller.rb b/app/controllers/instructeurs/procedures_controller.rb
index e7772b88e..a93eabf2f 100644
--- a/app/controllers/instructeurs/procedures_controller.rb
+++ b/app/controllers/instructeurs/procedures_controller.rb
@@ -204,7 +204,6 @@ module Instructeurs
def exports
@procedure = procedure
@exports = Export.for_groupe_instructeurs(groupe_instructeur_ids).ante_chronological
- @export_templates = current_instructeur.export_templates_for(@procedure).includes(:groupe_instructeur)
cookies.encrypted[cookies_export_key] = {
value: DateTime.current,
expires: Export::MAX_DUREE_GENERATION + Export::MAX_DUREE_CONSERVATION_EXPORT,
@@ -218,6 +217,11 @@ module Instructeurs
end
end
+ def export_templates
+ @procedure = procedure
+ @export_templates = current_instructeur.export_templates_for(@procedure).includes(:groupe_instructeur)
+ end
+
def email_usagers
@procedure = procedure
@bulk_messages = BulkMessage.where(procedure: procedure)
diff --git a/app/helpers/navigation_helper.rb b/app/helpers/navigation_helper.rb
index 870785327..662ffac1d 100644
--- a/app/helpers/navigation_helper.rb
+++ b/app/helpers/navigation_helper.rb
@@ -27,7 +27,9 @@ module NavigationHelper
end
def downloads_section?
- params[:action] == 'exports' ||
- params[:controller] == 'instructeurs/archives'
+ return true if params[:action].in?(['exports', 'export_templates'])
+ return true if params[:controller] == 'instructeurs/archives'
+
+ false
end
end
diff --git a/app/views/instructeurs/procedures/_header.html.haml b/app/views/instructeurs/procedures/_header.html.haml
index c990fade0..f144f9abd 100644
--- a/app/views/instructeurs/procedures/_header.html.haml
+++ b/app/views/instructeurs/procedures/_header.html.haml
@@ -52,7 +52,7 @@
%li
= link_to t('instructeurs.dossiers.header.banner.archives'), instructeur_archives_path(procedure), class: 'fr-nav__link'
%li
- = link_to t('instructeurs.dossiers.header.banner.exports_models'), exports_instructeur_procedure_path(procedure), class: 'fr-nav__link'
+ = link_to t('instructeurs.dossiers.header.banner.export_templates'), export_templates_instructeur_procedure_path(procedure), class: 'fr-nav__link'
- if @has_export_notification
%span.notifications{ 'aria-label': t('instructeurs.dossiers.header.banner.exports_notification_label') }
diff --git a/app/views/instructeurs/procedures/export_templates.html.haml b/app/views/instructeurs/procedures/export_templates.html.haml
new file mode 100644
index 000000000..1cb76e076
--- /dev/null
+++ b/app/views/instructeurs/procedures/export_templates.html.haml
@@ -0,0 +1,49 @@
+- title = t('.page_title', procedure: @procedure.libelle)
+- content_for(:title, title)
+
+.sub-header
+ .fr-container.flex.column
+ = render partial: 'instructeurs/breadcrumbs', locals: { steps: [[@procedure.libelle.truncate_words(10), instructeur_procedure_path(@procedure)], [t('instructeurs.dossiers.header.banner.export_templates')]] }
+
+ = render partial: 'instructeurs/procedures/header', locals: { procedure: @procedure }
+
+
+.fr-container
+ %h1.fr-h4= t('instructeurs.dossiers.header.banner.export_templates')
+ = render Dsfr::AlertComponent.new(state: :info) do |c|
+ - c.with_body do
+ %p= t('.export_template_list_description_html')
+
+ .fr-mt-5w
+ = link_to t('.new_zip_export_template'), new_instructeur_procedure_export_template_path(@procedure, kind: 'zip'), class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-add-line fr-mr-1w"
+ = link_to t('.new_tabular_export_template'), new_instructeur_procedure_export_template_path(@procedure, kind: 'tabular'), class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-add-line"
+
+ - if @export_templates.any?
+ .fr-table.fr-table--bordered.fr-table--no-caption.fr-mt-5w
+ .fr-table__wrapper
+ .fr-table__container
+ %table.fr-table__content
+ %thead
+ %tr
+ %th{ scope: 'col' }= t('.template_name')
+ %th{ scope: 'col' }= t('.template_format')
+ %th{ scope: 'col' }= t('.template_creation_date')
+ - if @procedure.groupe_instructeurs.many?
+ %th{ scope: 'col' }= t('.template_shared_with')
+ %th{ scope: 'col' }= t('.actions')
+
+ %tbody
+ - @export_templates.each do |export_template|
+ %tr
+ %td= link_to export_template.name, [:edit, :instructeur, @procedure, export_template]
+ %td= pretty_kind(export_template.kind)
+ %td= l(export_template.created_at)
+ - if @procedure.groupe_instructeurs.many?
+ %td= export_template.groupe_instructeur.label
+ %td
+ = link_to t('.modify_template'), [:edit, :instructeur, @procedure, export_template], class: "fr-btn fr-btn--icon-left fr-icon-edit-line fr-mr-1w"
+ = link_to t('.delete_template'), [:instructeur, @procedure, export_template], method: :delete, data: { confirm: t('.delete_template_alert')}, class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-delete-line"
+ - else
+ .fr-alert.fr-alert--info.fr-mt-4w
+ .fr-alert__body
+ %p= t('.no_existing_template')
diff --git a/app/views/instructeurs/procedures/exports.html.haml b/app/views/instructeurs/procedures/exports.html.haml
index f22aecc25..30021b77e 100644
--- a/app/views/instructeurs/procedures/exports.html.haml
+++ b/app/views/instructeurs/procedures/exports.html.haml
@@ -12,59 +12,19 @@
.fr-container
%h1.fr-h4= t('.title')
- .fr-tabs.mb-3
- %ul.fr-tabs__list{ role: 'tablist' }
- %li{ role: 'presentation' }
- %button.fr-tabs__tab.fr-tabs__tab--icon-left{ id: "tabpanel-exports", tabindex: "0", role: "tab", "aria-selected": "true", "aria-controls": "tabpanel-exports-panel" } Liste des exports
- %li{ role: 'presentation' }
- %button.fr-tabs__tab.fr-tabs__tab--icon-left{ id: "tabpanel-export-templates", tabindex: "-1", role: "tab", "aria-selected": "false", "aria-controls": "tabpanel-export-templates-panel" } Modèles d'export
- .fr-tabs__panel.fr-tabs__panel--selected{ id: "tabpanel-exports-panel", role: "tabpanel", "aria-labelledby": "tabpanel-exports", tabindex: "0" }
- = render Dsfr::CalloutComponent.new(title: nil) do |c|
+ = render Dsfr::CalloutComponent.new(title: nil) do |c|
+ - c.with_body do
+ %p= t('.export_description', expiration_time: Export::MAX_DUREE_CONSERVATION_EXPORT.in_hours.to_i)
+
+ - if @exports.present?
+ %div{ data: @exports.any?(&:pending?) ? { controller: "turbo-poll", turbo_poll_url_value: "", turbo_poll_interval_value: 10_000, turbo_poll_max_checks_value: 6 } : {} }
+ = render Dossiers::ExportLinkComponent.new(procedure: @procedure, exports: @exports, statut: @statut, count: @dossiers_count, class_btn: 'fr-btn--tertiary', export_url: method(:download_export_instructeur_procedure_path))
+
+ - if @exports.any?{_1.format == Export.formats.fetch(:zip)}
+ = render Dsfr::AlertComponent.new(title: t('.title_zip'), state: :info, extra_class_names: 'fr-mb-3w') do |c|
- c.with_body do
- %p= t('.export_description', expiration_time: Export::MAX_DUREE_CONSERVATION_EXPORT.in_hours.to_i)
+ %p= t('.export_description_zip_html')
- - if @exports.present?
- %div{ data: @exports.any?(&:pending?) ? { controller: "turbo-poll", turbo_poll_url_value: "", turbo_poll_interval_value: 10_000, turbo_poll_max_checks_value: 6 } : {} }
- = render Dossiers::ExportLinkComponent.new(procedure: @procedure, exports: @exports, statut: @statut, count: @dossiers_count, class_btn: 'fr-btn--tertiary', export_url: method(:download_export_instructeur_procedure_path))
-
- - if @exports.any?{_1.format == Export.formats.fetch(:zip)}
- = render Dsfr::AlertComponent.new(title: t('.title_zip'), state: :info, extra_class_names: 'fr-mb-3w') do |c|
- - c.with_body do
- %p= t('.export_description_zip_html')
-
- - else
- = t('.no_export_html', expiration_time: Export::MAX_DUREE_CONSERVATION_EXPORT.in_hours.to_i )
-
- .fr-tabs__panel.fr-tabs__panel{ id: "tabpanel-export-templates-panel", role: "tabpanel", "aria-labelledby": "tabpanel-export-templates", tabindex: "0" }
- = render Dsfr::AlertComponent.new(state: :info) do |c|
- - c.with_body do
- %p= t('.export_template_list_description_html')
-
-
- .fr-mt-5w
- = link_to t('.new_zip_export_template'), new_instructeur_procedure_export_template_path(@procedure, kind: 'zip'), class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-add-line fr-mr-1w"
- = link_to t('.new_tabular_export_template'), new_instructeur_procedure_export_template_path(@procedure, kind: 'tabular'), class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-add-line"
-
- .fr-table.fr-table--bordered.fr-table--no-caption.fr-mt-5w
- .fr-table__wrapper
- .fr-table__container
- .fr-table__content
- %table
- %thead
- %tr
- = tag.th "Nom du modèle", scope: 'col'
- = tag.th "Format", scope: 'col'
- = tag.th "Date de création", scope: 'col'
- = tag.th "Partagé avec (groupe instructeurs)", scope: 'col' if @procedure.groupe_instructeurs.many?
- = tag.th "Actions", scope: 'col'
- %tbody
- - @export_templates.each do |export_template|
- %tr
- %td= link_to export_template.name, [:edit, :instructeur, @procedure, export_template]
- %td= pretty_kind(export_template.kind)
- %td= l(export_template.created_at)
- = tag.td export_template.groupe_instructeur.label if @procedure.groupe_instructeurs.many?
- %td
- = link_to "Modifier", [:edit, :instructeur, @procedure, export_template], class: "fr-btn fr-btn--icon-left fr-icon-edit-line fr-mr-1w"
- = link_to "Supprimer", [:instructeur, @procedure, export_template], method: :delete, data: { confirm: "Voulez-vous vraiment supprimer ce modèle ? Il sera supprimé pour tous les instructeurs du groupe"}, class: "fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-delete-line"
+ - else
+ = t('.no_export_html', expiration_time: Export::MAX_DUREE_CONSERVATION_EXPORT.in_hours.to_i )
diff --git a/config/locales/views/instructeurs/header/en.yml b/config/locales/views/instructeurs/header/en.yml
index 3e4299acb..39c7ca7c7 100644
--- a/config/locales/views/instructeurs/header/en.yml
+++ b/config/locales/views/instructeurs/header/en.yml
@@ -15,6 +15,7 @@ en:
notification_management: notification management
administrators_list: administrators list
exports_list: exports and export templates
+ export_templates: Export templates
exports_notification_label: A new export is ready to download
statistics: statistics
instructeurs: instructors
diff --git a/config/locales/views/instructeurs/header/fr.yml b/config/locales/views/instructeurs/header/fr.yml
index d3b7e4fbe..c96de8e14 100644
--- a/config/locales/views/instructeurs/header/fr.yml
+++ b/config/locales/views/instructeurs/header/fr.yml
@@ -16,7 +16,7 @@ fr:
procedure_management: Gestion de la démarche
administrators_list: Administrateurs de la démarche
exports_list: Liste des exports
- exports_models: Modèles d'exports
+ export_templates: Modèles d'export
exports_notification_label: Un nouvel export est prêt à être téléchargé
statistics: Statistiques de la démarche
user_support: Accompagnement des usagers
diff --git a/config/locales/views/instructeurs/procedures/exports/en.yml b/config/locales/views/instructeurs/procedures/exports/en.yml
index f1f7bc753..762bc8cc9 100644
--- a/config/locales/views/instructeurs/procedures/exports/en.yml
+++ b/config/locales/views/instructeurs/procedures/exports/en.yml
@@ -18,9 +18,19 @@ en:
no_export_html: You have no export at the moment.
Can't find an export? It may have expired, exports are deleted after %{expiration_time} hours.
-
+ export_templates:
export_template_list_description_html: |
Each instructor can configure an export template to customize exports (attachments name for a zip export, columns selection for a tabular export). It will be made available to all instructors assigned to the procedure.
Find out more about export template configuration
- new_zip_export_template: Create zip export template
+ new_zip_export_template: Create ZIP export template
new_tabular_export_template: Create tabular export template
+ template_name: Template name
+ no_existing_template: No export templates have been created yet. Use the buttons above to get started.
+ template_format: Format
+ template_creation_date: Creation date
+ template_shared_with: Shared with (instructor groups)
+ modify_template: Edit
+ delete_template: Delete
+ delete_template_alert: Are you sure you want to delete this template? It will be removed for all instructors in the group
+ page_title: "Export templates · %{procedure}"
+ actions: Actions
diff --git a/config/locales/views/instructeurs/procedures/exports/fr.yml b/config/locales/views/instructeurs/procedures/exports/fr.yml
index fa0945652..40760b6e3 100644
--- a/config/locales/views/instructeurs/procedures/exports/fr.yml
+++ b/config/locales/views/instructeurs/procedures/exports/fr.yml
@@ -17,8 +17,19 @@ fr:
Vous n'arrivez pas à extraire un export au format .zip sur un réseau d'entreprise ? Essayer de renommer l'archive avec un nom plus court et ré-essayer de l'extraire.
no_export_html: Vous n'avez pas d'export pour le moment.
Vous ne trouvez pas un export ? Il a peut-être expiré, les exports sont supprimés au bout de %{expiration_time} heures.
+ export_templates:
export_template_list_description_html: |
Chaque instructeur a la possibilité de configurer un modèle d'export pour personnaliser les exports (nom des pièces jointes pour un export au format zip, sélection des colonnes pour un export tabulaire). Il sera mis à disposition de l'ensemble des instructeurs affectés à la démarche
En savoir plus sur la configuration des modèles d'export
new_zip_export_template: Créer un modèle d'export zip
new_tabular_export_template: Créer un modèle d'export tabulaire
+ template_name: Nom du modèle
+ no_existing_template: Aucun modèle d'export n'a encore été créé. Utilisez les boutons ci-dessus pour commencer.
+ template_format: Format
+ template_creation_date: Date de création
+ template_shared_with: Partagé avec (groupe instructeurs)
+ modify_template: Modifier
+ delete_template: Supprimer
+ delete_template_alert: Voulez-vous vraiment supprimer ce modèle ? Il sera supprimé pour tous les instructeurs du groupe
+ page_title: "Modèles d'export · %{procedure}"
+ actions: Actions
diff --git a/config/routes.rb b/config/routes.rb
index 518f513aa..f4532277e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -495,6 +495,7 @@ Rails.application.routes.draw do
get 'polling_last_export'
get 'stats'
get 'exports'
+ get 'export_templates'
get 'email_notifications'
get 'administrateurs'
patch 'update_email_notifications'
diff --git a/spec/controllers/instructeurs/export_templates_controller_spec.rb b/spec/controllers/instructeurs/export_templates_controller_spec.rb
index 32fba6ba8..573d514b2 100644
--- a/spec/controllers/instructeurs/export_templates_controller_spec.rb
+++ b/spec/controllers/instructeurs/export_templates_controller_spec.rb
@@ -42,7 +42,7 @@ describe Instructeurs::ExportTemplatesController, type: :controller do
context 'with valid params' do
it 'redirect to some page' do
subject
- expect(response).to redirect_to(exports_instructeur_procedure_path(procedure))
+ expect(response).to redirect_to(export_templates_instructeur_procedure_path(procedure))
expect(flash.notice).to eq "Le modèle d'export coucou a bien été créé"
end
end
@@ -116,7 +116,7 @@ describe Instructeurs::ExportTemplatesController, type: :controller do
context 'with valid params' do
it 'redirect to some page' do
subject
- expect(response).to redirect_to(exports_instructeur_procedure_path(procedure))
+ expect(response).to redirect_to(export_templates_instructeur_procedure_path(procedure))
expect(flash.notice).to eq "Le modèle d'export ExportODS a bien été créé"
expect(ExportTemplate.last.exported_columns.map(&:libelle)).to match_array ['Demandeur', 'Date du dernier évènement']
end
diff --git a/spec/controllers/instructeurs/procedures_controller_spec.rb b/spec/controllers/instructeurs/procedures_controller_spec.rb
index d759412f9..bb9725a39 100644
--- a/spec/controllers/instructeurs/procedures_controller_spec.rb
+++ b/spec/controllers/instructeurs/procedures_controller_spec.rb
@@ -869,6 +869,27 @@ describe Instructeurs::ProceduresController, type: :controller do
end
end
+ describe '#export_templates' do
+ render_views
+
+ let(:instructeur) { create(:instructeur) }
+ let(:procedure) { create(:procedure) }
+ let(:groupe_instructeur) { create(:groupe_instructeur, procedure: procedure) }
+ let!(:export_template) { create(:export_template, name: "My Template", groupe_instructeur: groupe_instructeur) }
+
+ before do
+ sign_in(instructeur.user)
+ create(:assign_to, instructeur: instructeur, groupe_instructeur: groupe_instructeur)
+ end
+
+ it 'displays export templates' do
+ get :export_templates, params: { procedure_id: procedure.id }
+
+ expect(response).to have_http_status(:success)
+ expect(response.body).to include("My Template")
+ end
+ end
+
describe '#exports' do
let(:instructeur) { create(:instructeur) }
let!(:procedure) { create(:procedure) }
diff --git a/spec/system/instructeurs/procedure_export_template_tabular_spec.rb b/spec/system/instructeurs/procedure_export_template_tabular_spec.rb
index bdefa98f6..056887be2 100644
--- a/spec/system/instructeurs/procedure_export_template_tabular_spec.rb
+++ b/spec/system/instructeurs/procedure_export_template_tabular_spec.rb
@@ -12,8 +12,6 @@ describe "procedure exports" do
find("button", text: "Téléchargements").click
- click_on "Liste des exports"
-
click_on "Modèles d'export"
click_on "Créer un modèle d'export tabulaire"
@@ -21,23 +19,20 @@ describe "procedure exports" do
fill_in "Nom du modèle", with: "Mon modèle"
find("#informations-usager-fieldset label", text: "Tout sélectionner").click
+
within '#informations-usager-fieldset' do
expect(all('input[type=checkbox]').all?(&:checked?)).to be_truthy
end
find("#informations-dossier-fieldset label", text: "Tout sélectionner").click
+
within '#informations-dossier-fieldset' do
expect(all('input[type=checkbox]').all?(&:checked?)).to be_truthy
end
click_on "Enregistrer"
- find("#tabpanel-export-templates", wait: 5, visible: true)
- find("#tabpanel-export-templates").click
-
- within 'table' do
- expect(page).to have_content('Mon modèle')
- end
+ expect(page).to have_content('Mon modèle')
# check if all usager colonnes are selected
#
diff --git a/spec/system/instructeurs/procedure_export_template_zip_spec.rb b/spec/system/instructeurs/procedure_export_template_zip_spec.rb
index 90e376751..8aeee3454 100644
--- a/spec/system/instructeurs/procedure_export_template_zip_spec.rb
+++ b/spec/system/instructeurs/procedure_export_template_zip_spec.rb
@@ -11,8 +11,6 @@ describe "procedure exports zip" do
find("button", text: "Téléchargements").click
- click_on "Liste des exports"
-
click_on "Modèles d'export"
click_on "Créer un modèle d'export zip"
@@ -21,11 +19,6 @@ describe "procedure exports zip" do
expect(page).to have_content("Sélectionnez les fichiers que vous souhaitez exporter")
click_on "Enregistrer"
- find("#tabpanel-export-templates", wait: 5, visible: true)
- find("#tabpanel-export-templates").click
-
- within 'table' do
- expect(page).to have_content('Mon modèle')
- end
+ expect(page).to have_content('Mon modèle')
end
end