Merge branch 'develop' into feature/ui2

This commit is contained in:
Martin Edenhofer 2013-08-19 17:39:31 +02:00
commit 42bf690ec4
41 changed files with 773 additions and 548 deletions

View file

@ -1,10 +1,6 @@
class App.DashboardActivityStream extends App.Controller class App.DashboardActivityStream extends App.Controller
events:
'click [data-type=edit]': 'zoom'
constructor: -> constructor: ->
super super
@items = []
@fetch() @fetch()
@ -36,34 +32,29 @@ class App.DashboardActivityStream extends App.Controller
load: (data) => load: (data) =>
items = data.activity_stream items = data.activity_stream
# load user collection # load collections
App.Collection.load( type: 'User', data: data.users ) App.Event.trigger 'loadAssets', data.assets
# load ticket collection
App.Collection.load( type: 'Ticket', data: data.tickets )
# load article collection
App.Collection.load( type: 'TicketArticle', data: data.articles )
@render(items) @render(items)
render: (items) -> render: (items) ->
# load user data
for item in items for item in items
item.created_by = App.User.find( item.created_by_id )
# load ticket data
for item in items
item.data = {}
if item.history_object is 'Ticket' if item.history_object is 'Ticket'
item.data.title = App.Ticket.find( item.o_id ).title ticket = App.Ticket.find( item.o_id )
if item.history_object is 'Ticket::Article' item.link = '#ticket/zoom/' + ticket.id
item.title = ticket.title
item.type = 'Ticket'
item.updated_by_id = ticket.updated_by_id
item.updated_by = App.User.find( ticket.updated_by_id )
else if item.history_object is 'Ticket::Article'
article = App.TicketArticle.find( item.o_id ) article = App.TicketArticle.find( item.o_id )
item.history_object = 'Article' ticket = App.Ticket.find( article.ticket_id )
item.sub_o_id = article.id item.link = '#ticket/zoom/' + ticket.id + '/' + article.id
item.o_id = article.ticket_id item.title = article.subject || ticket.title
item.data.title = article.subject item.type = 'Article'
item.updated_by_id = article.updated_by_id
item.updated_by = App.User.find( article.updated_by_id )
html = App.view('dashboard/activity_stream')( html = App.view('dashboard/activity_stream')(
head: 'Activity Stream', head: 'Activity Stream',
@ -76,11 +67,3 @@ class App.DashboardActivityStream extends App.Controller
# start user popups # start user popups
@userPopups('left') @userPopups('left')
zoom: (e) =>
e.preventDefault()
id = $(e.target).parents('[data-id]').data('id')
subid = $(e.target).parents('[data-subid]').data('subid')
if subid
@navigate 'ticket/zoom/' + id + '/' + subid
else
@navigate 'ticket/zoom/' + id

View file

@ -1,7 +1,4 @@
class App.DashboardRecentViewed extends App.Controller class App.DashboardRecentViewed extends App.Controller
events:
'click [data-type=edit]': 'zoom'
constructor: -> constructor: ->
super super
@ -16,28 +13,21 @@ class App.DashboardRecentViewed extends App.Controller
limit: 5, limit: 5,
} }
processData: true, processData: true,
# data: JSON.stringify( view: @view ),
success: (data, status, xhr) => success: (data, status, xhr) =>
@items = data.recent_viewed @items = data.recent_viewed
# load user collection # load collections
App.Collection.load( type: 'User', data: data.users ) App.Event.trigger 'loadAssets', data.assets
# load ticket collection
App.Collection.load( type: 'Ticket', data: data.tickets )
@render() @render()
) )
render: -> render: ->
# load user data
for item in @items for item in @items
item.created_by = App.User.find( item.created_by_id ) item.link = '#ticket_zoom/' + item.o_id
item.title = App.Ticket.find( item.o_id ).title
# load ticket data item.type = item.recent_view_object
for item in @items
item.ticket = App.User.find( item.o_id )
html = App.view('dashboard/recent_viewed')( html = App.view('dashboard/recent_viewed')(
head: 'Recent Viewed', head: 'Recent Viewed',
@ -49,9 +39,3 @@ class App.DashboardRecentViewed extends App.Controller
# start user popups # start user popups
@userPopups('left') @userPopups('left')
zoom: (e) =>
e.preventDefault()
id = $(e.target).parents('[data-id]').data('id')
@navigate 'ticket/zoom/' + id

View file

@ -48,11 +48,8 @@ class App.DashboardTicket extends App.Controller
data.ajax = false data.ajax = false
App.Store.write( @key, data ) App.Store.write( @key, data )
# load user collection # load collections
App.Collection.load( type: 'User', data: data.collections.users ) App.Event.trigger 'loadAssets', data.assets
# load ticket collection
App.Collection.load( type: 'Ticket', data: data.collections.tickets )
# get meta data # get meta data
App.Overview.refresh( data.overview, options: { clear: true } ) App.Overview.refresh( data.overview, options: { clear: true } )
@ -71,12 +68,12 @@ class App.DashboardTicket extends App.Controller
render: (data) -> render: (data) ->
return if !data return if !data
return if !data.ticket_list return if !data.ticket_ids
return if !data.overview return if !data.overview
@overview = data.overview @overview = data.overview
@tickets_count = data.tickets_count @tickets_count = data.tickets_count
@ticket_list = data.ticket_list @ticket_ids = data.ticket_ids
# FIXME 10 # FIXME 10
pages_total = parseInt( ( @tickets_count / 10 ) + 0.99999 ) || 1 pages_total = parseInt( ( @tickets_count / 10 ) + 0.99999 ) || 1
html = App.view('dashboard/ticket')( html = App.view('dashboard/ticket')(
@ -94,8 +91,8 @@ class App.DashboardTicket extends App.Controller
i = start i = start
while i < end while i < end
i = i + 1 i = i + 1
if @ticket_list[ i - 1 ] if @ticket_ids[ i - 1 ]
@tickets_in_table.push App.Ticket.retrieve( @ticket_list[ i - 1 ] ) @tickets_in_table.push App.Ticket.retrieve( @ticket_ids[ i - 1 ] )
shown_all_attributes = @ticketTableAttributes( App.Overview.find(@overview.id).view.d ) shown_all_attributes = @ticketTableAttributes( App.Overview.find(@overview.id).view.d )
new App.ControllerTable( new App.ControllerTable(

View file

@ -35,12 +35,18 @@ class App.TicketCreate extends App.Controller
title: 'Email' title: 'Email'
@article_attributes = article_sender_type_map[@type] @article_attributes = article_sender_type_map[@type]
# remember split info if exists
split = ''
if @ticket_id && @article_id
split = "/#{@ticket_id}/#{@article_id}"
# if no map entry exists, route to default # if no map entry exists, route to default
if !@article_attributes if !@article_attributes
@navigate '#ticket_create/' + default_type @navigate '#ticket_create/' + default_type + split
return
# update navbar highlighting # update navbar highlighting
@navupdate '#ticket_create/' + @type + '/id/' + @id @navupdate '#ticket_create/' + @type + '/id/' + @id + split
@fetch(params) @fetch(params)
@ -97,8 +103,8 @@ class App.TicketCreate extends App.Controller
# get edit form attributes # get edit form attributes
@edit_form = cache.edit_form @edit_form = cache.edit_form
# load user collection # load collections
App.Collection.load( type: 'User', data: cache.users ) App.Event.trigger 'loadAssets', cache.assets
@render() @render()
else else
@ -118,17 +124,11 @@ class App.TicketCreate extends App.Controller
# get edit form attributes # get edit form attributes
@edit_form = data.edit_form @edit_form = data.edit_form
# load user collection # load collections
App.Collection.load( type: 'User', data: data.users ) App.Event.trigger 'loadAssets', data.assets
# load ticket collection # split ticket
if data.ticket && data.articles if data.split && data.split.ticket_id && data.split.article_id
App.Collection.load( type: 'Ticket', data: [data.ticket] )
# load article collections
App.Collection.load( type: 'TicketArticle', data: data.articles || [] )
# render page
t = App.Ticket.find( params.ticket_id ).attributes() t = App.Ticket.find( params.ticket_id ).attributes()
a = App.TicketArticle.find( params.article_id ) a = App.TicketArticle.find( params.article_id )
@ -137,6 +137,8 @@ class App.TicketCreate extends App.Controller
t.customer_id_autocompletion = a.from t.customer_id_autocompletion = a.from
t.subject = a.subject || t.title t.subject = a.subject || t.title
t.body = a.body t.body = a.body
# render page
@render( options: t ) @render( options: t )
) )
@ -209,9 +211,8 @@ class App.TicketCreate extends App.Controller
# update text module UI # update text module UI
callback = (user) => callback = (user) =>
@textModule.reload( @textModule.reload(
data: ticket:
ticket: customer: user
customer: user
) )
@userInfo( @userInfo(
@ -386,8 +387,13 @@ class TicketCreateRouter extends App.ControllerPermanent
# create new uniq form id # create new uniq form id
if !params['id'] if !params['id']
# remember split info if exists
split = ''
if params['ticket_id'] && params['article_id']
split = "/#{params['ticket_id']}/#{params['article_id']}"
id = Math.floor( Math.random() * 99999 ) id = Math.floor( Math.random() * 99999 )
@navigate "#ticket_create/#{params['type']}/id/#{id}" @navigate "#ticket_create/#{params['type']}/id/#{id}#{split}"
return return
# cleanup params # cleanup params
@ -399,14 +405,16 @@ class TicketCreateRouter extends App.ControllerPermanent
App.TaskManager.add( 'TicketCreateScreen-' + params['type'] + '-' + params['id'], 'TicketCreate', clean_params ) App.TaskManager.add( 'TicketCreateScreen-' + params['type'] + '-' + params['id'], 'TicketCreate', clean_params )
# split ticket
App.Config.set( 'ticket_create/:ticket_id/:article_id', TicketCreateRouter, 'Routes' )
# create new ticket routs/controller # create new ticket routs/controller
App.Config.set( 'ticket_create', TicketCreateRouter, 'Routes' ) App.Config.set( 'ticket_create', TicketCreateRouter, 'Routes' )
App.Config.set( 'ticket_create/:type', TicketCreateRouter, 'Routes' ) App.Config.set( 'ticket_create/:type', TicketCreateRouter, 'Routes' )
App.Config.set( 'ticket_create/:type/id/:id', TicketCreateRouter, 'Routes' ) App.Config.set( 'ticket_create/:type/id/:id', TicketCreateRouter, 'Routes' )
# split ticket
App.Config.set( 'ticket_create/:type/:ticket_id/:article_id', TicketCreateRouter, 'Routes' )
App.Config.set( 'ticket_create/:type/id/:id/:ticket_id/:article_id', TicketCreateRouter, 'Routes' )
# set new task actions # set new task actions
App.Config.set( 'TicketNewCallOutbound', { prio: 8001, name: 'Call Outbound', target: '#ticket_create/call_outbound', role: ['Agent'] }, 'TaskActions' ) App.Config.set( 'TicketNewCallOutbound', { prio: 8001, name: 'Call Outbound', target: '#ticket_create/call_outbound', role: ['Agent'] }, 'TaskActions' )
App.Config.set( 'TicketNewCallInbound', { prio: 8002, name: 'Call Inbound', target: '#ticket_create/call_inbound', role: ['Agent'] }, 'TaskActions' ) App.Config.set( 'TicketNewCallInbound', { prio: 8002, name: 'Call Inbound', target: '#ticket_create/call_inbound', role: ['Agent'] }, 'TaskActions' )

View file

@ -15,23 +15,9 @@ class App.TicketHistory extends App.ControllerModal
type: 'GET', type: 'GET',
url: @apiPath + '/ticket_history/' + ticket_id, url: @apiPath + '/ticket_history/' + ticket_id,
success: (data, status, xhr) => success: (data, status, xhr) =>
# remember ticket
@ticket = data.ticket
# load user collection # load collections
App.Collection.load( type: 'User', data: data.users ) App.Event.trigger 'loadAssets', data.assets
# load ticket collection
App.Collection.load( type: 'Ticket', data: [data.ticket] )
# load history_type collections
App.Collection.load( type: 'HistoryType', data: data.history_types )
# load history_object collections
App.Collection.load( type: 'HistoryObject', data: data.history_objects )
# load history_attributes collections
App.Collection.load( type: 'HistoryAttribute', data: data.history_attributes )
# load history collections # load history collections
App.History.deleteAll() App.History.deleteAll()
@ -53,7 +39,7 @@ class App.TicketHistory extends App.ControllerModal
@userPopups() @userPopups()
# show frontend times # show frontend times
@delay( @frontendTimeUpdate, 200, 'ui-time-update' ) @delay( @frontendTimeUpdate, 300, 'ui-time-update' )
sortorder: (e) -> sortorder: (e) ->
e.preventDefault() e.preventDefault()
@ -72,7 +58,6 @@ class App.TicketHistory extends App.ControllerModal
state: @sortstate state: @sortstate
) )
@modalShow() @modalShow()
# enable user popups # enable user popups

View file

@ -16,25 +16,23 @@ class App.TicketMerge extends App.ControllerModal
processData: true, processData: true,
success: (data, status, xhr) => success: (data, status, xhr) =>
if data.customer # load collections
App.Collection.load( type: 'Ticket', data: data.customer.tickets ) App.Event.trigger 'loadAssets', data.assets
App.Collection.load( type: 'User', data: data.customer.users )
if data.recent @ticket_ids_by_customer = data.ticket_ids_by_customer
App.Collection.load( type: 'Ticket', data: data.recent.tickets ) @ticket_ids_recent_viewed = data.ticket_ids_recent_viewed
App.Collection.load( type: 'User', data: data.recent.users )
@render( data ) @render()
) )
render: (data) -> render: ->
@html App.view('agent_ticket_merge')() @html App.view('agent_ticket_merge')()
list = [] list = []
for t in data.customer.tickets for ticket_id in @ticket_ids_by_customer
if t.id isnt @ticket_id if ticket_id isnt @ticket_id
ticketItem = App.Ticket.retrieve( t.id ) ticketItem = App.Ticket.retrieve( ticket_id )
list.push ticketItem list.push ticketItem
new App.ControllerTable( new App.ControllerTable(
el: @el.find('#ticket-merge-customer-tickets'), el: @el.find('#ticket-merge-customer-tickets'),
@ -59,9 +57,9 @@ class App.TicketMerge extends App.ControllerModal
) )
list = [] list = []
for t in data.recent.tickets for ticket_id in @ticket_ids_recent_viewed
if t.id isnt @ticket_id if ticket_id isnt @ticket_id
ticketItem = App.Ticket.retrieve( t.id ) ticketItem = App.Ticket.retrieve( ticket_id )
list.push ticketItem list.push ticketItem
new App.ControllerTable( new App.ControllerTable(
el: @el.find('#ticket-merge-recent-tickets'), el: @el.find('#ticket-merge-recent-tickets'),

View file

@ -24,13 +24,13 @@ class Index extends App.ControllerContent
# use cache # use cache
cache = App.Store.get( 'ticket_create_attributes' ) cache = App.Store.get( 'ticket_create_attributes' )
if cache && !params.ticket_id && !params.article_id if cache
# get edit form attributes # get edit form attributes
@edit_form = cache.edit_form @edit_form = cache.edit_form
# load user collection # load collections
App.Collection.load( type: 'User', data: cache.users ) App.Event.trigger 'loadAssets', cache.assets
@render() @render()
else else
@ -38,10 +38,6 @@ class Index extends App.ControllerContent
id: 'ticket_create', id: 'ticket_create',
type: 'GET', type: 'GET',
url: @apiPath + '/ticket_create', url: @apiPath + '/ticket_create',
data: {
ticket_id: params.ticket_id,
article_id: params.article_id,
},
processData: true, processData: true,
success: (data, status, xhr) => success: (data, status, xhr) =>
@ -51,27 +47,10 @@ class Index extends App.ControllerContent
# get edit form attributes # get edit form attributes
@edit_form = data.edit_form @edit_form = data.edit_form
# load user collection # load collections
App.Collection.load( type: 'User', data: data.users ) App.Event.trigger 'loadAssets', data.assets
# load ticket collection @render()
if data.ticket && data.articles
App.Collection.load( type: 'Ticket', data: [data.ticket] )
# load article collections
App.Collection.load( type: 'TicketArticle', data: data.articles || [] )
# render page
t = App.Ticket.find( params.ticket_id ).attributes()
a = App.TicketArticle.find( params.article_id )
# reset owner
t.owner_id = 0
t.customer_id_autocompletion = a.from
t.subject = a.subject || t.title
t.body = a.body
@log 'CustomerTicketCreate', 'notice', 'created', t
@render( options: t )
) )
render: (template = {}) -> render: (template = {}) ->

View file

@ -53,9 +53,9 @@ class Index extends App.ControllerContent
# }, # },
# }, # },
# recent_viewed: { recent_viewed: {
# controller: App.DashboardRecentViewed, controller: App.DashboardRecentViewed,
# } }
} }
} }

