Refectory task rendering (just updated certain elements if needed).

This commit is contained in:
Martin Edenhofer 2016-03-31 15:41:34 +02:00
parent 618d583587
commit 8195e0f262
23 changed files with 295 additions and 273 deletions

View file

@ -559,15 +559,6 @@ class App.Controller extends Spine.Controller
renderScreenUnauthorized: (data) -> renderScreenUnauthorized: (data) ->
@html App.view('generic/error/unauthorized')(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) => locationVerify: (e) =>
newLocation = $(e.currentTarget).attr 'href' newLocation = $(e.currentTarget).attr 'href'
@log 'debug', "new location '#{newLocation}'" @log 'debug', "new location '#{newLocation}'"
@ -587,7 +578,6 @@ class App.Controller extends Spine.Controller
newLocation = newLocation.replace(/#/, '') newLocation = newLocation.replace(/#/, '')
@log 'debug', "execute controller again for '#{newLocation}' because of same hash" @log 'debug', "execute controller again for '#{newLocation}' because of same hash"
Spine.Route.matchRoutes(newLocation) Spine.Route.matchRoutes(newLocation)
@metaTaskUpdate()
logoUrl: -> logoUrl: ->
"#{@Config.get('image_path')}/#{@Config.get('product_logo')}" "#{@Config.get('image_path')}/#{@Config.get('product_logo')}"
@ -812,7 +802,7 @@ class App.UpdateTastbar extends App.Controller
update: (genericObject) => update: (genericObject) =>
# update taskbar with new meta data # update taskbar with new meta data
@metaTaskUpdate() App.TaskManager.touch(@task_key)
class App.ControllerWidgetPermanent extends App.Controller class App.ControllerWidgetPermanent extends App.Controller
constructor: (params) -> constructor: (params) ->

View file

@ -119,7 +119,7 @@ class App.TicketCreate extends App.Controller
"#ticket/create/id/#{@id}" "#ticket/create/id/#{@id}"
show: => show: =>
@navupdate '#' @navupdate(url: '#', type: 'menu')
changed: => changed: =>
formCurrent = @formParam( @$('.ticket-create') ) formCurrent = @formParam( @$('.ticket-create') )
@ -140,7 +140,7 @@ class App.TicketCreate extends App.Controller
title = @$('[name=title]').val() title = @$('[name=title]').val()
if @latestTitle isnt title if @latestTitle isnt title
@latestTitle = title @latestTitle = title
@metaTaskUpdate() App.TaskManager.touch(@task_key)
@interval(update, 3000, @id) @interval(update, 3000, @id)
@ -185,6 +185,7 @@ class App.TicketCreate extends App.Controller
) )
render: (template = {}) -> render: (template = {}) ->
App.TaskManager.touch(@task_key)
# get params # get params
params = {} params = {}
@ -317,7 +318,7 @@ class App.TicketCreate extends App.Controller
@autosave() @autosave()
# update taskbar with new meta data # update taskbar with new meta data
@metaTaskUpdate() App.TaskManager.touch(@task_key)
localUserInfo: (e) => localUserInfo: (e) =>

View file

@ -65,30 +65,30 @@ class App.TicketMerge extends App.ControllerModal
if data['result'] is 'success' if data['result'] is 'success'
# update collection # update collection
App.Collection.load( type: 'Ticket', data: [data.master_ticket] ) 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.slave_ticket])
# hide dialog # hide dialog
@close() @close()
# view ticket # 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'] @navigate '#ticket/zoom/' + data.master_ticket['id']
# notify UI # notify UI
@notify @notify
type: 'success' 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 timeout: 4000
App.TaskManager.remove( 'Ticket-' + data.slave_ticket['id'] ) App.TaskManager.remove("Ticket-#{data.slave_ticket['id']}")
else else
# notify UI # notify UI
@notify @notify
type: 'error' type: 'error'
msg: App.i18n.translateContent( data['message'] ) msg: App.i18n.translateContent(data['message'])
timeout: 6000 timeout: 6000
@formEnable(e) @formEnable(e)

View file

