From 60ed0a21c9a63b5c815f256a85020ad643d13f35 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Fri, 31 May 2013 13:29:48 +0200 Subject: [PATCH] Rewritten taskbar manager. --- .../controllers/agent_ticket_create.js.coffee | 4 +- .../controllers/agent_ticket_merge.js.coffee | 2 +- .../controllers/agent_ticket_zoom.js.coffee | 9 +- .../app/controllers/task_widget.js.coffee | 49 +-- .../app/lib/app_post/task_manager.js.coffee | 300 ++++++++---------- .../javascripts/app/views/task_widget.jst.eco | 4 +- app/assets/javascripts/application.js | 1 + 7 files changed, 173 insertions(+), 196 deletions(-) diff --git a/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee b/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee index 8a5b5e1e9..fe91d8159 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee @@ -89,7 +89,7 @@ class App.TicketCreate extends App.Controller if !@autosaveLast || ( diff && !_.isEmpty( diff ) ) @autosaveLast = data console.log('form hash changed', diff, data) - App.TaskManager.update( @task_key, { 'state': data }) + App.TaskManager.update( 'TicketCreateScreen', @type + '-' + @id, { 'state': data }) @interval( update, 10000, @id, @auto_save_key ) # get data / in case also ticket data for split @@ -302,7 +302,7 @@ class App.TicketCreate extends App.Controller # create new create screen # ui.render() - App.TaskManager.remove( ui.task_key ) + App.TaskManager.remove( 'TicketCreateScreen', ui.type + '-' + ui.id ) # scroll to top ui.scrollTo() diff --git a/app/assets/javascripts/app/controllers/agent_ticket_merge.js.coffee b/app/assets/javascripts/app/controllers/agent_ticket_merge.js.coffee index 42c09b701..b2255d688 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_merge.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_merge.js.coffee @@ -133,7 +133,7 @@ class App.TicketMerge extends App.ControllerModal msg: App.i18n.translateContent( 'Ticket %s merged!', data.slave_ticket['number'] ), timeout: 4000, - App.TaskManager.remove( @task_key ) + App.TaskManager.remove( 'Ticket', data.slave_ticket['id'] ) else diff --git a/app/assets/javascripts/app/controllers/agent_ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/agent_ticket_zoom.js.coffee index aedaae759..1ad04e10c 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_zoom.js.coffee @@ -11,7 +11,7 @@ class App.TicketZoom extends App.Controller constructor: (params) -> super - @log 'zoom', params +# console.log 'zoom', params # check authentication return if !@authenticate() @@ -31,7 +31,7 @@ class App.TicketZoom extends App.Controller if cache @load(cache) update = => - @fetch( @ticket_id, false) + @fetch( @ticket_id, false ) @interval( update, 30000, @key, 'ticket_zoom' ) # start auto save @@ -73,7 +73,7 @@ class App.TicketZoom extends App.Controller if !@autosaveLast || ( diff && !_.isEmpty( diff ) ) @autosaveLast = data console.log('form hash changed', diff, data) - App.TaskManager.update( @task_key, { 'state': data }) + App.TaskManager.update( 'Ticket', @ticket_id, { 'state': data }) @interval( update, 10000, @id, @auto_save_key ) fetch: (ticket_id, force) -> @@ -93,7 +93,7 @@ class App.TicketZoom extends App.Controller return if _.isEqual( @dataLastCall.ticket, data.ticket) diff = difference( @dataLastCall.ticket, data.ticket ) console.log('diff', diff) - App.TaskManager.notify(@task_key) + App.TaskManager.notify( 'Ticket', @ticket_id ) if $('[name="body"]').val() App.Event.trigger 'notify', { type: 'success' @@ -293,7 +293,6 @@ class App.TicketZoom extends App.Controller internal = true if article.internal == true internal = false - article.updateAttributes( internal: internal ) diff --git a/app/assets/javascripts/app/controllers/task_widget.js.coffee b/app/assets/javascripts/app/controllers/task_widget.js.coffee index 3e345d870..6b235579f 100644 --- a/app/assets/javascripts/app/controllers/task_widget.js.coffee +++ b/app/assets/javascripts/app/controllers/task_widget.js.coffee @@ -10,37 +10,31 @@ class App.TaskWidget extends App.Controller App.Event.bind 'ui:rerender', (data) => @render() - # rebuild chat widget + # rebuild taskbar widget App.Event.bind 'auth', (user) => App.TaskManager.reset() @el.html('') - sync = => - App.TaskManager.sync() - @delay( sync, 3000, 'task-widget' ) - - @delay( sync, 5000, 'task-widget' ) - render: -> return if _.isEmpty( @Session.all() ) tasks = App.TaskManager.all() item_list = [] - for key, task of tasks + for task in tasks data = url: '#' id: false title: App.i18n.translateInline('Loading...') head: App.i18n.translateInline('Loading...') - if task.worker - meta = task.worker.meta() + worker = App.TaskManager.worker( task.type, task.type_id ) + if worker + meta = worker.meta() if meta data = meta data.title = App.i18n.escape( data.title ) data.head = App.i18n.escape( data.head ) item = {} - item.key = key item.task = task item.data = data item_list.push item @@ -52,34 +46,41 @@ class App.TaskWidget extends App.Controller remove: (e) => e.preventDefault() - key = $(e.target).parent().data('id') + type_id = $(e.target).parent().data('type-id') + type = $(e.target).parent().data('type') + if !type_id && !type + throw "No such type and type-id attributes found for task item" # check if input has changed - task = App.TaskManager.get( key ) - if task.worker && task.worker.changed - if task.worker.changed() + worker = App.TaskManager.worker( type, type_id ) + if worker && worker.changed + if worker.changed() return if !window.confirm( App.i18n.translateInline('Tab has changed, you really want to close it?') ) # check if active task is closed - task_last = undefined - tasks_all = App.TaskManager.all() + currentTask = App.TaskManager.get( type, type_id ) + tasks = App.TaskManager.all() active_is_closed = false - for task_key, task of tasks_all - if task.active && task_key.toString() is key.toString() + for task in tasks + if currentTask.active && task.type is type && task.type_id.toString() is type_id.toString() active_is_closed = true # remove task - App.TaskManager.remove( key ) + App.TaskManager.remove( type, type_id ) @render() # navigate to next task if needed - if active_is_closed && !_.isEmpty( tasks_all ) - for key, task of tasks_all + tasks = App.TaskManager.all() + if active_is_closed && !_.isEmpty( tasks ) + task_last = undefined + for task in tasks task_last = task if task_last - @navigate task_last.worker.url() + worker = App.TaskManager.worker( task_last.type, task_last.type_id ) + if worker + @navigate worker.url() return - if _.isEmpty( tasks_all ) + if _.isEmpty( tasks ) @navigate '#' _getTaskActions: -> diff --git a/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee b/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee index d43aca9c8..3b21e534b 100644 --- a/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee @@ -14,240 +14,216 @@ class App.TaskManager _instance ?= new _Singleton _instance.add( type, type_id, callback, params, to_not_show, state ) - @get: ( key ) -> + @get: ( type, type_id ) -> if _instance == undefined _instance ?= new _Singleton - _instance.get( key ) + _instance.get( type, type_id ) - @update: ( key, params ) -> + @update: ( type, type_id, params ) -> if _instance == undefined _instance ?= new _Singleton - _instance.update( key, params ) + _instance.update( type, type_id, params ) - @remove: ( key ) -> + @remove: ( type, type_id ) -> if _instance == undefined _instance ?= new _Singleton - _instance.remove( key ) + _instance.remove( type, type_id ) - @notify: ( key ) -> + @notify: ( type, type_id ) -> if _instance == undefined _instance ?= new _Singleton - _instance.notify( key ) + _instance.notify( type, type_id ) @reset: -> if _instance == undefined _instance ?= new _Singleton _instance.reset() - @syncInitial: -> + @worker: ( type, type_id ) -> if _instance == undefined _instance ?= new _Singleton - _instance.syncTasksInitial() + _instance.worker( type, type_id ) - @syncSave: -> + @workerAll: -> if _instance == undefined _instance ?= new _Singleton - _instance.syncSave() - - @sync: -> - if _instance == undefined - _instance ?= new _Singleton - _instance.syncTasks() + _instance.workerAll() class _Singleton extends App.Controller @include App.Log constructor: -> - @tasks = {} - @task_count = 0 - @syncTasksInitial() - + @workers = {} + @workersStarted = {} + @activeTask = undefined + @tasksInitial() + all: -> - @tasks + App.Taskbar.all() + + worker: ( type, type_id ) -> + key = @keyGenerate(type, type_id) + return @workers[ key ] if @workers[ key ] + return + + workerAll: -> + @workers add: ( type, type_id, callback, params, to_not_show = false, state ) -> - for key, task of @tasks - if task.type is type && task.type_id is type_id - return key if to_not_show - $('#content').empty() - $('.content_permanent').hide() - $('.content_permanent').removeClass('active') - $('#content_permanent_' + key ).show() - $('#content_permanent_' + key ).addClass('active') - @tasks[key].worker.activate() - @tasks[key].notify = false - for task_key, task of @tasks - if task_key isnt key - task.active = false - else - task.active = true - App.Event.trigger 'ui:rerender' - App.Event.trigger 'ui:rerender:content' - return key - - @task_count++ - if !to_not_show - for task_key, task of @tasks - task.active = false active = true if to_not_show active = false + + # create new task if not exists + task = @get( type, type_id ) +# console.log('add', type, type_id, callback, params, to_not_show, state, task) + if !task + task = new App.Taskbar + task.load( + type: type + type_id: type_id + params: params + callback: callback + notify: false + active: active + ) + task.save() + + tasks = @all() + + # empty static content if task is shown + key = @keyGenerate(type, type_id) if active + @activeTask = key $('#content').empty() - $('#content_permanent').append('
') - - if active + # hide all tasks $('.content_permanent').hide() $('.content_permanent').removeClass('active') - $('#content_permanent_' + @task_count ).show() - $('#content_permanent_' + @task_count ).addClass('active') + + # create div for task if not exists + if !$("#content_permanent_#{key}")[0] + $('#content_permanent').append('
') + + # set task to shown and active + if @activeTask is key + $('#content_permanent_' + key ).show() + $('#content_permanent_' + key ).addClass('active') else - $('#content_permanent_' + @task_count ).removeClass('active') - $('#content_permanent_' + @task_count ).hide() + $('#content_permanent_' + key ).hide() + $('#content_permanent_' + key ).removeClass('active') + + # set all tasks to active false, only new/selected one to active + if active + for task in tasks + task_key = @keyGenerate(task.type, task.type_id) + if task_key isnt key + task.active = false + else + task.active = true + task.save() + else + for task in tasks + task_key = @keyGenerate(task.type, task.type_id) + if @activeTask isnt task_key + if task.active + task.active = false + task.save() + + # start worker for task if not exists + @startController(type, type_id, callback, params, state, key, to_not_show) + + App.Event.trigger 'ui:rerender' + App.Event.trigger 'ui:rerender:content' + return key + + startController: (type, type_id, callback, params, state, key, to_not_show) => + +# console.log('controller started...', callback, type, type_id, params, state) + + # activate controller + worker = @worker( type, type_id ) + if worker && worker.activate + worker.activate() + + # return if controller is alreary started + return if @workersStarted[key] + @workersStarted[key] = true # create new controller instanz params_app = _.clone(params) - params_app['el'] = $('#content_permanent_' + @task_count ) - params_app['task_key'] = @task_count + params_app['el'] = $('#content_permanent_' + key ) + params_app['task_key'] = key # check if we have old state there if !state - oldTask = @get_by_type( type, type_id ) + oldTask = @get( type, type_id ) if oldTask state = oldTask.state params_app['form_state'] = state + if to_not_show params_app['doNotLog'] = 1 a = new App[callback]( params_app ) - - # remember new controller / prepare for task storage - task = - type: type - type_id: type_id - params: params - callback: callback - worker: a - active: active - @tasks[@task_count] = task + @workers[ key ] = a # activate controller if !to_not_show a.activate() - App.Event.trigger 'ui:rerender' + return a - # add new controller to task storage - if !to_not_show - @syncAdd(task) + get: ( type, type_id ) => + tasks = App.Taskbar.all() + for task in tasks + return task if task.type is type && task.type_id.toString() is type_id.toString() + return +# throw "No such task with '#{type}' and '#{type_id}'" - @task_count - - get: ( key ) => - return @tasks[key] - - update: ( key, params ) => - return false if !@tasks[key] + update: ( type, type_id, params ) => + task = @get( type, type_id ) + if !task + throw "No such task with '#{type}' and '#{type_id}' to update" for item, value of params - @tasks[key][item] = value - @syncSave() + task.updateAttribute(item, value) +# task.save() - remove: ( key, to_not_show = false ) => - if @tasks[key] - @tasks[key].worker.release() - if !to_not_show - @syncRemove( @tasks[key] ) - delete @tasks[key] + remove: ( type, type_id, to_not_show = false ) => + task = @get( type, type_id ) + if !task + throw "No such task with '#{type}' and '#{type_id}' to remove" + + worker = @worker( type, type_id ) + if worker && worker.release + worker.release() + @workersStarted[ @keyGenerate(type, type_id) ] = false + task.destroy() App.Event.trigger 'ui:rerender' - notify: ( key ) => - @tasks[key].notify = true + notify: ( type, type_id ) => + task = @get( type, type_id ) + if !task + throw "No such task with '#{type}' and '#{type_id}' to notify" + task.notify = true reset: => - @tasks = {} + App.Taskbar.deleteAll() App.Event.trigger 'ui:rerender' - get_by_type: (type, type_id) => - store = @syncLoad() || [] - for item in store - return item if item.type is type && item.type_id is type_id - - syncAdd: (task) => - store = @syncLoad() || [] - for item in store - return if item.type is task.type && item.type_id is task.type_id - item = - type: task.type - type_id: task.type_id - params: task.params - callback: task.callback - store.push item - App.Store.write( 'tasks', store ) - - syncRemove: (task) => - store = @syncLoad() || [] - storeNew = [] - for item in store - if item.type isnt task.type || item.type_id isnt task.type_id - storeNew.push item - App.Store.write( 'tasks', storeNew ) - - syncSave: => - store = @syncLoad() || [] - storeNew = [] - for item in store - for key, task of @tasks - if task.type is item.type && task.type_id is item.type_id - console.log('MATCH', item) - if @tasks[key]['state'] - item['state'] = @tasks[key]['state'] - storeNew.push item -# if @tasks[key] -# @tasks[key].worker.release() -# -# storeNew.push item -# item = -# type: task.type -# type_id: task.type_id -# params: task.params -# callback: task.callback - App.Store.write( 'tasks', storeNew ) - - syncLoad: => - App.Store.get( 'tasks' ) - - syncTasksInitial: => + tasksInitial: => # reopen tasks - store = _.clone(@syncLoad()) - return if !store + App.Taskbar.fetch() + tasks = @all() + return if !tasks task_count = 0 - for task in store + for task in tasks task_count += 1 @delay( => - task = store.shift() + task = tasks.shift() @add(task.type, task.type_id, task.callback, task.params, true, task.state) task_count * 500 ) - syncTasks: => - store = @syncLoad() || [] - - # open tasks - for item in store - existsLocal = false - for task_key, task of @tasks - if item.type is task.type && item.type_id is task.type_id - # also open here - existsLocal = true - if !existsLocal - @add(item.type, item.type_id, item.callback, item.params, true) - - # close tasks - for task_key, task of @tasks - onlyLocal = true - for item in store - if item.type is task.type && item.type_id is task.type_id - onlyLocal = false - if onlyLocal - @remove( task_key, true ) + keyGenerate: ( type, type_id )-> + "#{type}_#{type_id}" diff --git a/app/assets/javascripts/app/views/task_widget.jst.eco b/app/assets/javascripts/app/views/task_widget.jst.eco index d01b2af76..fb1cedc9b 100644 --- a/app/assets/javascripts/app/views/task_widget.jst.eco +++ b/app/assets/javascripts/app/views/task_widget.jst.eco @@ -1,6 +1,6 @@ -
+
<% for item in @item_list: %> - <%- item.data.head %> + <%- item.data.head %> <% end %> <% if !_.isEmpty( @taskBarActions ): %>
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 96e379f6c..c48fe7f4f 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -12,6 +12,7 @@ //not_used= require_tree ./app/lib/spine //= require ./app/lib/spine/spine.js //= require ./app/lib/spine/ajax.js +//= require ./app/lib/spine/local.js //= require ./app/lib/spine/route.js //= require ./app/lib/flot/jquery.flot.js