Init version of new search.
This commit is contained in:
parent
08eee6f86c
commit
79d5dfdd76
13 changed files with 289 additions and 67 deletions
|
@ -219,12 +219,39 @@ 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
|
||||||
$('.popover-inner').parent().remove()
|
$('.popover-inner').parent().remove()
|
||||||
|
|
||||||
# show user popup
|
# show user popup
|
||||||
$('.user-data').popover(
|
$('.user-data').popover(
|
||||||
trigger: 'hover'
|
trigger: 'hover'
|
||||||
html: true
|
html: true
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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: %>
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<table style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<td><%- @P( @organization ) %></td>
|
||||||
|
<td>...</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
17
app/assets/javascripts/app/views/ticket_info_small.jst.eco
Normal file
17
app/assets/javascripts/app/views/ticket_info_small.jst.eco
Normal 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>
|
80
app/controllers/search_controller.rb
Normal file
80
app/controllers/search_controller.rb
Normal 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
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
9
config/routes/search.rb
Normal 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
|
|
@ -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" )
|
||||||
|
|
Loading…
Reference in a new issue