View file

@ -23,11 +23,8 @@ class App.LinkInfo extends App.Controller
success: (data, status, xhr) => success: (data, status, xhr) =>
@links = data.links @links = data.links
# load user collection # load collections
App.Collection.load( type: 'User', data: data.users ) App.Event.trigger 'loadAssets', data.assets
# load ticket collection
App.Collection.load( type: 'Ticket', data: data.tickets )
@render() @render()
) )

View file

@ -99,24 +99,8 @@ class App.Navigation extends App.Controller
processData: true, processData: true,
success: (data, status, xhr) => success: (data, status, xhr) =>
# load user collection # load collections
if data.load.users App.Event.trigger 'loadAssets', data.assets
App.Collection.load( type: 'User', data: data.load.users )
# load user collection
if data.load.organizations
for organization_id, organization of data.load.organizations
if organization.user_ids
organization.users = []
for user_id in organization.user_ids
user = App.User.find( user_id )
organization.users.push user
App.Collection.load( type: 'Organization', data: data.load.organizations )
# load ticket collection
if data.load.tickets
App.Collection.load( type: 'Ticket', data: data.load.tickets )
@result = data.result @result = data.result
for area in @result for area in @result

View file

@ -2,6 +2,7 @@ class App.TextModuleUI extends App.Controller
constructor: -> constructor: ->
super super
@lastData = {}
customItemTemplate = "<div><span />&nbsp;<small /></div>" customItemTemplate = "<div><span />&nbsp;<small /></div>"
elementFactory = (element, e) -> elementFactory = (element, e) ->
template = $(customItemTemplate).find('span') template = $(customItemTemplate).find('span')
@ -23,7 +24,7 @@ class App.TextModuleUI extends App.Controller
reload: (data = false) => reload: (data = false) =>
if data if data
@lastData = data @lastData['data'] = data
@update() @update()
update: => update: =>
@ -35,10 +36,12 @@ class App.TextModuleUI extends App.Controller
contentNew = item.content.replace( /<%=\s{0,2}(.+?)\s{0,2}%>/g, ( all, key ) -> contentNew = item.content.replace( /<%=\s{0,2}(.+?)\s{0,2}%>/g, ( all, key ) ->
key = key.replace( /@/g, 'ui.data.' ) key = key.replace( /@/g, 'ui.data.' )
varString = "#{key}" + '' varString = "#{key}" + ''
# console.log( "tag replacement env: ", ui.data)
try try
# console.log( "tag replacement: " + key, varString )
key = eval (varString) key = eval (varString)
catch error catch error
#console.log( "tag replacement: " + error ) # console.log( "tag replacement error: " + error )
key = '' key = ''
return key return key
) )