@ -22,8 +22,8 @@ class App.Navigation extends App.ControllerWidgetPermanent
@renderPersonal() @renderPersonal()
# update selected item # update selected item
@bind 'navupdate', => @bind 'navupdate', (params) =>
@update(arguments[0]) @update(params)
# rebuild nav bar with given user data # rebuild nav bar with given user data
@bind 'auth', (user) => @bind 'auth', (user) =>
@ -86,18 +86,10 @@ class App.Navigation extends App.ControllerWidgetPermanent
open_tab[href] = true 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 # render menu
@$('.js-menu').html App.view('navigation/menu')( @$('.js-menu').html App.view('navigation/menu')(
items: items items: items
open_tab: open_tab open_tab: open_tab
active_tab: active_tab
) )
# bind on switch changes and execute it on controller # bind on switch changes and execute it on controller
@ -121,17 +113,9 @@ class App.Navigation extends App.ControllerWidgetPermanent
open_tab[href] = true 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')( @$('.navbar-items-personal').html App.view('navigation/personal')(
items: items items: items
open_tab: open_tab open_tab: open_tab
active_tab: active_tab
) )
# only start avatar widget on existing session # only start avatar widget on existing session
@ -428,8 +412,15 @@ class App.Navigation extends App.ControllerWidgetPermanent
if newlist[ item['prio'] ] if newlist[ item['prio'] ]
@addPrioCount newlist, item @addPrioCount newlist, item
update: (url) => update: (params) =>
@$('.is-active').removeClass('is-active') 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 '#' return if !url || url is '#'
@$("[href=\"#{url}\"]").addClass('is-active') @$("[href=\"#{url}\"]").addClass('is-active')

View file

@ -34,13 +34,16 @@ class App.OrganizationProfile extends App.Controller
show: => show: =>
App.OnlineNotification.seen('Organization', @organization_id) App.OnlineNotification.seen('Organization', @organization_id)
@navupdate '#' @navupdate(url: '#', type: 'menu')
changed: -> changed: ->
false false
render: (organization) => render: (organization) =>
# update taskbar with new meta data
App.TaskManager.touch(@task_key)
if !@doNotLog if !@doNotLog
@doNotLog = 1 @doNotLog = 1
@recentView('Organization', @organization_id) @recentView('Organization', @organization_id)
@ -80,9 +83,6 @@ class Object extends App.Controller
render: (organization) => render: (organization) =>
# update taskbar with new meta data
@metaTaskUpdate()
# get display data # get display data
organizationData = [] organizationData = []
for attributeName, attributeConfig of App.Organization.attributesGet('view') for attributeName, attributeConfig of App.Organization.attributesGet('view')

View file

@ -2,60 +2,31 @@ class App.TaskbarWidget extends App.Controller
events: events:
'click .js-close': 'remove' 'click .js-close': 'remove'
'click .js-locationVerify': 'location' '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: -> constructor: ->
super super
@render() @renderAll()
# 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
)
dndOptions = dndOptions =
tolerance: 'pointer' tolerance: 'pointer'
@ -75,6 +46,86 @@ class App.TaskbarWidget extends App.Controller
@el.sortable(dndOptions) @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) => location: (e) =>
return if !$(e.currentTarget).hasClass('is-modified') return if !$(e.currentTarget).hasClass('is-modified')
@locationVerify(e) @locationVerify(e)
@ -107,9 +158,7 @@ class App.TaskbarWidget extends App.Controller
activeIsClosed = true activeIsClosed = true
# remove task # remove task
App.TaskManager.remove(key, false) App.TaskManager.remove(key)
$(e.target).closest('.task').remove()
# if we do not need to move to an other task # if we do not need to move to an other task
return if !activeIsClosed return if !activeIsClosed

View file

@ -88,7 +88,7 @@ class App.TicketZoom extends App.Controller
show: (params) => show: (params) =>
@navupdate '#' @navupdate(url: '#', type: 'menu')
# set all notifications to seen # set all notifications to seen
App.OnlineNotification.seen('Ticket', @ticket_id) App.OnlineNotification.seen('Ticket', @ticket_id)
@ -212,7 +212,7 @@ class App.TicketZoom extends App.Controller
) )
# update taskbar with new meta data # update taskbar with new meta data
@metaTaskUpdate() App.TaskManager.touch(@task_key)
) )
@ -284,7 +284,7 @@ class App.TicketZoom extends App.Controller
render: => render: =>
# update taskbar with new meta data # update taskbar with new meta data
@metaTaskUpdate() App.TaskManager.touch(@task_key)
@formEnable( @$('.submit') ) @formEnable( @$('.submit') )

