use displayed_columns !
This commit is contained in:
parent
7e4ca07df2
commit
14fe11b612
9 changed files with 78 additions and 97 deletions
|
@ -12,7 +12,7 @@ class Instructeurs::ColumnPickerComponent < ApplicationComponent
|
|||
def displayable_columns_for_select
|
||||
[
|
||||
procedure.columns.filter(&:displayable).map { |column| [column.label, column.id] },
|
||||
procedure_presentation.displayed_fields.map { Column.new(**_1.deep_symbolize_keys.merge(procedure_id: procedure.id)).id }
|
||||
procedure_presentation.displayed_columns.map(&:id)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -104,7 +104,7 @@ module Instructeurs
|
|||
.page(page)
|
||||
.per(ITEMS_PER_PAGE)
|
||||
|
||||
@projected_dossiers = DossierProjectionService.project(@filtered_sorted_paginated_ids, procedure_presentation.displayed_fields)
|
||||
@projected_dossiers = DossierProjectionService.project(@filtered_sorted_paginated_ids, procedure_presentation.displayed_columns)
|
||||
@disable_checkbox_all = @projected_dossiers.all? { _1.batch_operation_id.present? }
|
||||
|
||||
@batch_operations = BatchOperation.joins(:groupe_instructeurs)
|
||||
|
@ -133,9 +133,9 @@ module Instructeurs
|
|||
end
|
||||
|
||||
def update_displayed_fields
|
||||
values = (params['values'].presence || []).reject(&:empty?)
|
||||
ids = (params['values'].presence || []).reject(&:empty?)
|
||||
|
||||
procedure_presentation.update_displayed_fields(values)
|
||||
procedure_presentation.update!(displayed_columns: ids)
|
||||
|
||||
redirect_back(fallback_location: instructeur_procedure_url(procedure))
|
||||
end
|
||||
|
|
|
@ -3,10 +3,14 @@
|
|||
class RechercheController < ApplicationController
|
||||
before_action :authenticate_logged_user!
|
||||
ITEMS_PER_PAGE = 25
|
||||
|
||||
# the columns are generally procedure specific
|
||||
# but in the search context, we are looking for dossiers from multiple procedures
|
||||
# so we are faking the columns with a random procedure_id
|
||||
PROJECTIONS = [
|
||||
{ "table" => 'procedure', "column" => 'libelle' },
|
||||
{ "table" => 'user', "column" => 'email' },
|
||||
{ "table" => 'procedure', "column" => 'procedure_id' }
|
||||
Column.new(procedure_id: 666, table: 'procedure', column: 'libelle'),
|
||||
Column.new(procedure_id: 666, table: 'user', column: 'email'),
|
||||
Column.new(procedure_id: 666, table: 'procedure', column: 'procedure_id')
|
||||
]
|
||||
|
||||
def nav_bar_profile
|
||||
|
|
|
@ -21,6 +21,8 @@ class ProcedurePresentation < ApplicationRecord
|
|||
validate :check_filters_max_length
|
||||
validate :check_filters_max_integer
|
||||
|
||||
attribute :displayed_columns, :column, array: true
|
||||
|
||||
attribute :sorted_column, :sorted_column
|
||||
def sorted_column = super || procedure.default_sorted_column # Dummy override to set default value
|
||||
|
||||
|
@ -42,7 +44,7 @@ class ProcedurePresentation < ApplicationRecord
|
|||
def displayed_fields_for_headers
|
||||
[
|
||||
Column.new(procedure_id: procedure.id, table: 'self', column: 'id', classname: 'number-col'),
|
||||
*displayed_fields.map { Column.new(**_1.deep_symbolize_keys.merge(procedure_id: procedure.id)) },
|
||||
*displayed_columns,
|
||||
Column.new(procedure_id: procedure.id, table: 'self', column: 'state', classname: 'state-col'),
|
||||
*procedure.sva_svr_columns
|
||||
]
|
||||
|
|
|
@ -40,8 +40,10 @@ class DossierProjectionService
|
|||
# Those hashes are needed because:
|
||||
# - the order of the intermediary query results are unknown
|
||||
# - some values can be missing (if a revision added or removed them)
|
||||
def self.project(dossiers_ids, fields)
|
||||
fields = fields.deep_dup
|
||||
def self.project(dossiers_ids, columns)
|
||||
fields = columns.map { |c| { TABLE => c.table, COLUMN => c.column } }
|
||||
champ_value = champ_value_formatter(dossiers_ids, fields)
|
||||
|
||||
state_field = { TABLE => 'self', COLUMN => 'state' }
|
||||
archived_field = { TABLE => 'self', COLUMN => 'archived' }
|
||||
batch_operation_field = { TABLE => 'self', COLUMN => 'batch_operation_id' }
|
||||
|
@ -53,7 +55,7 @@ class DossierProjectionService
|
|||
individual_last_name = { TABLE => 'individual', COLUMN => 'nom' }
|
||||
sva_svr_decision_on_field = { TABLE => 'self', COLUMN => 'sva_svr_decision_on' }
|
||||
dossier_corrections = { TABLE => 'dossier_corrections', COLUMN => 'resolved_at' }
|
||||
champ_value = champ_value_formatter(dossiers_ids, fields)
|
||||
|
||||
([state_field, archived_field, sva_svr_decision_on_field, hidden_by_user_at_field, hidden_by_administration_at_field, hidden_by_reason_field, for_tiers_field, individual_first_name, individual_last_name, batch_operation_field, dossier_corrections] + fields)
|
||||
.each { |f| f[:id_value_h] = {} }
|
||||
.group_by { |f| f[TABLE] } # one query per table
|
||||
|
|
|
@ -38,10 +38,7 @@ describe '20240920130741_migrate_procedure_presentation_to_columns.rake' do
|
|||
it 'populates the columns' do
|
||||
procedure_id = procedure.id
|
||||
|
||||
expect(procedure_presentation.displayed_columns).to eq([
|
||||
{ "procedure_id" => procedure_id, "column_id" => "etablissement/entreprise_raison_sociale" },
|
||||
{ "procedure_id" => procedure_id, "column_id" => "type_de_champ/#{stable_id}" }
|
||||
])
|
||||
expect(procedure_presentation.displayed_columns.map(&:label)).to eq(["Raison sociale", procedure.active_revision.types_de_champ.first.libelle])
|
||||
|
||||
order, column_id = procedure_presentation
|
||||
.sorted_column
|
||||
|
|
|
@ -167,20 +167,6 @@ describe Instructeur, type: :model do
|
|||
it { expect(errors).to be_nil }
|
||||
end
|
||||
|
||||
context 'with invalid presentation' do
|
||||
let(:procedure_id) { procedure.id }
|
||||
before do
|
||||
pp = ProcedurePresentation.create(assign_to: procedure_assign, displayed_fields: [{ 'table' => 'invalid', 'column' => 'random' }])
|
||||
pp.save(:validate => false)
|
||||
end
|
||||
|
||||
it 'recreates a valid prsentation' do
|
||||
expect(procedure_presentation).to be_persisted
|
||||
end
|
||||
it { expect(procedure_presentation).to be_valid }
|
||||
it { expect(errors).to be_present }
|
||||
end
|
||||
|
||||
context 'with default presentation' do
|
||||
let(:procedure_id) { procedure_2.id }
|
||||
|
||||
|
|
|
@ -40,8 +40,11 @@ describe ProcedurePresentation do
|
|||
describe 'validation' do
|
||||
it { expect(build(:procedure_presentation)).to be_valid }
|
||||
|
||||
context 'of displayed fields' do
|
||||
it { expect(build(:procedure_presentation, displayed_fields: [{ table: "user", column: "reset_password_token", "order" => "asc" }])).to be_invalid }
|
||||
context 'of displayed columns' do
|
||||
it do
|
||||
pp = build(:procedure_presentation, displayed_columns: [{ table: "user", column: "reset_password_token", procedure_id: }])
|
||||
expect { pp.displayed_columns }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
context 'of filters' do
|
||||
|
@ -795,6 +798,9 @@ describe ProcedurePresentation do
|
|||
end
|
||||
|
||||
describe '#update_displayed_fields' do
|
||||
let(:en_construction_column) { procedure.find_column(label: 'En construction le') }
|
||||
let(:mise_a_jour_column) { procedure.find_column(label: 'Mis à jour le') }
|
||||
|
||||
let(:procedure_presentation) do
|
||||
create(:procedure_presentation, assign_to:).tap do |pp|
|
||||
pp.update(sorted_column: SortedColumn.new(column: procedure.find_column(label: 'Demandeur'), order: 'desc'))
|
||||
|
@ -802,24 +808,19 @@ describe ProcedurePresentation do
|
|||
end
|
||||
|
||||
subject do
|
||||
procedure_presentation.update_displayed_fields([
|
||||
procedure.find_column(label: 'En construction le').id,
|
||||
procedure.find_column(label: 'Mis à jour le').id
|
||||
procedure_presentation.update(displayed_columns: [
|
||||
en_construction_column.id, mise_a_jour_column.id
|
||||
])
|
||||
end
|
||||
|
||||
it 'should update displayed_fields' do
|
||||
expect(procedure_presentation.displayed_columns).to eq([])
|
||||
expect(procedure_presentation.displayed_columns).to eq(procedure.default_displayed_columns)
|
||||
|
||||
subject
|
||||
|
||||
expect(procedure_presentation.displayed_columns).to eq([
|
||||
{ "column_id" => "self/en_construction_at", "procedure_id" => procedure.id },
|
||||
{ "column_id" => "self/updated_at", "procedure_id" => procedure.id }
|
||||
en_construction_column, mise_a_jour_column
|
||||
])
|
||||
|
||||
expect(procedure_presentation.sorted_column).to eq(procedure.default_sorted_column)
|
||||
expect(procedure_presentation.sorted_column.order).to eq('desc')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
describe DossierProjectionService do
|
||||
describe '#project' do
|
||||
subject { described_class.project(dossiers_ids, fields) }
|
||||
subject { described_class.project(dossiers_ids, columns) }
|
||||
|
||||
context 'with multiple dossier' do
|
||||
let!(:procedure) { create(:procedure, types_de_champ_public: [{}, { type: :linked_drop_down_list }]) }
|
||||
|
@ -11,12 +11,9 @@ describe DossierProjectionService do
|
|||
let!(:dossier_3) { create(:dossier, :en_instruction, procedure: procedure) }
|
||||
|
||||
let(:dossiers_ids) { [dossier_3.id, dossier_1.id, dossier_2.id] }
|
||||
let(:fields) do
|
||||
let(:columns) do
|
||||
procedure.active_revision.types_de_champ_public.map do |type_de_champ|
|
||||
{
|
||||
"table" => "type_de_champ",
|
||||
"column" => type_de_champ.stable_id.to_s
|
||||
}
|
||||
procedure.find_column(label: type_de_champ.libelle)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -55,12 +52,9 @@ describe DossierProjectionService do
|
|||
let!(:dossier) { create(:dossier, procedure:) }
|
||||
|
||||
let(:dossiers_ids) { [dossier.id] }
|
||||
let(:fields) do
|
||||
let(:columns) do
|
||||
[
|
||||
{
|
||||
"table" => "type_de_champ",
|
||||
"column" => procedure.active_revision.types_de_champ_public[0].stable_id.to_s
|
||||
}
|
||||
procedure.find_column(label: procedure.active_revision.types_de_champ_public[0].libelle)
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -78,38 +72,37 @@ describe DossierProjectionService do
|
|||
end
|
||||
|
||||
context 'attributes by attributes' do
|
||||
let(:fields) { [{ "table" => table, "column" => column }] }
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:columns) { [procedure.find_column(label:)] }
|
||||
let(:dossiers_ids) { [dossier.id] }
|
||||
|
||||
subject { super()[0].columns[0] }
|
||||
|
||||
context 'for self table' do
|
||||
let(:table) { 'self' }
|
||||
|
||||
context 'for created_at column' do
|
||||
let(:column) { 'created_at' }
|
||||
let(:dossier) { Timecop.freeze(Time.zone.local(1992, 3, 22)) { create(:dossier) } }
|
||||
let(:label) { 'Créé le' }
|
||||
let(:dossier) { Timecop.freeze(Time.zone.local(1992, 3, 22)) { create(:dossier, procedure:) } }
|
||||
|
||||
it { is_expected.to eq('22/03/1992') }
|
||||
end
|
||||
|
||||
context 'for en_construction_at column' do
|
||||
let(:column) { 'en_construction_at' }
|
||||
let(:dossier) { create(:dossier, :en_construction, en_construction_at: Time.zone.local(2018, 10, 17)) }
|
||||
let(:label) { 'En construction le' }
|
||||
let(:dossier) { create(:dossier, :en_construction, en_construction_at: Time.zone.local(2018, 10, 17), procedure:) }
|
||||
|
||||
it { is_expected.to eq('17/10/2018') }
|
||||
end
|
||||
|
||||
context 'for depose_at column' do
|
||||
let(:column) { 'depose_at' }
|
||||
let(:dossier) { create(:dossier, :en_construction, depose_at: Time.zone.local(2018, 10, 17)) }
|
||||
let(:label) { 'Déposé le' }
|
||||
let(:dossier) { create(:dossier, :en_construction, depose_at: Time.zone.local(2018, 10, 17), procedure:) }
|
||||
|
||||
it { is_expected.to eq('17/10/2018') }
|
||||
end
|
||||
|
||||
context 'for updated_at column' do
|
||||
let(:column) { 'updated_at' }
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:label) { 'Mis à jour le' }
|
||||
let(:dossier) { create(:dossier, procedure:) }
|
||||
|
||||
before { dossier.touch(time: Time.zone.local(2018, 9, 25)) }
|
||||
|
||||
|
@ -118,61 +111,56 @@ describe DossierProjectionService do
|
|||
end
|
||||
|
||||
context 'for user table' do
|
||||
let(:table) { 'user' }
|
||||
let(:column) { 'email' }
|
||||
let(:label) { 'Demandeur' }
|
||||
|
||||
let(:dossier) { create(:dossier, user: create(:user, email: 'bla@yopmail.com')) }
|
||||
let(:dossier) { create(:dossier, user: create(:user, email: 'bla@yopmail.com'), procedure:) }
|
||||
|
||||
it { is_expected.to eq('bla@yopmail.com') }
|
||||
end
|
||||
|
||||
context 'for individual table' do
|
||||
let(:table) { 'individual' }
|
||||
let(:procedure) { create(:procedure, :for_individual, :with_type_de_champ, :with_type_de_champ_private) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure, individual: build(:individual, nom: 'Martin', prenom: 'Jacques', gender: 'M.')) }
|
||||
let(:dossier) { create(:dossier, procedure:, individual: build(:individual, nom: 'Martin', prenom: 'Jacques', gender: 'M.')) }
|
||||
|
||||
context 'for prenom column' do
|
||||
let(:column) { 'prenom' }
|
||||
let(:label) { 'Prénom' }
|
||||
|
||||
it { is_expected.to eq('Jacques') }
|
||||
end
|
||||
|
||||
context 'for nom column' do
|
||||
let(:column) { 'nom' }
|
||||
let(:label) { 'Nom' }
|
||||
|
||||
it { is_expected.to eq('Martin') }
|
||||
end
|
||||
|
||||
context 'for gender column' do
|
||||
let(:column) { 'gender' }
|
||||
let(:label) { 'Civilité' }
|
||||
|
||||
it { is_expected.to eq('M.') }
|
||||
end
|
||||
end
|
||||
|
||||
context 'for etablissement table' do
|
||||
let(:table) { 'etablissement' }
|
||||
let(:column) { 'code_postal' } # All other columns work the same, no extra test required
|
||||
let(:label) { 'Code postal' }
|
||||
|
||||
let!(:dossier) { create(:dossier, etablissement: create(:etablissement, code_postal: '75008')) }
|
||||
let!(:dossier) { create(:dossier, procedure:, etablissement: create(:etablissement, code_postal: '75008')) }
|
||||
|
||||
it { is_expected.to eq('75008') }
|
||||
end
|
||||
|
||||
context 'for groupe_instructeur table' do
|
||||
let(:table) { 'groupe_instructeur' }
|
||||
let(:column) { 'label' }
|
||||
let(:label) { 'Groupe instructeur' }
|
||||
|
||||
let!(:dossier) { create(:dossier) }
|
||||
let!(:dossier) { create(:dossier, procedure:) }
|
||||
|
||||
it { is_expected.to eq('défaut') }
|
||||
end
|
||||
|
||||
context 'for followers_instructeurs table' do
|
||||
let(:table) { 'followers_instructeurs' }
|
||||
let(:column) { 'email' }
|
||||
let(:label) { 'Email instructeur' }
|
||||
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:dossier) { create(:dossier, procedure:) }
|
||||
let!(:follow1) { create(:follow, dossier: dossier, instructeur: create(:instructeur, email: 'b@host.fr')) }
|
||||
let!(:follow2) { create(:follow, dossier: dossier, instructeur: create(:instructeur, email: 'a@host.fr')) }
|
||||
let!(:follow3) { create(:follow, dossier: dossier, instructeur: create(:instructeur, email: 'c@host.fr')) }
|
||||
|
@ -181,19 +169,21 @@ describe DossierProjectionService do
|
|||
end
|
||||
|
||||
context 'for type_de_champ table' do
|
||||
let(:table) { 'type_de_champ' }
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:column) { dossier.procedure.active_revision.types_de_champ_public.first.stable_id.to_s }
|
||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :text }]) }
|
||||
let(:dossier) { create(:dossier, procedure:) }
|
||||
let(:label) { dossier.procedure.active_revision.types_de_champ_public.first.libelle }
|
||||
|
||||
before { dossier.project_champs_public.first.update(value: 'kale') }
|
||||
before do
|
||||
dossier.project_champs_public.first.update(value: 'kale')
|
||||
end
|
||||
|
||||
it { is_expected.to eq('kale') }
|
||||
end
|
||||
|
||||
context 'for type_de_champ_private table' do
|
||||
let(:table) { 'type_de_champ_private' }
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:column) { dossier.procedure.active_revision.types_de_champ_private.first.stable_id.to_s }
|
||||
let(:procedure) { create(:procedure, types_de_champ_private: [{ type: :text }]) }
|
||||
let(:dossier) { create(:dossier, procedure:) }
|
||||
let(:label) { dossier.procedure.active_revision.types_de_champ_private.first.libelle }
|
||||
|
||||
before { dossier.project_champs_private.first.update(value: 'quinoa') }
|
||||
|
||||
|
@ -201,10 +191,9 @@ describe DossierProjectionService do
|
|||
end
|
||||
|
||||
context 'for type_de_champ table and value to.s' do
|
||||
let(:table) { 'type_de_champ' }
|
||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :yes_no }]) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
let(:column) { dossier.procedure.active_revision.types_de_champ_public.first.stable_id.to_s }
|
||||
let(:dossier) { create(:dossier, procedure:) }
|
||||
let(:label) { dossier.procedure.active_revision.types_de_champ_public.first.libelle }
|
||||
|
||||
before { dossier.project_champs_public.first.update(value: 'true') }
|
||||
|
||||
|
@ -212,10 +201,9 @@ describe DossierProjectionService do
|
|||
end
|
||||
|
||||
context 'for type_de_champ table and value to.s which needs data field' do
|
||||
let(:table) { 'type_de_champ' }
|
||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :address }]) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
let(:column) { dossier.procedure.active_revision.types_de_champ_public.first.stable_id.to_s }
|
||||
let(:dossier) { create(:dossier, procedure:) }
|
||||
let(:label) { dossier.procedure.active_revision.types_de_champ_public.first.libelle }
|
||||
|
||||
before { dossier.project_champs_public.first.update(value: '18 a la bonne rue', data: { 'label' => '18 a la bonne rue', 'departement' => 'd' }) }
|
||||
|
||||
|
@ -223,10 +211,9 @@ describe DossierProjectionService do
|
|||
end
|
||||
|
||||
context 'for type_de_champ table: type_de_champ pays which needs external_id field' do
|
||||
let(:table) { 'type_de_champ' }
|
||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :pays }]) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
let(:column) { dossier.procedure.active_revision.types_de_champ_public.first.stable_id.to_s }
|
||||
let(:dossier) { create(:dossier, procedure:) }
|
||||
let(:label) { dossier.procedure.active_revision.types_de_champ_public.first.libelle }
|
||||
|
||||
around do |example|
|
||||
I18n.with_locale(:fr) do
|
||||
|
@ -254,8 +241,10 @@ describe DossierProjectionService do
|
|||
context 'for dossier corrections table' do
|
||||
let(:table) { 'dossier_corrections' }
|
||||
let(:column) { 'resolved_at' }
|
||||
let(:dossier) { create(:dossier, :en_construction) }
|
||||
subject { described_class.project(dossiers_ids, fields)[0] }
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:columns) { [Column.new(procedure_id: procedure.id, table:, column:)] } # should somehow be present in column concern
|
||||
let(:dossier) { create(:dossier, :en_construction, procedure:) }
|
||||
subject { described_class.project(dossiers_ids, columns)[0] }
|
||||
|
||||
context "when dossier has pending correction" do
|
||||
before { create(:dossier_correction, dossier:) }
|
||||
|
|
Loading…
Reference in a new issue