View file

@ -80,22 +80,19 @@ class Table extends App.ControllerContent
load: (data) => load: (data) =>
return if !data return if !data
return if !data.ticket_list return if !data.ticket_ids
return if !data.overview return if !data.overview
@overview = data.overview @overview = data.overview
@tickets_count = data.tickets_count @tickets_count = data.tickets_count
@ticket_list = data.ticket_list @ticket_ids = data.ticket_ids
if data.ajax if data.ajax
data.ajax = false data.ajax = false
App.Store.write( @key, data ) App.Store.write( @key, data )
# load user collection # load collections
App.Collection.load( type: 'User', data: data.collections.users ) App.Event.trigger 'loadAssets', data.assets
# load ticket collection
App.Collection.load( type: 'Ticket', data: data.collections.tickets )
# get meta data # get meta data
@overview = data.overview @overview = data.overview
@ -112,7 +109,7 @@ class Table extends App.ControllerContent
@fetch() @fetch()
@ticket_list_show = [] @ticket_list_show = []
for ticket_id in @ticket_list for ticket_id in @ticket_ids
@ticket_list_show.push App.Ticket.retrieve( ticket_id ) @ticket_list_show.push App.Ticket.retrieve( ticket_id )
# remeber bulk attributes # remeber bulk attributes
@ -556,7 +553,7 @@ class Router extends App.Controller
cache = App.Store.get( @key ) cache = App.Store.get( @key )
if cache if cache
@tickets_count = cache.tickets_count @tickets_count = cache.tickets_count
@ticket_list = cache.ticket_list @ticket_ids = cache.ticket_ids
@redirect() @redirect()
else else
@ajax( @ajax(
@ -570,7 +567,7 @@ class Router extends App.Controller
) )
load: (data) => load: (data) =>
@ticket_list = data.ticket_list @ticket_ids = data.ticket_ids
@tickets_count = data.tickets_count @tickets_count = data.tickets_count
# App.Store.write( data ) # App.Store.write( data )
@redirect() @redirect()
@ -583,19 +580,19 @@ class Router extends App.Controller
# redirect # redirect
if @direction == 'next' if @direction == 'next'
if @ticket_list[ @position ] && @ticket_list[ @position ] if @ticket_ids[ @position ] && @ticket_ids[ @position ]
position = @position + 1 position = @position + 1
@Config.set( 'LastOverviewPosition', position ) @Config.set( 'LastOverviewPosition', position )
@navigate 'ticket/zoom/' + @ticket_list[ @position ] + '/nav/true' @navigate 'ticket/zoom/' + @ticket_ids[ @position ] + '/nav/true'
else else
@navigate 'ticket/zoom/' + @ticket_list[ @position - 1 ] + '/nav/true' @navigate 'ticket/zoom/' + @ticket_ids[ @position - 1 ] + '/nav/true'
else else
if @ticket_list[ @position - 2 ] && @ticket_list[ @position - 2 ] + '/nav/true' if @ticket_ids[ @position - 2 ] && @ticket_ids[ @position - 2 ] + '/nav/true'
position = @position - 1 position = @position - 1
@Config.set( 'LastOverviewPosition', position ) @Config.set( 'LastOverviewPosition', position )
@navigate 'ticket/zoom/' + @ticket_list[ @position - 2 ] + '/nav/true' @navigate 'ticket/zoom/' + @ticket_ids[ @position - 2 ] + '/nav/true'
else else
@navigate 'ticket/zoom/' + @ticket_list[ @position - 1 ] + '/nav/true' @navigate 'ticket/zoom/' + @ticket_ids[ @position - 1 ] + '/nav/true'
App.Config.set( 'ticket_view', Index, 'Routes' ) App.Config.set( 'ticket_view', Index, 'Routes' )
App.Config.set( 'ticket_view/:view', Index, 'Routes' ) App.Config.set( 'ticket_view/:view', Index, 'Routes' )

View file