View file

@ -51,7 +51,7 @@ class App.TicketZoomTitle extends App.Controller
App.TaskManager.mute(@task_key) App.TaskManager.mute(@task_key)
# update taskbar with new meta data # update taskbar with new meta data
@metaTaskUpdate() App.TaskManager.touch(@task_key)
App.Event.trigger('overview:fetch') App.Event.trigger('overview:fetch')

View file

@ -36,13 +36,16 @@ class App.UserProfile extends App.Controller
show: => show: =>
App.OnlineNotification.seen('User', @user_id) App.OnlineNotification.seen('User', @user_id)
@navupdate '#' @navupdate(url: '#', type: 'menu')
changed: -> changed: ->
false false
render: (user) => render: (user) =>
# update taskbar with new meta data
App.TaskManager.touch(@task_key)
if !@doNotLog if !@doNotLog
@doNotLog = 1 @doNotLog = 1
@recentView('User', @user_id) @recentView('User', @user_id)
@ -83,9 +86,6 @@ class Object extends App.Controller
render: (user) => render: (user) =>
# update taskbar with new meta data
@metaTaskUpdate()
# get display data # get display data
userData = [] userData = []
for attributeName, attributeConfig of App.User.attributesGet('view') for attributeName, attributeConfig of App.User.attributesGet('view')

View file

@ -1,20 +1,20 @@
class App.Delay class App.Delay
_instance = undefined _instance = undefined
@set: ( callback, timeout, key, level ) -> @set: (callback, timeout, key, level) ->
if _instance == undefined if _instance == undefined
_instance ?= new _delaySingleton _instance ?= new _delaySingleton
_instance.set( callback, timeout, key, level ) _instance.set(callback, timeout, key, level)
@clear: ( key, level ) -> @clear: (key, level) ->
if _instance == undefined if _instance == undefined
_instance ?= new _delaySingleton _instance ?= new _delaySingleton
_instance.clear( key, level ) _instance.clear(key, level)
@clearLevel: ( level ) -> @clearLevel: (level) ->
if _instance == undefined if _instance == undefined
_instance ?= new _delaySingleton _instance ?= new _delaySingleton
_instance.clearLevel( level ) _instance.clearLevel(level)
@reset: -> @reset: ->
if _instance == undefined if _instance == undefined
@ -32,23 +32,23 @@ class _delaySingleton extends Spine.Module
constructor: -> constructor: ->
@levelStack = {} @levelStack = {}
set: ( callback, timeout, key, level ) => set: (callback, timeout, key, level) =>
if !level if !level
level = '_all' level = '_all'
if key if key
@clear( key, level ) @clear(key, level)
if !key if !key
key = Math.floor( Math.random() * 99999 ) key = Math.floor(Math.random() * 99999)
# setTimeout # setTimeout
@log 'debug', 'set', key, timeout, level, callback @log 'debug', 'set', key, timeout, level, callback
call = => call = =>
@clear( key, level ) @clear(key, level)
callback() callback()
delay_id = setTimeout( call, timeout ) delay_id = setTimeout(call, timeout)
# remember all delays # remember all delays
if !@levelStack[level] if !@levelStack[level]
@ -61,7 +61,7 @@ class _delaySingleton extends Spine.Module
key.toString() key.toString()
clear: ( key, level ) => clear: (key, level) =>
if !level if !level
level = '_all' level = '_all'
@ -73,23 +73,23 @@ class _delaySingleton extends Spine.Module
return if !data return if !data
@log 'debug', 'clear', data @log 'debug', 'clear', data
clearTimeout( data['delay_id'] ) clearTimeout(data['delay_id'])
# cleanup if needed # cleanup if needed
delete @levelStack[ level ][ key.toString() ] delete @levelStack[ level ][ key.toString() ]
if _.isEmpty( @levelStack[ level ] ) if _.isEmpty(@levelStack[ level ])
delete @levelStack[ level ] delete @levelStack[ level ]
clearLevel: (level) => clearLevel: (level) =>
return if !@levelStack[ level ] return if !@levelStack[ level ]
for key, data of @levelStack[ level ] for key, data of @levelStack[ level ]
@clear( key, level ) @clear(key, level)
delete @levelStack[level] delete @levelStack[level]
reset: => reset: =>
for level, items of @levelStack for level, items of @levelStack
for key, data of items for key, data of items
@clear( key, level ) @clear(key, level)
@levelStack[level] = {} @levelStack[level] = {}
true true

