summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Wintermeyer <stefan.wintermeyer@amooma.de>2013-06-27 20:58:33 +0200
committerStefan Wintermeyer <stefan.wintermeyer@amooma.de>2013-06-27 20:58:33 +0200
commitaad51572a6c75a4cbd2d44804b82f634a4ddd732 (patch)
treeeb1e50afb7f8667fc6d5ac4a856c5f1fd396efd7
parent29213546a4468aa4a853dee8091bbd556f7d0f51 (diff)
Add the possiblity to search the phone_books in the Switchboard#view
-rw-r--r--app/controllers/api/v1/phone_book_entries_controller.rb76
-rw-r--r--app/controllers/switchboards_controller.rb2
-rw-r--r--app/serializers/phone_book_entry_serializer.rb14
-rw-r--r--app/serializers/switchboard_serializer.rb2
-rw-r--r--app/views/switchboards/_form_core.html.haml1
-rw-r--r--app/views/switchboards/show.html.erb29
-rw-r--r--config/locales/views/switchboards/de.yml6
-rw-r--r--config/locales/views/switchboards/en.yml5
-rw-r--r--config/routes.rb1
-rw-r--r--db/migrate/20130627162201_add_search_activated_to_switchboard.rb5
-rw-r--r--public/js/app.js36
11 files changed, 166 insertions, 11 deletions
diff --git a/app/controllers/api/v1/phone_book_entries_controller.rb b/app/controllers/api/v1/phone_book_entries_controller.rb
new file mode 100644
index 0000000..7cae5a5
--- /dev/null
+++ b/app/controllers/api/v1/phone_book_entries_controller.rb
@@ -0,0 +1,76 @@
+module Api
+ module V1
+ class PhoneBookEntriesController < ApplicationController
+ respond_to :json
+
+ def index
+ query = params[:query]
+
+ return nil if query.blank?
+
+ current_ability = Ability.new(current_user)
+ phone_book_entries = PhoneBookEntry.accessible_by(current_ability)
+
+ if query.match(/^\+?\d+$/) != nil
+ # Find by phone number
+ phone_book_entries_ids = phone_book_entries.map{|entry| entry.id}
+ found_phone_numbers = PhoneNumber.
+ where(:phone_numberable_type => 'PhoneBookEntry', :phone_numberable_id => phone_book_entries_ids).
+ where('number LIKE ?', "#{query}%")
+ search_result = phone_book_entries.where(:id => found_phone_numbers.map{|entry| entry.phone_numberable_id})
+ elsif query.match(/^[\"\'](.*)[\"\']$/) != nil
+ # The User searched for =>'example'<= so he wants an EXACT search for that.
+ # This is the fasted and most accurate way of searching.
+ # The order to search is: last_name, first_name and organization.
+ # It stops searching as soon as it finds results.
+ #
+ query = $1
+ search_result = phone_book_entries.where(:last_name => query)
+ search_result = phone_book_entries.where(:first_name => query) if search_result.blank?
+ search_result = phone_book_entries.where(:organization => query) if search_result.blank?
+
+ exact_search = true
+ else
+ # Search with SQL LIKE
+ #
+ search_result = phone_book_entries.
+ where( '( ( last_name LIKE ? ) OR ( first_name LIKE ? ) OR ( organization LIKE ? ) )',
+ "#{query}%", "#{query}%", "#{query}%" )
+
+ exact_search = false
+ end
+
+ # Let's have a run with our phonetic search.
+ #
+ phonetic_query = PhoneBookEntry.koelner_phonetik(query)
+ phonetic_search_result = phone_book_entries.where(:last_name_phonetic => phonetic_query)
+ phonetic_search_result = phone_book_entries.where(:first_name_phonetic => phonetic_query) if phonetic_search_result.blank?
+ phonetic_search_result = phone_book_entries.where(:organization_phonetic => phonetic_query) if phonetic_search_result.blank?
+
+ if phonetic_search_result.blank?
+ # Let's try the search with SQL LIKE. Just in case.
+ #
+ phonetic_search_result = phone_book_entries.where( 'last_name_phonetic LIKE ?', "#{phonetic_query}%" )
+ phonetic_search_result = phone_book_entries.where( 'first_name_phonetic LIKE ?', "#{phonetic_query}%" ) if phonetic_search_result.blank?
+ phonetic_search_result = phone_book_entries.where( 'organization_phonetic LIKE ?', "#{phonetic_query}%" ) if phonetic_search_result.blank?
+ end
+
+ phonetic_search = true if phonetic_search_result.any?
+
+ phone_book_entries = search_result
+
+ if phone_book_entries.count == 0 && exact_search == false && phonetic_search
+ phone_book_entries = phonetic_search_result
+ end
+
+ # Let's sort the results and do pagination.
+ #
+ phone_book_entries = phone_book_entries.
+ order([ :last_name, :first_name, :organization ])
+
+ respond_with phone_book_entries
+ end
+
+ end
+ end
+end
diff --git a/app/controllers/switchboards_controller.rb b/app/controllers/switchboards_controller.rb
index d162a85..03fd73e 100644
--- a/app/controllers/switchboards_controller.rb
+++ b/app/controllers/switchboards_controller.rb
@@ -58,7 +58,7 @@ class SwitchboardsController < ApplicationController
private
def switchboard_params
- params.require(:switchboard).permit(:name, :reload_interval, :show_avatars, :entry_width, :amount_of_displayed_phone_numbers, :blind_transfer_activated, :attended_transfer_activated)
+ params.require(:switchboard).permit(:name, :reload_interval, :show_avatars, :entry_width, :amount_of_displayed_phone_numbers, :blind_transfer_activated, :attended_transfer_activated, :search_activated)
end
def spread_breadcrumbs
diff --git a/app/serializers/phone_book_entry_serializer.rb b/app/serializers/phone_book_entry_serializer.rb
new file mode 100644
index 0000000..ac25832
--- /dev/null
+++ b/app/serializers/phone_book_entry_serializer.rb
@@ -0,0 +1,14 @@
+class PhoneBookEntrySerializer < ActiveModel::Serializer
+ embed :ids, :include => true
+
+ attributes :id, :first_name, :last_name, :organization, :search_result_display
+ has_many :phone_numbers
+
+ def search_result_display
+ result = "#{object.last_name}, #{object.first_name}".strip.gsub(/^, /,'').gsub(/,$/,'')
+ if result.blank?
+ result = "#{object.organization}"
+ end
+ return result
+ end
+end
diff --git a/app/serializers/switchboard_serializer.rb b/app/serializers/switchboard_serializer.rb
index 7ad7792..8a8bd42 100644
--- a/app/serializers/switchboard_serializer.rb
+++ b/app/serializers/switchboard_serializer.rb
@@ -1,7 +1,7 @@
class SwitchboardSerializer < ActiveModel::Serializer
embed :ids, :include => true
- attributes :id, :name, :show_avatars, :blind_transfer_activated, :attended_transfer_activated
+ attributes :id, :name, :show_avatars, :blind_transfer_activated, :attended_transfer_activated, :search_activated
has_many :switchboard_entries
has_many :sip_accounts, :through => :switchboard_entries
has_many :phone_numbers
diff --git a/app/views/switchboards/_form_core.html.haml b/app/views/switchboards/_form_core.html.haml
index a4fd15f..0bfcb86 100644
--- a/app/views/switchboards/_form_core.html.haml
+++ b/app/views/switchboards/_form_core.html.haml
@@ -6,3 +6,4 @@
= f.input :amount_of_displayed_phone_numbers, :label => t('switchboards.form.amount_of_displayed_phone_numbers.label'), :hint => conditional_hint('switchboards.form.amount_of_displayed_phone_numbers.hint')
= f.input :blind_transfer_activated, :label => t('switchboards.form.blind_transfer_activated.label'), :hint => conditional_hint('switchboards.form.blind_transfer_activated.hint')
= f.input :attended_transfer_activated, :label => t('switchboards.form.attended_transfer_activated.label'), :hint => conditional_hint('switchboards.form.attended_transfer_activated.hint')
+ = f.input :search_activated, :label => t('switchboards.form.search_activated.label'), :hint => conditional_hint('switchboards.form.search_activated.hint') \ No newline at end of file
diff --git a/app/views/switchboards/show.html.erb b/app/views/switchboards/show.html.erb
index 3bc4da4..b2cdbd4 100644
--- a/app/views/switchboards/show.html.erb
+++ b/app/views/switchboards/show.html.erb
@@ -26,6 +26,35 @@
{{/each}}
{{/if}}
+ {{#if search_activated}}
+ <div class="well span3 pull-right">
+ <p>
+ {{input type="text" value=searchText size="10" placeholder="Suchen..."}}
+ </p>
+ <ul>
+ {{#each phoneBookEntry in searchResults}}
+ <li>
+ {{phoneBookEntry.search_result_display}}<br />
+
+ {{#each phoneNumber in phoneBookEntry.phoneNumbers}}
+ <span class="label">
+ {{phoneNumber.number}}
+ </span>
+
+ {{#each dispatchableIncomingCall in dispatchableIncomingCalls}}
+ {{#if blind_transfer_activated}}
+ <button {{action transfer_blind dispatchableIncomingCall.id phoneNumber.number}} class="btn btn-small">Transfer</button>
+ {{/if}}
+ {{#if attended_transfer_activated}}
+ <button {{action transfer_attended dispatchableIncomingCall.id phoneNumber.number}} class="btn btn-small">Attended Transfer</button>
+ {{/if}}
+ {{/each}}
+ {{/each}}
+ </li>
+ {{/each}}
+ </ul>
+ </div>
+ {{/if}}
{{#if switchboardEntrys.length}}
<ul class="thumbnails">
diff --git a/config/locales/views/switchboards/de.yml b/config/locales/views/switchboards/de.yml
index d86a656..3bb45a5 100644
--- a/config/locales/views/switchboards/de.yml
+++ b/config/locales/views/switchboards/de.yml
@@ -15,6 +15,7 @@ de:
amount_of_displayed_phone_numbers: 'Anzahl der angezeigten Telefonnummern'
blind_transfer_activated: 'Transfer'
attended_transfer_activated: 'Transfer mit Rückfrage'
+ search_activated: 'Suche'
actions:
confirm_destroy: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Switchboard'
destroy: 'Löschen'
@@ -32,6 +33,7 @@ de:
amount_of_displayed_phone_numbers: 'Anzahl der angezeigten Telefonnummern'
blind_transfer_activated: 'Transfer'
attended_transfer_activated: 'Transfer mit Rückfrage'
+ search_activated: 'Suche'
actions:
confirm_destroy: 'Sind Sie sicher, dass die dieses Element löschen möchten?'
destroy: 'Löschen'
@@ -72,5 +74,7 @@ de:
attended_transfer_activated:
label: 'Transfer mit Rückfrage'
hint: 'Funktioniert nicht mit allen Telefonen.'
-
+ search_activated:
+ label: 'Suche aktivieren'
+ hint: ''
submit: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/switchboards/en.yml b/config/locales/views/switchboards/en.yml
index 6a5dd6f..0cc5ef2 100644
--- a/config/locales/views/switchboards/en.yml
+++ b/config/locales/views/switchboards/en.yml
@@ -15,6 +15,7 @@ en:
amount_of_displayed_phone_numbers: 'Amount of displayed phone numbers'
blind_transfer_activated: 'Blind Transfer'
attended_transfer_activated: 'Attended Transfer'
+ search_activated: 'Search function'
actions:
confirm_destroy: 'Are you sure you want to delete this Switchboard?'
destroy: 'Delete'
@@ -32,6 +33,7 @@ en:
amount_of_displayed_phone_numbers: 'Amount of displayed phone numbers'
blind_transfer_activated: 'Blind Transfer'
attended_transfer_activated: 'Attended Transfer'
+ search_activated: 'Search function'
actions:
confirm_destroy: 'Are you sure you want to delete this element?'
destroy: 'Delete'
@@ -72,4 +74,7 @@ en:
attended_transfer_activated:
label: 'Attended Transfer'
hint: 'Does not work with all phone models.'
+ search_activated:
+ label: 'Activate search function'
+ hint: ''
submit: 'Submit' \ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index eeb9c0b..707d0fc 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -12,6 +12,7 @@ Gemeinschaft42c::Application.routes.draw do
resources :pager_groups
resources :phone_numbers, :only => [:show, :index]
resources :calls, :only => [:index, :show, :update]
+ resources :phone_book_entries, :only => [:index]
end
resources :rows
diff --git a/db/migrate/20130627162201_add_search_activated_to_switchboard.rb b/db/migrate/20130627162201_add_search_activated_to_switchboard.rb
new file mode 100644
index 0000000..48916ac
--- /dev/null
+++ b/db/migrate/20130627162201_add_search_activated_to_switchboard.rb
@@ -0,0 +1,5 @@
+class AddSearchActivatedToSwitchboard < ActiveRecord::Migration
+ def change
+ add_column :switchboards, :search_activated, :boolean
+ end
+end
diff --git a/public/js/app.js b/public/js/app.js
index 733989a..5560ae7 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -34,14 +34,23 @@ App.SwitchboardController = Ember.ObjectController.extend({
transfer_attended: function(call_id, destination) {
request_url = '/api/v1/calls/' + call_id + '.json';
jQuery.get(request_url, { transfer_attended: destination });
- }
+ },
+
+ searchText: null,
+
+ searchResults: function() {
+ var searchText = this.get('searchText');
+ if (!searchText) { return; }
+ return App.PhoneBookEntry.find({ query: searchText });
+ }.property('searchText')
});
// Models
App.Store = DS.Store.extend();
DS.RESTAdapter.configure("plurals", {
- switchboard_entry: "switchboard_entries"
+ switchboard_entry: "switchboard_entries",
+ phone_book_entry: "phone_book_entries"
});
DS.RESTAdapter.reopen({
@@ -55,6 +64,7 @@ App.Switchboard = DS.Model.extend({
name: DS.attr('string'),
show_avatars: DS.attr('boolean'),
blind_transfer_activated: DS.attr('boolean'),
+ search_activated: DS.attr('boolean'),
attended_transfer_activated: DS.attr('boolean')
});
@@ -139,12 +149,6 @@ App.SipAccount = DS.Model.extend({
});
-App.PhoneNumber = DS.Model.extend({
- name: DS.attr('string'),
- number: DS.attr('string'),
- destination: DS.attr('string')
-});
-
App.Call = DS.Model.extend({
start_stamp: DS.attr('number'),
callstate: DS.attr('string'),
@@ -169,8 +173,24 @@ App.Call = DS.Model.extend({
}.property('b_callstate')
});
+App.PhoneBookEntry = DS.Model.extend({
+ first_name: DS.attr('string'),
+ last_name: DS.attr('string'),
+ organization: DS.attr('string'),
+ search_result_display: DS.attr('string'),
+ phoneNumbers: DS.hasMany('App.PhoneNumber')
+});
+
+App.PhoneNumber = DS.Model.extend({
+ name: DS.attr('string'),
+ number: DS.attr('string'),
+ destination: DS.attr('string')
+});
+
App.store.adapter.serializer.configure(App.PhoneNumber, { sideloadAs: 'phone_numbers' });
+// Handlebar Helpers
+//
Ember.Handlebars.registerBoundHelper('avatar_img', function(value) {
return new Handlebars.SafeString('<img alt="Avatar image" class="img-rounded" src="' + value + '" style="width: 100px;">');
});