@ -27,7 +27,7 @@ class App.TicketZoom extends App.Controller
(data) => (data) =>
update = => update = =>
if data.id.toString() is @ticket_id.toString() if data.id.toString() is @ticket_id.toString()
ticket = App.Ticket.retrieve( @ticket_id ) ticket = App.Ticket.find( @ticket_id )
@log 'notice', 'TRY', data.updated_at, ticket.updated_at @log 'notice', 'TRY', data.updated_at, ticket.updated_at
if data.updated_at isnt ticket.updated_at if data.updated_at isnt ticket.updated_at
@fetch( @ticket_id, false ) @fetch( @ticket_id, false )
@ -68,28 +68,25 @@ class App.TicketZoom extends App.Controller
id: 'ticket_zoom_' + ticket_id id: 'ticket_zoom_' + ticket_id
type: 'GET' type: 'GET'
url: @apiPath + '/ticket_full/' + ticket_id + '?do_not_log=' + @doNotLog url: @apiPath + '/ticket_full/' + ticket_id + '?do_not_log=' + @doNotLog
data:
view: @view
processData: true processData: true
success: (data, status, xhr) => success: (data, status, xhr) =>
if @dataLastCall && !force
# check if ticket has changed
newTicketRaw = data.assets.tickets[ticket_id]
if @ticketUpdatedAtLastCall && !force
# return if ticket hasnt changed # return if ticket hasnt changed
return if _.isEqual( @dataLastCall.ticket, data.ticket ) return if @ticketUpdatedAtLastCall is newTicketRaw.updated_at
# trigger task notify
diff = difference( @dataLastCall.ticket, data.ticket )
@log 'diff', diff
# notify if ticket changed not by my self # notify if ticket changed not by my self
if !_.isEmpty(diff) && data.ticket.updated_by_id isnt @Session.all().id if newTicketRaw.updated_by_id isnt @Session.all().id
App.TaskManager.notify( @task_key ) App.TaskManager.notify( @task_key )
# rerender edit box # rerender edit box
@editDone = false @editDone = false
# remember current data # remember current data
@dataLastCall = data @ticketUpdatedAtLastCall = newTicketRaw.updated_at
@load(data, force) @load(data, force)
App.Store.write( @key, data ) App.Store.write( @key, data )
@ -112,20 +109,17 @@ class App.TicketZoom extends App.Controller
# reset old indexes # reset old indexes
@ticket = undefined @ticket = undefined
# remember article ids
@ticket_article_ids = data.ticket_article_ids
# get edit form attributes # get edit form attributes
@edit_form = data.edit_form @edit_form = data.edit_form
# get signature # get signature
@signature = data.signature @signature = data.signature
# load user collection # load collections
App.Collection.load( type: 'User', data: data.users ) App.Event.trigger 'loadAssets', data.assets
# load ticket collection
App.Collection.load( type: 'Ticket', data: [data.ticket] )
# load article collections
App.Collection.load( type: 'TicketArticle', data: data.articles )
# render page # render page
@render(force) @render(force)
@ -196,9 +190,10 @@ class App.TicketZoom extends App.Controller
ArticleView: => ArticleView: =>
# show article # show article
new ArticleView( new ArticleView(
ticket: @ticket ticket: @ticket
el: @el.find('.article-view') ticket_article_ids: @ticket_article_ids
ui: @ el: @el.find('.article-view')
ui: @
) )
Edit: => Edit: =>
@ -571,7 +566,7 @@ class ArticleView extends App.Controller
# get all articles # get all articles
@articles = [] @articles = []
for article_id in @ticket.article_ids for article_id in @ticket_article_ids
article = App.TicketArticle.retrieve( article_id ) article = App.TicketArticle.retrieve( article_id )
@articles.push article @articles.push article
@ -621,16 +616,16 @@ class ArticleView extends App.Controller
checkIfSignatureIsNeeded: (article_type) => checkIfSignatureIsNeeded: (article_type) =>
# add signature # add signature
if @ui.signature && @ui.signature.body && article_type.name is 'email' if @ui.signature && @ui.signature.body && article_type.name is 'email'
body = @ui.el.find('[name="body"]').val() || '' body = @ui.el.find('[name="body"]').val() || ''
regexp = new RegExp( escapeRegExp( @ui.signature.body ) , 'i') regexp = new RegExp( escapeRegExp( @ui.signature.body ) , 'i')
if !body.match(regexp) if !body.match(regexp)
body = body + "\n" + @ui.signature.body body = body + "\n" + @ui.signature.body
@ui.el.find('[name="body"]').val( body ) @ui.el.find('[name="body"]').val( body )
# update textarea size # update textarea size
@ui.el.find('[name="body"]').trigger('change') @ui.el.find('[name="body"]').trigger('change')
reply: (e) => reply: (e) =>
e.preventDefault() e.preventDefault()
@ -775,7 +770,7 @@ class Article extends App.Controller
actions.push { actions.push {
name: 'split' name: 'split'
type: 'split' type: 'split'
href: '#ticket_create/' + @article.ticket_id + '/' + @article.id href: '#ticket_create/call_inbound/' + @article.ticket_id + '/' + @article.id
} }
@article.actions = actions @article.actions = actions

View file

@ -19,6 +19,28 @@ class _collectionSingleton extends Spine.Module
constructor: (@args) -> constructor: (@args) ->
# add trigger - bind new events
App.Event.bind 'loadAssets', (data) =>
if data
for type, collections of data
if type is 'users'
type = 'User'
if type is 'tickets'
type = 'Ticket'
if type is 'ticket_article'
type = 'TicketArticle'
if type is 'organization'
type = 'Organization'
if type is 'history_object'
type = 'HistoryObject'
if type is 'history_type'
type = 'HistoryType'
if type is 'history_attribute'
type = 'HistoryAttribute'
@log 'debug', 'loadCollection:trigger', type, collections
@load( localStorage: data.localStorage, type: type, data: collections )
# add trigger - bind new events # add trigger - bind new events
App.Event.bind 'loadCollection', (data) => App.Event.bind 'loadCollection', (data) =>

View file

@ -13,3 +13,14 @@ class App.Organization extends App.Model
'name', 'name',
'shared', 'shared',
] ]
@_fillUp: (data) ->
# addd users of organization
if data['user_ids']
data['user_ids'] = []
for user_id in data['user_ids']
if App.User.exists( user_id )
user = App.User.find( user_id )
data['user_ids'].push user
data

View file

@ -2,8 +2,8 @@
<h2 class="can-move"><%- @T( @head ) %></h2> <h2 class="can-move"><%- @T( @head ) %></h2>
<dl> <dl>
<% for item in @items: %> <% for item in @items: %>
<dt><span class="user-data" data-id="<%= item.created_by_id %>">"<%= item.created_by.displayName() %>"</span></dt> <dt><span class="user-data" data-id="<%= item.updated_by_id %>">"<%= item.updated_by.displayName() %>"</span></dt>
<dd><%- @T( item.history_type ) %> <span data-id="<%= item.o_id %>" data-subid="<%= item.sub_o_id %>"><a data-type="edit" href="#"><%= item.history_object %><% if item.data.title: %> (<%= item.data.title %>)<% end %></a></span>.</dd> <dd><%- @T( item.history_type ) %> <a href="<%- item.link %>"><%= item.type %><% if item.title: %> (<%= item.title %>)<% end %></a>.</dd>
<% end %> <% end %>
</dl> </dl>
</div> </div>

View file

@ -3,7 +3,7 @@
<h2 class="can-move"><%- @T( @head ) %></h2> <h2 class="can-move"><%- @T( @head ) %></h2>
<ul> <ul>
<% for item in @items: %> <% for item in @items: %>
<li><span data-id="<%= item.o_id %>"><a data-type="edit" href="#"><%= item.history_object.name %> (<%= item.ticket.title %>)</a></span></li> <li><span data-id="<%= item.o_id %>"><a href="<%= item.link %>"><%= item.type %> (<%= item.title %>)</a></span></li>
<% end %> <% end %>
</ul> </ul>
</div> </div>

View file

@ -10,32 +10,20 @@ class LinksController < ApplicationController
:link_object_value => params[:link_object_value], :link_object_value => params[:link_object_value],
) )
# assets = {}
tickets = []
users = {}
link_list = [] link_list = []
links.each { |item| links.each { |item|
link_list.push item link_list.push item
if item['link_object'] == 'Ticket' if item['link_object'] == 'Ticket'
data = Ticket.lookup( :id => item['link_object_value'] ) ticket = Ticket.lookup( :id => item['link_object_value'] )
tickets.push data assets = ticket.assets(assets)
if !users[ data['owner_id'] ]
users[ data['owner_id'] ] = User.user_data_full( data['owner_id'] )
end
if !users[ data['customer_id'] ]
users[ data['customer_id'] ] = User.user_data_full( data['customer_id'] )
end
if !users[ data['created_by_id'] ]
users[ data['created_by_id'] ] = User.user_data_full( data['created_by_id'] )
end
end end
} }
# return result # return result
render :json => { render :json => {
:links => link_list, :links => link_list,
:tickets => tickets, :assets => assets,
:users => users,
} }
end end

View file

@ -12,13 +12,11 @@ class SearchController < ApplicationController
:query => params[:term], :query => params[:term],
:current_user => current_user, :current_user => current_user,
) )
users_data = {} assets = {}
ticket_result = [] ticket_result = []
tickets.each do |ticket| tickets.each do |ticket|
assets = ticket.assets(assets)
ticket_result.push ticket.id 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
# do query # do query
@ -30,7 +28,7 @@ class SearchController < ApplicationController
user_result = [] user_result = []
users.each do |user| users.each do |user|
user_result.push user.id user_result.push user.id
users_data[ user.id ] = User.user_data_full( user.id ) assets = user.assets(assets)
end end
organizations = Organization.search( organizations = Organization.search(
@ -39,17 +37,10 @@ class SearchController < ApplicationController
:current_user => current_user, :current_user => current_user,
) )
organizations_data = {}
organization_result = [] organization_result = []
organizations.each do |organization| organizations.each do |organization|
organization_result.push organization.id organization_result.push organization.id
organizations_data[ organization.id ] = Organization.find( organization.id ).attributes assets = organization.assets(assets)
organizations_data[ organization.id ][:user_ids] = []
users = User.where( :organization_id => organization.id ).limit(10)
users.each {|user|
users_data[ user.id ] = User.user_data_full( user.id )
organizations_data[ organization.id ][:user_ids].push user.id
}
end end
result = [] result = []
@ -77,11 +68,7 @@ class SearchController < ApplicationController
# return result # return result
render :json => { render :json => {
:load => { :assets => assets,
:tickets => tickets,
:users => users_data,
:organizations => organizations_data,
},
:result => result, :result => result,
} }
end end

View file