View file

@ -4,20 +4,24 @@ class App.Event
@init: -> @init: ->
_instance = new _eventSingleton _instance = new _eventSingleton
@bind: ( events, callback, level ) -> @bind: (events, callback, level) ->
if _instance == undefined if _instance == undefined
_instance ?= new _eventSingleton _instance ?= new _eventSingleton
_instance.bind( events, callback, level ) _instance.bind(events, callback, level, false)
@unbind: ( events, callback, level ) -> one: (events, callback, level) ->
if _instance == undefined @bind(events, callback, level, true)
_instance ?= new _eventSingleton _instance.bind(events, callback, level, true)
_instance.unbind( events, callback, level )
@trigger: ( events, data ) -> @unbind: (events, callback, level) ->
if _instance == undefined if _instance == undefined
_instance ?= new _eventSingleton _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) -> @unbindLevel: (level) ->
if _instance == undefined if _instance == undefined
@ -38,10 +42,10 @@ class _eventSingleton extends Spine.Module
unbindLevel: (level) -> unbindLevel: (level) ->
return if !@eventCurrent[level] return if !@eventCurrent[level]
for item in @eventCurrent[level] for item in @eventCurrent[level]
@unbind( item.event, item.callback, level ) @unbind(item.event, item.callback, level)
delete @eventCurrent[level] delete @eventCurrent[level]
bind: ( events, callback, level ) -> bind: (events, callback, level, one = false) ->
if !level if !level
level = '_all' level = '_all'
@ -55,15 +59,20 @@ class _eventSingleton extends Spine.Module
# remember all events # remember all events
@eventCurrent[ level ].push { @eventCurrent[ level ].push {
event: event, event: event
callback: callback, callback: callback
one: false
} }
# bind # bind
@log 'debug', 'bind', event, callback if one
Spine.bind( event, callback ) @log 'debug', 'one', event, callback
Spine.one(event, callback)
else
@log 'debug', 'bind', event, callback
Spine.bind(event, callback)
unbind: ( events, callback, level ) -> unbind: (events, callback, level) ->
if !level if !level
level = '_all' level = '_all'
@ -82,9 +91,9 @@ class _eventSingleton extends Spine.Module
return item if item.event isnt event return item if item.event isnt event
) )
@log 'debug', 'unbind', event, callback @log 'debug', 'unbind', event, callback
Spine.unbind( event, callback ) Spine.unbind(event, callback)
trigger: ( events, data ) -> trigger: (events, data) ->
eventList = events.split(' ') eventList = events.split(' ')
for event in eventList for event in eventList
@log 'debug', 'trigger', event, data @log 'debug', 'trigger', event, data

View file

