Add field sort to the dossiers table
This commit is contained in:
parent
88ad986143
commit
3df9356021
11 changed files with 156 additions and 25 deletions
1
app/assets/images/table/down_caret.svg
Normal file
1
app/assets/images/table/down_caret.svg
Normal 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 |
1
app/assets/images/table/up_caret.svg
Normal file
1
app/assets/images/table/up_caret.svg
Normal 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 |
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -6,4 +6,8 @@ class ProcedurePresentation < ActiveRecord::Base
|
|||
field = JSON.parse(field)
|
||||
end
|
||||
end
|
||||
|
||||
def sort
|
||||
JSON.parse(read_attribute(:sort))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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") }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue