Skip to content

Commit 7f63a31

Browse files
committed
feat(personnalisation): display chosen champ values on the dossiers list
1 parent 130a042 commit 7f63a31

6 files changed

Lines changed: 119 additions & 2 deletions

File tree

app/controllers/users/dossiers_controller.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def index
5555
Skylight.instrument(title: list_title) do
5656
@dossiers.load
5757
end
58+
load_personnalisation_data(@dossiers)
5859
@corbeille_count = current_user.dossiers.hidden_by_user.or(current_user.dossiers.hidden_by_expired).count
5960
@pending_transfers_count = current_user.dossier_transfers_received_pending.count
6061
@show_simple_list = params[:search].blank? && !@filter.active? && @total_count <= SIMPLE_LIST_THRESHOLD
@@ -691,6 +692,29 @@ def commentaire_params
691692
params.require(:commentaire).permit(:body, piece_jointe: [])
692693
end
693694

695+
def load_personnalisation_data(dossiers)
696+
@personnalisations_by_procedure_id = {}
697+
@champs_by_dossier_id = {}
698+
return if !feature_enabled?(:dossiers_list_personnalisation)
699+
700+
@personnalisations_by_procedure_id = current_user.dossiers_list_personnalisations
701+
.where(procedure_id: dossiers.map { _1.procedure.id }.uniq)
702+
.index_by(&:procedure_id)
703+
return if @personnalisations_by_procedure_id.empty?
704+
705+
stable_ids = @personnalisations_by_procedure_id.values
706+
.flat_map(&:displayed_columns)
707+
.filter(&:champ_column?)
708+
.map(&:stable_id)
709+
.uniq
710+
return if stable_ids.empty?
711+
712+
Champ.where(dossier_id: dossiers.map(&:id), stable_id: stable_ids, stream: Champ::MAIN_STREAM)
713+
.find_each do |champ|
714+
(@champs_by_dossier_id[champ.dossier_id] ||= {})[champ.stable_id] = champ
715+
end
716+
end
717+
694718
def personnalisation_available?
695719
feature_enabled?(:dossiers_list_personnalisation) &&
696720
current_user.dossiers.visible_by_user.count > SIMPLE_LIST_THRESHOLD

app/models/concerns/columns_concern.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ def moral_columns
281281
end
282282

283283
def types_de_champ_columns
284-
all_revisions_types_de_champ.flat_map { _1.columns(procedure_id: id) }
284+
all_revisions_types_de_champ.filter(&:dynamic_type).flat_map { _1.columns(procedure_id: id) }
285285
end
286286

287287
def dossier_col(**args) = Columns::DossierColumn.new(**(args.merge(procedure_id: id)))

app/views/users/dossiers/_dossier_card_content.html.erb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@
7676
</p>
7777
<% end %>
7878
<% end %>
79+
80+
<% if local_assigns[:personnalisation].present? %>
81+
<%= render Users::DossierCardChampsComponent.new(
82+
columns: personnalisation.displayed_columns,
83+
champs_by_stable_id: local_assigns[:champs_by_stable_id] || {}
84+
) %>
85+
<% end %>
7986
</div>
8087

8188
<div class="badge_info text-right fr-hidden unhidden-md">

app/views/users/dossiers/_dossiers_list.html.erb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
<% if dossiers.present? %>
22
<% dossiers.each do |dossier| %>
33
<div class="card" id="dossier_<%= dossier.id %>">
4-
<%= render partial: 'dossier_card_content', locals: { dossier: dossier, linkable: @statut != "dossiers-supprimes" } %>
4+
<%= render partial: 'dossier_card_content', locals: {
5+
dossier: dossier,
6+
linkable: @statut != "dossiers-supprimes",
7+
personnalisation: @personnalisations_by_procedure_id&.[](dossier.procedure.id),
8+
champs_by_stable_id: @champs_by_dossier_id&.[](dossier.id) || {}
9+
} %>
510

611
<% if dossier.procedure.close? %>
712
<%= render Dsfr::AlertComponent.new(state: :info, size: :sm, extra_class_names: "fr-mb-2w") do |c| %>

spec/controllers/users/dossiers_controller_spec.rb

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,67 @@
27692769
end
27702770
end
27712771

