Init version of new search.

This commit is contained in:
Martin Edenhofer 2013-05-22 00:30:09 +02:00
parent 08eee6f86c
commit 79d5dfdd76
13 changed files with 289 additions and 67 deletions

View file

@ -219,6 +219,33 @@ class App.Controller extends Spine.Controller
interval: (callback, interval, interval_id, level) => interval: (callback, interval, interval_id, level) =>
App.Interval.set(callback, interval, interval_id, level) App.Interval.set(callback, interval, interval_id, level)
ticketPopups: (position = 'right') ->
# remove old popovers
$('.popover-inner').parent().remove()
# show ticket popup
ui = @
$('.ticket-data').popover(
trigger: 'hover'
html: true
delay: { show: 500, hide: 1200 }
# placement: 'bottom'
placement: position
title: ->
ticket_id = $(@).data('id')
ticket = App.Collection.find( 'Ticket', ticket_id )
ticket.title
content: ->
ticket_id = $(@).data('id')
ticket = App.Collection.find( 'Ticket', ticket_id )
ticket.humanTime = ui.humanTime(ticket.created_at)
# insert data
App.view('ticket_info_small')(
ticket: ticket,
)
)
userPopups: (position = 'right') -> userPopups: (position = 'right') ->
# remove old popovers # remove old popovers
@ -265,6 +292,31 @@ class App.Controller extends Spine.Controller
) )
) )
organizationPopups: (position = 'right') ->
# remove old popovers
$('.popover-inner').parent().remove()
# show organization popup
$('.organization-data').popover(
trigger: 'hover'
html: true
delay: { show: 500, hide: 1200 }
# placement: 'bottom'
placement: position
title: ->
organization_id = $(@).data('id')
organization = App.Collection.find( 'Organization', organization_id )
organization.name
content: ->
organization_id = $(@).data('id')
organization = App.Collection.find( 'Organization', organization_id )
# insert data
App.view('organization_info_small')(
organization: organization,
)
)
userTicketPopups: (data) -> userTicketPopups: (data) ->
# remove old popovers # remove old popovers

View file

@ -61,10 +61,19 @@ class App.Navigation extends App.Controller
open_tab: open_tab open_tab: open_tab
active_tab: active_tab active_tab: active_tab
user: user user: user
tickets: @tickets || [] result: @result || []
search: search search: search
) )
# start ticket popups
@ticketPopups('right')
# start user popups
@userPopups('right')
# start oorganization popups
@organizationPopups('right')
# set focus to search box # set focus to search box
if @searchFocus if @searchFocus
@searchFocusSet = true @searchFocusSet = true
@ -77,29 +86,59 @@ class App.Navigation extends App.Controller
App.Com.ajax( App.Com.ajax(
id: 'ticket_search' id: 'ticket_search'
type: 'GET' type: 'GET'
url: 'api/tickets/search' url: 'api/search'
data: data:
term: @term term: @term
processData: true, processData: true,
success: (data, status, xhr) => success: (data, status, xhr) =>
# load user collection # load user collection
if data.users if data.load.organizations
App.Collection.load( type: 'User', data: data.users ) App.Collection.load( type: 'Organization', data: data.load.organizations )
# load user collection
if data.load.users
App.Collection.load( type: 'User', data: data.load.users )
# load ticket collection # load ticket collection
if data.tickets if data.load.tickets
App.Collection.load( type: 'Ticket', data: data.tickets ) App.Collection.load( type: 'Ticket', data: data.load.tickets )
@tickets = [] @result = data.result
for area in @result
if area.name is 'Ticket'
area.result = []
for id in area.ids
ticket = App.Collection.find( 'Ticket', id )
ticket.humanTime = @humanTime(ticket.created_at)
data =
display: "##{ticket.number} - #{ticket.title} - #{ticket.humanTime}"
id: ticket.id
class: "ticket-data"
url: "#ticket/zoom/#{ticket.id}"
area.result.push data
else if area.name is 'User'
area.result = []
for id in area.ids
user = App.Collection.find( 'User', id )
data =
display: "#{user.displayName()}"
id: user.id
class: "user-data"
url: "#users/#{user.id}"
area.result.push data
else if area.name is 'Organization'
area.result = []
for id in area.ids
organization = App.Collection.find( 'Organization', id )
data =
display: "#{organization.displayName()}"
id: organization.id
class: "organization-data"
url: "#organizations/#{ticket.id}"
area.result.push data
for ticket_raw in data.tickets if @result
ticket = App.Collection.find( 'Ticket', ticket_raw.id )
# set human time
ticket.humanTime = @humanTime(ticket.created_at)
@tickets.push ticket
@render(user) @render(user)
) )
@ -121,7 +160,7 @@ class App.Navigation extends App.Controller
@delay( @delay(
=> =>
@searchFocus = false @searchFocus = false
@tickets = [] @result = []
@render(user) @render(user)
320 320
) )

