First version of user and organisation zoom.
This commit is contained in:
parent
a0c15166ae
commit
5581324823
9 changed files with 328 additions and 35 deletions
|
@ -0,0 +1,132 @@
|
|||
class App.DashboardTicketSearch extends App.Controller
|
||||
events:
|
||||
'click [data-type=page]': 'page'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
@start_page = 1
|
||||
@navupdate '#'
|
||||
|
||||
# render
|
||||
@fetch()
|
||||
|
||||
fetch: (force) =>
|
||||
|
||||
@ajax(
|
||||
id: 'dashboard_ticket_search' + @name,
|
||||
type: 'GET',
|
||||
url: @apiPath + '/tickets/search',
|
||||
data:
|
||||
condition: @condition
|
||||
order: @order
|
||||
detail: true
|
||||
limit: 200
|
||||
processData: true,
|
||||
success: (data) =>
|
||||
|
||||
@load( data, true )
|
||||
)
|
||||
|
||||
load: (data = false, ajax = false) =>
|
||||
|
||||
if ajax
|
||||
App.Store.write( 'dashboard_ticket_search' + @name, data )
|
||||
|
||||
# load assets
|
||||
App.Collection.loadAssets( data.assets )
|
||||
|
||||
@render( data )
|
||||
|
||||
else
|
||||
data = App.Store.get( 'dashboard_ticket_search' + @name )
|
||||
if data
|
||||
@render( data )
|
||||
|
||||
|
||||
render: (data) ->
|
||||
return if !data
|
||||
return if !data.tickets
|
||||
|
||||
@overview =
|
||||
name: @name
|
||||
@tickets_count = data.tickets_count
|
||||
@ticket_ids = data.tickets
|
||||
per_page = @per_page || 5
|
||||
pages_total = parseInt( ( @tickets_count / per_page ) + 0.99999 ) || 1
|
||||
html = App.view('dashboard/ticket')(
|
||||
overview: @overview,
|
||||
pages_total: pages_total,
|
||||
start_page: @start_page,
|
||||
)
|
||||
html = $(html)
|
||||
html.find('li').removeClass('active')
|
||||
html.find(".page [data-id=\"#{@start_page}\"]").parents('li').addClass('active')
|
||||
|
||||
@tickets_in_table = []
|
||||
start = ( @start_page-1 ) * 5
|
||||
end = ( @start_page ) * 5
|
||||
i = start
|
||||
while i < end
|
||||
i = i + 1
|
||||
if @ticket_ids[ i - 1 ]
|
||||
@tickets_in_table.push App.Ticket.fullLocal( @ticket_ids[ i - 1 ] )
|
||||
|
||||
openTicket = (id,e) =>
|
||||
ticket = App.Ticket.fullLocal(id)
|
||||
@navigate ticket.uiUrl()
|
||||
callbackTicketTitleAdd = (value, object, attribute, attributes, refObject) =>
|
||||
attribute.title = object.title
|
||||
value
|
||||
callbackLinkToTicket = (value, object, attribute, attributes, refObject) =>
|
||||
attribute.link = object.uiUrl()
|
||||
value
|
||||
callbackResetLink = (value, object, attribute, attributes, refObject) =>
|
||||
attribute.link = undefined
|
||||
value
|
||||
callbackUserPopover = (value, object, attribute, attributes, refObject) =>
|
||||
attribute.class = 'user-popover'
|
||||
attribute.data =
|
||||
id: refObject.id
|
||||
value
|
||||
|
||||
new App.ControllerTable(
|
||||
overview: @view.d
|
||||
el: html.find('.table-overview'),
|
||||
model: App.Ticket
|
||||
objects: @tickets_in_table,
|
||||
checkbox: false
|
||||
groupBy: @group_by
|
||||
bindRow:
|
||||
events:
|
||||
'click': openTicket
|
||||
callbackAttributes:
|
||||
customer_id:
|
||||
[ callbackResetLink, callbackUserPopover ]
|
||||
owner_id:
|
||||
[ callbackResetLink, callbackUserPopover ]
|
||||
title:
|
||||
[ callbackLinkToTicket, callbackTicketTitleAdd ]
|
||||
number:
|
||||
[ callbackLinkToTicket, callbackTicketTitleAdd ]
|
||||
)
|
||||
|
||||
@html html
|
||||
|
||||
# show frontend times
|
||||
@frontendTimeUpdate()
|
||||
|
||||
# start user popups
|
||||
@userPopups()
|
||||
|
||||
zoom: (e) =>
|
||||
e.preventDefault()
|
||||
id = $(e.target).parents('[data-id]').data('id')
|
||||
|
||||
@navigate 'ticket/zoom/' + id
|
||||
|
||||
page: (e) =>
|
||||
e.preventDefault()
|
||||
id = $(e.target).data('id')
|
||||
@start_page = id
|
||||
@load()
|
||||
|
|
@ -2,7 +2,7 @@ class Index extends App.ControllerContent
|
|||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
|
||||
# check authentication
|
||||
return if !@authenticate()
|
||||
|
||||
|
|
|
@ -38,6 +38,11 @@ class App.OrganizationZoom extends App.Controller
|
|||
organization: organization
|
||||
)
|
||||
|
||||
new Overviews(
|
||||
el: @el
|
||||
organization: organization
|
||||
)
|
||||
|
||||
new App.UpdateTastbar(
|
||||
genericObject: organization
|
||||
)
|
||||
|
@ -60,6 +65,55 @@ class App.OrganizationZoom extends App.Controller
|
|||
ui: @
|
||||
)
|
||||
|
||||
class Overviews extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# subscribe and reload data / fetch new data if triggered
|
||||
@subscribeId = App.Organization.full( @organization.id, @render, false, true )
|
||||
|
||||
release: =>
|
||||
App.Organization.unsubscribe(@subscribeId)
|
||||
|
||||
render: (organization) =>
|
||||
|
||||
plugins =
|
||||
main:
|
||||
my_organization:
|
||||
controller: App.DashboardTicketSearch,
|
||||
params:
|
||||
name: 'Tickets of Organization'
|
||||
condition:
|
||||
'tickets.state_id': [ 1,2,3,4,6 ]
|
||||
'tickets.organization_id': organization.id
|
||||
order:
|
||||
by: 'created_at'
|
||||
direction: 'DESC'
|
||||
view:
|
||||
d: [ 'number', 'title', 'customer', 'state', 'priority', 'created_at' ]
|
||||
view_mode_default: 'd'
|
||||
|
||||
for area, plugins of plugins
|
||||
for name, plugin of plugins
|
||||
target = area + '_' + name
|
||||
@el.find('.' + area + '-overviews').append('<div class="" id="' + target + '"></div>')
|
||||
if plugin.controller
|
||||
params = plugin.params || {}
|
||||
params.el = @el.find( '#' + target )
|
||||
new plugin.controller( params )
|
||||
|
||||
dndOptions =
|
||||
handle: 'h2.can-move'
|
||||
placeholder: 'can-move-plcaeholder'
|
||||
tolerance: 'pointer'
|
||||
distance: 15
|
||||
opacity: 0.6
|
||||
forcePlaceholderSize: true
|
||||
|
||||
@el.find( '#sortable' ).sortable( dndOptions )
|
||||
@el.find( '#sortable-sidebar' ).sortable( dndOptions )
|
||||
|
||||
|
||||
class Widgets extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
|
|
|
@ -34,10 +34,16 @@ class App.UserZoom extends App.Controller
|
|||
|
||||
render: (user) =>
|
||||
|
||||
|
||||
@html App.view('user_zoom')(
|
||||
user: user
|
||||
)
|
||||
|
||||
new Overviews(
|
||||
el: @el
|
||||
user: user
|
||||
)
|
||||
|
||||
new App.UpdateTastbar(
|
||||
genericObject: user
|
||||
)
|
||||
|
@ -60,6 +66,74 @@ class App.UserZoom extends App.Controller
|
|||
ui: @
|
||||
)
|
||||
|
||||
class Overviews extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# subscribe and reload data / fetch new data if triggered
|
||||
@subscribeId = App.User.full( @user.id, @render, false, true )
|
||||
|
||||
release: =>
|
||||
App.User.unsubscribe(@subscribeId)
|
||||
|
||||
render: (user) =>
|
||||
|
||||
plugins = {
|
||||
main: {
|
||||
my_assigned: {
|
||||
controller: App.DashboardTicketSearch,
|
||||
params: {
|
||||
name: 'Tickets of User'
|
||||
condition:
|
||||
'tickets.state_id': [ 1,2,3,4,6 ]
|
||||
'tickets.customer_id': user.id
|
||||
order:
|
||||
by: 'created_at'
|
||||
direction: 'DESC'
|
||||
view:
|
||||
d: [ 'number', 'title', 'state', 'priority', 'created_at' ]
|
||||
view_mode_default: 'd'
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if user.organization_id
|
||||
plugins.main.my_organization = {
|
||||
controller: App.DashboardTicketSearch,
|
||||
params: {
|
||||
name: 'Tickets of Organization'
|
||||
condition:
|
||||
'tickets.state_id': [ 1,2,3,4,6 ]
|
||||
'tickets.organization_id': user.organization_id
|
||||
order:
|
||||
by: 'created_at'
|
||||
direction: 'DESC'
|
||||
view:
|
||||
d: [ 'number', 'title', 'customer', 'state', 'priority', 'created_at' ]
|
||||
view_mode_default: 'd'
|
||||
},
|
||||
}
|
||||
|
||||
for area, plugins of plugins
|
||||
for name, plugin of plugins
|
||||
target = area + '_' + name
|
||||
@el.find('.' + area + '-overviews').append('<div class="" id="' + target + '"></div>')
|
||||
if plugin.controller
|
||||
params = plugin.params || {}
|
||||
params.el = @el.find( '#' + target )
|
||||
new plugin.controller( params )
|
||||
|
||||
dndOptions =
|
||||
handle: 'h2.can-move'
|
||||
placeholder: 'can-move-plcaeholder'
|
||||
tolerance: 'pointer'
|
||||
distance: 15
|
||||
opacity: 0.6
|
||||
forcePlaceholderSize: true
|
||||
|
||||
@el.find( '#sortable' ).sortable( dndOptions )
|
||||
@el.find( '#sortable-sidebar' ).sortable( dndOptions )
|
||||
|
||||
class Widgets extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="span9">
|
||||
<div class="page-header clearfix">
|
||||
<div class="page-header-title">
|
||||
<h2 class="can-move"><%- @T( @overview.name ) %> <small><a href="#" data-type="settings" class="glyphicon glyphicon-edit"></a></small></h2>
|
||||
<h2 class="can-move"><%- @T( @overview.name ) %> <small><% if @overview.id: %><a href="#" data-type="settings" class="glyphicon glyphicon-edit"></a><% end %></small></h2>
|
||||
</div>
|
||||
<div class="page-header-meta">
|
||||
<ul class="pagination">
|
||||
|
|
|
@ -9,10 +9,7 @@
|
|||
<h1></h1>
|
||||
</div>
|
||||
|
||||
<div class="ticket-answer">
|
||||
<div class="article-view"></div>
|
||||
<div class="edit"></div>
|
||||
</div>
|
||||
<div class="main-overviews" id="sortable"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -9,10 +9,7 @@
|
|||
<h1></h1>
|
||||
</div>
|
||||
|
||||
<div class="ticket-answer">
|
||||
<div class="article-view"></div>
|
||||
<div class="edit"></div>
|
||||
</div>
|
||||
<div class="main-overviews" id="sortable"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -364,7 +364,9 @@ class TicketsController < ApplicationController
|
|||
tickets = Ticket.search(
|
||||
:limit => params[:limit],
|
||||
:query => params[:term],
|
||||
:condition => params[:condition],
|
||||
:current_user => current_user,
|
||||
:detail => params[:detail]
|
||||
)
|
||||
assets = {}
|
||||
ticket_result = []
|
||||
|
@ -375,8 +377,9 @@ class TicketsController < ApplicationController
|
|||
|
||||
# return result
|
||||
render :json => {
|
||||
:tickets => ticket_result,
|
||||
:assets => assets,
|
||||
:tickets => ticket_result,
|
||||
:tickets_count => tickets.count,
|
||||
:assets => assets,
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -16,6 +16,20 @@ returns
|
|||
|
||||
result = [ticket_model1, ticket_model2]
|
||||
|
||||
|
||||
search tickets
|
||||
|
||||
result = Ticket.search(
|
||||
:current_user => User.find(123),
|
||||
:query => 'search something',
|
||||
:limit => 15,
|
||||
:full => 0
|
||||
)
|
||||
|
||||
returns
|
||||
|
||||
result = [1,3,5,6,7]
|
||||
|
||||
=end
|
||||
|
||||
def search (params)
|
||||
|
@ -24,9 +38,13 @@ returns
|
|||
query = params[:query]
|
||||
limit = params[:limit] || 12
|
||||
current_user = params[:current_user]
|
||||
full = false
|
||||
if params[:full] || !params.has_key?(:full)
|
||||
full = true
|
||||
end
|
||||
|
||||
# try search index backend
|
||||
if SearchIndexBackend.enabled?
|
||||
if !params[:detail] && SearchIndexBackend.enabled?
|
||||
query_extention = {}
|
||||
query_extention['bool'] = {}
|
||||
query_extention['bool']['must'] = []
|
||||
|
@ -39,28 +57,31 @@ returns
|
|||
groups.each {|group|
|
||||
group_condition.push group.name
|
||||
}
|
||||
condition = {
|
||||
access_condition = {
|
||||
'query_string' => { 'default_field' => 'Ticket.group.name', 'query' => "\"#{group_condition.join('" OR "')}\"" }
|
||||
}
|
||||
query_extention['bool']['must'].push condition
|
||||
query_extention['bool']['must'].push access_condition
|
||||
else
|
||||
if !current_user.organization || ( !current_user.organization.shared || current_user.organization.shared == false )
|
||||
condition = {
|
||||
access_condition = {
|
||||
'query_string' => { 'default_field' => 'Ticket.customer_id', 'query' => current_user.id }
|
||||
}
|
||||
# customer_id: XXX
|
||||
# conditions = [ 'customer_id = ?', current_user.id ]
|
||||
else
|
||||
condition = {
|
||||
access_condition = {
|
||||
'query_string' => { 'query' => "Ticket.customer_id:#{current_user.id} OR Ticket.organization_id:#{current_user.organization.id}" }
|
||||
}
|
||||
# customer_id: XXX OR organization_id: XXX
|
||||
# conditions = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
|
||||
end
|
||||
query_extention['bool']['must'].push condition
|
||||
query_extention['bool']['must'].push access_condition
|
||||
end
|
||||
|
||||
ids = SearchIndexBackend.search( query, limit, 'Ticket', query_extention )
|
||||
if !full
|
||||
return ids
|
||||
end
|
||||
tickets = []
|
||||
ids.each { |id|
|
||||
tickets.push Ticket.lookup( :id => id )
|
||||
|
@ -69,38 +90,53 @@ returns
|
|||
end
|
||||
|
||||
# fallback do sql query
|
||||
conditions = []
|
||||
access_condition = []
|
||||
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 ]
|
||||
access_condition = [ '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 ]
|
||||
access_condition = [ 'customer_id = ?', current_user.id ]
|
||||
else
|
||||
conditions = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
|
||||
access_condition = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
|
||||
end
|
||||
end
|
||||
|
||||
# do query
|
||||
# - stip out * we already search for *query* -
|
||||
query.gsub! '*', ''
|
||||
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).
|
||||
order('`tickets`.`created_at` DESC').
|
||||
limit(limit)
|
||||
|
||||
# build result list
|
||||
tickets = []
|
||||
tickets_all.each do |ticket|
|
||||
tickets.push Ticket.lookup( :id => ticket.id )
|
||||
if query
|
||||
query.gsub! '*', ''
|
||||
tickets_all = Ticket.select('DISTINCT(tickets.id)').
|
||||
where(access_condition).
|
||||
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).
|
||||
order('`tickets`.`created_at` DESC').
|
||||
limit(limit)
|
||||
else
|
||||
tickets_all = Ticket.select('DISTINCT(tickets.id)').
|
||||
where(access_condition).
|
||||
where(params[:condition]).
|
||||
order('`tickets`.`created_at` DESC').
|
||||
limit(limit)
|
||||
end
|
||||
|
||||
tickets
|
||||
# build result list
|
||||
if !full
|
||||
ids = []
|
||||
tickets_all.each { |ticket|
|
||||
ids.push ticket.id
|
||||
}
|
||||
return ids
|
||||
end
|
||||
|
||||
tickets = []
|
||||
tickets_all.each { |ticket|
|
||||
tickets.push Ticket.lookup( :id => ticket.id )
|
||||
}
|
||||
return tickets
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue