Add filtering to the dossiers table
This commit is contained in:
parent
801318b053
commit
0705efde30
8 changed files with 164 additions and 12 deletions
1
app/assets/images/close.svg
Normal file
1
app/assets/images/close.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="14" height="14" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g stroke="#FFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12.749 1L1 12.75M12.749 12.75L1 1"/></g><path d="M-5-5h24v24H-5z"/></g></svg>
|
After Width: | Height: | Size: 286 B |
|
@ -104,6 +104,11 @@
|
|||
cursor: default;
|
||||
z-index: 10;
|
||||
|
||||
&.left-aligned {
|
||||
left: 0;
|
||||
right: unset;
|
||||
}
|
||||
|
||||
&.terminated {
|
||||
width: 600px;
|
||||
color: $black;
|
||||
|
@ -186,6 +191,22 @@
|
|||
border: 1px solid $border-grey;
|
||||
}
|
||||
}
|
||||
|
||||
&.large {
|
||||
width: 340px;
|
||||
}
|
||||
|
||||
label {
|
||||
width: 100px;
|
||||
display: inline-block;
|
||||
margin-bottom: 2 * $default-spacer;
|
||||
}
|
||||
|
||||
input,
|
||||
select {
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.select2-dropdown {
|
||||
|
|
|
@ -26,4 +26,22 @@
|
|||
min-width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter {
|
||||
display: inline-block;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
background-color: $light-blue;
|
||||
border-radius: 4px;
|
||||
color: #FFFFFF;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
vertical-align: top;
|
||||
margin-top: 12px;
|
||||
margin-left: 6px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ module NewGestionnaire
|
|||
def show
|
||||
@procedure = procedure
|
||||
|
||||
@current_filters = current_filters
|
||||
@available_fields_to_filters = available_fields_to_filters
|
||||
@displayed_fields = procedure_presentation.displayed_fields
|
||||
@displayed_fields_values = displayed_fields_values
|
||||
|
||||
|
@ -69,20 +71,27 @@ module NewGestionnaire
|
|||
|
||||
sorted_ids = sorted_ids(@dossiers)
|
||||
|
||||
if @current_filters.count > 0
|
||||
filtered_ids = filtered_ids(@dossiers)
|
||||
filtered_sorted_ids = sorted_ids.select { |id| filtered_ids.include?(id) }
|
||||
else
|
||||
filtered_sorted_ids = sorted_ids
|
||||
end
|
||||
|
||||
page = params[:page].present? ? params[:page] : 1
|
||||
|
||||
sorted_paginated_ids = Kaminari
|
||||
.paginate_array(sorted_ids)
|
||||
filtered_sorted_paginated_ids = Kaminari
|
||||
.paginate_array(filtered_sorted_ids)
|
||||
.page(page)
|
||||
.per(ITEMS_PER_PAGE)
|
||||
|
||||
@dossiers = @dossiers.where(id: sorted_paginated_ids)
|
||||
@dossiers = @dossiers.where(id: filtered_sorted_paginated_ids)
|
||||
|
||||
eager_load_displayed_fields
|
||||
|
||||
@dossiers = @dossiers.sort_by { |d| sorted_paginated_ids.index(d.id) }
|
||||
@dossiers = @dossiers.sort_by { |d| filtered_sorted_paginated_ids.index(d.id) }
|
||||
|
||||
kaminarize(page, sorted_ids.count)
|
||||
kaminarize(page, filtered_sorted_ids.count)
|
||||
end
|
||||
|
||||
def update_displayed_fields
|
||||
|
@ -134,6 +143,36 @@ module NewGestionnaire
|
|||
redirect_back(fallback_location: procedure_url(procedure))
|
||||
end
|
||||
|
||||
def add_filter
|
||||
filters = procedure_presentation.filters
|
||||
table, column = params[:field].split('/')
|
||||
label = procedure.fields.find { |c| c['table'] == table && c['column'] == column }['label']
|
||||
|
||||
filters[statut] << {
|
||||
'label' => label,
|
||||
'table' => table,
|
||||
'column' => column,
|
||||
'value' => params[:value]
|
||||
}
|
||||
|
||||
procedure_presentation.update_attributes(filters: filters.to_json)
|
||||
|
||||
redirect_back(fallback_location: procedure_url(procedure))
|
||||
end
|
||||
|
||||
def remove_filter
|
||||
filters = procedure_presentation.filters
|
||||
filter_to_remove = current_filters.find do |filter|
|
||||
filter['table'] == params[:table] && filter['column'] == params[:column]
|
||||
end
|
||||
|
||||
filters[statut] = filters[statut] - [filter_to_remove]
|
||||
|
||||
procedure_presentation.update_attributes(filters: filters.to_json)
|
||||
|
||||
redirect_back(fallback_location: procedure_url(procedure))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def statut
|
||||
|
@ -167,6 +206,33 @@ module NewGestionnaire
|
|||
end
|
||||
end
|
||||
|
||||
def filtered_ids(dossiers)
|
||||
current_filters.map do |filter|
|
||||
case filter['table']
|
||||
when 'self'
|
||||
dossiers.where("? LIKE ?", filter['column'], "%#{filter['value']}%")
|
||||
|
||||
when 'france_connect_information'
|
||||
dossiers
|
||||
.includes(user: :france_connect_information)
|
||||
.where("? LIKE ?", "france_connect_informations.#{filter['column']}", "%#{filter['value']}%")
|
||||
|
||||
when 'type_de_champ', 'type_de_champ_private'
|
||||
relation = filter['table'] == 'type_de_champ' ? :champs : :champs_private
|
||||
dossiers
|
||||
.includes(relation)
|
||||
.where("champs.type_de_champ_id = ?", filter['column'].to_i)
|
||||
.where("champs.value LIKE ?", "%#{filter['value']}%")
|
||||
|
||||
when 'user', 'etablissement', 'entreprise'
|
||||
dossiers
|
||||
.includes(filter['table'])
|
||||
.where("#{filter['table'].pluralize}.#{filter['column']} LIKE ?", "%#{filter['value']}%")
|
||||
|
||||
end.pluck(:id)
|
||||
end.reduce(:&)
|
||||
end
|
||||
|
||||
def sorted_ids(dossiers)
|
||||
table = procedure_presentation.sort['table']
|
||||
column = procedure_presentation.sort['column']
|
||||
|
@ -192,6 +258,20 @@ module NewGestionnaire
|
|||
dossiers.includes(includes).where(where).order(Dossier.sanitize_for_order(order)).pluck(:id)
|
||||
end
|
||||
|
||||
def current_filters
|
||||
@current_filters ||= procedure_presentation.filters[statut]
|
||||
end
|
||||
|
||||
def available_fields_to_filters
|
||||
current_filters_fields_ids = current_filters.map do |field|
|
||||
"#{field['table']}/#{field['column']}"
|
||||
end
|
||||
|
||||
procedure.fields_for_select.reject do |field|
|
||||
current_filters_fields_ids.include?(field[1])
|
||||
end
|
||||
end
|
||||
|
||||
def eager_load_displayed_fields
|
||||
@displayed_fields
|
||||
.reject { |field| field['table'] == 'self' }
|
||||
|
|
|
@ -10,4 +10,8 @@ class ProcedurePresentation < ActiveRecord::Base
|
|||
def sort
|
||||
JSON.parse(read_attribute(:sort))
|
||||
end
|
||||
|
||||
def filters
|
||||
JSON.parse(read_attribute(:filters))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,7 +51,26 @@
|
|||
= link_to "Au format .ods", backoffice_download_dossiers_tps_path(format: :ods, procedure_id: @procedure.id), target: "_blank"
|
||||
|
||||
.container
|
||||
- if @dossiers.present?
|
||||
- if @dossiers.present? || @current_filters.count > 0
|
||||
%span.button.dropdown
|
||||
Filtrer
|
||||
.dropdown-content.left-aligned.fade-in-down
|
||||
= form_tag add_filter_procedure_path(@procedure), method: :post, class: 'dropdown-form large' do
|
||||
= label_tag :field, "Colonne"
|
||||
= select_tag :field, options_for_select(@available_fields_to_filters)
|
||||
%br
|
||||
= label_tag :value, "Valeur"
|
||||
= text_field_tag :value
|
||||
= hidden_field_tag :statut, @statut
|
||||
%br
|
||||
= submit_tag "Ajouter le filtre", class: 'button'
|
||||
|
||||
- @current_filters.each do |filter|
|
||||
%span.filter
|
||||
= "#{filter['label']} : #{filter['value']}"
|
||||
= link_to remove_filter_procedure_path(@procedure, statut: @statut, table: filter['table'], column: filter['column']) do
|
||||
%img.close-icon{ src: image_url("close.svg") }
|
||||
|
||||
%table.table.dossiers-table.hoverable
|
||||
%thead
|
||||
%tr
|
||||
|
|
|
@ -239,6 +239,8 @@ Rails.application.routes.draw do
|
|||
member do
|
||||
patch 'update_displayed_fields'
|
||||
get 'update_sort/:table/:column' => 'procedures#update_sort', as: 'update_sort'
|
||||
post 'add_filter'
|
||||
get 'remove_filter/:statut/:table/:column' => 'procedures#remove_filter', as: 'remove_filter'
|
||||
|
||||
resources :dossiers, only: [:show], param: :dossier_id do
|
||||
member do
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
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],
|
||||
sort: { "table" => "user","column" => "email","order" => "asc" }.to_json
|
||||
).id }
|
||||
let (:procedure_presentation_id) {
|
||||
ProcedurePresentation.create(
|
||||
displayed_fields: [
|
||||
{ "label" => "test1", "table" => "user" }.to_json,
|
||||
{ "label" => "test2", "table" => "champs" }.to_json],
|
||||
sort: { "table" => "user","column" => "email","order" => "asc" }.to_json,
|
||||
filters: { "a-suivre" => [], "suivis" => [{ "label" => "label1", "table" => "table1", "column" => "column1" }] }.to_json
|
||||
).id
|
||||
}
|
||||
let (:procedure_presentation) { ProcedurePresentation.find(procedure_presentation_id) }
|
||||
|
||||
describe "#displayed_fields" do
|
||||
|
@ -16,4 +19,8 @@ describe ProcedurePresentation do
|
|||
describe "#sort" do
|
||||
it { expect(procedure_presentation.sort).to eq({ "table" => "user","column" => "email","order" => "asc" }) }
|
||||
end
|
||||
|
||||
describe "#filters" do
|
||||
it { expect(procedure_presentation.filters).to eq({ "a-suivre" => [], "suivis" => [{ "label" => "label1", "table" => "table1", "column" => "column1" }] }) }
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue