Merge pull request #11013 from colinux/admin-knows-api-fields

ETQ admin je suis informé des infos remontées par le champ SIRET
This commit is contained in:
Colin Darie 2024-12-17 14:12:58 +00:00 committed by GitHub
commit 123d363184
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 168 additions and 43 deletions

View file

@ -75,3 +75,19 @@
.flex-1 {
flex: 1;
}
.two-column-list {
display: flex;
flex-wrap: wrap;
li {
flex: 0 0 50%;
box-sizing: border-box;
}
@media (max-width: 62em) {
li {
flex: 0 0 100%;
}
}
}

View file

@ -1,6 +1,3 @@
fr:
en:
modal:
title: "Your file does not match submission criteria"
close: "Close"
close_alt: "Close this modal"
body: "The procedure « %{procedure_libelle} » have submission criteria, unfortunately your file does not match them. You can not submit your file"
title: 'Your file does not match submission criteria'

View file

@ -1,5 +1,3 @@
fr:
modal:
title: "Vous ne pouvez pas déposer votre dossier"
close: "Fermer"
close_alt: "Fermer la fenêtre modale"
title: 'Vous ne pouvez pas déposer votre dossier'

View file

@ -8,7 +8,7 @@
.fr-col-12.fr-col-md-8.fr-col-lg-6
.fr-modal__body
.fr-modal__header
%button.fr-btn--close.fr-btn{ aria: { controls: 'modal-eligibilite-rules-dialog' }, title: t('.modal.close_alt') }= t('.modal.close')
%button.fr-btn--close.fr-btn{ aria: { controls: 'modal-eligibilite-rules-dialog' }, title: t('utils.modal_close_alt') }= t('utils.modal_close')
.fr-modal__content
%h1#fr-modal-title-modal-1.fr-modal__title
%span.fr-icon-arrow-right-line.fr-icon--lg>

View file

@ -12,6 +12,13 @@
= form.label :type_champ, "Type de champ", for: dom_id(type_de_champ, :type_champ)
= form.select :type_champ, grouped_options_for_select(types_of_type_de_champ, type_de_champ.type_champ), {}, class: 'fr-select small-margin small inline width-100', id: dom_id(type_de_champ, :type_champ), disabled: coordinate.used_by_routing_rules? || coordinate.used_by_ineligibilite_rules?
- if type_de_champ.siret?
.cell.fr-mt-1w
= button_tag("Liste des informations remontées", type: :button, class: "fr-btn fr-icon-info-line fr-btn--icon-left fr-btn--tertiary-no-outline fr-btn--sm",
data: { "fr-opened" => "false", "turbo-frame" => "api-champ-columns", action: "lazy-modal#load" },
src: api_champ_columns_admin_procedure_path(id: procedure.id, stable_id: type_de_champ.stable_id),
"aria-controls" => "api-champ-columns-modal")
.flex.column.justify-start.flex-grow
.cell
.flex.align-center
@ -66,7 +73,6 @@
= render Attachment::EditComponent.new(**notice_explicative_options)
.flex.justify-start.fr-mt-1w.flex-gap
- if type_de_champ.any_drop_down_list?
.flex.column.justify-start.width-33

View file

@ -5,7 +5,7 @@ module Administrateurs
layout 'all', only: [:all, :administrateurs]
respond_to :html, :xlsx
before_action :retrieve_procedure, only: [:champs, :annotations, :modifications, :edit, :zones, :monavis, :update_monavis, :accuse_lecture, :update_accuse_lecture, :jeton, :update_jeton, :publication, :publish, :transfert, :close, :confirmation, :allow_expert_review, :allow_expert_messaging, :experts_require_administrateur_invitation, :reset_draft, :publish_revision, :check_path]
before_action :retrieve_procedure, only: [:champs, :annotations, :modifications, :edit, :zones, :monavis, :update_monavis, :accuse_lecture, :update_accuse_lecture, :jeton, :update_jeton, :publication, :publish, :transfert, :close, :confirmation, :allow_expert_review, :allow_expert_messaging, :experts_require_administrateur_invitation, :reset_draft, :publish_revision, :check_path, :api_champ_columns]
before_action :draft_valid?, only: [:apercu]
after_action :reset_procedure, only: [:update]
@ -421,6 +421,26 @@ module Administrateurs
@admins = paginate(@admins, 'users.email')
end
def api_champ_columns
_, @type_de_champ = @procedure.draft_revision.coordinate_and_tdc(params[:stable_id])
regex_prefix = /^#{Regexp.escape(@type_de_champ.libelle)}([^\p{L}]+SIRET)?[^\p{L}]+/
@column_labels = @type_de_champ
.columns(procedure: @procedure)
.filter_map do |column|
# Remove tdc libelle prefix added in columns:
# Numéro SIRET - Entreprise SIREN => Entreprise SIREN
column.label.sub(regex_prefix, '')
end
if @type_de_champ.type_champ == "siret"
@column_labels.concat Etablissement::EXPORTABLE_COLUMNS.dup.map { I18n.t(_1, scope: [:activerecord, :attributes, :procedure_presentation, :fields, :etablissement]) }
# Hardcode non columns data
@column_labels << "Bilans BDF"
end
end
private
def paginated_published_procedures

View file

@ -0,0 +1,21 @@
import { ApplicationController } from './application_controller';
interface HTMLTurboFrameElement extends HTMLElement {
src: string | null;
}
export default class LazyModalController extends ApplicationController {
static targets = ['frame'];
declare readonly frameTarget: HTMLTurboFrameElement;
load(event: Event): void {
const button = event.currentTarget as HTMLButtonElement;
const frame = this.frameTarget;
const src = button.getAttribute('src');
if (src) {
frame.src = src;
}
}
}

View file

@ -162,31 +162,7 @@ module ColumnsConcern
others = %w[code_postal].map { |column| dossier_col(table: 'etablissement', column:) }
for_export = %w[
siege_social
code_naf
adresse
numero_voie
type_voie
nom_voie
complement_adresse
localite
code_insee_localite
entreprise_capital_social
entreprise_numero_tva_intracommunautaire
entreprise_forme_juridique_code
entreprise_code_effectif_entreprise
entreprise_etat_administratif
entreprise_siret_siege_social
entreprise_nom
entreprise_prenom
association_rna
association_titre
association_objet
association_date_creation
association_date_declaration
association_date_publication
].map { |column| dossier_col(table: 'etablissement', column:, displayable: false, filterable: false) }
for_export = Etablissement::EXPORTABLE_COLUMNS.map { |column| dossier_col(table: 'etablissement', column:) }
[siret_column, etablissements, others, for_export].flatten
end

View file

@ -34,6 +34,32 @@ class Etablissement < ApplicationRecord
"libelle_naf" => { type: :text }
}.freeze
EXPORTABLE_COLUMNS = %w[
siege_social
code_naf
adresse
numero_voie
type_voie
nom_voie
complement_adresse
localite
code_insee_localite
entreprise_capital_social
entreprise_numero_tva_intracommunautaire
entreprise_forme_juridique_code
entreprise_code_effectif_entreprise
entreprise_etat_administratif
entreprise_siret_siege_social
entreprise_nom
entreprise_prenom
association_rna
association_titre
association_objet
association_date_creation
association_date_declaration
association_date_publication
].freeze
def entreprise_raison_sociale
read_attribute(:entreprise_raison_sociale).presence || raison_sociale_for_ei
end

View file

@ -0,0 +1,16 @@
= turbo_frame_tag("api-champ-columns") do
%h1#fr-modal-api-champ-columns-h1.fr-modal__title
= t('.title', type_de_champ: t(@type_de_champ.type_champ, scope: 'activerecord.attributes.type_de_champ.type_champs'))
%p.fr-hint-text
= t('.hint_html')
%ul.two-column-list.fr-mb-3w
- @column_labels.each do |label|
%li= label.upcase_first
- if @type_de_champ.type_champ == "siret"
%p.fr-hint-text
Nous affichons aussi aux instructeurs un lien vers lannuaire de lentreprise,
qui comporte davantage dinformations comme des données équivalentes aux extraits KBIS.
= link_to("Voir un exemple", annuaire_link("35600000000048"), **external_link_attributes)

View file

@ -16,9 +16,20 @@
= render NestedForms::FormOwnerComponent.new
.fr-grid-row
= render TypesDeChampEditor::HeaderSectionsSummaryComponent.new(procedure: @procedure, is_private: false)
.fr-col
.fr-col{ data: { controller: "lazy-modal" } }
= render TypesDeChampEditor::EditorComponent.new(revision: @procedure.draft_revision, is_annotation: false)
%dialog#api-champ-columns-modal.fr-modal{ "aria-labelledby" => 'fr-modal-api-champ-columns-h1', role: "dialog" }
.fr-container.fr-container--fluid.fr-container-md
.fr-grid-row.fr-grid-row--center
.fr-col-12.fr-col-md-8
.fr-modal__body
.fr-modal__header
%button.fr-btn--close.fr-btn{ aria: { controls: "api-champ-columns-modal" }, title: t('utils.modal_close_alt') }= t('utils.modal_close')
.fr-modal__content
= turbo_frame_tag "api-champ-columns", data: { "lazy-modal-target": "frame" }
.padded-fixed-footer
.fixed-footer
.fr-container

View file

@ -4,7 +4,7 @@
.fr-col-12.fr-col-md-6.fr-col-lg-4
.fr-modal__body
.fr-modal__header
%button#button-5622.fr-btn--close.fr-btn{ "aria-controls" => "fr-theme-modal", title: "Fermer" } Fermer
%button#button-5622.fr-btn--close.fr-btn{ "aria-controls" => "fr-theme-modal", title: t('utils.modal_close_alt') }= t('utils.modal_close')
.fr-modal__content
%h1#fr-theme-modal-title.fr-modal__title Paramètres daffichage
#fr-display.fr-display

View file

