Skip to content

Commit

Permalink
Merge pull request #751 from instedd/feature/phonebook-sorting
Browse files Browse the repository at this point in the history
Phonebook sorting by address or variables
  • Loading branch information
ggiraldez authored Oct 17, 2016
2 parents 1c68962 + edfd4f5 commit 4fa7272
Show file tree
Hide file tree
Showing 7 changed files with 313 additions and 164 deletions.
23 changes: 22 additions & 1 deletion app/assets/javascripts/contacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,28 @@ $(function() {
$('.file-upload .import').click(function (elem) {
$(this).closest('form').submit();
});

var contactsList = $('.contacts-list'),
sortKeyField = $('#sort_key'),
sortTypeField = $('#sort_type'),
sortDirField = $('#sort_dir'),
filtersForm = $('#filters-form');

contactsList.on('click', '.GralTable th.sort', function(evt) {
var header = $(evt.target);
var sortDir = $(header).hasClass('up') ? 'down' : 'up';
var sortKey = $(header).data('sort-key');
var sortType = $(header).data('sort-type');
$('th', contactsList).removeClass('sort').removeClass('up').removeClass('down');
$(header).addClass('sort').addClass(sortDir);

sortKeyField.val(sortKey);
sortTypeField.val(sortType);
sortDirField.val(sortDir);

filtersForm.submit();
return false;
});
});

function initContactsFilter(count) {
Expand All @@ -75,4 +97,3 @@ function initContactsFilter(count) {
}
});
}

9 changes: 8 additions & 1 deletion app/controllers/contacts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ class ContactsController < ApplicationController
before_filter :authenticate_account!
before_filter :load_project
before_filter :load_filters, :only => :index
before_filter :load_sorting, :only => :index
before_filter :initialize_context, :only => [:show, :edit, :update, :destroy]
before_filter :check_project_admin, :only => [:create, :edit, :update, :destroy]
before_filter :init_calls_context, :only => [:calls, :queued_calls]

def index
@page = params[:page] || 1
@contacts = ContactsFinder.for(@project).find(@filters, includes: [:addresses, :recorded_audios, :persisted_variables, :project_variables])
@contacts = ContactsFinder.for(@project).find(@filters, includes: [:addresses, :recorded_audios, :persisted_variables, :project_variables], sorting: @sorting)
@project_variables = @project.project_variables
@implicit_variables = ImplicitVariable.subclasses

Expand Down Expand Up @@ -187,6 +188,12 @@ def load_filters
@filters = params[:filters_json].present? ? JSON.parse(params[:filters_json]) : []
end

def load_sorting
@sorting = if params[:sort_type].presence
{ params[:sort_type] => params[:sort_key], :direction => (params[:sort_dir] == 'down' ? 'DESC' : 'ASC') }.with_indifferent_access
end
end

def init_calls_context
@contact = @project.contacts.find(params[:id])
@page = params[:page] || 1
Expand Down
3 changes: 1 addition & 2 deletions app/helpers/contact_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@

module ContactHelper
def addresses_for_contact(contact)
address_count = contact.addresses.count
address_count = contact.addresses.size
result = contact.addresses.take(2).map(&:address).join(', ')
result << " and #{address_count - 2} more" if address_count > 2
result
end
end

24 changes: 23 additions & 1 deletion app/models/contacts_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ def self.for(project)

def find(filters = [], options = {})
contacts = @project.contacts.includes(options[:includes] || [])
filters.inject contacts do |contacts, filter|
contacts = filters.inject contacts do |contacts, filter|
contacts.where(*query_for(filter.with_indifferent_access))
end
contacts = with_sorting(contacts, options[:sorting])
return contacts
end

private
Expand Down Expand Up @@ -75,7 +77,27 @@ def query_for(filter)
end

[query] + args
end

def with_sorting(contacts, options)
sorting, join = sorting_for(options)
return contacts if sorting.nil?
contacts.order("#{sorting} #{options[:direction] || 'ASC'}").joins(join)
end

def sorting_for(options)
return nil if options.nil?

if variable_id = options[:project_variable_id]
["sorting_var.value",
"LEFT JOIN persisted_variables AS sorting_var ON sorting_var.contact_id = contacts.id AND sorting_var.project_variable_id = #{variable_id.to_i}"]
elsif implicit_key = options[:implicit_key] and ImplicitVariable.subclasses.map(&:key).include?(implicit_key)
["sorting_var.value",
"LEFT JOIN persisted_variables AS sorting_var ON sorting_var.contact_id = contacts.id AND sorting_var.implicit_key = '#{implicit_key}'"]
elsif options[:address]
["sorting_address.first_address",
"LEFT JOIN (SELECT contact_id, COALESCE(address) as first_address FROM contact_addresses WHERE project_id = #{@project.id} GROUP BY contact_id ORDER BY id) AS sorting_address ON sorting_address.contact_id = contacts.id"]
end
end

end
17 changes: 12 additions & 5 deletions app/views/contacts/_list.html.haml
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
.tablewrapp.no-wrap.scroll.contacts-table
%table.GralTable.w-pagination
%tr
%th{colspan: 2} Phone numbers
%th.sort{colspan: 2, data: {"sort-key" => true, "sort-type" => "address"}, class: ((params[:sort_type].try(&:to_s) == 'address') ? params[:sort_dir] || 'up' : nil)}
Phone numbers
%span
- @implicit_variables.each do |variable|
%th=variable.key
%th.sort{data: {"sort-key" => variable.key, "sort-type" => "implicit_key"}, class: ((params[:sort_key] == variable.key) ? params[:sort_dir] || 'up' : nil)}
=variable.key
%span
- @project_variables.each do |variable|
%th=variable.name
%th.sort{data: {"sort-key" => variable.id, "sort-type" => "project_variable_id"}, class: ((params[:sort_key] == variable.id.to_s) ? params[:sort_dir] || 'up' : nil)}
=variable.name
%span
- @recorded_audio_descriptions.each do |audio_description|
%th=audio_description
Expand All @@ -21,11 +27,12 @@
%td= variable.try(:value)
- @project_variables.each do |project_variable|
- variable = contact.persisted_variables.detect do |variable|
- variable.project_variable == project_variable
- variable.project_variable_id == project_variable.id
%td= variable.try(:value)
- @recorded_audio_descriptions.each do |audio_description|
- audios = contact.recorded_audios.collect do |audio|
- audio.description == audio_description
%td= audios.size
= paginate @contacts, :param_name => 'page', :params => {filters_json: params[:filters_json]}, :remote => true
= paginate @contacts, :param_name => 'page', :remote => true,
:params => { filters_json: params[:filters_json], sort_key: params[:sort_key], sort_dir: params[:sort_dir], sort_type: params[:sort_type] }
4 changes: 3 additions & 1 deletion app/views/contacts/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@
.contacts-list
#contactsFilter.filters-box.w30.tablewrapp
.search
= form_tag search_project_contacts_path(@project), remote: true, method: 'GET' do
= form_tag search_project_contacts_path(@project), remote: true, method: 'GET', id: 'filters-form' do
%p
Filters
%span{'data-bind' => 'text: countDescription'}
%hr
= hidden_field_tag :filters_json, params[:filters_json] || '[]', 'data-bind' => 'value: json', 'class' => 'filters'
- [:sort_key, :sort_type, :sort_dir].each do |key|
= hidden_field_tag key, params[key]
= render 'shared/contacts_filter'
%button.fsearch Search

Expand Down
Loading

0 comments on commit 4fa7272

Please sign in to comment.