View file

@ -79,7 +79,7 @@
<div class="row article"> <div class="row article">
<div class="avatar span1 thumbnails"> <div class="avatar span1 thumbnails">
<img class="thumbnail user-data" data-id="<%= @S('id') %>"" src="<%- @S('image') %>" alt=""> <img class="thumbnail user-data" data-id="<%= @S('id') %>" src="<%- @S('image') %>" alt="">
</div> </div>
<div class="span8 well-muted article-message"> <div class="span8 well-muted article-message">
<form class="form-stacked pull-left ticket-update"> <form class="form-stacked pull-left ticket-update">

View file

@ -23,16 +23,21 @@
<li class="<% if @active_tab[item.target] : %>active<% end %>"><a href="<%= item.target %>"><%- @T( item.name ) %></a></li> <li class="<% if @active_tab[item.target] : %>active<% end %>"><a href="<%= item.target %>"><%- @T( item.name ) %></a></li>
<% end %> <% end %>
<% end %> <% end %>
<li class="dropdown <% if @tickets[0] : %>open<% end %>">
<li class="dropdown <% if @result[0] : %>open<% end %>">
<form class="navbar-search"> <form class="navbar-search">
<input id="global-search" class="search-query" type="search" value="<%= @search %>" placeholder="<%- @Ti( 'Search' ) %>" autocomplete="off"/> <input id="global-search" class="search-query" type="search" value="<%= @search %>" placeholder="<%- @Ti( 'Search' ) %>" autocomplete="off"/>
</form> </form>
<ul class="dropdown-menu"> <ul class="dropdown-menu" style="margin-right: 22px;">
<% for ticket in @tickets: %> <% for area in @result: %>
<li><a href="#ticket/zoom/<%= ticket.id %>">Ticket <%= ticket.number %> - <%- ticket.humanTime %> - <%= @P( ticket.group) %><br><%= ticket.title %></a></li> <li class="divider" style="padding: 2px 10px; height: auto; margin: 4px 0px;"><%- @T( area.name ) %></li>
<% for item in area.result: %>
<li><a href="<%- item.url %>" class="<%= item.class %>" data-id="<%= item.id %>" style="max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"><%= item.display %></a></li>
<% end %>
<% end %> <% end %>
</ul> </ul>
</li> </li>
</ul> </ul>
<div class="spinner"/> <div class="spinner"/>
<% if @user: %> <% if @user: %>

View file

@ -0,0 +1,6 @@
<table style="width: 100%;">
<tr>
<td><%- @P( @organization ) %></td>
<td>...</td>
</tr>
</table>

View file

@ -0,0 +1,17 @@
<table style="width: 100%;">
<tr>
<td>#<%- @P( @ticket.number ) %></td>
<td><%- @P( @ticket.humanTime ) %></td>
</tr>
<tr>
<td><%- @P( @ticket.group ) %></td>
<td><%- @T( @ticket.ticket_state.name ) %></td>
</tr>
<tr>
<td><%- @T( @ticket.ticket_priority.name ) %></td>
<td></td>
</tr>
<tr>
<td colspan="2"><%- @P( @ticket.owner ) %></td>
</tr>
</table>

