Allow the customization of the dossiers table
This commit is contained in:
parent
7036f9778b
commit
e1bdbec815
14 changed files with 311 additions and 5 deletions
|
@ -1,3 +1,9 @@
|
|||
document.addEventListener('turbolinks:load', function() {
|
||||
$('select.select2').select2();
|
||||
|
||||
$('select.select2-limited').select2({
|
||||
'placeholder': 'Sélectionnez des colonnes',
|
||||
'maximumSelectionLength': '2',
|
||||
'width': '300px'
|
||||
});
|
||||
});
|
||||
|
|
|
@ -172,6 +172,26 @@
|
|||
}
|
||||
}
|
||||
|
||||
.dropdown-form {
|
||||
padding: 2 * $default-spacer;
|
||||
|
||||
.select2-container {
|
||||
margin-bottom: 2 * $default-spacer;
|
||||
}
|
||||
|
||||
.select2-selection {
|
||||
border: 1px solid $border-grey;
|
||||
|
||||
&.select2-selection--multiple {
|
||||
border: 1px solid $border-grey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select2-dropdown {
|
||||
border: 1px solid $border-grey;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: $blue;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ module NewGestionnaire
|
|||
def show
|
||||
@procedure = procedure
|
||||
|
||||
@displayed_fields = procedure_presentation.displayed_fields
|
||||
@displayed_fields_values = displayed_fields_values
|
||||
|
||||
@a_suivre_dossiers = procedure
|
||||
.dossiers
|
||||
.includes(:user)
|
||||
|
@ -64,9 +67,33 @@ module NewGestionnaire
|
|||
@archived_dossiers
|
||||
end
|
||||
|
||||
eager_load_displayed_fields
|
||||
|
||||
@dossiers = @dossiers.page([params[:page].to_i, 1].max)
|
||||
end
|
||||
|
||||
def update_displayed_fields
|
||||
values = params[:values]
|
||||
|
||||
if values.nil?
|
||||
values = []
|
||||
end
|
||||
|
||||
fields = values.map do |value|
|
||||
table, column = value.split("/")
|
||||
|
||||
c = procedure.fields.find do |field|
|
||||
field['table'] == table && field['column'] == column
|
||||
end
|
||||
|
||||
c.to_json
|
||||
end
|
||||
|
||||
procedure_presentation.update_attributes(displayed_fields: fields)
|
||||
|
||||
redirect_back(fallback_location: procedure_url(procedure))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def procedure
|
||||
|
@ -85,5 +112,49 @@ module NewGestionnaire
|
|||
redirect_to avis_index_path
|
||||
end
|
||||
end
|
||||
|
||||
def procedure_presentation
|
||||
@procedure_presentation ||= current_gestionnaire.procedure_presentation_for_procedure_id(params[:procedure_id])
|
||||
end
|
||||
|
||||
def displayed_fields_values
|
||||
procedure_presentation.displayed_fields.map do |field|
|
||||
"#{field['table']}/#{field['column']}"
|
||||
end
|
||||
end
|
||||
|
||||
def eager_load_displayed_fields
|
||||
@displayed_fields
|
||||
.reject { |field| field['table'] == 'self' }
|
||||
.group_by do |field|
|
||||
if ['type_de_champ', 'type_de_champ_private'].include?(field['table'])
|
||||
'type_de_champ_group'
|
||||
else
|
||||
field['table']
|
||||
end
|
||||
end.each do |_, fields|
|
||||
|
||||
case fields.first['table']
|
||||
when'france_connect_information'
|
||||
@dossiers = @dossiers.includes({ user: :france_connect_information })
|
||||
when 'type_de_champ', 'type_de_champ_private'
|
||||
if fields.any? { |field| field['table'] == 'type_de_champ' }
|
||||
@dossiers = @dossiers.includes(:champs)
|
||||
end
|
||||
|
||||
if fields.any? { |field| field['table'] == 'type_de_champ_private' }
|
||||
@dossiers = @dossiers.includes(:champs_private)
|
||||
end
|
||||
|
||||
where_conditions = fields.map do |field|
|
||||
"champs.type_de_champ_id = #{field['column']}"
|
||||
end.join(" OR ")
|
||||
|
||||
@dossiers = @dossiers.where(where_conditions)
|
||||
else
|
||||
@dossiers = @dossiers.includes(fields.first['table'])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -330,6 +330,25 @@ class Dossier < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def get_value(table, column)
|
||||
case table
|
||||
when 'self'
|
||||
self.send(column)
|
||||
when 'user'
|
||||
self.user.send(column)
|
||||
when 'france_connect_information'
|
||||
self.user.france_connect_information&.send(column)
|
||||
when 'entreprise'
|
||||
self.entreprise&.send(column)
|
||||
when 'etablissement'
|
||||
self.etablissement&.send(column)
|
||||
when 'type_de_champ'
|
||||
self.champs.find {|c| c.type_de_champ_id == column.to_i }.value
|
||||
when 'type_de_champ_private'
|
||||
self.champs_private.find {|c| c.type_de_champ_id == column.to_i }.value
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_attestation
|
||||
|
|
|
@ -123,6 +123,10 @@ class Gestionnaire < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def procedure_presentation_for_procedure_id(procedure_id)
|
||||
assign_to.find_by(procedure_id: procedure_id).procedure_presentation_or_default
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_couple_table_attr? table, column
|
||||
|
|
|
@ -184,4 +184,61 @@ class Procedure < ActiveRecord::Base
|
|||
def without_continuation_mail_template
|
||||
without_continuation_mail || Mails::WithoutContinuationMail.default
|
||||
end
|
||||
|
||||
def fields
|
||||
fields = [
|
||||
field_hash('Créé le', 'self', 'created_at'),
|
||||
field_hash('Mis à jour le', 'self', 'updated_at'),
|
||||
field_hash('Demandeur', 'user', 'email')
|
||||
]
|
||||
|
||||
fields << [
|
||||
field_hash('Civilité (FC)', 'france_connect_information', 'gender'),
|
||||
field_hash('Prénom (FC)', 'france_connect_information', 'given_name'),
|
||||
field_hash('Nom (FC)', 'france_connect_information', 'family_name')
|
||||
]
|
||||
|
||||
if !for_individual || (for_individual && individual_with_siret)
|
||||
fields << [
|
||||
field_hash('SIREN', 'entreprise', 'siren'),
|
||||
field_hash('Forme juridique', 'entreprise', 'forme_juridique'),
|
||||
field_hash('Nom commercial', 'entreprise', 'nom_commercial'),
|
||||
field_hash('Raison sociale', 'entreprise', 'raison_sociale'),
|
||||
field_hash('SIRET siège social', 'entreprise', 'siret_siege_social'),
|
||||
field_hash('Date de création', 'entreprise', 'date_creation')
|
||||
]
|
||||
|
||||
fields << [
|
||||
field_hash('SIRET', 'etablissement', 'siret'),
|
||||
field_hash('Nom établissement', 'etablissement', 'libelle_naf'),
|
||||
field_hash('Code postal', 'etablissement', 'code_postal')
|
||||
]
|
||||
end
|
||||
|
||||
types_de_champ.reject { |tdc| tdc.type_champ == 'header_section' }.each do |type_de_champ|
|
||||
fields << field_hash(type_de_champ.libelle, 'type_de_champ', type_de_champ.id.to_s)
|
||||
end
|
||||
|
||||
types_de_champ_private.reject { |tdc| tdc.type_champ == 'header_section' }.each do |type_de_champ|
|
||||
fields << field_hash(type_de_champ.libelle, 'type_de_champ_private', type_de_champ.id.to_s)
|
||||
end
|
||||
|
||||
fields.flatten
|
||||
end
|
||||
|
||||
def fields_for_select
|
||||
fields.map do |field|
|
||||
[field['label'], "#{field['table']}/#{field['column']}"]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def field_hash(label, table, column)
|
||||
{
|
||||
'label' => label,
|
||||
'table' => table,
|
||||
'column' => column
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
class ProcedurePresentation < ActiveRecord::Base
|
||||
belongs_to :assign_to
|
||||
|
||||
def displayed_fields
|
||||
read_attribute(:displayed_fields).map do |field|
|
||||
field = JSON.parse(field)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -56,9 +56,23 @@
|
|||
%thead
|
||||
%tr
|
||||
%th.number-col Nº dossier
|
||||
%th Demandeur
|
||||
|
||||
- @displayed_fields.each do |field|
|
||||
%th= field['label']
|
||||
|
||||
%th.status-col Statut
|
||||
%th.follow-col
|
||||
%span.button.dropdown
|
||||
Personnaliser
|
||||
.dropdown-content.fade-in-down
|
||||
= form_tag update_displayed_fields_procedure_path(@procedure), method: :patch, class: 'dropdown-form' do
|
||||
= select_tag :values,
|
||||
options_for_select(@procedure.fields_for_select,
|
||||
selected: @displayed_fields_values),
|
||||
multiple: true,
|
||||
class: 'select2-limited'
|
||||
= submit_tag "Enregistrer", class: 'button'
|
||||
|
||||
%tbody
|
||||
- @dossiers.each do |dossier|
|
||||
%tr
|
||||
|
@ -68,7 +82,12 @@
|
|||
- if @followed_dossiers.with_unread_notifications.include?(dossier)
|
||||
%span.notifications{ 'aria-label': 'notifications' }
|
||||
= dossier.id
|
||||
%td= link_to(dossier.user.email, dossier_path(@procedure, dossier), class: 'cell-link')
|
||||
|
||||
- @displayed_fields.each do |field|
|
||||
%td
|
||||
= link_to(dossier_path(@procedure, dossier), class: 'cell-link') do
|
||||
= dossier.get_value(field['table'], field['column'])
|
||||
|
||||
%td.status-col
|
||||
= link_to(dossier_path(@procedure, dossier), class: 'cell-link') do
|
||||
= render partial: 'status', locals: { dossier: dossier }
|
||||
|
|
|
@ -237,6 +237,8 @@ Rails.application.routes.draw do
|
|||
scope module: 'new_gestionnaire' do
|
||||
resources :procedures, only: [:index, :show], param: :procedure_id do
|
||||
member do
|
||||
patch 'update_displayed_fields'
|
||||
|
||||
resources :dossiers, only: [:show], param: :dossier_id do
|
||||
member do
|
||||
get 'attestation'
|
||||
|
|
|
@ -44,12 +44,18 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
trait :with_type_de_champ_private do
|
||||
after(:build) do |procedure, _evaluator|
|
||||
transient do
|
||||
types_de_champ_private_count 1
|
||||
end
|
||||
|
||||
after(:build) do |procedure, evaluator|
|
||||
evaluator.types_de_champ_private_count.times do
|
||||
type_de_champ = create(:type_de_champ_private)
|
||||
|
||||
procedure.types_de_champ_private << type_de_champ
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
trait :with_type_de_champ_mandatory do
|
||||
after(:build) do |procedure, _evaluator|
|
||||
|
|
|
@ -835,4 +835,28 @@ describe Dossier do
|
|||
it { expect(Dossier.count).to eq(0) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "#get_value" do
|
||||
let(:dossier) { create(:dossier, :with_entreprise, user: user) }
|
||||
|
||||
before do
|
||||
FranceConnectInformation.create(france_connect_particulier_id: 123, user: user, gender: 'male')
|
||||
|
||||
@champ_public = dossier.champs.first
|
||||
@champ_public.value = "kiwi"
|
||||
@champ_public.save
|
||||
|
||||
@champ_private = dossier.champs_private.first
|
||||
@champ_private.value = "banane"
|
||||
@champ_private.save
|
||||
end
|
||||
|
||||
it { expect(dossier.get_value('self', 'created_at')).to eq(dossier.created_at) }
|
||||
it { expect(dossier.get_value('user', 'email')).to eq(user.email) }
|
||||
it { expect(dossier.get_value('france_connect_information', 'gender')).to eq(user.france_connect_information.gender) }
|
||||
it { expect(dossier.get_value('entreprise', 'siren')).to eq(dossier.entreprise.siren) }
|
||||
it { expect(dossier.get_value('etablissement', 'siret')).to eq(dossier.etablissement.siret) }
|
||||
it { expect(dossier.get_value('type_de_champ', @champ_public.type_de_champ.id.to_s)).to eq(dossier.champs.first.value) }
|
||||
it { expect(dossier.get_value('type_de_champ_private', @champ_private.type_de_champ.id.to_s)).to eq(dossier.champs_private.first.value) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -382,4 +382,12 @@ describe Gestionnaire, type: :model do
|
|||
it { is_expected.to eq({ }) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "procedure_presentation_for_procedure_id" do
|
||||
let!(:procedure_assign_2) { create :assign_to, gestionnaire: gestionnaire, procedure: procedure_2 }
|
||||
let!(:pp) { ProcedurePresentation.create(assign_to: procedure_assign) }
|
||||
|
||||
it { expect(gestionnaire.procedure_presentation_for_procedure_id(procedure.id)).to eq(pp)}
|
||||
it { expect(gestionnaire.procedure_presentation_for_procedure_id(procedure_2.id).persisted?).to be_falsey}
|
||||
end
|
||||
end
|
||||
|
|
13
spec/models/procedure_presentation_spec.rb
Normal file
13
spec/models/procedure_presentation_spec.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ProcedurePresentation do
|
||||
let (:procedure_presentation_id) { ProcedurePresentation.create(displayed_fields: [
|
||||
{ "label" => "test1", "table" => "user" }.to_json,
|
||||
{ "label" => "test2", "table" => "champs" }.to_json]
|
||||
).id }
|
||||
let (:procedure_presentation) { ProcedurePresentation.find(procedure_presentation_id) }
|
||||
|
||||
describe "#displayed_fields" do
|
||||
it { expect(procedure_presentation.displayed_fields).to eq([{"label" => "test1", "table" => "user"}, {"label" => "test2", "table" => "champs"}]) }
|
||||
end
|
||||
end
|
|
@ -421,4 +421,55 @@ describe Procedure do
|
|||
it { expect(Dossier.count).to eq(0) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fields" do
|
||||
subject { create(:procedure, :with_type_de_champ, :with_type_de_champ_private, :types_de_champ_count => 2, :types_de_champ_private_count => 2) }
|
||||
let(:tdc_1) { subject.types_de_champ.first }
|
||||
let(:tdc_2) { subject.types_de_champ.last }
|
||||
let(:tdc_private_1) { subject.types_de_champ_private.first }
|
||||
let(:tdc_private_2) { subject.types_de_champ_private.last }
|
||||
let(:expected) {
|
||||
[
|
||||
{ "label" => 'Créé le', "table" => 'self', "column" => 'created_at' },
|
||||
{ "label" => 'Mis à jour le', "table" => 'self', "column" => 'updated_at' },
|
||||
{ "label" => 'Demandeur', "table" => 'user', "column" => 'email' },
|
||||
{ "label" => 'Civilité (FC)', "table" => 'france_connect_information', "column" => 'gender' },
|
||||
{ "label" => 'Prénom (FC)', "table" => 'france_connect_information', "column" => 'given_name' },
|
||||
{ "label" => 'Nom (FC)', "table" => 'france_connect_information', "column" => 'family_name' },
|
||||
{ "label" => 'SIREN', "table" => 'entreprise', "column" => 'siren' },
|
||||
{ "label" => 'Forme juridique', "table" => 'entreprise', "column" => 'forme_juridique' },
|
||||
{ "label" => 'Nom commercial', "table" => 'entreprise', "column" => 'nom_commercial' },
|
||||
{ "label" => 'Raison sociale', "table" => 'entreprise', "column" => 'raison_sociale' },
|
||||
{ "label" => 'SIRET siège social', "table" => 'entreprise', "column" => 'siret_siege_social' },
|
||||
{ "label" => 'Date de création', "table" => 'entreprise', "column" => 'date_creation' },
|
||||
{ "label" => 'SIRET', "table" => 'etablissement', "column" => 'siret' },
|
||||
{ "label" => 'Nom établissement', "table" => 'etablissement', "column" => 'libelle_naf' },
|
||||
{ "label" => 'Code postal', "table" => 'etablissement', "column" => 'code_postal' },
|
||||
{ "label" => tdc_1.libelle, "table" => 'type_de_champ', "column" => tdc_1.id.to_s },
|
||||
{ "label" => tdc_2.libelle, "table" => 'type_de_champ', "column" => tdc_2.id.to_s },
|
||||
{ "label" => tdc_private_1.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_1.id.to_s },
|
||||
{ "label" => tdc_private_2.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_2.id.to_s }
|
||||
]
|
||||
}
|
||||
|
||||
it { expect(subject.fields).to eq(expected) }
|
||||
end
|
||||
|
||||
describe "#fields_for_select" do
|
||||
subject { create(:procedure) }
|
||||
|
||||
before do
|
||||
allow(subject).to receive(:fields).and_return([{
|
||||
"label" => "label1",
|
||||
"table" => "table1",
|
||||
"column" => "column1"
|
||||
}, {
|
||||
"label" => "label2",
|
||||
"table" => "table2",
|
||||
"column" => "column2"
|
||||
}])
|
||||
end
|
||||
|
||||
it { expect(subject.fields_for_select).to eq([["label1", "table1/column1"], ["label2", "table2/column2"]]) }
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue