Refectory task rendering (just updated certain elements if needed).
This commit is contained in:
parent
618d583587
commit
8195e0f262
23 changed files with 295 additions and 273 deletions
|
@ -559,15 +559,6 @@ class App.Controller extends Spine.Controller
|
|||
renderScreenUnauthorized: (data) ->
|
||||
@html App.view('generic/error/unauthorized')(data)
|
||||
|
||||
metaTaskUpdate: ->
|
||||
delay = App.TaskManager.renderDelay()
|
||||
return if !delay
|
||||
App.Delay.set(
|
||||
-> App.Event.trigger 'task:render'
|
||||
delay
|
||||
'meta-task-update'
|
||||
)
|
||||
|
||||
locationVerify: (e) =>
|
||||
newLocation = $(e.currentTarget).attr 'href'
|
||||
@log 'debug', "new location '#{newLocation}'"
|
||||
|
@ -587,7 +578,6 @@ class App.Controller extends Spine.Controller
|
|||
newLocation = newLocation.replace(/#/, '')
|
||||
@log 'debug', "execute controller again for '#{newLocation}' because of same hash"
|
||||
Spine.Route.matchRoutes(newLocation)
|
||||
@metaTaskUpdate()
|
||||
|
||||
logoUrl: ->
|
||||
"#{@Config.get('image_path')}/#{@Config.get('product_logo')}"
|
||||
|
@ -812,7 +802,7 @@ class App.UpdateTastbar extends App.Controller
|
|||
update: (genericObject) =>
|
||||
|
||||
# update taskbar with new meta data
|
||||
@metaTaskUpdate()
|
||||
App.TaskManager.touch(@task_key)
|
||||
|
||||
class App.ControllerWidgetPermanent extends App.Controller
|
||||
constructor: (params) ->
|
||||
|
|
|
@ -119,7 +119,7 @@ class App.TicketCreate extends App.Controller
|
|||
"#ticket/create/id/#{@id}"
|
||||
|
||||
show: =>
|
||||
@navupdate '#'
|
||||
@navupdate(url: '#', type: 'menu')
|
||||
|
||||
changed: =>
|
||||
formCurrent = @formParam( @$('.ticket-create') )
|
||||
|
@ -140,7 +140,7 @@ class App.TicketCreate extends App.Controller
|
|||
title = @$('[name=title]').val()
|
||||
if @latestTitle isnt title
|
||||
@latestTitle = title
|
||||
@metaTaskUpdate()
|
||||
App.TaskManager.touch(@task_key)
|
||||
|
||||
@interval(update, 3000, @id)
|
||||
|
||||
|
@ -185,6 +185,7 @@ class App.TicketCreate extends App.Controller
|
|||
)
|
||||
|
||||
render: (template = {}) ->
|
||||
App.TaskManager.touch(@task_key)
|
||||
|
||||
# get params
|
||||
params = {}
|
||||
|
@ -317,7 +318,7 @@ class App.TicketCreate extends App.Controller
|
|||
@autosave()
|
||||
|
||||
# update taskbar with new meta data
|
||||
@metaTaskUpdate()
|
||||
App.TaskManager.touch(@task_key)
|
||||
|
||||
localUserInfo: (e) =>
|
||||
|
||||
|
|
|
@ -65,30 +65,30 @@ class App.TicketMerge extends App.ControllerModal
|
|||
if data['result'] is 'success'
|
||||
|
||||
# update collection
|
||||
App.Collection.load( type: 'Ticket', data: [data.master_ticket] )
|
||||
App.Collection.load( type: 'Ticket', data: [data.slave_ticket] )
|
||||
App.Collection.load(type: 'Ticket', data: [data.master_ticket])
|
||||
App.Collection.load(type: 'Ticket', data: [data.slave_ticket])
|
||||
|
||||
# hide dialog
|
||||
@close()
|
||||
|
||||
# view ticket
|
||||
@log 'notice', 'nav...', App.Ticket.find( data.master_ticket['id'] )
|
||||
@log 'notice', 'nav...', App.Ticket.find(data.master_ticket['id'])
|
||||
@navigate '#ticket/zoom/' + data.master_ticket['id']
|
||||
|
||||
# notify UI
|
||||
@notify
|
||||
type: 'success'
|
||||
msg: App.i18n.translateContent( 'Ticket %s merged!', data.slave_ticket['number'] )
|
||||
msg: App.i18n.translateContent('Ticket %s merged!', data.slave_ticket['number'])
|
||||
timeout: 4000
|
||||
|
||||
App.TaskManager.remove( 'Ticket-' + data.slave_ticket['id'] )
|
||||
App.TaskManager.remove("Ticket-#{data.slave_ticket['id']}")
|
||||
|
||||
else
|
||||
|
||||
# notify UI
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent( data['message'] )
|
||||
msg: App.i18n.translateContent(data['message'])
|
||||
timeout: 6000
|
||||
|
||||
@formEnable(e)
|
||||
|
|
|
@ -22,8 +22,8 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
|||
@renderPersonal()
|
||||
|
||||
# update selected item
|
||||
@bind 'navupdate', =>
|
||||
@update(arguments[0])
|
||||
@bind 'navupdate', (params) =>
|
||||
@update(params)
|
||||
|
||||
# rebuild nav bar with given user data
|
||||
@bind 'auth', (user) =>
|
||||
|
@ -86,18 +86,10 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
|||
open_tab[href] = true
|
||||
)
|
||||
|
||||
# get active tabs to reactivate on rerender
|
||||
active_tab = {}
|
||||
@$('.is-active').each( (i,d) ->
|
||||
href = $(d).attr('href')
|
||||
active_tab[href] = true
|
||||
)
|
||||
|
||||
# render menu
|
||||
@$('.js-menu').html App.view('navigation/menu')(
|
||||
items: items
|
||||
open_tab: open_tab
|
||||
active_tab: active_tab
|
||||
)
|
||||
|
||||
# bind on switch changes and execute it on controller
|
||||
|
@ -121,17 +113,9 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
|||
open_tab[href] = true
|
||||
)
|
||||
|
||||
# get active tabs to reactivate on rerender
|
||||
active_tab = {}
|
||||
@$('.active').children('a').each( (i,d) ->
|
||||
href = $(d).attr('href')
|
||||
active_tab[href] = true
|
||||
)
|
||||
|
||||
@$('.navbar-items-personal').html App.view('navigation/personal')(
|
||||
items: items
|
||||
open_tab: open_tab
|
||||
active_tab: active_tab
|
||||
)
|
||||
|
||||
# only start avatar widget on existing session
|
||||
|
@ -428,7 +412,14 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
|||
if newlist[ item['prio'] ]
|
||||
@addPrioCount newlist, item
|
||||
|
||||
update: (url) =>
|
||||
update: (params) =>
|
||||
url = params
|
||||
if _.isObject(params)
|
||||
url = params.url
|
||||
type = params.type
|
||||
if type is 'menu'
|
||||
@$('.js-menu .is-active').removeClass('is-active')
|
||||
else
|
||||
@$('.is-active').removeClass('is-active')
|
||||
return if !url || url is '#'
|
||||
@$("[href=\"#{url}\"]").addClass('is-active')
|
||||
|
|
|
@ -34,13 +34,16 @@ class App.OrganizationProfile extends App.Controller
|
|||
|
||||
show: =>
|
||||
App.OnlineNotification.seen('Organization', @organization_id)
|
||||
@navupdate '#'
|
||||
@navupdate(url: '#', type: 'menu')
|
||||
|
||||
changed: ->
|
||||
false
|
||||
|
||||
render: (organization) =>
|
||||
|
||||
# update taskbar with new meta data
|
||||
App.TaskManager.touch(@task_key)
|
||||
|
||||
if !@doNotLog
|
||||
@doNotLog = 1
|
||||
@recentView('Organization', @organization_id)
|
||||
|
@ -80,9 +83,6 @@ class Object extends App.Controller
|
|||
|
||||
render: (organization) =>
|
||||
|
||||
# update taskbar with new meta data
|
||||
@metaTaskUpdate()
|
||||
|
||||
# get display data
|
||||
organizationData = []
|
||||
for attributeName, attributeConfig of App.Organization.attributesGet('view')
|
||||
|
|
|
@ -2,60 +2,31 @@ class App.TaskbarWidget extends App.Controller
|
|||
events:
|
||||
'click .js-close': 'remove'
|
||||
'click .js-locationVerify': 'location'
|
||||
fields:
|
||||
observe:
|
||||
field1: true
|
||||
field2: false
|
||||
meta: true
|
||||
active: true
|
||||
notify: true
|
||||
observeNot:
|
||||
field1: true
|
||||
field2: false
|
||||
currentItems: {}
|
||||
#1:
|
||||
# a: 123
|
||||
# b: 'some string'
|
||||
#2:
|
||||
# a: 123
|
||||
# b: 'some string'
|
||||
renderList: {}
|
||||
#1: ..dom..ref..
|
||||
#2: ..dom..ref..
|
||||
template: 'widget/task_item'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
@render()
|
||||
|
||||
# render on generic ui call
|
||||
@bind 'ui:rerender', => @render()
|
||||
|
||||
# render view
|
||||
@bind 'task:render', => @render()
|
||||
|
||||
# render on login
|
||||
@bind 'auth:login', => @render()
|
||||
|
||||
# reset current tasks on logout
|
||||
@bind 'auth:logout', => @render()
|
||||
|
||||
render: ->
|
||||
return if !@Session.get()
|
||||
|
||||
tasks = App.TaskManager.all()
|
||||
taskItems = []
|
||||
for task in tasks
|
||||
|
||||
# collect meta data of task for task bar item
|
||||
meta =
|
||||
url: '#'
|
||||
id: false
|
||||
iconClass: 'loading'
|
||||
title: App.i18n.translateInline('Loading...')
|
||||
head: App.i18n.translateInline('Loading...')
|
||||
active: false
|
||||
worker = App.TaskManager.worker(task.key)
|
||||
if worker
|
||||
data = worker.meta()
|
||||
|
||||
# apply meta data of controller
|
||||
if data
|
||||
for key, value of data
|
||||
meta[key] = value
|
||||
|
||||
# collect new task bar items
|
||||
item = {}
|
||||
item.task = task
|
||||
item.meta = meta
|
||||
taskItems.push item
|
||||
|
||||
# update title
|
||||
if task.active
|
||||
@title meta.title
|
||||
|
||||
@html App.view('task_widget_tasks')(
|
||||
taskItems: taskItems
|
||||
)
|
||||
@renderAll()
|
||||
|
||||
dndOptions =
|
||||
tolerance: 'pointer'
|
||||
|
@ -75,6 +46,86 @@ class App.TaskbarWidget extends App.Controller
|
|||
|
||||
@el.sortable(dndOptions)
|
||||
|
||||
# bind to changes
|
||||
@bind('taskInit', => @renderAll())
|
||||
@bind('taskUpdate', (tasks) =>
|
||||
@checkChanges(tasks)
|
||||
)
|
||||
@bind('taskRemove', (task_ids) =>
|
||||
@checkRemoves(task_ids)
|
||||
)
|
||||
|
||||
# render on generic ui call
|
||||
@bind('ui:rerender', => @renderAll())
|
||||
|
||||
# render on login
|
||||
@bind('auth:login', => @renderAll())
|
||||
|
||||
# reset current tasks on logout
|
||||
@bind('auth:logout', => @renderAll())
|
||||
|
||||
checkRemoves: (task_ids) ->
|
||||
for task_id in task_ids
|
||||
delete @currentItems[task_id]
|
||||
if @renderList[task_id]
|
||||
@renderList[task_id].remove()
|
||||
delete @renderList[task_id]
|
||||
|
||||
checkChanges: (items) ->
|
||||
#console.log('checkChanges', items, @currentItems)
|
||||
changedItems = []
|
||||
for item in items
|
||||
attributes = {}
|
||||
for field of @fields.observe
|
||||
attributes[field] = item[field]
|
||||
#console.log('item', item)
|
||||
#attributes = item.attributes()
|
||||
#console.log('item', @fields.observe, item, attributes)
|
||||
if !@currentItems[item.id]
|
||||
changedItems.push item
|
||||
@currentItems[item.id] = attributes
|
||||
else
|
||||
currentItem = @currentItems[item.id]
|
||||
hit = false
|
||||
for field of @fields.observe
|
||||
diff = _.isEqual(currentItem[field], attributes[field])
|
||||
#console.log('diff', field, diff, currentItem[field], attributes[field])
|
||||
if !hit && diff
|
||||
changedItems.push item
|
||||
@currentItems[item.id] = attributes
|
||||
hit = true
|
||||
console.log('checkChanges, changedItems', changedItems)
|
||||
return if _.isEmpty(changedItems)
|
||||
@renderParts(changedItems)
|
||||
|
||||
renderAll: ->
|
||||
#@html ''
|
||||
items = App.TaskManager.allWithMeta()
|
||||
localeEls = []
|
||||
for item in items
|
||||
localeEls.push @renderItem(item, false)
|
||||
@html localeEls
|
||||
|
||||
renderParts: (items) ->
|
||||
for item in items
|
||||
if !@renderList[item.id]
|
||||
@renderItem(item)
|
||||
else
|
||||
@renderItem(item, @renderList[item.id])
|
||||
|
||||
renderItem: (item, el) ->
|
||||
html = $(App.view(@template)(
|
||||
item: item
|
||||
))
|
||||
console.log('renderItem', item)
|
||||
@renderList[item.id] = html
|
||||
if el is false
|
||||
return html
|
||||
else if !el
|
||||
@el.append(html)
|
||||
else
|
||||
el.replaceWith(html)
|
||||
|
||||
location: (e) =>
|
||||
return if !$(e.currentTarget).hasClass('is-modified')
|
||||
@locationVerify(e)
|
||||
|
@ -107,9 +158,7 @@ class App.TaskbarWidget extends App.Controller
|
|||
activeIsClosed = true
|
||||
|
||||
# remove task
|
||||
App.TaskManager.remove(key, false)
|
||||
|
||||
$(e.target).closest('.task').remove()
|
||||
App.TaskManager.remove(key)
|
||||
|
||||
# if we do not need to move to an other task
|
||||
return if !activeIsClosed
|
||||
|
|
|
@ -88,7 +88,7 @@ class App.TicketZoom extends App.Controller
|
|||
|
||||
show: (params) =>
|
||||
|
||||
@navupdate '#'
|
||||
@navupdate(url: '#', type: 'menu')
|
||||
|
||||
# set all notifications to seen
|
||||
App.OnlineNotification.seen('Ticket', @ticket_id)
|
||||
|
@ -212,7 +212,7 @@ class App.TicketZoom extends App.Controller
|
|||
)
|
||||
|
||||
# update taskbar with new meta data
|
||||
@metaTaskUpdate()
|
||||
App.TaskManager.touch(@task_key)
|
||||
)
|
||||
|
||||
|
||||
|
@ -284,7 +284,7 @@ class App.TicketZoom extends App.Controller
|
|||
render: =>
|
||||
|
||||
# update taskbar with new meta data
|
||||
@metaTaskUpdate()
|
||||
App.TaskManager.touch(@task_key)
|
||||
|
||||
@formEnable( @$('.submit') )
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ class App.TicketZoomTitle extends App.Controller
|
|||
App.TaskManager.mute(@task_key)
|
||||
|
||||
# update taskbar with new meta data
|
||||
@metaTaskUpdate()
|
||||
App.TaskManager.touch(@task_key)
|
||||
|
||||
App.Event.trigger('overview:fetch')
|
||||
|
||||
|
|
|
@ -36,13 +36,16 @@ class App.UserProfile extends App.Controller
|
|||
|
||||
show: =>
|
||||
App.OnlineNotification.seen('User', @user_id)
|
||||
@navupdate '#'
|
||||
@navupdate(url: '#', type: 'menu')
|
||||
|
||||
changed: ->
|
||||
false
|
||||
|
||||
render: (user) =>
|
||||
|
||||
# update taskbar with new meta data
|
||||
App.TaskManager.touch(@task_key)
|
||||
|
||||
if !@doNotLog
|
||||
@doNotLog = 1
|
||||
@recentView('User', @user_id)
|
||||
|
@ -83,9 +86,6 @@ class Object extends App.Controller
|
|||
|
||||
render: (user) =>
|
||||
|
||||
# update taskbar with new meta data
|
||||
@metaTaskUpdate()
|
||||
|
||||
# get display data
|
||||
userData = []
|
||||
for attributeName, attributeConfig of App.User.attributesGet('view')
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
class App.Delay
|
||||
_instance = undefined
|
||||
|
||||
@set: ( callback, timeout, key, level ) ->
|
||||
@set: (callback, timeout, key, level) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _delaySingleton
|
||||
_instance.set( callback, timeout, key, level )
|
||||
_instance.set(callback, timeout, key, level)
|
||||
|
||||
@clear: ( key, level ) ->
|
||||
@clear: (key, level) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _delaySingleton
|
||||
_instance.clear( key, level )
|
||||
_instance.clear(key, level)
|
||||
|
||||
@clearLevel: ( level ) ->
|
||||
@clearLevel: (level) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _delaySingleton
|
||||
_instance.clearLevel( level )
|
||||
_instance.clearLevel(level)
|
||||
|
||||
@reset: ->
|
||||
if _instance == undefined
|
||||
|
@ -32,23 +32,23 @@ class _delaySingleton extends Spine.Module
|
|||
constructor: ->
|
||||
@levelStack = {}
|
||||
|
||||
set: ( callback, timeout, key, level ) =>
|
||||
set: (callback, timeout, key, level) =>
|
||||
|
||||
if !level
|
||||
level = '_all'
|
||||
|
||||
if key
|
||||
@clear( key, level )
|
||||
@clear(key, level)
|
||||
|
||||
if !key
|
||||
key = Math.floor( Math.random() * 99999 )
|
||||
key = Math.floor(Math.random() * 99999)
|
||||
|
||||
# setTimeout
|
||||
@log 'debug', 'set', key, timeout, level, callback
|
||||
call = =>
|
||||
@clear( key, level )
|
||||
@clear(key, level)
|
||||
callback()
|
||||
delay_id = setTimeout( call, timeout )
|
||||
delay_id = setTimeout(call, timeout)
|
||||
|
||||
# remember all delays
|
||||
if !@levelStack[level]
|
||||
|
@ -61,7 +61,7 @@ class _delaySingleton extends Spine.Module
|
|||
|
||||
key.toString()
|
||||
|
||||
clear: ( key, level ) =>
|
||||
clear: (key, level) =>
|
||||
|
||||
if !level
|
||||
level = '_all'
|
||||
|
@ -73,23 +73,23 @@ class _delaySingleton extends Spine.Module
|
|||
return if !data
|
||||
|
||||
@log 'debug', 'clear', data
|
||||
clearTimeout( data['delay_id'] )
|
||||
clearTimeout(data['delay_id'])
|
||||
|
||||
# cleanup if needed
|
||||
delete @levelStack[ level ][ key.toString() ]
|
||||
if _.isEmpty( @levelStack[ level ] )
|
||||
if _.isEmpty(@levelStack[ level ])
|
||||
delete @levelStack[ level ]
|
||||
|
||||
clearLevel: (level) =>
|
||||
return if !@levelStack[ level ]
|
||||
for key, data of @levelStack[ level ]
|
||||
@clear( key, level )
|
||||
@clear(key, level)
|
||||
delete @levelStack[level]
|
||||
|
||||
reset: =>
|
||||
for level, items of @levelStack
|
||||
for key, data of items
|
||||
@clear( key, level )
|
||||
@clear(key, level)
|
||||
@levelStack[level] = {}
|
||||
true
|
||||
|
||||
|
|
|
@ -4,20 +4,24 @@ class App.Event
|
|||
@init: ->
|
||||
_instance = new _eventSingleton
|
||||
|
||||
@bind: ( events, callback, level ) ->
|
||||
@bind: (events, callback, level) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _eventSingleton
|
||||
_instance.bind( events, callback, level )
|
||||
_instance.bind(events, callback, level, false)
|
||||
|
||||
@unbind: ( events, callback, level ) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _eventSingleton
|
||||
_instance.unbind( events, callback, level )
|
||||
one: (events, callback, level) ->
|
||||
@bind(events, callback, level, true)
|
||||
_instance.bind(events, callback, level, true)
|
||||
|
||||
@trigger: ( events, data ) ->
|
||||
@unbind: (events, callback, level) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _eventSingleton
|
||||
_instance.trigger( events, data )
|
||||
_instance.unbind(events, callback, level)
|
||||
|
||||
@trigger: (events, data) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _eventSingleton
|
||||
_instance.trigger( events, data)
|
||||
|
||||
@unbindLevel: (level) ->
|
||||
if _instance == undefined
|
||||
|
@ -38,10 +42,10 @@ class _eventSingleton extends Spine.Module
|
|||
unbindLevel: (level) ->
|
||||
return if !@eventCurrent[level]
|
||||
for item in @eventCurrent[level]
|
||||
@unbind( item.event, item.callback, level )
|
||||
@unbind(item.event, item.callback, level)
|
||||
delete @eventCurrent[level]
|
||||
|
||||
bind: ( events, callback, level ) ->
|
||||
bind: (events, callback, level, one = false) ->
|
||||
|
||||
if !level
|
||||
level = '_all'
|
||||
|
@ -55,15 +59,20 @@ class _eventSingleton extends Spine.Module
|
|||
|
||||
# remember all events
|
||||
@eventCurrent[ level ].push {
|
||||
event: event,
|
||||
callback: callback,
|
||||
event: event
|
||||
callback: callback
|
||||
one: false
|
||||
}
|
||||
|
||||
# bind
|
||||
if one
|
||||
@log 'debug', 'one', event, callback
|
||||
Spine.one(event, callback)
|
||||
else
|
||||
@log 'debug', 'bind', event, callback
|
||||
Spine.bind( event, callback )
|
||||
Spine.bind(event, callback)
|
||||
|
||||
unbind: ( events, callback, level ) ->
|
||||
unbind: (events, callback, level) ->
|
||||
|
||||
if !level
|
||||
level = '_all'
|
||||
|
@ -82,9 +91,9 @@ class _eventSingleton extends Spine.Module
|
|||
return item if item.event isnt event
|
||||
)
|
||||
@log 'debug', 'unbind', event, callback
|
||||
Spine.unbind( event, callback )
|
||||
Spine.unbind(event, callback)
|
||||
|
||||
trigger: ( events, data ) ->
|
||||
trigger: (events, data) ->
|
||||
eventList = events.split(' ')
|
||||
for event in eventList
|
||||
@log 'debug', 'trigger', event, data
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
class App.Interval
|
||||
_instance = undefined
|
||||
|
||||
@set: ( callback, timeout, key, level ) ->
|
||||
@set: (callback, timeout, key, level) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _intervalSingleton
|
||||
_instance.set( callback, timeout, key, level )
|
||||
_instance.set(callback, timeout, key, level)
|
||||
|
||||
@clear: ( key, level ) ->
|
||||
@clear: (key, level) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _intervalSingleton
|
||||
_instance.clear( key, level )
|
||||
_instance.clear(key, level)
|
||||
|
||||
@clearLevel: ( level ) ->
|
||||
@clearLevel: (level) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _intervalSingleton
|
||||
_instance.clearLevel( level )
|
||||
_instance.clearLevel(level)
|
||||
|
||||
@reset: ->
|
||||
if _instance == undefined
|
||||
|
@ -32,21 +32,21 @@ class _intervalSingleton extends Spine.Module
|
|||
constructor: ->
|
||||
@levelStack = {}
|
||||
|
||||
set: ( callback, timeout, key, level ) =>
|
||||
set: (callback, timeout, key, level) =>
|
||||
|
||||
if !level
|
||||
level = '_all'
|
||||
|
||||
if key
|
||||
@clear( key, level )
|
||||
@clear(key, level)
|
||||
|
||||
if !key
|
||||
key = Math.floor( Math.random() * 99999 )
|
||||
key = Math.floor(Math.random() * 99999)
|
||||
|
||||
# setTimeout
|
||||
@log 'debug', 'set', key, timeout, level, callback
|
||||
callback()
|
||||
interval_id = setInterval( callback, timeout )
|
||||
interval_id = setInterval(callback, timeout)
|
||||
|
||||
# remember all interval
|
||||
if !@levelStack[level]
|
||||
|
@ -59,7 +59,7 @@ class _intervalSingleton extends Spine.Module
|
|||
|
||||
key.toString()
|
||||
|
||||
clear: ( key, level ) =>
|
||||
clear: (key, level) =>
|
||||
|
||||
if !level
|
||||
level = '_all'
|
||||
|
@ -71,23 +71,23 @@ class _intervalSingleton extends Spine.Module
|
|||
return if !data
|
||||
|
||||
@log 'debug', 'clear', data
|
||||
clearInterval( data['interval_id'] )
|
||||
clearInterval(data['interval_id'])
|
||||
|
||||
# cleanup if needed
|
||||
delete @levelStack[ level ][ key.toString() ]
|
||||
if _.isEmpty( @levelStack[ level ] )
|
||||
if _.isEmpty(@levelStack[ level ])
|
||||
delete @levelStack[ level ]
|
||||
|
||||
clearLevel: (level) =>
|
||||
return if !@levelStack[ level ]
|
||||
for key, data of @levelStack[ level ]
|
||||
@clear( key, level )
|
||||
@clear(key, level)
|
||||
delete @levelStack[level]
|
||||
|
||||
reset: =>
|
||||
for level, items of @levelStack
|
||||
for key, data of items
|
||||
@clear( key, level )
|
||||
@clear(key, level)
|
||||
@levelStack[level] = {}
|
||||
true
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@ class App.TaskManager
|
|||
@all: ->
|
||||
_instance.all()
|
||||
|
||||
@allWithMeta: ->
|
||||
_instance.allWithMeta()
|
||||
|
||||
@execute: (params) ->
|
||||
_instance.execute(params)
|
||||
|
||||
|
@ -16,8 +19,8 @@ class App.TaskManager
|
|||
@update: (key, params) ->
|
||||
_instance.update(key, params)
|
||||
|
||||
@remove: (key, rerender = true) ->
|
||||
_instance.remove(key, rerender)
|
||||
@remove: (key) ->
|
||||
_instance.remove(key)
|
||||
|
||||
@notify: (key) ->
|
||||
_instance.notify(key)
|
||||
|
@ -28,6 +31,9 @@ class App.TaskManager
|
|||
@reorder: (order) ->
|
||||
_instance.reorder(order)
|
||||
|
||||
@touch: (key) ->
|
||||
_instance.touch(key)
|
||||
|
||||
@reset: ->
|
||||
_instance.reset()
|
||||
|
||||
|
@ -40,9 +46,6 @@ class App.TaskManager
|
|||
@TaskbarId: ->
|
||||
_instance.TaskbarId()
|
||||
|
||||
@renderDelay: ->
|
||||
_instance.renderDelay()
|
||||
|
||||
class _taskManagerSingleton extends App.Controller
|
||||
@include App.LogInclude
|
||||
|
||||
|
@ -78,18 +81,6 @@ class _taskManagerSingleton extends App.Controller
|
|||
@tasksToUpdate = {}
|
||||
@activeTaskHistory = []
|
||||
|
||||
# speed improvements for certain browsers
|
||||
@renderInitTime = 2200
|
||||
@renderDelayTime = 3400
|
||||
data = App.Browser.detection()
|
||||
if data.browser
|
||||
if data.browser.name is 'Chrome'
|
||||
@renderInitTime = 1000
|
||||
@renderDelayTime = 1600
|
||||
else if data.browser.anem is 'Firefox'
|
||||
@renderInitTime = 1200
|
||||
@renderDelayTime = 1800
|
||||
|
||||
all: ->
|
||||
|
||||
# sort by prio
|
||||
|
@ -98,6 +89,33 @@ class _taskManagerSingleton extends App.Controller
|
|||
)
|
||||
return @allTasks
|
||||
|
||||
allWithMeta: ->
|
||||
all = @all()
|
||||
for task in all
|
||||
task = @getMeta(task)
|
||||
all
|
||||
|
||||
getMeta: (task) ->
|
||||
|
||||
# collect meta data of task for task bar item
|
||||
meta =
|
||||
url: '#'
|
||||
id: false
|
||||
iconClass: 'loading'
|
||||
title: App.i18n.translateInline('Loading...')
|
||||
head: App.i18n.translateInline('Loading...')
|
||||
worker = App.TaskManager.worker(task.key)
|
||||
if worker
|
||||
data = worker.meta()
|
||||
|
||||
# apply meta data of controller
|
||||
if data
|
||||
for key, value of data
|
||||
meta[key] = value
|
||||
|
||||
task.meta = meta
|
||||
task
|
||||
|
||||
newPrio: ->
|
||||
prio = 1
|
||||
for task in @allTasks
|
||||
|
@ -192,7 +210,7 @@ class _taskManagerSingleton extends App.Controller
|
|||
if task.key isnt params.key
|
||||
if task.active
|
||||
task.active = false
|
||||
@taskUpdate(task, true)
|
||||
@taskUpdate(task)
|
||||
else
|
||||
changed = false
|
||||
if !task.active
|
||||
|
@ -202,25 +220,11 @@ class _taskManagerSingleton extends App.Controller
|
|||
changed = true
|
||||
task.notify = false
|
||||
if changed
|
||||
@taskUpdate(task, true)
|
||||
@taskUpdate(task)
|
||||
|
||||
# start worker for task if not exists
|
||||
@startController(params)
|
||||
|
||||
# set active state
|
||||
if !params.init
|
||||
$('.nav-tab.task').each( (_index, element) =>
|
||||
localElement = $(element)
|
||||
key = localElement.data('key')
|
||||
return if !key
|
||||
task = @get(key)
|
||||
return if !task
|
||||
if task.active
|
||||
localElement.addClass('is-active')
|
||||
else
|
||||
localElement.removeClass('is-active')
|
||||
)
|
||||
|
||||
startController: (params) =>
|
||||
|
||||
#console.log 'debug', 'controller start try...', params
|
||||
|
@ -269,11 +273,6 @@ class _taskManagerSingleton extends App.Controller
|
|||
if controller.show && _.isFunction(controller.show)
|
||||
controller.show(params_app)
|
||||
|
||||
# update title
|
||||
if controller.meta && _.isFunction(controller.meta)
|
||||
meta = controller.meta()
|
||||
@title meta.title
|
||||
|
||||
true
|
||||
|
||||
# hide task content
|
||||
|
@ -299,6 +298,12 @@ class _taskManagerSingleton extends App.Controller
|
|||
if task.key is key
|
||||
return task
|
||||
|
||||
# get task
|
||||
getWithMeta: (key) =>
|
||||
task = @get(key)
|
||||
return if !task
|
||||
@getMeta(task)
|
||||
|
||||
# update task
|
||||
update: (key, params) =>
|
||||
task = @get(key)
|
||||
|
@ -314,7 +319,7 @@ class _taskManagerSingleton extends App.Controller
|
|||
@taskUpdate(task, mute)
|
||||
|
||||
# remove task certain task from tasks
|
||||
remove: (key, rerender) =>
|
||||
remove: (key) =>
|
||||
|
||||
# remember started task
|
||||
delete @tasksStarted[key]
|
||||
|
@ -335,8 +340,7 @@ class _taskManagerSingleton extends App.Controller
|
|||
@release(key)
|
||||
|
||||
# rerender taskbar
|
||||
if rerender
|
||||
@metaTaskUpdate()
|
||||
App.Event.trigger('taskRemove', [task.id])
|
||||
|
||||
# destroy in backend storage
|
||||
@taskDestroy(task)
|
||||
|
@ -401,7 +405,7 @@ class _taskManagerSingleton extends App.Controller
|
|||
App.Taskbar.deleteAll()
|
||||
|
||||
# rerender task bar
|
||||
@metaTaskUpdate()
|
||||
App.Event.trigger('taskInit')
|
||||
|
||||
nextTaskUrl: =>
|
||||
|
||||
|
@ -432,8 +436,21 @@ class _taskManagerSingleton extends App.Controller
|
|||
taskUpdate: (task, mute = false) ->
|
||||
@log 'debug', 'UPDATE task', task, mute
|
||||
@tasksToUpdate[ task.key ] = 'toUpdate'
|
||||
if !mute
|
||||
@metaTaskUpdate()
|
||||
return if mute
|
||||
@touch(task.key)
|
||||
|
||||
touch: (key) ->
|
||||
delay = =>
|
||||
task = @getWithMeta(key)
|
||||
return if !task
|
||||
# throw "No such task with '#{key}' to touch"
|
||||
|
||||
# update title
|
||||
if task.active && task.meta
|
||||
@title task.meta.title
|
||||
|
||||
App.Event.trigger('taskUpdate', [task])
|
||||
App.Delay.set(delay, 20, "task-#{key}")
|
||||
|
||||
taskUpdateLoop: =>
|
||||
return if @offlineModus
|
||||
|
@ -482,6 +499,7 @@ class _taskManagerSingleton extends App.Controller
|
|||
# set taskbar collection stored in database
|
||||
tasks = App.Taskbar.all()
|
||||
for task in tasks
|
||||
task.active = false
|
||||
@allTasks.push task.attributes()
|
||||
|
||||
# reopen tasks
|
||||
|
@ -525,26 +543,9 @@ class _taskManagerSingleton extends App.Controller
|
|||
persistent: false
|
||||
init: true
|
||||
)
|
||||
task_count * 850
|
||||
task_count * 650
|
||||
undefined
|
||||
'task'
|
||||
)
|
||||
|
||||
# handle init task rendering at loading time, prevent multible, not needed dom operations
|
||||
@initTaskRenderInterval = App.Interval.set(
|
||||
->
|
||||
App.Event.trigger('task:render')
|
||||
@renderInitTime
|
||||
)
|
||||
App.Delay.set(
|
||||
=>
|
||||
App.Interval.clear(@initTaskRenderInterval)
|
||||
@renderDelayTime = 20
|
||||
App.Event.trigger('task:render')
|
||||
task_count * 950
|
||||
)
|
||||
|
||||
App.Event.trigger 'taskbar:ready'
|
||||
|
||||
renderDelay: =>
|
||||
@renderDelayTime
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
<% if item.navheader: %>
|
||||
<li class="dropdown-header"><%- @T( item.navheader ) %></li>
|
||||
<% end %>
|
||||
<li<%- ' class="is-active"' if @active_tab[item.target] %>><a href="<%= item.target %>"><%- @T( item.name ) %><% if item['count'] isnt undefined: %><span class="badge badge--text count"><%= item['count'] %></span><% end %></a></li>
|
||||
<li><a href="<%= item.target %>"><%- @T( item.name ) %><% if item['count'] isnt undefined: %><span class="badge badge--text count"><%= item['count'] %></span><% end %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% else: %>
|
||||
<a class="menu-item js-<%- item.class %>MenuItem<%- ' is-active' if @active_tab[item.target] %>" href="<%= item.target %>" data-key="<%- item.key %>">
|
||||
<a class="menu-item js-<%- item.class %>MenuItem" href="<%= item.target %>" data-key="<%- item.key %>">
|
||||
<%- @Icon(item.class, 'menu-item-icon') %>
|
||||
<span class="menu-item-name">
|
||||
<%- @T(item.name) %>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<% if item.navheader: %>
|
||||
<li class="dropdown-header"><%- @T( item.navheader ) %></li>
|
||||
<% end %>
|
||||
<li class="<% if @active_tab[item.target] : %>active<% end %>">
|
||||
<li>
|
||||
<a href="<%= item.target %>" class="horizontal center">
|
||||
<span class="flex u-textTruncate"><% if item.translate: %><%- @T( item.name ) %><% else: %><%= item.name %><% end %></span>
|
||||
<% if item['count'] isnt undefined: %><span class="badge badge--text count"><%= item['count'] %></span><% end %>
|
||||
|
@ -28,7 +28,7 @@
|
|||
</ul>
|
||||
</li>
|
||||
<% else: %>
|
||||
<li class="settings <% if @active_tab[item.target] : %>active<% end %>">
|
||||
<li class="settings">
|
||||
<a class="list-button fit horizontal centered" href="<%= item.target %>" title="<%- @Ti( item.name ) %>">
|
||||
<%- @Icon(item.icon, 'user-menu-icon') %>
|
||||
</a>
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<div class="well taskbar">
|
||||
<div class="taskbar-items"></div>
|
||||
<% if !_.isEmpty( @taskBarActions ): %>
|
||||
<div class="taskbar-new">
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-small btn--primary dropdown-toggle" data-toggle="dropdown" href="#new">
|
||||
<%- @T('New') %>
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-right">
|
||||
<% for item in @taskBarActions: %>
|
||||
<li><a href="<%- item.target %>"><%- @T(item.name) %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
|
@ -1,22 +0,0 @@
|
|||
<% for item in @taskItems: %>
|
||||
<a href="<%- item.meta.url %>" title="<%= item.meta.title %>" class="nav-tab task js-locationVerify <%= item.meta.class %><% if item.task.active: %> is-active<% end %><% if item.task.notify: %> is-modified<% end %>" data-key="<%- item.task.key %>">
|
||||
<div class="nav-tab-icon" title="<%- @Ti(item.meta.iconTitle) %>">
|
||||
<% if item.meta.type is 'task': %>
|
||||
<% if item.task.notify: %>
|
||||
<%- @Icon('small-dot', "icon-status-modified-inner-circle icon-task-state #{item.meta.iconClass}") %>
|
||||
<%- @Icon('status-modified-outer-circle', "icon-task-state #{item.meta.iconClass}") %>
|
||||
<% else: %>
|
||||
<%- @Icon('task-state', item.meta.iconClass) %>
|
||||
<% end %>
|
||||
<% else: %>
|
||||
<%- @Icon(item.meta.iconClass) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="nav-tab-name u-textTruncate flex"><%= item.meta.head %></div>
|
||||
<div class="nav-tab-close js-close" title="<%- @Ti('close') %>">
|
||||
<div class="nav-tab-close-inner">
|
||||
<%- @Icon('diagonal-cross') %>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<% end %>
|
20
app/assets/javascripts/app/views/widget/task_item.jst.eco
Normal file
20
app/assets/javascripts/app/views/widget/task_item.jst.eco
Normal file
|
@ -0,0 +1,20 @@
|
|||
<a href="<%- @item.meta.url %>" title="<%= @item.meta.title %>" class="nav-tab task js-locationVerify <%= @item.meta.class %><% if @item.active: %> is-active<% end %><% if @item.notify: %> is-modified<% end %>" data-key="<%- @item.key %>">
|
||||
<div class="nav-tab-icon" title="<%- @Ti(@item.meta.iconTitle) %>">
|
||||
<% if @item.meta.type is 'task': %>
|
||||
<% if @item.notify: %>
|
||||
<%- @Icon('small-dot', "icon-status-modified-inner-circle icon-task-state #{@item.meta.iconClass}") %>
|
||||
<%- @Icon('status-modified-outer-circle', "icon-task-state #{@item.meta.iconClass}") %>
|
||||
<% else: %>
|
||||
<%- @Icon('task-state', @item.meta.iconClass) %>
|
||||
<% end %>
|
||||
<% else: %>
|
||||
<%- @Icon(@item.meta.iconClass) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="nav-tab-name u-textTruncate flex"><%= @item.meta.head %></div>
|
||||
<div class="nav-tab-close js-close" title="<%- @Ti('close') %>">
|
||||
<div class="nav-tab-close-inner">
|
||||
<%- @Icon('diagonal-cross') %>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
|
@ -4,14 +4,14 @@ module ExtraCollection
|
|||
def session( collections, assets, user )
|
||||
|
||||
# all base stuff
|
||||
collections[ Locale.to_app_model ] = Locale.where( active: true )
|
||||
collections[ Locale.to_app_model ] = Locale.where(active: true)
|
||||
|
||||
collections[ Taskbar.to_app_model ] = Taskbar.where( user_id: user.id )
|
||||
collections[ Taskbar.to_app_model ] = Taskbar.where(user_id: user.id)
|
||||
collections[ Taskbar.to_app_model ].each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
|
||||
collections[ OnlineNotification.to_app_model ] = OnlineNotification.list(user, 50)
|
||||
collections[ OnlineNotification.to_app_model ] = OnlineNotification.list(user, 100)
|
||||
assets = ApplicationModel.assets_of_object_list(collections[ OnlineNotification.to_app_model ], assets)
|
||||
|
||||
collections[ RecentView.to_app_model ] = RecentView.list(user, 10)
|
||||
|
@ -29,7 +29,7 @@ module ExtraCollection
|
|||
|
||||
collections[ Organization.to_app_model ] = []
|
||||
if user.organization_id
|
||||
Organization.where( id: user.organization_id ).each {|item|
|
||||
Organization.where(id: user.organization_id).each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ module Service
|
|||
|
||||
lookup lat and lng for address
|
||||
|
||||
result = Service::GeoLocation.geocode( 'Marienstrasse 13, 10117 Berlin' )
|
||||
result = Service::GeoLocation.geocode('Marienstrasse 13, 10117 Berlin')
|
||||
|
||||
returns
|
||||
|
||||
|
@ -30,7 +30,7 @@ returns
|
|||
|
||||
lookup address for lat and lng
|
||||
|
||||
result = GeoLocation.reverse_geocode( 4.21312, 1.3123 )
|
||||
result = GeoLocation.reverse_geocode(4.21312, 1.3123)
|
||||
|
||||
returns
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class AgentTicketActionLevel4Test < TestCase
|
|||
)
|
||||
|
||||
# finally create ticket
|
||||
click( css: '.content.active .js-submit' )
|
||||
click(css: '.content.active .js-submit')
|
||||
sleep 5
|
||||
|
||||
location_check(
|
||||
|
|
|
@ -333,6 +333,7 @@ class TestCase < Test::Unit::TestCase
|
|||
if !instance.find_elements(css: 'body')[0] || instance.find_elements(css: 'body')[0].text =~ /unavailable or too busy/i
|
||||
instance.navigate.refresh
|
||||
end
|
||||
sleep 2
|
||||
screenshot(browser: instance, comment: 'reload_after')
|
||||
end
|
||||
|
||||
|
|
|
@ -6,22 +6,22 @@ class GeoLocationTest < ActiveSupport::TestCase
|
|||
# check
|
||||
test 'check simple results' do
|
||||
|
||||
result = Service::GeoLocation.geocode( 'Marienstrasse 13, 10117 Berlin' )
|
||||
result = Service::GeoLocation.geocode('Marienstrasse 13, 10117 Berlin')
|
||||
assert(result)
|
||||
assert_equal(52.52204, result[0])
|
||||
assert_equal(13.38319, result[1])
|
||||
|
||||
result = Service::GeoLocation.geocode( 'Marienstrasse 13 10117 Berlin' )
|
||||
result = Service::GeoLocation.geocode('Marienstrasse 13 10117 Berlin')
|
||||
assert(result)
|
||||
assert_equal(52.52204, result[0])
|
||||
assert_equal(13.38319, result[1])
|
||||
|
||||
result = Service::GeoLocation.geocode( 'Martinsbruggstrasse 35, 9016 St. Gallen' )
|
||||
result = Service::GeoLocation.geocode('Martinsbruggstrasse 35, 9016 St. Gallen')
|
||||
assert(result)
|
||||
assert_equal(47.4366664, result[0])
|
||||
assert_equal(9.409814899999999, result[1])
|
||||
|
||||
result = Service::GeoLocation.geocode( 'Martinsbruggstrasse 35 9016 St. Gallen' )
|
||||
result = Service::GeoLocation.geocode('Martinsbruggstrasse 35 9016 St. Gallen')
|
||||
assert(result)
|
||||
assert_equal(47.4366664, result[0])
|
||||
assert_equal(9.409814899999999, result[1])
|
||||
|
|
Loading…
Reference in a new issue