Improved handling of unsaved forms.

This commit is contained in:
Martin Edenhofer 2013-07-02 14:37:40 +02:00
parent c735187def
commit beb0efa9f7
6 changed files with 65 additions and 37 deletions

View file

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

View file

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

View file

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

View file

@ -2,7 +2,13 @@
<div class="avatar span1 thumbnails">
<img class="thumbnail user-data" data-id="<%= @S('id') %>" src="<%- @S('image') %>" alt="">
</div>
<div class="span8 well-muted article-message">
<div class="span8 well-muted article-message <% if @formChanged: %>form-changed<% end %>">
<div class="reset-message<% if !@formChanged: %> hide<% end %>">
<div>
<a href="#" data-type="reset"><%- @T('Discard your unsaved changes.') %></a> <href="#" class="icon-repeat" data-type="reset"></a>
</div>
<hr>
</div>
<form class="form-stacked pull-left ticket-update">
<div class="form-ticket-update"></div>
<div class="form-article-update"></div>

View file

@ -450,6 +450,11 @@ footer {
margin-left: 80px;
}
.form-changed {
border: 1px solid #fbeed5;
background-color: #fcf8e3;
}
#splash {
background-color: #eee;
position: absolute;

View file

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