@ -3,12 +3,12 @@
class TicketOverviewsController < ApplicationController class TicketOverviewsController < ApplicationController
before_filter :authentication_check before_filter :authentication_check
# GET /api/v1/tickets # GET /api/v1/ticket_overviews
def show def show
# get navbar overview data # get navbar overview data
if !params[:view] if !params[:view]
result = Ticket::Overview.list( result = Ticket::Overviews.list(
:current_user => current_user, :current_user => current_user,
) )
render :json => result render :json => result
@ -17,7 +17,7 @@ class TicketOverviewsController < ApplicationController
# get real overview data # get real overview data
if params[:array] if params[:array]
overview = Ticket::Overview.list( overview = Ticket::Overviews.list(
:view => params[:view], :view => params[:view],
:current_user => current_user, :current_user => current_user,
:array => true, :array => true,
@ -36,10 +36,9 @@ class TicketOverviewsController < ApplicationController
} }
return return
end end
overview = Ticket::Overview.list( overview = Ticket::Overviews.list(
:view => params[:view], :view => params[:view],
# :view_mode => params[:view_mode], :current_user => current_user,
:current_user => User.find( current_user.id ),
:array => true, :array => true,
) )
if !overview if !overview
@ -48,20 +47,10 @@ class TicketOverviewsController < ApplicationController
end end
# get related users # get related users
users = {} assets = { :users => {} }
tickets = [] overview[:ticket_ids].each {|ticket_id|
overview[:ticket_list].each {|ticket_id| ticket = Ticket.lookup( :id => ticket_id )
data = Ticket.lookup( :id => ticket_id ) assets = ticket.assets(assets)
tickets.push data
if !users[ data['owner_id'] ]
users[ data['owner_id'] ] = User.user_data_full( data['owner_id'] )
end
if !users[ data['customer_id'] ]
users[ data['customer_id'] ] = User.user_data_full( data['customer_id'] )
end
if !users[ data['created_by_id'] ]
users[ data['created_by_id'] ] = User.user_data_full( data['created_by_id'] )
end
} }
# get groups # get groups
@ -79,8 +68,8 @@ class TicketOverviewsController < ApplicationController
Group.find(group_id).users.each {|user| Group.find(group_id).users.each {|user|
next if !agents[ user.id ] next if !agents[ user.id ]
groups_users[ group_id ].push user.id groups_users[ group_id ].push user.id
if !users[user.id] if !assets[:users][user.id]
users[user.id] = User.user_data_full(user.id) assets[:users][user.id] = User.user_data_full(user.id)
end end
} }
} }
@ -88,15 +77,12 @@ class TicketOverviewsController < ApplicationController
# return result # return result
render :json => { render :json => {
:overview => overview[:overview], :overview => overview[:overview],
:ticket_list => overview[:ticket_list], :ticket_ids => overview[:ticket_ids],
:tickets_count => overview[:tickets_count], :tickets_count => overview[:tickets_count],
:bulk => { :bulk => {
:group_id__owner_id => groups_users, :group_id__owner_id => groups_users,
}, },
:collections => { :assets => assets,
:users => users,
:tickets => tickets,
},
} }
end end

View file

@ -132,14 +132,13 @@ class TicketsController < ApplicationController
# get history of ticket # get history of ticket
history = History.list( 'Ticket', params[:id], 'Ticket::Article' ) history = History.list( 'Ticket', params[:id], 'Ticket::Article' )
# get related users # get related assets
users = {} assets = ticket.assets({})
users[ ticket.owner_id ] = User.user_data_full( ticket.owner_id )
users[ ticket.customer_id ] = User.user_data_full( ticket.customer_id )
history_list = [] history_list = []
history.each do |item| history.each do |item|
users[ item[:created_by_id] ] = User.user_data_full( item[:created_by_id] ) assets = item.assets(assets)
item_tmp = item.attributes item_tmp = item.attributes
if item['history_object'] == 'Ticket::Article' if item['history_object'] == 'Ticket::Article'
item_temp['type'] = 'Article ' + item['type'].to_s item_temp['type'] = 'Article ' + item['type'].to_s
@ -171,29 +170,22 @@ class TicketsController < ApplicationController
item_tmp.delete( 'related_o_id' ) item_tmp.delete( 'related_o_id' )
end end
history_list.push item_tmp history_list.push item_tmp
end end
# fetch meta relations
history_objects = History::Object.all()
history_types = History::Type.all()
history_attributes = History::Attribute.all()
# return result # return result
render :json => { render :json => {
:ticket => ticket, :assets => assets,
:users => users, :history => history_list,
:history => history_list,
:history_objects => history_objects,
:history_types => history_types,
:history_attributes => history_attributes
} }
end end
# GET /api/v1/ticket_merge_list/1 # GET /api/v1/ticket_merge_list/1
def ticket_merge_list def ticket_merge_list
ticket = Ticket.find( params[:ticket_id] ) ticket = Ticket.find( params[:ticket_id] )
assets = ticket.assets({})
# open tickets by customer
ticket_list = Ticket.where( ticket_list = Ticket.where(
:customer_id => ticket.customer_id, :customer_id => ticket.customer_id,
:ticket_state_id => Ticket::State.by_category( 'open' ) :ticket_state_id => Ticket::State.by_category( 'open' )
@ -202,35 +194,29 @@ class TicketsController < ApplicationController
.order('created_at DESC') .order('created_at DESC')
.limit(6) .limit(6)
# get related users # get related assets
users = {} ticket_ids_by_customer = []
tickets = []
ticket_list.each {|ticket| ticket_list.each {|ticket|
data = Ticket.lookup( :id => ticket.id ) ticket_ids_by_customer.push ticket.id
tickets.push data assets = ticket.assets(assets)
if !users[ data['owner_id'] ] }
users[ data['owner_id'] ] = User.user_data_full( data['owner_id'] )
end
if !users[ data['customer_id'] ] ticket_ids_recent_viewed = []
users[ data['customer_id'] ] = User.user_data_full( data['customer_id'] ) ticket_recent_view = RecentView.list( current_user, 8 )
end ticket_recent_view.each {|item|
if !users[ data['created_by_id'] ] if item['recent_view_object'] == 'Ticket'
users[ data['created_by_id'] ] = User.user_data_full( data['created_by_id'] ) ticket_ids_recent_viewed.push item['o_id']
end ticket = Ticket.find( item['o_id'] )
if !users[ data['updated_by_id'] ] assets = ticket.assets(assets)
users[ data['updated_by_id'] ] = User.user_data_full( data['updated_by_id'] )
end end
} }
recent_viewed = RecentView.list_fulldata( current_user, 8 )
# return result # return result
render :json => { render :json => {
:customer => { :assets => assets,
:tickets => tickets, :ticket_ids_by_customer => ticket_ids_by_customer,
:users => users, :ticket_ids_recent_viewed => ticket_ids_recent_viewed,
},
:recent => recent_viewed
} }
end end
@ -295,18 +281,6 @@ class TicketsController < ApplicationController
ticket = Ticket.find( params[:id] ) ticket = Ticket.find( params[:id] )
return if !ticket_permission( ticket ) return if !ticket_permission( ticket )
# get related users
users = {}
if !users[ticket.owner_id]
users[ticket.owner_id] = User.user_data_full( ticket.owner_id )
end
if !users[ticket.customer_id]
users[ticket.customer_id] = User.user_data_full( ticket.customer_id )
end
if !users[ticket.created_by_id]
users[ticket.created_by_id] = User.user_data_full( ticket.created_by_id )
end
# log object as viewed # log object as viewed
if !params[:do_not_log] || params[:do_not_log].to_i == 0 if !params[:do_not_log] || params[:do_not_log].to_i == 0
log_view( ticket ) log_view( ticket )
@ -328,58 +302,52 @@ class TicketsController < ApplicationController
) )
end end
# get related users
assets = {}
assets[:users] = {}
assets = ticket.assets(assets)
# get attributes to update # get attributes to update
attributes_to_change = Ticket::ScreenOptions.attributes_to_change( :user => current_user, :ticket => ticket ) attributes_to_change = Ticket::ScreenOptions.attributes_to_change( :user => current_user, :ticket => ticket )
attributes_to_change[:owner_id].each { |user_id| attributes_to_change[:owner_id].each { |user_id|
if !users[user_id] if !assets[:users][user_id]
users[user_id] = User.user_data_full( user_id ) assets[:users][user_id] = User.user_data_full( user_id )
end end
} }
attributes_to_change[:group_id__owner_id].each {|group_id, user_ids| attributes_to_change[:group_id__owner_id].each {|group_id, user_ids|
user_ids.each {|user_id| user_ids.each {|user_id|
if !users[user_id] if !assets[:users][user_id]
users[user_id] = User.user_data_full( user_id ) assets[:users][user_id] = User.user_data_full( user_id )
end end
} }
} }
# get related articles # get related articles
ticket = ticket.attributes
ticket[:article_ids] = []
articles = Ticket::Article.where( :ticket_id => params[:id] ) articles = Ticket::Article.where( :ticket_id => params[:id] )
# get related users # get related users
articles_used = [] article_ids = []
articles.each {|article| articles.each {|article|
# ignore internal article if customer is requesting # ignore internal article if customer is requesting
next if article.internal == true && is_role('Customer') next if article.internal == true && is_role('Customer')
article_tmp = article.attributes
# load article ids # load article ids
ticket[:article_ids].push article_tmp['id'] article_ids.push article.id
# add attachment list to article # load assets
article_tmp['attachments'] = Store.list( :object => 'Ticket::Article', :o_id => article.id ) assets = article.assets(assets)
# remember article
articles_used.push article_tmp
# load users
if !users[article.created_by_id]
users[article.created_by_id] = User.user_data_full( article.created_by_id )
end
} }
# return result # return result
render :json => { render :json => {
:ticket => ticket, :ticket_id => ticket.id,
:articles => articles_used, :ticket_article_ids => article_ids,
:signature => signature, :signature => signature,
:users => users, :assets => assets,
:edit_form => attributes_to_change, :edit_form => attributes_to_change,
} }
end end
@ -393,65 +361,47 @@ class TicketsController < ApplicationController
# :article_id => params[:article_id] # :article_id => params[:article_id]
) )
users = {} assets = {}
assets[:users] = {}
attributes_to_change[:owner_id].each { |user_id| attributes_to_change[:owner_id].each { |user_id|
if !users[user_id] if !assets[:users][user_id]
users[user_id] = User.user_data_full( user_id ) assets[:users][user_id] = User.user_data_full( user_id )
end end
} }
attributes_to_change[:group_id__owner_id].each {|group_id, user_ids| attributes_to_change[:group_id__owner_id].each {|group_id, user_ids|
user_ids.each {|user_id| user_ids.each {|user_id|
if !users[user_id] if !assets[:users][user_id]
users[user_id] = User.user_data_full( user_id ) assets[:users][user_id] = User.user_data_full( user_id )
end end
} }
} }
# split data # split data
ticket = nil split = {}
articles = nil
if params[:ticket_id] && params[:article_id] if params[:ticket_id] && params[:article_id]
ticket = Ticket.find( params[:ticket_id] ) ticket = Ticket.find( params[:ticket_id] )
split[:ticket_id] = ticket.id
# get related users assets = ticket.assets(assets)
if !users[ticket.owner_id]
users[ticket.owner_id] = User.user_data_full( ticket.owner_id )
end
if !users[ticket.customer_id]
users[ticket.customer_id] = User.user_data_full( ticket.customer_id )
end
if !users[ticket.created_by_id]
users[ticket.created_by_id] = User.user_data_full( ticket.created_by_id )
end
owner_ids = [] owner_ids = []
ticket.agent_of_group.each { |user| ticket.agent_of_group.each { |user|
owner_ids.push user.id owner_ids.push user.id
if !users[user.id] if !assets[:users][user.id]
users[user.id] = User.user_data_full( user.id ) assets[:users][user.id] = User.user_data_full( user.id )
end end
} }
# get related articles # get related articles
ticket[:article_ids] = [ params[:article_id] ]
article = Ticket::Article.find( params[:article_id] ) article = Ticket::Article.find( params[:article_id] )
split[:article_id] = article.id
# add attachment list to article assets = article.assets(assets)
article['attachments'] = Store.list( :object => 'Ticket::Article', :o_id => article.id )
# load users
if !users[article.created_by_id]
users[article.created_by_id] = User.user_data_full( article.created_by_id )
end
end end
# return result # return result
render :json => { render :json => {
:ticket => ticket, :split => split,
:articles => [ article ], :assets => assets,
:users => users,
:edit_form => attributes_to_change, :edit_form => attributes_to_change,
} }
end end
@ -465,19 +415,17 @@ class TicketsController < ApplicationController
:query => params[:term], :query => params[:term],
:current_user => current_user, :current_user => current_user,
) )
users_data = {} assets = {}
ticket_result = [] ticket_result = []
tickets.each do |ticket| tickets.each do |ticket|
ticket_result.push ticket.id ticket_result.push ticket.id
users_data[ ticket['owner_id'] ] = User.user_data_full( ticket['owner_id'] ) assets = ticket.assets(assets)
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 => ticket_result, :tickets => ticket_result,
:users => users_data, :assets => assets,
} }
end end

