Add field sort to the dossiers table

This commit is contained in:
gregoirenovel 2017-09-27 15:16:07 +02:00
parent 88ad986143
commit 3df9356021
11 changed files with 156 additions and 25 deletions

View file

@ -0,0 +1 @@
<svg width="10" height="6" viewBox="0 0 10 6" xmlns="http://www.w3.org/2000/svg"><title>ic_dropdown</title><g fill="none" fill-rule="evenodd"><path stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M1 1l4 4 4-4"/><path d="M-7-9h24v24H-7z"/></g></svg>

After

Width:  |  Height:  |  Size: 281 B

View file

@ -0,0 +1 @@
<svg width="10" height="6" viewBox="0 0 10 6" xmlns="http://www.w3.org/2000/svg"><title>ic_dropdown</title><g fill="none" fill-rule="evenodd"><path stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M1 5l4-4 4 4"/><path d="M-7 15h24V-9H-7z"/></g></svg>

After

Width:  |  Height:  |  Size: 282 B

View file

@ -6,6 +6,16 @@
padding: 0;
}
thead a {
color: #000000;
}
.caret-icon {
vertical-align: top;
margin-top: 9px;
margin-left: 4px;
}
.cell-link {
color: $black;
padding: (3 * $default-spacer) 2px;

View file

@ -3,6 +3,8 @@ module NewGestionnaire
before_action :ensure_ownership!, except: [:index]
before_action :redirect_to_avis_if_needed, only: [:index]
ITEMS_PER_PAGE = 12
def index
@procedures = current_gestionnaire.procedures.order(archived_at: :desc, published_at: :desc)
@ -67,9 +69,22 @@ module NewGestionnaire
@archived_dossiers
end
sorted_ids = sorted_ids(@dossiers)
page = params[:page].present? ? params[:page] : 1
sorted_paginated_ids = Kaminari
.paginate_array(sorted_ids)
.page(page)
.per(ITEMS_PER_PAGE)
@dossiers = @dossiers.where(id: sorted_paginated_ids)
eager_load_displayed_fields
@dossiers = @dossiers.page([params[:page].to_i, 1].max)
@dossiers = @dossiers.sort_by { |d| sorted_paginated_ids.index(d.id) }
kaminarize(page, sorted_ids.count)
end
def update_displayed_fields
@ -91,6 +106,33 @@ module NewGestionnaire
procedure_presentation.update_attributes(displayed_fields: fields)
current_sort = procedure_presentation.sort
if !values.include?("#{current_sort['table']}/#{current_sort['column']}")
procedure_presentation.update_attributes(sort: Procedure.default_sort)
end
redirect_back(fallback_location: procedure_url(procedure))
end
def update_sort
current_sort = procedure_presentation.sort
table = params[:table]
column = params[:column]
if table == current_sort['table'] && column == current_sort['column']
order = current_sort['order'] == 'asc' ? 'desc' : 'asc'
else
order = 'asc'
end
sort = {
'table' => table,
'column' => column,
'order' => order
}.to_json
procedure_presentation.update_attributes(sort: sort)
redirect_back(fallback_location: procedure_url(procedure))
end
@ -123,6 +165,31 @@ module NewGestionnaire
end
end
def sorted_ids(dossiers)
table = procedure_presentation.sort['table']
column = procedure_presentation.sort['column']
order = procedure_presentation.sort['order']
includes = ''
where = ''
case table
when 'self'
order = "dossiers.#{column} #{order}"
when'france_connect_information'
includes = { user: :france_connect_information }
order = "france_connect_informations.#{column} #{order}"
when 'type_de_champ', 'type_de_champ_private'
includes = table == 'type_de_champ' ? :champs : :champs_private
where = "champs.type_de_champ_id = #{column.to_i}"
order = "champs.value #{order}"
else
includes = table
order = "#{table.pluralize}.#{column} #{order}"
end
dossiers.includes(includes).where(where).order(Dossier.sanitize_for_order(order)).pluck(:id)
end
def eager_load_displayed_fields
@displayed_fields
.reject { |field| field['table'] == 'self' }
@ -132,29 +199,48 @@ module NewGestionnaire
else
field['table']
end
end.each do |_, fields|
end.each do |group_key, fields|
case group_key
when'france_connect_information'
@dossiers = @dossiers.includes({ user: :france_connect_information })
when 'type_de_champ_group'
if fields.any? { |field| field['table'] == 'type_de_champ' }
@dossiers = @dossiers.includes(:champs)
end
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)
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
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
def kaminarize(current_page, total)
@dossiers.instance_eval <<-EVAL
def current_page
#{current_page}
end
def total_pages
(#{total} / #{ITEMS_PER_PAGE}.to_f).ceil
end
def limit_value
#{ITEMS_PER_PAGE}
end
def first_page?
current_page == 1
end
def last_page?
current_page == total_pages
end
EVAL
end
end
end

View file

@ -349,6 +349,10 @@ class Dossier < ActiveRecord::Base
end
end
def self.sanitize_for_order(order)
sanitize_sql_for_order(order)
end
private
def build_attestation

View file

@ -232,6 +232,14 @@ class Procedure < ActiveRecord::Base
end
end
def self.default_sort
{
'table' => 'self',
'column' => 'id',
'order' => 'desc'
}.to_json
end
private
def field_hash(label, table, column)

View file

@ -6,4 +6,8 @@ class ProcedurePresentation < ActiveRecord::Base
field = JSON.parse(field)
end
end
def sort
JSON.parse(read_attribute(:sort))
end
end

View file

@ -1,2 +1,8 @@
%th{ class: classname }
= field['label']
= link_to update_sort_procedure_path(@procedure, table: field['table'], column: field['column']) do
= field['label']
- if @procedure_presentation.sort['table'] == field['table'] && @procedure_presentation.sort['column'] == field['column']
- if @procedure_presentation.sort['order'] == 'asc'
%img.caret-icon{ src: image_url("table/up_caret.svg") }
- else
%img.caret-icon{ src: image_url("table/down_caret.svg") }

View file

@ -238,6 +238,7 @@ Rails.application.routes.draw do
resources :procedures, only: [:index, :show], param: :procedure_id do
member do
patch 'update_displayed_fields'
get 'update_sort/:table/:column' => 'procedures#update_sort', as: 'update_sort'
resources :dossiers, only: [:show], param: :dossier_id do
member do

View file

@ -1,13 +1,19 @@
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]
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) { 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
describe "#sort" do
it { expect(procedure_presentation.sort).to eq({ "table" => "user","column" => "email","order" => "asc" }) }
end
end

View file

@ -472,4 +472,8 @@ describe Procedure do
it { expect(subject.fields_for_select).to eq([["label1", "table1/column1"], ["label2", "table2/column2"]]) }
end
describe ".default_sort" do
it { expect(Procedure.default_sort).to eq("{\"table\":\"self\",\"column\":\"id\",\"order\":\"desc\"}") }
end
end