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 fe91d8159..84d3ff611 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee @@ -50,7 +50,10 @@ class App.TicketCreate extends App.Controller @render(defaults) # start auto save - @autosave() + @delay( + => @autosave(), + 5000 + ) meta: => text = App.i18n.translateInline( @article_attributes['title'] ) @@ -68,7 +71,7 @@ class App.TicketCreate extends App.Controller activate: => @navupdate '#' - @title @article_attributes['title'] + @title @meta().title changed: => formCurrent = @formParam( @el.find('.ticket-create') ) @@ -89,7 +92,7 @@ class App.TicketCreate extends App.Controller if !@autosaveLast || ( diff && !_.isEmpty( diff ) ) @autosaveLast = data console.log('form hash changed', diff, data) - App.TaskManager.update( 'TicketCreateScreen', @type + '-' + @id, { 'state': data }) + App.TaskManager.update( @task_key, { 'state': data }) @interval( update, 10000, @id, @auto_save_key ) # get data / in case also ticket data for split @@ -164,7 +167,7 @@ class App.TicketCreate extends App.Controller # defaults['customer_id'] = '2' # defaults['customer_id_autocompletion'] = '12312313' - # generate form + # generate form configure_attributes = [ { name: 'customer_id', display: 'Customer', tag: 'autocompletion', type: 'text', limit: 200, null: false, relation: 'User', class: 'span7', autocapitalize: false, help: 'Select the customer of the Ticket or create one.', link: '»', callback: @localUserInfo }, { name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: @edit_form, nulloption: true, relation: 'Group', default: defaults['group_id'], class: 'span7', }, @@ -296,13 +299,13 @@ class App.TicketCreate extends App.Controller # notify UI ui.notify type: 'success', - msg: App.i18n.translateContent( 'Ticket %s created!', @number ), + msg: App.i18n.translateInline( 'Ticket %s created!', @number ), link: "#ticket/zoom/#{@id}" timeout: 12000, # create new create screen # ui.render() - App.TaskManager.remove( 'TicketCreateScreen', ui.type + '-' + ui.id ) + App.TaskManager.remove( ui.task_key ) # scroll to top ui.scrollTo() @@ -394,7 +397,7 @@ class TicketCreateRouter extends App.ControllerPermanent type: params.type id: params.id - 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' ) 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 b2255d688..04504f1fc 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( 'Ticket', data.slave_ticket['id'] ) + App.TaskManager.remove( 'Ticket-' + data.slave_ticket['id'] ) else @@ -144,4 +144,4 @@ class App.TicketMerge extends App.ControllerModal timeout: 6000, # error: => ) - + 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 1ad04e10c..4820db2bc 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_zoom.js.coffee @@ -34,14 +34,11 @@ class App.TicketZoom extends App.Controller @fetch( @ticket_id, false ) @interval( update, 30000, @key, 'ticket_zoom' ) - # start auto save - @autosave() - meta: => return if !@ticket meta = url: @url() - head: @ticket.title + head: @ticket.title + ' ' + @ticket.title title: @ticket.number + ' ' + @ticket.title id: @ticket.id @@ -51,9 +48,9 @@ class App.TicketZoom extends App.Controller activate: => @navupdate '#' if @ticket - @title 'Ticket Zoom ' + @ticket.number -# else -# @title 'Loading...' + @title App.i18n.translateInline('Ticket Zoom') + ' ' + @ticket.number + ' ' + @ticket.title + else + @title App.i18n.translateInline('Loading...') changed: => formCurrent = @formParam( @el.find('.ticket-update') ) @@ -73,7 +70,7 @@ class App.TicketZoom extends App.Controller if !@autosaveLast || ( diff && !_.isEmpty( diff ) ) @autosaveLast = data console.log('form hash changed', diff, data) - App.TaskManager.update( 'Ticket', @ticket_id, { 'state': data }) + App.TaskManager.update( @task_key, { 'state': data }) @interval( update, 10000, @id, @auto_save_key ) fetch: (ticket_id, force) -> @@ -82,7 +79,7 @@ class App.TicketZoom extends App.Controller # get data App.Com.ajax( - id: 'ticket_zoom_' + ticket_id + id: 'ticket_zoom_' + ticket_id type: 'GET' url: 'api/ticket_full/' + ticket_id + '?do_not_log=' + @doNotLog data: @@ -93,11 +90,11 @@ 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( 'Ticket', @ticket_id ) + App.TaskManager.notify( @task_key ) if $('[name="body"]').val() App.Event.trigger 'notify', { type: 'success' - msg: App.i18n.translateContent('Ticket has changed!') + msg: App.i18n.translateInline('Ticket has changed!') timeout: 30000 } return @@ -106,6 +103,9 @@ class App.TicketZoom extends App.Controller @load(data) App.Store.write( @key, data ) + # start auto save + @autosave() + error: (xhr, status, error) => # do not close window if request is abort or network error exists @@ -392,7 +392,7 @@ class App.TicketZoom extends App.Controller if selectedText body = @el.find('[name="body"]').val() || '' selectedText = selectedText.replace /^(.*)$/mg, (match) => - '> ' + match + '> ' + match body = selectedText + "\n" + body @el.find('[name="body"]').val(body) @@ -645,8 +645,8 @@ class TicketZoomRouter extends App.ControllerPermanent article_id: params.article_id nav: params.nav - App.TaskManager.add( 'Ticket', @ticket_id, 'TicketZoom', clean_params ) + App.TaskManager.add( 'Ticket-' + @ticket_id, 'TicketZoom', clean_params ) App.Config.set( 'ticket/zoom/:ticket_id', TicketZoomRouter, 'Routes' ) App.Config.set( 'ticket/zoom/:ticket_id/nav/:nav', TicketZoomRouter, 'Routes' ) -App.Config.set( 'ticket/zoom/:ticket_id/:article_id', TicketZoomRouter, 'Routes' ) \ No newline at end of file +App.Config.set( 'ticket/zoom/:ticket_id/:article_id', TicketZoomRouter, 'Routes' ) diff --git a/app/assets/javascripts/app/controllers/task_widget.js.coffee b/app/assets/javascripts/app/controllers/task_widget.js.coffee index 6b235579f..73ef89084 100644 --- a/app/assets/javascripts/app/controllers/task_widget.js.coffee +++ b/app/assets/javascripts/app/controllers/task_widget.js.coffee @@ -27,7 +27,7 @@ class App.TaskWidget extends App.Controller id: false title: App.i18n.translateInline('Loading...') head: App.i18n.translateInline('Loading...') - worker = App.TaskManager.worker( task.type, task.type_id ) + worker = App.TaskManager.worker( task.key ) if worker meta = worker.meta() if meta @@ -46,27 +46,26 @@ class App.TaskWidget extends App.Controller remove: (e) => e.preventDefault() - 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" + key = $(e.target).parent().data('key') + if !key + throw "No such key attributes found for task item" # check if input has changed - worker = App.TaskManager.worker( type, type_id ) + worker = App.TaskManager.worker( key ) 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 - currentTask = App.TaskManager.get( type, type_id ) + currentTask = App.TaskManager.get( key ) tasks = App.TaskManager.all() active_is_closed = false for task in tasks - if currentTask.active && task.type is type && task.type_id.toString() is type_id.toString() + if currentTask.active && task.key is key active_is_closed = true # remove task - App.TaskManager.remove( type, type_id ) + App.TaskManager.remove( key ) @render() # navigate to next task if needed @@ -76,11 +75,11 @@ class App.TaskWidget extends App.Controller for task in tasks task_last = task if task_last - worker = App.TaskManager.worker( task_last.type, task_last.type_id ) + worker = App.TaskManager.worker( task_last.key ) if worker @navigate worker.url() return - if _.isEmpty( tasks ) + if _.isEmpty( tasks ) @navigate '#' _getTaskActions: -> @@ -108,5 +107,4 @@ class App.TaskWidget extends App.Controller level1.push item level1 - App.Config.set( 'task', App.TaskWidget, 'Widgets' ) 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 3b21e534b..f6d445404 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 @@ -9,40 +9,40 @@ class App.TaskManager _instance ?= new _Singleton _instance.all() - @add: ( type, type_id, callback, params, to_not_show, state ) -> + @add: ( key, callback, params, to_not_show, state ) -> if _instance == undefined _instance ?= new _Singleton - _instance.add( type, type_id, callback, params, to_not_show, state ) + _instance.add( key, callback, params, to_not_show, state ) - @get: ( type, type_id ) -> + @get: ( key ) -> if _instance == undefined _instance ?= new _Singleton - _instance.get( type, type_id ) + _instance.get( key ) - @update: ( type, type_id, params ) -> + @update: ( key, params ) -> if _instance == undefined _instance ?= new _Singleton - _instance.update( type, type_id, params ) + _instance.update( key, params ) - @remove: ( type, type_id ) -> + @remove: ( key ) -> if _instance == undefined _instance ?= new _Singleton - _instance.remove( type, type_id ) + _instance.remove( key ) - @notify: ( type, type_id ) -> + @notify: ( key ) -> if _instance == undefined _instance ?= new _Singleton - _instance.notify( type, type_id ) + _instance.notify( key ) @reset: -> if _instance == undefined _instance ?= new _Singleton _instance.reset() - @worker: ( type, type_id ) -> + @worker: ( key ) -> if _instance == undefined _instance ?= new _Singleton - _instance.worker( type, type_id ) + _instance.worker( key ) @workerAll: -> if _instance == undefined @@ -57,42 +57,40 @@ class _Singleton extends App.Controller @workersStarted = {} @activeTask = undefined @tasksInitial() - + all: -> App.Taskbar.all() - worker: ( type, type_id ) -> - key = @keyGenerate(type, type_id) + worker: ( key ) -> return @workers[ key ] if @workers[ key ] return workerAll: -> @workers - add: ( type, type_id, callback, params, to_not_show = false, state ) -> + add: ( key, callback, params, to_not_show = false, state ) -> 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) + task = @get( key ) +# console.log('add', key, callback, params, to_not_show, state, task) if !task task = new App.Taskbar task.load( - type: type - type_id: type_id + key: key params: params callback: callback + client_id: 123 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() @@ -116,37 +114,41 @@ class _Singleton extends App.Controller # 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.key isnt key if task.active task.active = false + console.log(111, 'save') + task.save() + else + if !task.active + console.log(222, 'save') + task.active = true + task.save() + else + for task in tasks + if @activeTask isnt task.key + if task.active + task.active = false + console.log(333, 'save') task.save() # start worker for task if not exists - @startController(type, type_id, callback, params, state, key, to_not_show) + @startController(key, callback, params, state, 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) => + startController: (key, callback, params, state, to_not_show) => -# console.log('controller started...', callback, type, type_id, params, state) +# console.log('controller started...', callback, key, params, state) # activate controller - worker = @worker( type, type_id ) + worker = @worker( key ) if worker && worker.activate worker.activate() - # return if controller is alreary started + # return if controller is alreary started return if @workersStarted[key] @workersStarted[key] = true @@ -157,7 +159,7 @@ class _Singleton extends App.Controller # check if we have old state there if !state - oldTask = @get( type, type_id ) + oldTask = @get( key ) if oldTask state = oldTask.state params_app['form_state'] = state @@ -173,37 +175,37 @@ class _Singleton extends App.Controller return a - get: ( type, type_id ) => + get: ( key ) => tasks = App.Taskbar.all() for task in tasks - return task if task.type is type && task.type_id.toString() is type_id.toString() + return task if task.key is key return -# throw "No such task with '#{type}' and '#{type_id}'" +# throw "No such task with '#{key}'" - update: ( type, type_id, params ) => - task = @get( type, type_id ) + update: ( key, params ) => + task = @get( key ) if !task - throw "No such task with '#{type}' and '#{type_id}' to update" + throw "No such task with '#{key}' to update" for item, value of params task.updateAttribute(item, value) # task.save() - remove: ( type, type_id, to_not_show = false ) => - task = @get( type, type_id ) + remove: ( key, to_not_show = false ) => + task = @get( key ) if !task - throw "No such task with '#{type}' and '#{type_id}' to remove" + throw "No such task with '#{key}' to remove" - worker = @worker( type, type_id ) + worker = @worker( key ) if worker && worker.release worker.release() - @workersStarted[ @keyGenerate(type, type_id) ] = false + @workersStarted[ key ] = false task.destroy() App.Event.trigger 'ui:rerender' - notify: ( type, type_id ) => - task = @get( type, type_id ) + notify: ( key ) => + task = @get( key ) if !task - throw "No such task with '#{type}' and '#{type_id}' to notify" + throw "No such task with '#{key}' to notify" task.notify = true reset: => @@ -212,7 +214,7 @@ class _Singleton extends App.Controller tasksInitial: => # reopen tasks - App.Taskbar.fetch() +# App.Taskbar.fetch() tasks = @all() return if !tasks task_count = 0 @@ -221,9 +223,7 @@ class _Singleton extends App.Controller @delay( => task = tasks.shift() - @add(task.type, task.type_id, task.callback, task.params, true, task.state) + @add(task.key, task.callback, task.params, true, task.state) task_count * 500 ) - keyGenerate: ( type, type_id )-> - "#{type}_#{type_id}" diff --git a/app/assets/javascripts/app/models/taskbar.js.coffee b/app/assets/javascripts/app/models/taskbar.js.coffee index 506d2e0f7..137a0429c 100644 --- a/app/assets/javascripts/app/models/taskbar.js.coffee +++ b/app/assets/javascripts/app/models/taskbar.js.coffee @@ -1,4 +1,5 @@ class App.Taskbar extends App.Model - @configure 'Taskbar', 'type', 'type_id', 'callback', 'state', 'params', 'notify', 'active' - @extend Spine.Model.Local -# @url: 'api/taskbar' + @configure 'Taskbar', 'key', 'client_id', 'callback', 'state', 'params', 'notify', 'active' +# @extend Spine.Model.Local + @extend Spine.Model.Ajax + @url: 'api/taskbar' diff --git a/app/assets/javascripts/app/views/task_widget.jst.eco b/app/assets/javascripts/app/views/task_widget.jst.eco index fb1cedc9b..109aa8a2e 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/controllers/sessions/collection_base.rb b/app/controllers/sessions/collection_base.rb index 3827228d5..235833414 100644 --- a/app/controllers/sessions/collection_base.rb +++ b/app/controllers/sessions/collection_base.rb @@ -2,7 +2,7 @@ module ExtraCollection def session( collections, user ) # all base stuff - collections['Taskbar'] = Taskbar.all + collections['Taskbar'] = Taskbar.where( :user_id => user.id ) collections['Role'] = Role.all collections['Group'] = Group.all diff --git a/app/controllers/taskbar_controller.rb b/app/controllers/taskbar_controller.rb new file mode 100644 index 000000000..f16b1c1ed --- /dev/null +++ b/app/controllers/taskbar_controller.rb @@ -0,0 +1,48 @@ +class TaskbarController < ApplicationController + before_filter :authentication_check + + def index + + current_user_tasks = Taskbar.where( :user_id => current_user.id ) + model_index_render_result(current_user_tasks) + + end + + def show + taskbar = Taskbar.find( params[:id] ) + return if !access(taskbar) + + model_show_render_item(taskbar) + end + + def create + params[:user_id] = current_user.id + model_create_render(Taskbar,params) + end + + def update + taskbar = Taskbar.find( params[:id] ) + return if !access(taskbar) + + params[:user_id] = current_user.id + taskbar.update_attributes!( Taskbar.param_cleanup(params) ) + model_update_render_item(taskbar) + end + + def destroy + taskbar = Taskbar.find( params[:id] ) + return if !access(taskbar) + + taskbar.destroy + model_destory_render_item() + end + + private + def access(taskbar) + if taskbar.user_id != current_user.id + render :json => { :error => 'Not allowed to access this task.' }, :status => :unprocessable_entity + return false + end + return true + end +end diff --git a/app/models/taskbar.rb b/app/models/taskbar.rb new file mode 100644 index 000000000..48a41813e --- /dev/null +++ b/app/models/taskbar.rb @@ -0,0 +1,11 @@ +class Taskbar < ApplicationModel + store :state + store :params + before_create :update_last_contact + before_update :update_last_contact + + private + def update_last_contact + self.last_contact = Time.now + end +end diff --git a/config/routes/taskbar.rb b/config/routes/taskbar.rb new file mode 100644 index 000000000..c965055ec --- /dev/null +++ b/config/routes/taskbar.rb @@ -0,0 +1,10 @@ +module ExtraRoutes + def add(map) + map.match '/api/taskbar', :to => 'taskbar#index', :via => :get + map.match '/api/taskbar/:id', :to => 'taskbar#show', :via => :get + map.match '/api/taskbar', :to => 'taskbar#create', :via => :post + map.match '/api/taskbar/:id', :to => 'taskbar#update', :via => :put + map.match '/api/taskbar/:id', :to => 'taskbar#destroy', :via => :delete + end + module_function :add +end diff --git a/db/migrate/20130529124443_taskbar.rb b/db/migrate/20130529124443_taskbar.rb index 77d95f8e2..1e6ba3325 100644 --- a/db/migrate/20130529124443_taskbar.rb +++ b/db/migrate/20130529124443_taskbar.rb @@ -3,17 +3,15 @@ class Taskbar < ActiveRecord::Migration create_table :taskbars do |t| t.column :user_id, :integer, :null => false t.column :last_contact, :datetime, :null => false - t.column :client_id, :string, :limit => 100, :null => false - t.column :type, :string, :limit => 100, :null => false - t.column :type_id, :string, :limit => 100, :null => false - t.column :callback, :string, :limit => 100, :null => false + t.column :client_id, :string, :null => false + t.column :key, :string, :limit => 100, :null => false + t.column :callback, :string, :limit => 100, :null => false + t.column :state, :string, :limit => 8000, :null => true + t.column :params, :string, :limit => 2000, :null => true t.column :notify, :boolean, :null => false, :default => false t.column :active, :boolean, :null => false, :default => false - t.column :state, :string, :limit => 8000,:null => true - t.column :params, :string, :limit => 2000,:null => true t.timestamps end - end def down