View file

@ -0,0 +1,80 @@
class SearchController < ApplicationController
before_filter :authentication_check
# GET /api/search
def search
# build result list
tickets = Ticket.search(
:limit => params[:limit],
:query => params[:term],
:current_user => current_user,
)
users_data = {}
ticket_result = []
tickets.each do |ticket|
ticket_result.push ticket.id
users_data[ ticket['owner_id'] ] = User.user_data_full( ticket['owner_id'] )
users_data[ ticket['customer_id'] ] = User.user_data_full( ticket['customer_id'] )
users_data[ ticket['created_by_id'] ] = User.user_data_full( ticket['created_by_id'] )
end
# do query
users = User.search(
:query => params[:term],
:limit => params[:limit],
:current_user => current_user,
)
user_result = []
users.each do |user|
user_result.push user.id
users_data[ user.id ] = User.user_data_full( user.id )
end
organizations = Organization.search(
:query => params[:term],
:limit => params[:limit],
:current_user => current_user,
)
organizations_data = {}
organization_result = []
organizations.each do |organization|
organization_result.push organization.id
organizations_data[ organization.id ] = Organization.find( organization.id )
end
result = []
if ticket_result[0]
data = {
:name => 'Ticket',
:ids => ticket_result,
}
result.push data
end
if user_result[0]
data = {
:name => 'User',
:ids => user_result,
}
result.push data
end
if organization_result[0]
data = {
:name => 'Organization',
:ids => organization_result,
}
result.push data
end
# return result
render :json => {
:load => {
:tickets => tickets,
:users => users_data,
:organizations => organizations_data,
},
:result => result,
}
end
end

View file