View file

@ -1,6 +1,8 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
class History < ApplicationModel class History < ApplicationModel
include History::Assets
self.table_name = 'histories' self.table_name = 'histories'
belongs_to :history_type, :class_name => 'History::Type' belongs_to :history_type, :class_name => 'History::Type'
belongs_to :history_object, :class_name => 'History::Object' belongs_to :history_object, :class_name => 'History::Object'
@ -157,51 +159,27 @@ return all histoy entries of an object
activity_stream = History.activity_stream( user, limit ) activity_stream = History.activity_stream( user, limit )
# get related users # get related users
users = {} assets = {}
tickets = []
articles = []
activity_stream.each {|item| activity_stream.each {|item|
# load article ids # load article ids
if item['history_object'] == 'Ticket' if item['history_object'] == 'Ticket'
ticket = Ticket.find( item['o_id'] ).attributes ticket = Ticket.find( item['o_id'] )
tickets.push ticket assets = ticket.assets(assets)
# load users
if !users[ ticket['owner_id'] ]
users[ ticket['owner_id'] ] = User.user_data_full( ticket['owner_id'] )
end
if !users[ ticket['customer_id'] ]
users[ ticket['customer_id'] ] = User.user_data_full( ticket['customer_id'] )
end
end end
if item['history_object'] == 'Ticket::Article' if item['history_object'] == 'Ticket::Article'
article = Ticket::Article.find( item['o_id'] ).attributes article = Ticket::Article.find( item['o_id'] )
if !article['subject'] || article['subject'] == '' assets = article.assets(assets)
article['subject'] = Ticket.find( article['ticket_id'] ).title
end
articles.push article
# load users
if !users[ article['created_by_id'] ]
users[ article['created_by_id'] ] = User.user_data_full( article['created_by_id'] )
end
end end
if item['history_object'] == 'User' if item['history_object'] == 'User'
users[ item['o_id'] ] = User.user_data_full( item['o_id'] ) user = User.find( item['o_id'] )
end assets = user.assets(assets)
# load users
if !users[ item['created_by_id'] ]
users[ item['created_by_id'] ] = User.user_data_full( item['created_by_id'] )
end end
} }
return { return {
:activity_stream => activity_stream, :activity_stream => activity_stream,
:tickets => tickets, :assets => assets,
:articles => articles,
:users => users,
} }
end end

View file

@ -0,0 +1,46 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
module History::Assets
=begin
get all assets / related models for this history entry
history = History.find(123)
result = history.assets( assets_if_exists )
returns
result = {
:users => {
123 => user_model_123,
1234 => user_model_1234,
}
}
=end
def assets (data)
if !data[:users]
data[:users] = {}
end
if !data[:users][ self['created_by_id'] ]
data[:users][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] )
end
# fetch meta relations
if !data[:history_object]
data[:history_object] = History::Object.all()
end
if !data[:history_type]
data[:history_type] = History::Type.all()
end
if !data[:history_attribute]
data[:history_attribute] = History::Attribute.all()
end
data
end
end

View file

@ -1,37 +1,10 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
class Organization < ApplicationModel class Organization < ApplicationModel
include Organization::Assets
extend Organization::Search
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 ? OR note LIKE ?', "%#{query}%", "%#{query}%"],
:order => 'name'
)
# if only a few organizations are found, search for names of users
if organizations.length <= 3
organizations = Organization.select('DISTINCT(organizations.id)').joins('LEFT OUTER JOIN users ON users.organization_id = organizations.id').find(
:all,
:limit => limit,
:conditions => ['users.firstname LIKE ? or users.lastname LIKE ? or users.email LIKE ?', "%#{query}%", "%#{query}%", "%#{query}%"],
:order => 'organizations.name'
)
end
return organizations
end
end end

View file

@ -0,0 +1,43 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
module Organization::Assets
=begin
get all assets / related models for this organization
organization = Organization.find(123)
result = organization.assets( assets_if_exists )
returns
result = {
:organizations => {
123 => organization_model_123,
1234 => organization_model_1234,
}
}
=end
def assets (data)
if !data[:organizations]
data[:organizations] = {}
end
if !data[:users]
data[:users] = {}
end
if !data[:organizations][ self.id ]
data[:organizations][ self.id ] = self.attributes
data[:organizations][ self.id ][:user_ids] = []
users = User.where( :organization_id => self.id ).limit(10)
users.each {|user|
data[:users][ user.id ] = User.user_data_full( user.id )
data[:organizations][ self.id ][:user_ids].push user.id
}
end
data
end
end

View file