@ -74,7 +74,7 @@
#modal-header__menu.fr-header__menu.fr-modal{ "aria-labelledby": "navbar-burger-button" }
.fr-container
%button.fr-btn--close.fr-btn{ "aria-controls" => "modal-header__menu", title: t('close_modal', scope: [:layouts, :header]) }= t('close_modal', scope: [:layouts, :header])
%button.fr-btn--close.fr-btn{ "aria-controls" => "modal-header__menu", title: t('utils.modal_close_alt') }= t('utils.modal_close')
.fr-header__menu-links
-# populated by dsfr js

View file

@ -1,6 +1,6 @@
#search-modal.fr-header__search.fr-modal{ "aria-label": t('views.users.dossiers.search.search_file') }
.fr-container.fr-container-lg--fluid
%button.fr-btn--close.fr-btn{ "aria-controls" => "search-modal", :title => t('close_modal', scope: [:layouts, :header]) }= t('close_modal', scope: [:layouts, :header])
%button.fr-btn--close.fr-btn{ "aria-controls" => "search-modal", title: t('utils.modal_close_alt') }= t('utils.modal_close')
#search-473.fr-search-bar.fr-search-bar--lg
= form_tag recherche_index_path, method: :get, :role => "search", class: "flex width-100" do
= hidden_field_tag :context, local_assigns[:context]

View file

@ -56,6 +56,8 @@ en:
no_mandatory: (optional)
send_mail: Send message
new_tab: New tab
modal_close: "Close"
modal_close_alt: "Close this modal"
helpers:
procedure:
testing_procedure: testing procedure
@ -78,7 +80,6 @@ en:
are_you_new: First time on %{app_name}?
my_account: My account
header:
close_modal: 'Close'
back: "Back"
back_title: "Back to my administration's website"
main_menu: "Main menu"

View file

@ -47,6 +47,8 @@ fr:
no_mandatory: (facultatif)
send_mail: Envoyer le message
new_tab: "Nouvel onglet"
modal_close: "Fermer"
modal_close_alt: "Fermer la fenêtre modale"
helpers:
procedure:
testing_procedure: démarche en test
@ -69,7 +71,6 @@ fr:
are_you_new: Vous êtes nouveau sur %{app_name} ?
my_account: Mon compte
header:
close_modal: 'Fermer'
back: "Revenir en arrière"
back_title: "Revenir en arrière, sur le site de mon administration"
main_menu: "Menu principal"

View file

@ -1,6 +1,11 @@
en:
administrateurs:
procedures:
api_champ_columns:
title: 'Informations complementary to the field %{type_de_champ}'
hint_html: |
The following data is automatically retrieved via API and displayed in files or exports.
<strong>No need to ask the user for this information in other fields!</strong>
close:
page_title: Close the procedure
replacement_procedure_callout_title: You are about to close a procedure

View file

@ -1,6 +1,11 @@
fr:
administrateurs:
procedures:
api_champ_columns:
title: 'Informations complémentaires au champ %{type_de_champ}'
hint_html: |
Les données suivantes sont automatiquement récupérées par API et affichées dans les dossiers ou exports.
<strong> Inutile de les redemander à lusager dans dautres champs !</strong>
close:
page_title: Clore la démarche
replacement_procedure_callout_title: Vous êtes sur le point de clore une démarche
@ -19,7 +24,7 @@ fr:
other: Souhaitez-vous envoyer un email aux %{count} utilisateurs avec un dossier en brouillon ?
email_content_brouillon: Contenu de l'email
email_toggle_en_cours:
one : Souhaitez-vous envoyer un email à l'utilisateur avec un dossier déposé ?
one: Souhaitez-vous envoyer un email à l'utilisateur avec un dossier déposé ?
other: Souhaitez-vous envoyer un email aux %{count} utilisateurs avec un dossier déposé ?
email_content_en_cours: Contenu de l'email
preview_unavailable: Aperçu non disponible car la démarche est mal configurée

View file

@ -642,6 +642,7 @@ Rails.application.routes.draw do
put :allow_expert_messaging
put :experts_require_administrateur_invitation
put :restore
get 'api_champ_columns'
end
get :api_particulier, controller: 'jeton_particulier'

View file

@ -413,4 +413,29 @@ describe 'As an administrateur I can edit types de champ', js: true do
expect(page).not_to have_selector('.sticky-header.sticky-header-warning')
end
end
context "SIRET field modal" do
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :siret, libelle: "SIRET de test" }]) }
scenario "loads modal content only when clicked" do
visit champs_admin_procedure_path(procedure)
expect(page).not_to have_content("Informations complémentaires au champ Numéro Siret")
click_button "Liste des informations remontées"
within "#api-champ-columns-modal" do
expect(page).to have_content("Informations complémentaires au champ Numéro Siret")
expect(page).to have_content("Entreprise raison sociale")
expect(page).not_to have_content("SIRET de test Commune") # no champ libelle
click_button "Fermer"
end
expect(page).not_to have_selector("#api-champ-columns-modal[open]")
click_button "Liste des informations remontées"
expect(page).to have_content("Informations complémentaires au champ Numéro Siret")
end
end
end