@ -445,48 +445,25 @@ class TicketsController < ApplicationController
# GET /api/tickets/search # GET /api/tickets/search
def search def search
# get params
query = params[:term]
limit = params[:limit] || 15
conditions = []
if current_user.is_role('Agent')
group_ids = Group.select( 'groups.id' ).joins(:users).
where( 'groups_users.user_id = ?', current_user.id ).
where( 'groups.active = ?', true ).
map( &:id )
conditions = [ 'group_id IN (?)', group_ids ]
else
if !current_user.organization || ( !current_user.organization.shared || current_user.organization.shared == false )
conditions = [ 'customer_id = ?', current_user.id ]
else
conditions = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
end
end
# do query
tickets_all = Ticket.select('DISTINCT(tickets.id)').
where(conditions).
where( '( `tickets`.`title` LIKE ? OR `tickets`.`number` LIKE ? OR `ticket_articles`.`body` LIKE ? OR `ticket_articles`.`from` LIKE ? OR `ticket_articles`.`to` LIKE ? OR `ticket_articles`.`subject` LIKE ?)', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%" ).
joins(:articles).
limit(limit).
order('`tickets`.`created_at` DESC')
# build result list # build result list
tickets = [] tickets = Ticket.search(
users = {} :limit => params[:limit],
tickets_all.each do |ticket| :query => params[:term],
ticket_tmp = Ticket.lookup( :id => ticket.id ) :current_user => current_user,
tickets.push ticket_tmp )
users[ ticket['owner_id'] ] = User.user_data_full( ticket_tmp['owner_id'] ) users_data = {}
users[ ticket['customer_id'] ] = User.user_data_full( ticket_tmp['customer_id'] ) ticket_result = []
users[ ticket['created_by_id'] ] = User.user_data_full( ticket_tmp['created_by_id'] ) tickets.each do |ticket|
ticket_result.push ticket.id
users_data[ ticket['owner_id'] ] = User.user_data_full( ticket['owner_id'] )
users_data[ ticket['customer_id'] ] = User.user_data_full( ticket['customer_id'] )
users_data[ ticket['created_by_id'] ] = User.user_data_full( ticket['created_by_id'] )
end end
# return result # return result
render :json => { render :json => {
:tickets => tickets, :tickets => ticket_result,
:users => users, :users => users_data,
} }
end end

View file

@ -306,16 +306,11 @@ curl http://localhost/api/users/2.json -v -u #{login}:#{password} -H "Content-Ty
# GET /api/users/search # GET /api/users/search
def search def search
# get params
query = params[:term]
limit = params[:limit] || 18
# do query # do query
user_all = User.find( user_all = User.search(
:all, :query => params[:term],
:limit => limit, :limit => params[:limit],
:conditions => ['firstname LIKE ? or lastname LIKE ? or email LIKE ?', "%#{query}%", "%#{query}%", "%#{query}%"], :current_user => current_user,
:order => 'firstname'
) )
# build result list # build result list

View file

@ -1,4 +1,25 @@
class Organization < ApplicationModel class Organization < ApplicationModel
has_and_belongs_to_many :users has_and_belongs_to_many :users
validates :name, :presence => true validates :name, :presence => true
def self.search(params)
# get params
query = params[:query]
limit = params[:limit] || 10
current_user = params[:current_user]
# enable search only for agents and admins
return [] if !current_user.is_role('Agent') && !current_user.is_role('Admin')
# do query
organizations = Organization.find(
:all,
:limit => limit,
:conditions => ['name LIKE ?', "%#{query}%"],
:order => 'name'
)
return organizations
end
end end

View file

@ -247,6 +247,26 @@ Your #{config.product_name} Team
return user return user
end end
def self.search(params)
# get params
query = params[:query]
limit = params[:limit] || 10
current_user = params[:current_user]
# enable search only for agents and admins
return [] if !current_user.is_role('Agent') && !current_user.is_role('Admin')
# do query
users = User.find(
:all,
:limit => limit,
:conditions => ['(firstname LIKE ? or lastname LIKE ? or email LIKE ?) AND id != 1', "%#{query}%", "%#{query}%", "%#{query}%"],
:order => 'firstname'
)
return users
end
def self.find_fulldata(user_id) def self.find_fulldata(user_id)
cache = self.cache_get(user_id, true) cache = self.cache_get(user_id, true)

9
config/routes/search.rb Normal file
View file

@ -0,0 +1,9 @@
module ExtraRoutes
def add(map)
# search
map.match '/api/search', :to => 'search#search', :via => [:get, :post]
end
module_function :add
end

View file

@ -1578,6 +1578,7 @@ Translation.create_if_not_exists( :locale => 'de', :source => "Settings", :targe
Translation.create_if_not_exists( :locale => 'de', :source => "Overviews", :target => "Übersichten" ) Translation.create_if_not_exists( :locale => 'de', :source => "Overviews", :target => "Übersichten" )
Translation.create_if_not_exists( :locale => 'de', :source => "Manage", :target => "Verwalten" ) Translation.create_if_not_exists( :locale => 'de', :source => "Manage", :target => "Verwalten" )
Translation.create_if_not_exists( :locale => 'de', :source => "Users", :target => "Benutzer" ) Translation.create_if_not_exists( :locale => 'de', :source => "Users", :target => "Benutzer" )
Translation.create_if_not_exists( :locale => 'de', :source => "User", :target => "Benutzer" )
Translation.create_if_not_exists( :locale => 'de', :source => "Groups", :target => "Gruppen" ) Translation.create_if_not_exists( :locale => 'de', :source => "Groups", :target => "Gruppen" )
Translation.create_if_not_exists( :locale => 'de', :source => "Group", :target => "Gruppe" ) Translation.create_if_not_exists( :locale => 'de', :source => "Group", :target => "Gruppe" )
Translation.create_if_not_exists( :locale => 'de', :source => "Organizations", :target => "Organisationen" ) Translation.create_if_not_exists( :locale => 'de', :source => "Organizations", :target => "Organisationen" )