2772+
describe 'GET #index with personnalisation values' do
2773+
render_views
2774+
2775+
let(:user) { create(:user) }
2776+
let(:procedure) { create(:procedure, :published, types_de_champ_public: [{ type: :text, libelle: 'Titre' }]) }
2777+
let(:column) { procedure.personnalisable_columns.first }
2778+
2779+
before do
2780+
Flipper.enable(:dossiers_list_personnalisation, user)
2781+
create(:dossiers_list_personnalisation, user:, procedure:, displayed_columns: [column])
2782+
sign_in(user)
2783+
end
2784+
2785+
def query_count
2786+
count = 0
2787+
callback = -> (*) { count += 1 }
2788+
ActiveSupport::Notifications.subscribed(callback, 'sql.active_record') { get :index }
2789+
count
2790+
end
2791+
2792+
it 'does not issue more queries as more dossiers are added (no N+1)' do
2793+
create_list(:dossier, 6, :en_construction, user:, procedure:, populate_champs: true)
2794+
baseline = query_count
2795+
2796+
create_list(:dossier, 6, :en_construction, user:, procedure:, populate_champs: true)
2797+
expect(query_count).to be <= baseline + 3
2798+
end
2799+
end
2800+
2801+
describe 'GET #index with personnalisation values – multi-procedure N+1 guard' do
2802+
render_views
2803+
2804+
let(:user) { create(:user) }
2805+
let(:procedure1) { create(:procedure, :published, types_de_champ_public: [{ type: :text, libelle: 'Titre' }]) }
2806+
let(:procedure2) { create(:procedure, :published, types_de_champ_public: [{ type: :text, libelle: 'Intitulé' }]) }
2807+
2808+
before do
2809+
Flipper.enable(:dossiers_list_personnalisation, user)
2810+
create(:dossiers_list_personnalisation, user:, procedure: procedure1, displayed_columns: [procedure1.personnalisable_columns.first])
2811+
create(:dossiers_list_personnalisation, user:, procedure: procedure2, displayed_columns: [procedure2.personnalisable_columns.first])
2812+
sign_in(user)
2813+
end
2814+
2815+
def query_count
2816+
count = 0
2817+
callback = -> (*) { count += 1 }
2818+
ActiveSupport::Notifications.subscribed(callback, 'sql.active_record') { get :index }
2819+
count
2820+
end
2821+
2822+
it 'does not issue more queries per dossier with multiple procedures (no N+1 on Column.find)' do
2823+
create_list(:dossier, 3, :en_construction, user:, procedure: procedure1, populate_champs: true)
2824+
create_list(:dossier, 3, :en_construction, user:, procedure: procedure2, populate_champs: true)
2825+
baseline = query_count
2826+
2827+
create_list(:dossier, 3, :en_construction, user:, procedure: procedure1, populate_champs: true)
2828+
create_list(:dossier, 3, :en_construction, user:, procedure: procedure2, populate_champs: true)
2829+
expect(query_count).to be <= baseline + 3
2830+
end
2831+
end
2832+
27722833
private
27732834

27742835
def find_champ_by_stable_id(dossier, stable_id)

spec/models/procedure_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,6 +2388,26 @@
23882388
end
23892389
end
23902390

2391+
describe '#columns' do
2392+
it 'does not raise and skips champs with unknown type_champ (legacy value)' do
2393+
procedure = create(:procedure, :published, types_de_champ_public: [
2394+
{ type: :text, libelle: 'Champ valide' },
2395+
{ type: :text, libelle: 'Champ legacy' },
2396+
])
2397+
valid_tdc = procedure.published_revision.types_de_champ_public.find { _1.libelle == 'Champ valide' }
2398+
legacy_tdc_id = procedure.published_revision.types_de_champ_public.find { _1.libelle == 'Champ legacy' }.id
2399+
TypeDeChamp.where(id: legacy_tdc_id).update_all(type_champ: 'titre_identite')
2400+
expect(TypeDeChamp.find(legacy_tdc_id).dynamic_type).to be_nil
2401+
procedure.reload
2402+
Current.procedure_columns = nil
2403+
2404+
expect { procedure.columns }.not_to raise_error
2405+
expect(procedure.columns.map(&:label)).not_to include('Champ legacy')
2406+
h_id = { procedure_id: procedure.id, column_id: "type_de_champ/#{valid_tdc.stable_id}" }
2407+
expect { procedure.find_column(h_id:) }.not_to raise_error
2408+
end
2409+
end
2410+
23912411
private
23922412

23932413
def create_dossier_with_pj_of_size(size, procedure)

0 commit comments

Comments
 (0)