@ -1,20 +1,20 @@
class App.Interval class App.Interval
_instance = undefined _instance = undefined
@set: ( callback, timeout, key, level ) -> @set: (callback, timeout, key, level) ->
if _instance == undefined if _instance == undefined
_instance ?= new _intervalSingleton _instance ?= new _intervalSingleton
_instance.set( callback, timeout, key, level ) _instance.set(callback, timeout, key, level)
@clear: ( key, level ) -> @clear: (key, level) ->
if _instance == undefined if _instance == undefined
_instance ?= new _intervalSingleton _instance ?= new _intervalSingleton
_instance.clear( key, level ) _instance.clear(key, level)
@clearLevel: ( level ) -> @clearLevel: (level) ->
if _instance == undefined if _instance == undefined
_instance ?= new _intervalSingleton _instance ?= new _intervalSingleton
_instance.clearLevel( level ) _instance.clearLevel(level)
@reset: -> @reset: ->
if _instance == undefined if _instance == undefined
@ -32,21 +32,21 @@ class _intervalSingleton extends Spine.Module
constructor: -> constructor: ->
@levelStack = {} @levelStack = {}
set: ( callback, timeout, key, level ) => set: (callback, timeout, key, level) =>
if !level if !level
level = '_all' level = '_all'
if key if key
@clear( key, level ) @clear(key, level)
if !key if !key
key = Math.floor( Math.random() * 99999 ) key = Math.floor(Math.random() * 99999)
# setTimeout # setTimeout
@log 'debug', 'set', key, timeout, level, callback @log 'debug', 'set', key, timeout, level, callback
callback() callback()
interval_id = setInterval( callback, timeout ) interval_id = setInterval(callback, timeout)
# remember all interval # remember all interval
if !@levelStack[level] if !@levelStack[level]
@ -59,7 +59,7 @@ class _intervalSingleton extends Spine.Module
key.toString() key.toString()
clear: ( key, level ) => clear: (key, level) =>
if !level if !level
level = '_all' level = '_all'
@ -71,23 +71,23 @@ class _intervalSingleton extends Spine.Module
return if !data return if !data
@log 'debug', 'clear', data @log 'debug', 'clear', data
clearInterval( data['interval_id'] ) clearInterval(data['interval_id'])
# cleanup if needed # cleanup if needed
delete @levelStack[ level ][ key.toString() ] delete @levelStack[ level ][ key.toString() ]
if _.isEmpty( @levelStack[ level ] ) if _.isEmpty(@levelStack[ level ])
delete @levelStack[ level ] delete @levelStack[ level ]
clearLevel: (level) => clearLevel: (level) =>
return if !@levelStack[ level ] return if !@levelStack[ level ]
for key, data of @levelStack[ level ] for key, data of @levelStack[ level ]
@clear( key, level ) @clear(key, level)
delete @levelStack[level] delete @levelStack[level]
reset: => reset: =>
for level, items of @levelStack for level, items of @levelStack
for key, data of items for key, data of items
@clear( key, level ) @clear(key, level)
@levelStack[level] = {} @levelStack[level] = {}
true true

View file

@ -7,6 +7,9 @@ class App.TaskManager
@all: -> @all: ->
_instance.all() _instance.all()
@allWithMeta: ->
_instance.allWithMeta()
@execute: (params) -> @execute: (params) ->
_instance.execute(params) _instance.execute(params)
@ -16,8 +19,8 @@ class App.TaskManager
@update: (key, params) -> @update: (key, params) ->
_instance.update(key, params) _instance.update(key, params)
@remove: (key, rerender = true) -> @remove: (key) ->
_instance.remove(key, rerender) _instance.remove(key)
@notify: (key) -> @notify: (key) ->
_instance.notify(key) _instance.notify(key)
@ -28,6 +31,9 @@ class App.TaskManager
@reorder: (order) -> @reorder: (order) ->
_instance.reorder(order) _instance.reorder(order)
@touch: (key) ->
_instance.touch(key)
@reset: -> @reset: ->
_instance.reset() _instance.reset()
@ -40,9 +46,6 @@ class App.TaskManager
@TaskbarId: -> @TaskbarId: ->
_instance.TaskbarId() _instance.TaskbarId()
@renderDelay: ->
_instance.renderDelay()
class _taskManagerSingleton extends App.Controller class _taskManagerSingleton extends App.Controller
@include App.LogInclude @include App.LogInclude
@ -78,18 +81,6 @@ class _taskManagerSingleton extends App.Controller
@tasksToUpdate = {} @tasksToUpdate = {}
@activeTaskHistory = [] @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: -> all: ->
# sort by prio # sort by prio
@ -98,6 +89,33 @@ class _taskManagerSingleton extends App.Controller
) )
return @allTasks 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: -> newPrio: ->
prio = 1 prio = 1
for task in @allTasks for task in @allTasks
@ -192,7 +210,7 @@ class _taskManagerSingleton extends App.Controller
if task.key isnt params.key if task.key isnt params.key
if task.active if task.active
task.active = false task.active = false
@taskUpdate(task, true) @taskUpdate(task)
else else
changed = false changed = false
if !task.active if !task.active
@ -202,25 +220,11 @@ class _taskManagerSingleton extends App.Controller
changed = true changed = true
task.notify = false task.notify = false
if changed if changed
@taskUpdate(task, true) @taskUpdate(task)
# start worker for task if not exists # start worker for task if not exists
@startController(params) @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) => startController: (params) =>
#console.log 'debug', 'controller start try...', params #console.log 'debug', 'controller start try...', params
@ -269,11 +273,6 @@ class _taskManagerSingleton extends App.Controller
if controller.show && _.isFunction(controller.show) if controller.show && _.isFunction(controller.show)
controller.show(params_app) controller.show(params_app)
# update title
if controller.meta && _.isFunction(controller.meta)
meta = controller.meta()
@title meta.title
true true
# hide task content # hide task content
@ -299,6 +298,12 @@ class _taskManagerSingleton extends App.Controller
if task.key is key if task.key is key
return task return task
# get task
getWithMeta: (key) =>
task = @get(key)
return if !task
@getMeta(task)
# update task # update task
update: (key, params) => update: (key, params) =>
task = @get(key) task = @get(key)
@ -314,7 +319,7 @@ class _taskManagerSingleton extends App.Controller
@taskUpdate(task, mute) @taskUpdate(task, mute)
# remove task certain task from tasks # remove task certain task from tasks
remove: (key, rerender) => remove: (key) =>
# remember started task # remember started task
delete @tasksStarted[key] delete @tasksStarted[key]
@ -335,8 +340,7 @@ class _taskManagerSingleton extends App.Controller
@release(key) @release(key)
# rerender taskbar # rerender taskbar
if rerender App.Event.trigger('taskRemove', [task.id])
@metaTaskUpdate()
# destroy in backend storage # destroy in backend storage
@taskDestroy(task) @taskDestroy(task)
@ -401,7 +405,7 @@ class _taskManagerSingleton extends App.Controller
App.Taskbar.deleteAll() App.Taskbar.deleteAll()
# rerender task bar # rerender task bar
@metaTaskUpdate() App.Event.trigger('taskInit')
nextTaskUrl: => nextTaskUrl: =>
@ -432,8 +436,21 @@ class _taskManagerSingleton extends App.Controller
taskUpdate: (task, mute = false) -> taskUpdate: (task, mute = false) ->
@log 'debug', 'UPDATE task', task, mute @log 'debug', 'UPDATE task', task, mute
@tasksToUpdate[ task.key ] = 'toUpdate' @tasksToUpdate[ task.key ] = 'toUpdate'
if !mute return if mute
@metaTaskUpdate() @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: => taskUpdateLoop: =>
return if @offlineModus return if @offlineModus
@ -482,6 +499,7 @@ class _taskManagerSingleton extends App.Controller
# set taskbar collection stored in database # set taskbar collection stored in database
tasks = App.Taskbar.all() tasks = App.Taskbar.all()
for task in tasks for task in tasks
task.active = false
@allTasks.push task.attributes() @allTasks.push task.attributes()
# reopen tasks # reopen tasks
@ -525,26 +543,9 @@ class _taskManagerSingleton extends App.Controller
persistent: false persistent: false
init: true init: true
) )
task_count * 850 task_count * 650
undefined undefined
'task' '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' App.Event.trigger 'taskbar:ready'
renderDelay: =>
@renderDelayTime

View file

@ -16,12 +16,12 @@
<% if item.navheader: %> <% if item.navheader: %>
<li class="dropdown-header"><%- @T( item.navheader ) %></li> <li class="dropdown-header"><%- @T( item.navheader ) %></li>
<% end %> <% 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 %> <% end %>
</ul> </ul>
</div> </div>
<% else: %> <% 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') %> <%- @Icon(item.class, 'menu-item-icon') %>
<span class="menu-item-name"> <span class="menu-item-name">
<%- @T(item.name) %> <%- @T(item.name) %>

View file

