Add filtering to the dossiers table

This commit is contained in:
gregoirenovel 2017-09-28 11:04:18 +02:00
parent 801318b053
commit 0705efde30
8 changed files with 164 additions and 12 deletions

View 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

View file

@ -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 {

View file

@ -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;
}
}

View file

@ -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' }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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