From beb0efa9f785e71b089bc19164403f4e4cad45d1 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Tue, 2 Jul 2013 14:37:40 +0200 Subject: [PATCH] Improved handling of unsaved forms. --- .../controllers/agent_ticket_create.js.coffee | 2 +- .../app/controllers/ticket_zoom.js.coffee | 62 +++++++++++++------ .../app/lib/app_post/task_manager.js.coffee | 23 +++---- .../app/views/ticket_zoom/edit.jst.eco | 8 ++- app/assets/stylesheets/zzz.css | 5 ++ db/seeds.rb | 2 +- 6 files changed, 65 insertions(+), 37 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 1a20cc875..3b0bfdac3 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee @@ -151,7 +151,7 @@ class App.TicketCreate extends App.Controller render: (template = {}) -> # set defaults - defaults = template['options'] || @form_state || {} + defaults = template['options'] || App.TaskManager.get(@task_key).state || {} if !( 'ticket_state_id' of defaults ) defaults['ticket_state_id'] = App.Collection.findByAttribute( 'TicketState', 'name', 'open' ).id if !( 'ticket_priority_id' of defaults ) diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index 8d29b5572..be2f19499 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -31,7 +31,7 @@ class App.TicketZoom extends App.Controller @log 'notice', 'TRY', data.updated_at, ticket.updated_at if data.updated_at isnt ticket.updated_at @fetch( @ticket_id, false ) - @delay( update, 2000, 'ticket-zoom-' + @ticket_id ) + @delay( update, 1800, 'ticket-zoom-' + @ticket_id ) 'ticket-zoom-' + @ticket_id ) @@ -63,14 +63,18 @@ class App.TicketZoom extends App.Controller autosave: => @auto_save_key = 'zoom' + @id + + @autosaveLast = _.clone( @formDefault ) update = => - data = @formParam( @el.find('.ticket-update') ) - diff = difference( @autosaveLast, data ) + currentData = @formParam( @el.find('.ticket-update') ) + diff = difference( @autosaveLast, currentData ) if !@autosaveLast || ( diff && !_.isEmpty( diff ) ) - @autosaveLast = data - @log 'notice', 'form hash changed', diff, data - App.TaskManager.update( @task_key, { 'state': data }) - @interval( update, 10000, @id, @auto_save_key ) + @autosaveLast = currentData + @log 'notice', 'form hash changed', diff, currentData + @el.find('.ticket-update').parent().addClass('form-changed') + @el.find('.ticket-update').parent().parent().find('.reset-message').show() + App.TaskManager.update( @task_key, { 'state': currentData }) + @interval( update, 1500, @id, @auto_save_key ) fetch: (ticket_id, force) -> @@ -98,15 +102,15 @@ class App.TicketZoom extends App.Controller if !_.isEmpty(diff) && data.ticket.updated_by_id isnt @Session.all().id App.TaskManager.notify( @task_key ) + # rerender edit box + @editDone = false + # remember current data @dataLastCall = data @load(data, force) App.Store.write( @key, data ) - # start auto save - @autosave() - error: (xhr, status, error) => # do not close window if request is aborted @@ -168,8 +172,14 @@ class App.TicketZoom extends App.Controller @ArticleView() if force || !@editDone + # reset form on force reload + if force && _.isEmpty( App.TaskManager.get(@task_key).state ) + App.TaskManager.update( @task_key, { 'state': {} }) @editDone = true - @Edit() + + # rerender widget if it hasn't changed + if !@editWidget || _.isEmpty( App.TaskManager.get(@task_key).state ) + @editWidget = @Edit() # show text module UI if !@isRole('Customer') @@ -214,7 +224,6 @@ class App.TicketZoom extends App.Controller new Edit( ticket: @ticket el: @el.find('.edit') - form_state: @form_state edit_form: @edit_form task_key: @task_key ui: @ @@ -319,7 +328,8 @@ class TicketAction extends App.Controller class Edit extends App.Controller events: - 'click .submit': 'update' + 'click .submit': 'update' + 'click [data-type="reset"]': 'reset' constructor: -> super @@ -332,6 +342,7 @@ class Edit extends App.Controller @html App.view('ticket_zoom/edit')( ticket: ticket isCustomer: @isRole('Customer') + formChanged: !_.isEmpty( App.TaskManager.get(@task_key).state ) ) @configure_attributes_ticket = [ @@ -365,7 +376,9 @@ class Edit extends App.Controller ] @form_id = App.ControllerForm.formId() - defaults = @form_state || ticket + defaults = ticket + if !_.isEmpty( App.TaskManager.get(@task_key).state ) + defaults = App.TaskManager.get(@task_key).state new App.ControllerForm( el: @el.find('.form-ticket-update') form_id: @form_id @@ -413,7 +426,10 @@ class Edit extends App.Controller @el.find('textarea').elastic() # remember form defaults - @formDefault = @formParam( @el.find('.ticket-update') ) + @ui.formDefault = @formParam( @el.find('.ticket-update') ) + + # start auto save + @ui.autosave() # enable user popups @userPopups() @@ -498,6 +514,10 @@ class Edit extends App.Controller errors = article.validate() if errors @log 'error', 'update article', errors + + # reset form after save + App.TaskManager.update( @task_key, { 'state': {} }) + article.save( success: (r) => @ui.fetch( ticket.id, true ) @@ -505,11 +525,10 @@ class Edit extends App.Controller @log 'error', 'update article', r ) else - @ui.fetch( ticket.id, true ) + # reset form after save + App.TaskManager.update( @task_key, { 'state': {} }) - # reset form after save - App.TaskManager.update( @task_key, { 'state': undefined }) - @ui.form_state = undefined + @ui.fetch( ticket.id, true ) ) # errors = article.validate() @@ -517,6 +536,11 @@ class Edit extends App.Controller # @formValidate( form: e.target, errors: errors ) return false + reset: (e) => + e.preventDefault() + App.TaskManager.update( @task_key, { 'state': {} }) + @render() + class ArticleView extends App.Controller events: 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 90e9d3dfd..d623f3aba 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,10 +9,10 @@ class App.TaskManager _instance ?= new _taskManagerSingleton _instance.all() - @add: ( key, callback, params, to_not_show, state ) -> + @add: ( key, callback, params, to_not_show ) -> if _instance == undefined _instance ?= new _taskManagerSingleton - _instance.add( key, callback, params, to_not_show, state ) + _instance.add( key, callback, params, to_not_show ) @get: ( key ) -> if _instance == undefined @@ -120,14 +120,14 @@ class _taskManagerSingleton extends App.Controller workerAll: -> @workers - add: ( key, callback, params, to_not_show = false, state ) -> + add: ( key, callback, params, to_not_show = false ) -> active = true if to_not_show active = false # create new task if not exists task = @get( key ) -# console.log('add', key, callback, params, to_not_show, state, task) +# console.log('add', key, callback, params, to_not_show, task) if !task task = new App.Taskbar task.load( @@ -201,14 +201,14 @@ class _taskManagerSingleton extends App.Controller @taskUpdate( task ) # start worker for task if not exists - @startController(key, callback, params, state, to_not_show) + @startController(key, callback, params, to_not_show) App.Event.trigger 'task:render' return key - startController: (key, callback, params, state, to_not_show) => + startController: (key, callback, params, to_not_show) => -# console.log('controller started...', callback, key, params, state) +# console.log('controller started...', callback, key, params) # activate controller worker = @worker( key ) @@ -224,13 +224,6 @@ class _taskManagerSingleton extends App.Controller params_app['el'] = $('#content_permanent_' + key ) params_app['task_key'] = key - # check if we have old state there - if !state - oldTask = @get( key ) - if oldTask - state = oldTask.state - params_app['form_state'] = state - if to_not_show params_app['doNotLog'] = 1 a = new App[callback]( params_app ) @@ -359,7 +352,7 @@ class _taskManagerSingleton extends App.Controller @delay( => task = tasks.shift() - @add(task.key, task.callback, task.params, true, task.state) + @add(task.key, task.callback, task.params, true) task_count * 300 ) diff --git a/app/assets/javascripts/app/views/ticket_zoom/edit.jst.eco b/app/assets/javascripts/app/views/ticket_zoom/edit.jst.eco index 1e911af01..ed1bb2a79 100644 --- a/app/assets/javascripts/app/views/ticket_zoom/edit.jst.eco +++ b/app/assets/javascripts/app/views/ticket_zoom/edit.jst.eco @@ -2,7 +2,13 @@
-
+
+
diff --git a/app/assets/stylesheets/zzz.css b/app/assets/stylesheets/zzz.css index 327529538..c4bcb06f7 100644 --- a/app/assets/stylesheets/zzz.css +++ b/app/assets/stylesheets/zzz.css @@ -450,6 +450,11 @@ footer { margin-left: 80px; } +.form-changed { + border: 1px solid #fbeed5; + background-color: #fcf8e3; +} + #splash { background-color: #eee; position: absolute; diff --git a/db/seeds.rb b/db/seeds.rb index b4e4afaf3..c309b1fce 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1808,7 +1808,7 @@ Translation.create_if_not_exists( :locale => 'de', :source => "Update Time", :ta Translation.create_if_not_exists( :locale => 'de', :source => "Solution Time", :target => "Lösungszeit" ) Translation.create_if_not_exists( :locale => 'de', :source => "Add Attribute", :target => "Attribut hinzufügen" ) Translation.create_if_not_exists( :locale => 'de', :source => "Back to top", :target => "Nach oben" ) - +Translation.create_if_not_exists( :locale => 'de', :source => "Discard your unsaved changes.", :target => "Verwerfen der ungespeicherten Änderungen." ) #Translation.create_if_not_exists( :locale => 'de', :source => "", :target => "" ) # install all packages in auto_install