From 52249f92b5799a53aaefb3677680e98423853064 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 4 Oct 2016 19:19:03 +0200 Subject: [PATCH] Add filter on gestionnaire dossier list --- .../javascripts/dossiers_list_filter.js | 27 +++++++ .../dossiers/procedure_controller.rb | 6 ++ .../backoffice/dossiers_controller.rb | 6 ++ .../backoffice/dossiers_list_controller.rb | 19 ++++- app/facades/dossiers_list_facades.rb | 4 + app/models/preference_list_dossier.rb | 5 ++ .../dossiers_list_gestionnaire_service.rb | 48 ++++++++++- .../dossiers/_filter_framed.html.haml | 8 ++ app/views/backoffice/dossiers/_list.html.haml | 30 +++---- app/views/backoffice/dossiers/index.js.erb | 2 + config/routes.rb | 4 + ...dossiers_list_gestionnaire_service_spec.rb | 79 +++++++++++++++++++ 12 files changed, 219 insertions(+), 19 deletions(-) create mode 100644 app/assets/javascripts/dossiers_list_filter.js create mode 100644 app/views/backoffice/dossiers/_filter_framed.html.haml diff --git a/app/assets/javascripts/dossiers_list_filter.js b/app/assets/javascripts/dossiers_list_filter.js new file mode 100644 index 000000000..dee999526 --- /dev/null +++ b/app/assets/javascripts/dossiers_list_filter.js @@ -0,0 +1,27 @@ +$(document).on('page:load', filters_init); +$(document).ready(filters_init); + + +function filters_init() { + $(".filter").on('click', function (event) { + filter_framed_show(event); + filter_framed_close_all_excepted(framed_id(event)); + }); +} + +function filter_framed_close_all_excepted(id) { + $(".filter_framed:not("+id+")").hide(); + + $(id).toggle(); +} + +function framed_id(event) { + return "#framed_" + event.target.id +} + +function filter_framed_show(event) { + dom_object = $(framed_id(event)); + + dom_object.css('top', (event.pageY + 7) + 'px'); + dom_object.css('left', (event.pageX + 7) + 'px'); +} \ No newline at end of file diff --git a/app/controllers/backoffice/dossiers/procedure_controller.rb b/app/controllers/backoffice/dossiers/procedure_controller.rb index bbcc1aebe..74b092f43 100644 --- a/app/controllers/backoffice/dossiers/procedure_controller.rb +++ b/app/controllers/backoffice/dossiers/procedure_controller.rb @@ -11,6 +11,12 @@ class Backoffice::Dossiers::ProcedureController < Backoffice::DossiersListContro redirect_to backoffice_dossiers_path end + def filter + super + + redirect_to backoffice_dossiers_procedure_path(id: params[:id], liste: param_liste) + end + private def retrieve_procedure diff --git a/app/controllers/backoffice/dossiers_controller.rb b/app/controllers/backoffice/dossiers_controller.rb index ec0a0efed..b0f108362 100644 --- a/app/controllers/backoffice/dossiers_controller.rb +++ b/app/controllers/backoffice/dossiers_controller.rb @@ -11,6 +11,12 @@ class Backoffice::DossiersController < Backoffice::DossiersListController @champs = @facade.champs_private unless @facade.nil? end + def filter + super + + redirect_to backoffice_dossiers_path(liste: param_liste) + end + def download_dossiers_tps dossiers = current_gestionnaire.dossiers.where.not(state: :draft) diff --git a/app/controllers/backoffice/dossiers_list_controller.rb b/app/controllers/backoffice/dossiers_list_controller.rb index 69a5c0ac9..c45a65edb 100644 --- a/app/controllers/backoffice/dossiers_list_controller.rb +++ b/app/controllers/backoffice/dossiers_list_controller.rb @@ -5,16 +5,19 @@ class Backoffice::DossiersListController < ApplicationController before_action :authenticate_gestionnaire! def index - liste = params[:liste] || cookies[:liste] || 'a_traiter' - cookies[:liste] = liste - - dossiers_list_facade liste + cookies[:liste] = param_liste + dossiers_list_facade param_liste dossiers_list_facade.service.change_sort! param_sort unless params[:dossiers_smart_listing].nil? smartlisting_dossier end + def filter + dossiers_list_facade param_liste + dossiers_list_facade.service.add_filter param_filter + end + def dossiers_list_facade liste='a_traiter' @dossiers_list_facade ||= DossiersListFacades.new current_gestionnaire, liste, retrieve_procedure end @@ -32,4 +35,12 @@ class Backoffice::DossiersListController < ApplicationController def param_sort params[:dossiers_smart_listing][:sort] end + + def param_filter + params[:filter_input] + end + + def param_liste + @liste ||= params[:liste] || cookies[:liste] || 'a_traiter' + end end diff --git a/app/facades/dossiers_list_facades.rb b/app/facades/dossiers_list_facades.rb index 87a72b22f..1c94b79cd 100644 --- a/app/facades/dossiers_list_facades.rb +++ b/app/facades/dossiers_list_facades.rb @@ -141,6 +141,10 @@ class DossiersListFacades base_url 'termine' end + def filter_url + @procedure.nil? ? backoffice_dossiers_filter_path(liste: liste) : backoffice_dossiers_procedure_filter_path(id: @procedure.id, liste: liste) + end + private def gestionnaire? diff --git a/app/models/preference_list_dossier.rb b/app/models/preference_list_dossier.rb index c5af12636..c8c68c1a5 100644 --- a/app/models/preference_list_dossier.rb +++ b/app/models/preference_list_dossier.rb @@ -7,6 +7,11 @@ class PreferenceListDossier < ActiveRecord::Base table + '.' + attr end + def table_with_s_attr + return self.attr if table.nil? || table.empty? + table + 's' + '.' + attr + end + def self.available_columns_for procedure_id = nil columns = { dossier: columns_dossier, diff --git a/app/services/dossiers_list_gestionnaire_service.rb b/app/services/dossiers_list_gestionnaire_service.rb index 2433304c4..73d25c734 100644 --- a/app/services/dossiers_list_gestionnaire_service.rb +++ b/app/services/dossiers_list_gestionnaire_service.rb @@ -39,7 +39,7 @@ class DossiersListGestionnaireService end def filter_dossiers - @filter_dossiers ||= @procedure.nil? ? @current_devise_profil.dossiers : @procedure.dossiers + @filter_dossiers ||= @procedure.nil? ? @current_devise_profil.dossiers.joins(joins_filter).where(where_filter) : @procedure.dossiers.joins(joins_filter).where(where_filter) end def filter_procedure_reset! @@ -65,6 +65,7 @@ class DossiersListGestionnaireService end def change_sort! new_sort + return if new_sort.blank? raw_table_attr = new_sort.keys.first.split('.') order = new_sort.values.first @@ -85,4 +86,49 @@ class DossiersListGestionnaireService .where.not(order: nil) .update_all order: nil end + + def joins_filter + filter_preference_list.inject([]) do |acc, preference| + acc.push(preference.table.to_sym) unless preference.table.blank? + acc + end + end + + def where_filter + filter_preference_list.inject('') do |acc, preference| + unless preference.filter.blank? + filter = preference.filter.gsub('*', '%') + filter = "%"+filter+"%" unless filter.include? '%' + + acc += (acc.to_s.empty? ? ''.to_s : " AND ") + + preference.table_with_s_attr + + " LIKE " + + "'" + + filter + + "'" + end + acc + end + end + + def add_filter new_filter + raw_table_attr = new_filter.keys.first.split('.') + filter = new_filter.values.first + + table = (raw_table_attr.size == 2 ? raw_table_attr.first : nil) + attr = (raw_table_attr.size == 2 ? raw_table_attr.second : raw_table_attr.first) + + @current_devise_profil.preference_list_dossiers + .find_by(table: table, attr: attr, procedure: @procedure) + .update filter: filter + end + + private + + def filter_preference_list + @filter_preference ||= @current_devise_profil.preference_list_dossiers + .where(procedure: @procedure) + .where.not(filter: nil) + .order(:id) + end end \ No newline at end of file diff --git a/app/views/backoffice/dossiers/_filter_framed.html.haml b/app/views/backoffice/dossiers/_filter_framed.html.haml new file mode 100644 index 000000000..0c69e2aed --- /dev/null +++ b/app/views/backoffice/dossiers/_filter_framed.html.haml @@ -0,0 +1,8 @@ +%div.filter_framed.panel.panel-primary{id: "#{filter_framed_id}", style:'width: 300px; height: 100px; position: absolute; top: 0; left: 0; display: none'} + .panel-heading + = preference.libelle + + =form_tag @dossiers_list_facade.filter_url, {class: 'panel-body form-inline', method: :post} do + %input.form-control.filter_input{name: "filter_input[#{preference.table_attr}]", style:'width: 84%', value: "#{preference.filter}"} + %button.btn.btn-sm.btn-success + %i.fa.fa-check \ No newline at end of file diff --git a/app/views/backoffice/dossiers/_list.html.haml b/app/views/backoffice/dossiers/_list.html.haml index f9fa09309..6f772a577 100644 --- a/app/views/backoffice/dossiers/_list.html.haml +++ b/app/views/backoffice/dossiers/_list.html.haml @@ -1,16 +1,18 @@ -- unless smart_listing.empty? - %table.table - %thead - - @dossiers_list_facade.preference_list_dossiers_filter.each do |preference| - %th{class: "col-md-#{preference.bootstrap_lg} col-lg-#{preference.bootstrap_lg}"} - - if preference.table == 'champs' - = preference.libelle - -else - = smart_listing.sortable preference.libelle, preference.table_attr +%table.table + %thead + - @dossiers_list_facade.preference_list_dossiers_filter.each do |preference| + %th{class: "col-md-#{preference.bootstrap_lg} col-lg-#{preference.bootstrap_lg}"} + - if preference.table == 'champs' + = preference.libelle + -else + = smart_listing.sortable preference.libelle, preference.table_attr + %i.filter.fa.fa-filter{style: "cursor: pointer; margin-left:3px; font-size: 1.1em; color:#{(preference.filter.blank? ? 'grey' : 'orange')}", id: "filter_"+preference.table_attr.sub('.', '_')} + = render partial: 'backoffice/dossiers/filter_framed', locals:{preference: preference, filter_framed_id: "framed_filter_"+preference.table_attr.sub('.', '_')} - %th.col-md-1.col-lg-1.center Actions - %th.col-md-1.col-lg-1.center Abonnés + %th.col-md-1.col-lg-1.center Actions + %th.col-md-1.col-lg-1.center Abonnés + - unless smart_listing.empty? - @dossiers.each do |dossier| %tr - @dossiers_list_facade.preference_list_dossiers_filter.each_with_index do |preference, index| @@ -38,9 +40,9 @@ %td.center{style:"color: #{dossier.total_follow == 0 ? 'red' : ''}"} = dossier.total_follow - = smart_listing.paginate - = smart_listing.pagination_per_page_links += smart_listing.paginate += smart_listing.pagination_per_page_links -- else +- if smart_listing.empty? %h4.center Aucun dossier \ No newline at end of file diff --git a/app/views/backoffice/dossiers/index.js.erb b/app/views/backoffice/dossiers/index.js.erb index 1517a60d3..0f7d43419 100644 --- a/app/views/backoffice/dossiers/index.js.erb +++ b/app/views/backoffice/dossiers/index.js.erb @@ -1 +1,3 @@ <%= smart_listing_update :dossiers %> + +filters_init(); \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 3dc0daa97..8fe43d22d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -162,8 +162,12 @@ Rails.application.routes.draw do put 'follow' => 'dossiers#follow' end + namespace :dossiers do + post 'filter' + get 'procedure/:id' => 'procedure#index', as: 'procedure' + post 'procedure/:id/filter' => 'procedure#filter', as: 'procedure_filter' end resources :commentaires, only: [:create] diff --git a/spec/services/dossiers_list_gestionnaire_service_spec.rb b/spec/services/dossiers_list_gestionnaire_service_spec.rb index a6c942f50..b3be84ce6 100644 --- a/spec/services/dossiers_list_gestionnaire_service_spec.rb +++ b/spec/services/dossiers_list_gestionnaire_service_spec.rb @@ -90,4 +90,83 @@ describe DossiersListGestionnaireService do end end end + + describe '#add_filter' do + let(:table) { 'entreprise' } + let(:attr) { 'raison_sociale' } + let(:filter_value) { 'plop' } + + let(:select_preference_list_dossier) { gestionnaire.preference_list_dossiers + .find_by(table: table, attr: attr, procedure: nil) } + + subject { described_class.new(gestionnaire, liste).add_filter new_filter } + + describe 'with one or two params in filter' do + before do + subject + gestionnaire.reload + end + + context 'when sort_params as table and attr' do + let(:new_filter) { ({"#{table}.#{attr}" => filter_value}) } + + it { expect(select_preference_list_dossier.filter).to eq filter_value } + end + + context 'when sort_params as no table' do + let(:new_filter) { ({"#{attr}" => filter_value}) } + let(:table) { nil } + let(:attr) { 'id' } + + it { expect(select_preference_list_dossier.filter).to eq filter_value } + end + end + end + + describe '#where_filter' do + before do + gestionnaire.preference_list_dossiers + .find_by(table: 'entreprise', attr: 'raison_sociale', procedure: nil) + .update_column :filter, 'plop' + + gestionnaire.preference_list_dossiers + .find_by(table: nil, attr: 'id', procedure: nil) + .update_column :filter, '23' + end + + subject { DossiersListGestionnaireService.new(gestionnaire, liste, nil).where_filter } + + it { is_expected.to eq "id LIKE '%23%' AND entreprises.raison_sociale LIKE '%plop%'" } + + context 'when last filter caractere is *' do + + before do + gestionnaire.preference_list_dossiers + .find_by(table: 'entreprise', attr: 'raison_sociale', procedure: nil) + .update_column :filter, 'plop*' + end + + it { is_expected.to eq "id LIKE '%23%' AND entreprises.raison_sociale LIKE 'plop%'" } + end + + context 'when first filter caractere is *' do + before do + gestionnaire.preference_list_dossiers + .find_by(table: nil, attr: 'id', procedure: nil) + .update_column :filter, '*23' + end + + it { is_expected.to eq "id LIKE '%23' AND entreprises.raison_sociale LIKE '%plop%'" } + end + + context 'when * caractere is presente' do + before do + gestionnaire.preference_list_dossiers + .find_by(table: 'entreprise', attr: 'raison_sociale', procedure: nil) + .update_column :filter, 'plop*plip' + end + + it { is_expected.to eq "id LIKE '%23%' AND entreprises.raison_sociale LIKE 'plop%plip'" } + end + end end