@ -0,0 +1,62 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
module Organization::Search
=begin
search organizations
result = Organization.search(
:current_user => User.find(123),
:query => 'search something',
:limit => 15,
)
returns
result = [organization_model1, organization_model2]
=end
def 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 ? OR note LIKE ?', "%#{query}%", "%#{query}%"],
:order => 'name'
)
# if only a few organizations are found, search for names of users
if organizations.length <= 3
organizations_by_user = Organization.select('DISTINCT(organizations.id)').joins('LEFT OUTER JOIN users ON users.organization_id = organizations.id').find(
:all,
:limit => limit,
:conditions => ['users.firstname LIKE ? or users.lastname LIKE ? or users.email LIKE ?', "%#{query}%", "%#{query}%", "%#{query}%"],
:order => 'organizations.name'
)
organizations_by_user.each {|organization_by_user|
puts 'OOO ' + organization_by_user.inspect
organization_exists = false
organizations.each {|organization|
if organization.id == organization_by_user.id
organization_exists = true
end
}
if !organization_exists
organizations.push organization
end
}
end
organizations
end
end

View file

@ -44,14 +44,14 @@ class RecentView < ApplicationModel
recent_viewed = self.list( user, limit ) recent_viewed = self.list( user, limit )
# get related users # get related users
users = {} assets = {}
tickets = [] ticket_ids = []
recent_viewed.each {|item| recent_viewed.each {|item|
# load article ids # load article ids
# if item.recent_view_object == 'Ticket' # if item.recent_view_object == 'Ticket'
ticket = Ticket.find( item['o_id'] ).attributes ticket = Ticket.find( item['o_id'] )
tickets.push ticket ticket_ids.push ticket.id
# end # end
# if item.recent_view_object 'Ticket::Article' # if item.recent_view_object 'Ticket::Article'
# tickets.push Ticket::Article.find(item.o_id) # tickets.push Ticket::Article.find(item.o_id)
@ -60,21 +60,12 @@ class RecentView < ApplicationModel
# tickets.push User.find(item.o_id) # tickets.push User.find(item.o_id)
# end # end
# load users assets = ticket.assets(assets)
if !users[ ticket['owner_id'] ]
users[ ticket['owner_id'] ] = User.user_data_full( ticket['owner_id'] )
end
if !users[ ticket['created_by_id'] ]
users[ ticket['created_by_id'] ] = User.user_data_full( ticket['created_by_id'] )
end
if !users[ item['created_by_id'] ]
users[ item['created_by_id'] ] = User.user_data_full( item['created_by_id'] )
end
} }
return { return {
:recent_viewed => recent_viewed, :recent_viewed => recent_viewed,
:tickets => tickets, :ticket_ids => ticket_ids,
:users => users, :assets => assets,
} }
end end

View file

@ -25,6 +25,7 @@ class Ticket < ApplicationModel
include Ticket::Escalation include Ticket::Escalation
include Ticket::Subject include Ticket::Subject
include Ticket::Permission include Ticket::Permission
include Ticket::Assets
extend Ticket::Search extend Ticket::Search
attr_accessor :callback_loop attr_accessor :callback_loop

View file

@ -1,6 +1,8 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
class Ticket::Article < ApplicationModel class Ticket::Article < ApplicationModel
include Ticket::Article::Assets
after_create :attachment_check after_create :attachment_check
belongs_to :ticket belongs_to :ticket
belongs_to :ticket_article_type, :class_name => 'Ticket::Article::Type' belongs_to :ticket_article_type, :class_name => 'Ticket::Article::Type'

View file

@ -0,0 +1,48 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
module Ticket::Article::Assets
=begin
get all assets / related models for this article
article = Ticket::Article.find(123)
result = article.assets( assets_if_exists )
returns
result = {
:users => {
123 => user_model_123,
1234 => user_model_1234,
}
:article => [ article_model1 ],
}
=end
def assets (data)
if !data[:ticket_article]
data[:ticket_article] = {}
end
if !data[:ticket_article][ self.id ]
data[:ticket_article][ self.id ] = self.attributes
# add attachment list to article
data[:ticket_article][ self.id ]['attachments'] = Store.list( :object => 'Ticket::Article', :o_id => self.id )
end
if !data[:users]
data[:users] = {}
end
if !data[:users][ self['created_by_id'] ]
data[:users][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] )
end
if !data[:users][ self['updated_by_id'] ]
data[:users][ self['updated_by_id'] ] = User.user_data_full( self['updated_by_id'] )
end
data
end
end

View file

@ -0,0 +1,51 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
module Ticket::Assets
=begin
get all assets / related models for this ticket
ticket = Ticket.find(123)
result = ticket.assets( assets_if_exists )
returns
result = {
:users => {
123 => user_model_123,
1234 => user_model_1234,
}
:tickets => [ ticket_model1 ]
}
=end
def assets (data)
if !data[:tickets]
data[:tickets] = {}
end
if !data[:tickets][ self.id ]
data[:tickets][ self.id ] = self.attributes
end
if !data[:users]
data[:users] = {}
end
if !data[:users][ self['owner_id'] ]
data[:users][ self['owner_id'] ] = User.user_data_full( self['owner_id'] )
end
if !data[:users][ self['customer_id'] ]
data[:users][ self['customer_id'] ] = User.user_data_full( self['customer_id'] )
end
if !data[:users][ self['created_by_id'] ]
data[:users][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] )
end
if !data[:users][ self['updated_by_id'] ]
data[:users][ self['updated_by_id'] ] = User.user_data_full( self['updated_by_id'] )
end
data
end
end

View file

@ -1,14 +1,12 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
require 'overview' module Ticket::Overviews
class Ticket::Overview
=begin =begin
all overview by user all overview by user
result = Ticket::Overview.all( result = Ticket::Overviews.all(
:current_user => User.find(123), :current_user => User.find(123),
) )
@ -33,15 +31,14 @@ returns
# get agent overviews # get agent overviews
role = data[:current_user].is_role( 'Agent' ) role = data[:current_user].is_role( 'Agent' )
overviews = Overview.where( :role_id => role.id, :active => true ) Overview.where( :role_id => role.id, :active => true )
return overviews
end end
=begin =begin
selected overview by user selected overview by user
result = Ticket::Overview.list( result = Ticket::Overviews.list(
:current_user => User.find(123), :current_user => User.find(123),
:view => 'some_view_url', :view => 'some_view_url',
) )
@ -164,7 +161,7 @@ returns
count() count()
return { return {
:ticket_list => ticket_ids, :ticket_ids => ticket_ids,
:tickets_count => tickets_count, :tickets_count => tickets_count,
:overview => overview_selected_raw, :overview => overview_selected_raw,
} }
@ -187,7 +184,6 @@ returns
:tickets_count => tickets_count, :tickets_count => tickets_count,
:overview => overview_selected_raw, :overview => overview_selected_raw,
} }
end end
private private
@ -249,5 +245,4 @@ returns
bind[0] = sql bind[0] = sql
return bind return bind
end end
end end

View file

@ -50,13 +50,11 @@ returns
# build result list # build result list
tickets = [] tickets = []
users = {}
tickets_all.each do |ticket| tickets_all.each do |ticket|
ticket_tmp = Ticket.lookup( :id => ticket.id ) tickets.push Ticket.lookup( :id => ticket.id )
tickets.push ticket_tmp
end end
return tickets tickets
end end
end end

View file

@ -4,6 +4,9 @@ require 'digest/sha2'
require 'organization' require 'organization'
class User < ApplicationModel class User < ApplicationModel
include User::Assets
extend User::Search
before_create :check_name, :check_email, :check_login, :check_image, :check_password before_create :check_name, :check_email, :check_login, :check_image, :check_password
before_update :check_password, :check_image, :check_email, :check_login_update before_update :check_password, :check_image, :check_email, :check_login_update
after_create :notify_clients_after_create after_create :notify_clients_after_create
@ -126,7 +129,7 @@ returns
def self.sso(params) def self.sso(params)
# try to login against configure auth backends # try to login against configure auth backends
user_auth = Sso.check( params, user ) user_auth = Sso.check( params )
return if !user_auth return if !user_auth
return user_auth return user_auth
@ -283,42 +286,6 @@ returns
return user return user
end end
=begin
search user
result = User.search(
:query => 'some search term'
:limit => 15,
:current_user => user_model,
)
returns
result = [user_model1, user_model2, ...]
=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)

34
app/models/user/assets.rb Normal file
View file

@ -0,0 +1,34 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
module User::Assets
=begin
get all assets / related models for this user
user = User.find(123)
result = user.assets( assets_if_exists )
returns
result = {
:users => {
123 => user_model_123,
1234 => user_model_1234,
}
}
=end
def assets (data)
if !data[:users]
data[:users] = {}
end
if !data[:users][ self.id ]
data[:users][ self.id ] = User.user_data_full( self.id )
end
data
end
end