@ -17,7 +17,7 @@
<% if item.navheader: %> <% if item.navheader: %>
<li class="dropdown-header"><%- @T( item.navheader ) %></li> <li class="dropdown-header"><%- @T( item.navheader ) %></li>
<% end %> <% end %>
<li class="<% if @active_tab[item.target] : %>active<% end %>"> <li>
<a href="<%= item.target %>" class="horizontal center"> <a href="<%= item.target %>" class="horizontal center">
<span class="flex u-textTruncate"><% if item.translate: %><%- @T( item.name ) %><% else: %><%= item.name %><% end %></span> <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 %> <% if item['count'] isnt undefined: %><span class="badge badge--text count"><%= item['count'] %></span><% end %>
@ -28,7 +28,7 @@
</ul> </ul>
</li> </li>
<% else: %> <% 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 ) %>"> <a class="list-button fit horizontal centered" href="<%= item.target %>" title="<%- @Ti( item.name ) %>">
<%- @Icon(item.icon, 'user-menu-icon') %> <%- @Icon(item.icon, 'user-menu-icon') %>
</a> </a>

View file

@ -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>

View file

@ -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 %>

View 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>

View file

@ -4,14 +4,14 @@ module ExtraCollection
def session( collections, assets, user ) def session( collections, assets, user )
# all base stuff # 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| collections[ Taskbar.to_app_model ].each {|item|
assets = item.assets(assets) 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) assets = ApplicationModel.assets_of_object_list(collections[ OnlineNotification.to_app_model ], assets)
collections[ RecentView.to_app_model ] = RecentView.list(user, 10) collections[ RecentView.to_app_model ] = RecentView.list(user, 10)
@ -29,7 +29,7 @@ module ExtraCollection
collections[ Organization.to_app_model ] = [] collections[ Organization.to_app_model ] = []
if user.organization_id if user.organization_id
Organization.where( id: user.organization_id ).each {|item| Organization.where(id: user.organization_id).each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
end end

View file

@ -8,7 +8,7 @@ module Service
lookup lat and lng for address lookup lat and lng for address
result = Service::GeoLocation.geocode( 'Marienstrasse 13, 10117 Berlin' ) result = Service::GeoLocation.geocode('Marienstrasse 13, 10117 Berlin')
returns returns
@ -30,7 +30,7 @@ returns
lookup address for lat and lng lookup address for lat and lng
result = GeoLocation.reverse_geocode( 4.21312, 1.3123 ) result = GeoLocation.reverse_geocode(4.21312, 1.3123)
returns returns

View file

@ -52,7 +52,7 @@ class AgentTicketActionLevel4Test < TestCase
) )
# finally create ticket # finally create ticket
click( css: '.content.active .js-submit' ) click(css: '.content.active .js-submit')
sleep 5 sleep 5
location_check( location_check(

View file

@ -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 if !instance.find_elements(css: 'body')[0] || instance.find_elements(css: 'body')[0].text =~ /unavailable or too busy/i
instance.navigate.refresh instance.navigate.refresh
end end
sleep 2
screenshot(browser: instance, comment: 'reload_after') screenshot(browser: instance, comment: 'reload_after')
end end

View file

@ -6,22 +6,22 @@ class GeoLocationTest < ActiveSupport::TestCase
# check # check
test 'check simple results' do test 'check simple results' do
result = Service::GeoLocation.geocode( 'Marienstrasse 13, 10117 Berlin' ) result = Service::GeoLocation.geocode('Marienstrasse 13, 10117 Berlin')
assert(result) assert(result)
assert_equal(52.52204, result[0]) assert_equal(52.52204, result[0])
assert_equal(13.38319, result[1]) 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(result)
assert_equal(52.52204, result[0]) assert_equal(52.52204, result[0])
assert_equal(13.38319, result[1]) 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(result)
assert_equal(47.4366664, result[0]) assert_equal(47.4366664, result[0])
assert_equal(9.409814899999999, result[1]) 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(result)
assert_equal(47.4366664, result[0]) assert_equal(47.4366664, result[0])
assert_equal(9.409814899999999, result[1]) assert_equal(9.409814899999999, result[1])