diff --git a/app/components/instructeurs/cell_component.rb b/app/components/instructeurs/cell_component.rb index 7786c60f6fd..0d50849b5b5 100644 --- a/app/components/instructeurs/cell_component.rb +++ b/app/components/instructeurs/cell_component.rb @@ -28,7 +28,7 @@ def simple_layout raw_value = raw_value_for_column(@dossier, @column) return '' if raw_value.nil? - format(raw_value, @column.type) + format(raw_value) end def raw_value_for_column(dossier, column) @@ -41,38 +41,8 @@ def raw_value_for_column(dossier, column) @column.value(data) end - def format(raw_value, type) - case @column.type - when :boolean - if @column.type_de_champ? && @column.tdc_type == 'checkbox' - raw_value ? I18n.t('activerecord.attributes.type_de_champ.type_champs.checkbox_true') : '' - else - raw_value ? I18n.t('utils.yes') : I18n.t('utils.no') - end - when :attachments - raw_value.present? ? 'présent' : 'absent' - when :enum - format_enum(column: @column, raw_value:) - when :enums - format_enums(column: @column, raw_values: raw_value) - when :date - raw_value = Date.parse(raw_value) if raw_value.is_a?(String) - I18n.l(raw_value, format: :short) - when :datetime - raw_value = DateTime.parse(raw_value) if raw_value.is_a?(String) - I18n.l(raw_value, format: :short_with_time) - else - # Escape if it's a string and not already safe - raw_value.html_safe? ? raw_value : html_escape(raw_value.to_s) - end - end - - def format_enums(column:, raw_values:) - safe_join(raw_values.map { format_enum(column:, raw_value: _1) }, ', ') - end - - def format_enum(column:, raw_value:) - column.label_for_value(raw_value) + def format(raw_value) + ColumnValueFormatter.format(column: @column, raw_value:) end def email_and_tiers(dossier) diff --git a/app/components/users/dossier_card_champs_component.rb b/app/components/users/dossier_card_champs_component.rb new file mode 100644 index 00000000000..76a3a8edc7e --- /dev/null +++ b/app/components/users/dossier_card_champs_component.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class Users::DossierCardChampsComponent < ApplicationComponent + Line = Data.define(:label, :value) + + def initialize(columns:, champs_by_stable_id:) + @columns = columns + @champs_by_stable_id = champs_by_stable_id + end + + def render? = lines.any? + + private + + attr_reader :columns, :champs_by_stable_id + + def lines + @lines ||= columns.filter_map do |column| + next unless column.champ_column? + + champ = champs_by_stable_id[column.stable_id] + raw = column.value(champ) + formatted = ColumnValueFormatter.format(column:, raw_value: raw) + next if formatted.blank? + + Line.new(label: column.label, value: formatted) + end + end +end diff --git a/app/components/users/dossier_card_champs_component/dossier_card_champs_component.en.yml b/app/components/users/dossier_card_champs_component/dossier_card_champs_component.en.yml new file mode 100644 index 00000000000..d77d7a7e9e8 --- /dev/null +++ b/app/components/users/dossier_card_champs_component/dossier_card_champs_component.en.yml @@ -0,0 +1,2 @@ +en: + label: "%{champ}:" diff --git a/app/components/users/dossier_card_champs_component/dossier_card_champs_component.fr.yml b/app/components/users/dossier_card_champs_component/dossier_card_champs_component.fr.yml new file mode 100644 index 00000000000..940b3e8601b --- /dev/null +++ b/app/components/users/dossier_card_champs_component/dossier_card_champs_component.fr.yml @@ -0,0 +1,2 @@ +fr: + label: "%{champ} :" diff --git a/app/components/users/dossier_card_champs_component/dossier_card_champs_component.html.erb b/app/components/users/dossier_card_champs_component/dossier_card_champs_component.html.erb new file mode 100644 index 00000000000..1bd3829ad0e --- /dev/null +++ b/app/components/users/dossier_card_champs_component/dossier_card_champs_component.html.erb @@ -0,0 +1,6 @@ +<% lines.each do |line| %> +
+<% end %> diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index 4614231663a..0383ff982d4 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -55,6 +55,7 @@ def index Skylight.instrument(title: list_title) do @dossiers.load end + load_personnalisation_data(@dossiers) @corbeille_count = current_user.dossiers.hidden_by_user.or(current_user.dossiers.hidden_by_expired).count @pending_transfers_count = current_user.dossier_transfers_received_pending.count @show_simple_list = params[:search].blank? && !@filter.active? && @total_count <= SIMPLE_LIST_THRESHOLD @@ -687,6 +688,29 @@ def commentaire_params params.require(:commentaire).permit(:body, piece_jointe: []) end + def load_personnalisation_data(dossiers) + @personnalisations_by_procedure_id = {} + @champs_by_dossier_id = {} + return if !feature_enabled?(:dossiers_list_personnalisation) + + @personnalisations_by_procedure_id = current_user.dossiers_list_personnalisations + .where(procedure_id: dossiers.map { _1.procedure.id }.uniq) + .index_by(&:procedure_id) + return if @personnalisations_by_procedure_id.empty? + + stable_ids = @personnalisations_by_procedure_id.values + .flat_map(&:displayed_columns) + .filter(&:champ_column?) + .map(&:stable_id) + .uniq + return if stable_ids.empty? + + Champ.where(dossier_id: dossiers.map(&:id), stable_id: stable_ids, stream: Champ::MAIN_STREAM) + .find_each do |champ| + (@champs_by_dossier_id[champ.dossier_id] ||= {})[champ.stable_id] = champ + end + end + def personnalisation_available? feature_enabled?(:dossiers_list_personnalisation) && current_user.dossiers.visible_by_user.count > SIMPLE_LIST_THRESHOLD diff --git a/app/lib/column_value_formatter.rb b/app/lib/column_value_formatter.rb new file mode 100644 index 00000000000..deed1a8e6cd --- /dev/null +++ b/app/lib/column_value_formatter.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module ColumnValueFormatter + module_function + + def format(column:, raw_value:) + return if raw_value.nil? + + case column.type + when :boolean + if column.type_de_champ? && column.tdc_type == 'checkbox' + raw_value ? I18n.t('activerecord.attributes.type_de_champ.type_champs.checkbox_true') : '' + else + raw_value ? I18n.t('utils.yes') : I18n.t('utils.no') + end + when :attachments + raw_value.present? ? 'présent' : 'absent' + when :enum + format_enum(column:, raw_value:) + when :enums + format_enums(column:, raw_values: raw_value) + when :date + raw_value = Date.parse(raw_value) if raw_value.is_a?(String) + I18n.l(raw_value, format: :short) + when :datetime + raw_value = DateTime.parse(raw_value) if raw_value.is_a?(String) + I18n.l(raw_value, format: :short_with_time) + else + raw_value.html_safe? ? raw_value : ERB::Util.html_escape(raw_value.to_s) + end + end + + def format_enums(column:, raw_values:) + ActionController::Base.helpers.safe_join( + raw_values.map { |v| format_enum(column:, raw_value: v) }, + ', ' + ) + end + + def format_enum(column:, raw_value:) + column.label_for_value(raw_value) + end +end diff --git a/app/models/concerns/columns_concern.rb b/app/models/concerns/columns_concern.rb index 85ac7e3bce4..af5c04bb041 100644 --- a/app/models/concerns/columns_concern.rb +++ b/app/models/concerns/columns_concern.rb @@ -281,7 +281,7 @@ def moral_columns end def types_de_champ_columns - all_revisions_types_de_champ.flat_map { _1.columns(procedure_id: id) } + all_revisions_types_de_champ.filter(&:dynamic_type).flat_map { _1.columns(procedure_id: id) } end def dossier_col(**args) = Columns::DossierColumn.new(**(args.merge(procedure_id: id))) diff --git a/app/views/users/dossiers/_dossier_card_content.html.erb b/app/views/users/dossiers/_dossier_card_content.html.erb index e2a50577b39..6d2e3bee713 100644 --- a/app/views/users/dossiers/_dossier_card_content.html.erb +++ b/app/views/users/dossiers/_dossier_card_content.html.erb @@ -76,6 +76,13 @@ <% end %> <% end %> + + <% if local_assigns[:personnalisation].present? %> + <%= render Users::DossierCardChampsComponent.new( + columns: personnalisation.displayed_columns, + champs_by_stable_id: local_assigns[:champs_by_stable_id] || {} + ) %> + <% end %>