57
app/models/user/search.rb Normal file
View file

@ -0,0 +1,57 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
module User::Search
=begin
search tickets
result = Ticket.search(
:current_user => User.find(123),
:query => 'search something',
:limit => 15,
)
returns
result = [ticket_model1, ticket_model2]
=end
=begin
search user
result = User.search(
:query => 'some search term'
:limit => 15,
:current_user => user_model,
)
returns
result = [user_model1, user_model2, ...]
=end
def 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
end

View file

@ -0,0 +1,52 @@
class UpdateAuth < ActiveRecord::Migration
def up
Setting.create_or_update(
:title => 'Authentication via OTRS',
:name => 'auth_otrs',
:area => 'Security::Authentication',
:description => 'Enables user authentication via OTRS.',
:state => {
:adapter => 'Auth::Otrs',
:required_group_ro => 'stats',
:group_rw_role_map => {
'admin' => 'Admin',
'stats' => 'Report',
},
:group_ro_role_map => {
'stats' => 'Report',
},
:always_role => {
'Agent' => true,
},
},
:frontend => false
)
Setting.create_or_update(
:title => 'Authentication via LDAP',
:name => 'auth_ldap',
:area => 'Security::Authentication',
:description => 'Enables user authentication via LDAP.',
:state => {
:adapter => 'Auth::Ldap',
:host => 'localhost',
:port => 389,
:bind_dn => 'cn=Manager,dc=example,dc=org',
:bind_pw => 'example',
:uid => 'mail',
:base => 'dc=example,dc=org',
:always_filter => '',
:always_roles => ['Admin', 'Agent'],
:always_groups => ['Users'],
:sync_params => {
:firstname => 'sn',
:lastname => 'givenName',
:email => 'mail',
:login => 'mail',
},
},
:frontend => false
)
end
def down
end
end

View file

@ -395,7 +395,7 @@ class UserState
# overview # overview
cache_key = @cache_key + '_overview' cache_key = @cache_key + '_overview'
if CacheIn.expired(cache_key) if CacheIn.expired(cache_key)
overview = Ticket::Overview.list( overview = Ticket::Overviews.list(
:current_user => user, :current_user => user,
) )
overview_cache = CacheIn.get( cache_key, { :re_expire => true } ) overview_cache = CacheIn.get( cache_key, { :re_expire => true } )
@ -410,13 +410,13 @@ class UserState
end end
# overview lists # overview lists
overviews = Ticket::Overview.all( overviews = Ticket::Overviews.all(
:current_user => user, :current_user => user,
) )
overviews.each { |overview| overviews.each { |overview|
cache_key = @cache_key + '_overview_data_' + overview.link cache_key = @cache_key + '_overview_data_' + overview.link
if CacheIn.expired(cache_key) if CacheIn.expired(cache_key)
overview_data = Ticket::Overview.list( overview_data = Ticket::Overviews.list(
:view => overview.link, :view => overview.link,
:current_user => user, :current_user => user,
:array => true, :array => true,
@ -597,14 +597,14 @@ class ClientState
if !CacheIn.get( 'pushed_tickets' + @client_id.to_s ) if !CacheIn.get( 'pushed_tickets' + @client_id.to_s )
CacheIn.set( 'pushed_tickets' + @client_id.to_s , true, { :expires_in => 20.seconds } ) CacheIn.set( 'pushed_tickets' + @client_id.to_s , true, { :expires_in => 20.seconds } )
if @pushed[:tickets] if @pushed[:tickets]
tickets = [] tickets = {}
users = {} users = {}
@pushed[:tickets].each {|ticket_id, ticket_data| @pushed[:tickets].each {|ticket_id, ticket_data|
self.ticket( ticket_id, tickets, users ) self.ticket( ticket_id, tickets, users )
} }
if !tickets.empty? if !tickets.empty?
tickets.each {|ticket| tickets.each {|id, ticket|
self.log 'notify', "push update of already pushed ticket id #{ticket['id']}" self.log 'notify', "push update of already pushed ticket id #{id}"
} }
# send update to browser # send update to browser
self.send({ self.send({
@ -637,7 +637,7 @@ class ClientState
end end
# overview_data # overview_data
overviews = Ticket::Overview.all( overviews = Ticket::Overviews.all(
:current_user => user, :current_user => user,
) )
overviews.each { |overview| overviews.each { |overview|
@ -649,8 +649,8 @@ class ClientState
overview_data = CacheIn.get( cache_key, { :ignore_expire => true } ) overview_data = CacheIn.get( cache_key, { :ignore_expire => true } )
self.log 'notify', "push overview_data #{overview.link} for user #{user.id}" self.log 'notify', "push overview_data #{overview.link} for user #{user.id}"
users = {} users = {}
tickets = [] tickets = {}
overview_data[:ticket_list].each {|ticket_id| overview_data[:ticket_ids].each {|ticket_id|
self.ticket( ticket_id, tickets, users ) self.ticket( ticket_id, tickets, users )
} }
@ -677,21 +677,24 @@ class ClientState
} }
# send update to browser # send update to browser
self.send({
:data => {
:users => users,
:tickets => tickets,
},
:event => [ 'loadAssets' ]
})
self.send({ self.send({
:data => { :data => {
:overview => overview_data[:overview], :overview => overview_data[:overview],
:ticket_list => overview_data[:ticket_list], :ticket_ids => overview_data[:ticket_ids],
:tickets_count => overview_data[:tickets_count], :tickets_count => overview_data[:tickets_count],
:collections => {
:User => users,
:Ticket => tickets,
},
:bulk => { :bulk => {
:group_id__owner_id => groups_users, :group_id__owner_id => groups_users,
:owner_id => [], :owner_id => [],
}, },
}, },
:event => [ 'loadCollection', 'ticket_overview_rebuild' ], :event => [ 'ticket_overview_rebuild' ],
:collection => 'ticket_overview_' + overview.link.to_s, :collection => 'ticket_overview_' + overview.link.to_s,
}) })
end end
@ -816,7 +819,7 @@ class ClientState
ticket = Ticket.lookup( :id => ticket_id ) ticket = Ticket.lookup( :id => ticket_id )
if @pushed[:tickets][ticket_id] != ticket['updated_at'] if @pushed[:tickets][ticket_id] != ticket['updated_at']
@pushed[:tickets][ticket_id] = ticket['updated_at'] @pushed[:tickets][ticket_id] = ticket['updated_at']
tickets.push ticket tickets[ticket_id] = ticket
end end
# add users if needed # add users if needed

View file

@ -6,7 +6,7 @@ class Sso < ApplicationLib
authenticate user via username and password authenticate user via username and password
result = Sso.check( params, config_item ) result = Sso.check( params )
returns returns

View file

@ -263,7 +263,7 @@ class TextModuleTest < TestCase
:action => [ :action => [
{ {
:execute => 'wait', :execute => 'wait',
:value => 3, :value => 4,
}, },
{ {
:where => :instance2, :where => :instance2,
@ -361,6 +361,78 @@ class TextModuleTest < TestCase
}, },
], ],
}, },
{
:name => 'verify zoom',
:action => [
# create ticket
{
:where => :instance2,
:execute => 'create_ticket',
:group => 'Users',
:subject => 'some subject 123äöü',
:body => 'some body 123äöü',
},
# check ticket
{
:where => :instance2,
:execute => 'match',
:css => '.active div.article',
:value => 'some body 123äöü',
:match_result => true,
},
# check ticket zoom
{
:execute => 'wait',
:value => 4,
},
{
:where => :instance2,
:execute => 'set',
:css => '.active textarea[name=body]',
:value => 'test',
},
{
:execute => 'wait',
:value => 4,
},
{
:where => :instance2,
:execute => 'set',
:css => '.active textarea[name=body]',
:value => '::' + random,
},
{
:execute => 'wait',
:value => 1,
},
{
:where => :instance2,
:execute => 'match',
:css => 'body',
:value => random,
:match_result => true,
},
{
:where => :instance2,
:execute => 'click',
:css => '.-sew-list-item.selected',
},
{
:execute => 'wait',
:value => 1,
},
{
:where => :instance2,
:execute => 'match',
:css => '.active textarea[name=body]',
:value => 'some content Braun' + random,
:match_result => true,
},
],
},
] ]
browser_double_test(tests) browser_double_test(tests)
end end

View file

@ -247,7 +247,7 @@ puts "NOTICE #{Time.now.to_s}: " + action.inspect
sleep 4 sleep 4
element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } ) element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } )
element.clear element.clear
element.send_keys( 'ma' ) element.send_keys( 'nico' )
sleep 4 sleep 4
element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } ) element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } )
element.send_keys( :arrow_down ) element.send_keys( :arrow_down )