Improved handling of unsaved forms.
This commit is contained in:
parent
c735187def
commit
beb0efa9f7
6 changed files with 65 additions and 37 deletions
|
@ -151,7 +151,7 @@ class App.TicketCreate extends App.Controller
|
||||||
render: (template = {}) ->
|
render: (template = {}) ->
|
||||||
|
|
||||||
# set defaults
|
# set defaults
|
||||||
defaults = template['options'] || @form_state || {}
|
defaults = template['options'] || App.TaskManager.get(@task_key).state || {}
|
||||||
if !( 'ticket_state_id' of defaults )
|
if !( 'ticket_state_id' of defaults )
|
||||||
defaults['ticket_state_id'] = App.Collection.findByAttribute( 'TicketState', 'name', 'open' ).id
|
defaults['ticket_state_id'] = App.Collection.findByAttribute( 'TicketState', 'name', 'open' ).id
|
||||||
if !( 'ticket_priority_id' of defaults )
|
if !( 'ticket_priority_id' of defaults )
|
||||||
|
|
|
@ -31,7 +31,7 @@ class App.TicketZoom extends App.Controller
|
||||||
@log 'notice', 'TRY', data.updated_at, ticket.updated_at
|
@log 'notice', 'TRY', data.updated_at, ticket.updated_at
|
||||||
if data.updated_at isnt ticket.updated_at
|
if data.updated_at isnt ticket.updated_at
|
||||||
@fetch( @ticket_id, false )
|
@fetch( @ticket_id, false )
|
||||||
@delay( update, 2000, 'ticket-zoom-' + @ticket_id )
|
@delay( update, 1800, 'ticket-zoom-' + @ticket_id )
|
||||||
'ticket-zoom-' + @ticket_id
|
'ticket-zoom-' + @ticket_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -63,14 +63,18 @@ class App.TicketZoom extends App.Controller
|
||||||
|
|
||||||
autosave: =>
|
autosave: =>
|
||||||
@auto_save_key = 'zoom' + @id
|
@auto_save_key = 'zoom' + @id
|
||||||
|
|
||||||
|
@autosaveLast = _.clone( @formDefault )
|
||||||
update = =>
|
update = =>
|
||||||
data = @formParam( @el.find('.ticket-update') )
|
currentData = @formParam( @el.find('.ticket-update') )
|
||||||
diff = difference( @autosaveLast, data )
|
diff = difference( @autosaveLast, currentData )
|
||||||
if !@autosaveLast || ( diff && !_.isEmpty( diff ) )
|
if !@autosaveLast || ( diff && !_.isEmpty( diff ) )
|
||||||
@autosaveLast = data
|
@autosaveLast = currentData
|
||||||
@log 'notice', 'form hash changed', diff, data
|
@log 'notice', 'form hash changed', diff, currentData
|
||||||
App.TaskManager.update( @task_key, { 'state': data })
|
@el.find('.ticket-update').parent().addClass('form-changed')
|
||||||
@interval( update, 10000, @id, @auto_save_key )
|
@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) ->
|
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
|
if !_.isEmpty(diff) && data.ticket.updated_by_id isnt @Session.all().id
|
||||||
App.TaskManager.notify( @task_key )
|
App.TaskManager.notify( @task_key )
|
||||||
|
|
||||||
|
# rerender edit box
|
||||||
|
@editDone = false
|
||||||
|
|
||||||
# remember current data
|
# remember current data
|
||||||
@dataLastCall = data
|
@dataLastCall = data
|
||||||
|
|
||||||
@load(data, force)
|
@load(data, force)
|
||||||
App.Store.write( @key, data )
|
App.Store.write( @key, data )
|
||||||
|
|
||||||
# start auto save
|
|
||||||
@autosave()
|
|
||||||
|
|
||||||
error: (xhr, status, error) =>
|
error: (xhr, status, error) =>
|
||||||
|
|
||||||
# do not close window if request is aborted
|
# do not close window if request is aborted
|
||||||
|
@ -168,8 +172,14 @@ class App.TicketZoom extends App.Controller
|
||||||
@ArticleView()
|
@ArticleView()
|
||||||
|
|
||||||
if force || !@editDone
|
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
|
@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
|
# show text module UI
|
||||||
if !@isRole('Customer')
|
if !@isRole('Customer')
|
||||||
|
@ -214,7 +224,6 @@ class App.TicketZoom extends App.Controller
|
||||||
new Edit(
|
new Edit(
|
||||||
ticket: @ticket
|
ticket: @ticket
|
||||||
el: @el.find('.edit')
|
el: @el.find('.edit')
|
||||||
form_state: @form_state
|
|
||||||
edit_form: @edit_form
|
edit_form: @edit_form
|
||||||
task_key: @task_key
|
task_key: @task_key
|
||||||
ui: @
|
ui: @
|
||||||
|
@ -320,6 +329,7 @@ class TicketAction extends App.Controller
|
||||||
class Edit extends App.Controller
|
class Edit extends App.Controller
|
||||||
events:
|
events:
|
||||||
'click .submit': 'update'
|
'click .submit': 'update'
|
||||||
|
'click [data-type="reset"]': 'reset'
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
|
@ -332,6 +342,7 @@ class Edit extends App.Controller
|
||||||
@html App.view('ticket_zoom/edit')(
|
@html App.view('ticket_zoom/edit')(
|
||||||
ticket: ticket
|
ticket: ticket
|
||||||
isCustomer: @isRole('Customer')
|
isCustomer: @isRole('Customer')
|
||||||
|
formChanged: !_.isEmpty( App.TaskManager.get(@task_key).state )
|
||||||
)
|
)
|
||||||
|
|
||||||
@configure_attributes_ticket = [
|
@configure_attributes_ticket = [
|
||||||
|
@ -365,7 +376,9 @@ class Edit extends App.Controller
|
||||||
]
|
]
|
||||||
|
|
||||||
@form_id = App.ControllerForm.formId()
|
@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(
|
new App.ControllerForm(
|
||||||
el: @el.find('.form-ticket-update')
|
el: @el.find('.form-ticket-update')
|
||||||
form_id: @form_id
|
form_id: @form_id
|
||||||
|
@ -413,7 +426,10 @@ class Edit extends App.Controller
|
||||||
@el.find('textarea').elastic()
|
@el.find('textarea').elastic()
|
||||||
|
|
||||||
# remember form defaults
|
# remember form defaults
|
||||||
@formDefault = @formParam( @el.find('.ticket-update') )
|
@ui.formDefault = @formParam( @el.find('.ticket-update') )
|
||||||
|
|
||||||
|
# start auto save
|
||||||
|
@ui.autosave()
|
||||||
|
|
||||||
# enable user popups
|
# enable user popups
|
||||||
@userPopups()
|
@userPopups()
|
||||||
|
@ -498,6 +514,10 @@ class Edit extends App.Controller
|
||||||
errors = article.validate()
|
errors = article.validate()
|
||||||
if errors
|
if errors
|
||||||
@log 'error', 'update article', errors
|
@log 'error', 'update article', errors
|
||||||
|
|
||||||
|
# reset form after save
|
||||||
|
App.TaskManager.update( @task_key, { 'state': {} })
|
||||||
|
|
||||||
article.save(
|
article.save(
|
||||||
success: (r) =>
|
success: (r) =>
|
||||||
@ui.fetch( ticket.id, true )
|
@ui.fetch( ticket.id, true )
|
||||||
|
@ -505,11 +525,10 @@ class Edit extends App.Controller
|
||||||
@log 'error', 'update article', r
|
@log 'error', 'update article', r
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
@ui.fetch( ticket.id, true )
|
|
||||||
|
|
||||||
# reset form after save
|
# reset form after save
|
||||||
App.TaskManager.update( @task_key, { 'state': undefined })
|
App.TaskManager.update( @task_key, { 'state': {} })
|
||||||
@ui.form_state = undefined
|
|
||||||
|
@ui.fetch( ticket.id, true )
|
||||||
)
|
)
|
||||||
|
|
||||||
# errors = article.validate()
|
# errors = article.validate()
|
||||||
|
@ -517,6 +536,11 @@ class Edit extends App.Controller
|
||||||
# @formValidate( form: e.target, errors: errors )
|
# @formValidate( form: e.target, errors: errors )
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
reset: (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
App.TaskManager.update( @task_key, { 'state': {} })
|
||||||
|
@render()
|
||||||
|
|
||||||
|
|
||||||
class ArticleView extends App.Controller
|
class ArticleView extends App.Controller
|
||||||
events:
|
events:
|
||||||
|
|
|
@ -9,10 +9,10 @@ class App.TaskManager
|
||||||
_instance ?= new _taskManagerSingleton
|
_instance ?= new _taskManagerSingleton
|
||||||
_instance.all()
|
_instance.all()
|
||||||
|
|
||||||
@add: ( key, callback, params, to_not_show, state ) ->
|
@add: ( key, callback, params, to_not_show ) ->
|
||||||
if _instance == undefined
|
if _instance == undefined
|
||||||
_instance ?= new _taskManagerSingleton
|
_instance ?= new _taskManagerSingleton
|
||||||
_instance.add( key, callback, params, to_not_show, state )
|
_instance.add( key, callback, params, to_not_show )
|
||||||
|
|
||||||
@get: ( key ) ->
|
@get: ( key ) ->
|
||||||
if _instance == undefined
|
if _instance == undefined
|
||||||
|
@ -120,14 +120,14 @@ class _taskManagerSingleton extends App.Controller
|
||||||
workerAll: ->
|
workerAll: ->
|
||||||
@workers
|
@workers
|
||||||
|
|
||||||
add: ( key, callback, params, to_not_show = false, state ) ->
|
add: ( key, callback, params, to_not_show = false ) ->
|
||||||
active = true
|
active = true
|
||||||
if to_not_show
|
if to_not_show
|
||||||
active = false
|
active = false
|
||||||
|
|
||||||
# create new task if not exists
|
# create new task if not exists
|
||||||
task = @get( key )
|
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
|
if !task
|
||||||
task = new App.Taskbar
|
task = new App.Taskbar
|
||||||
task.load(
|
task.load(
|
||||||
|
@ -201,14 +201,14 @@ class _taskManagerSingleton extends App.Controller
|
||||||
@taskUpdate( task )
|
@taskUpdate( task )
|
||||||
|
|
||||||
# start worker for task if not exists
|
# 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'
|
App.Event.trigger 'task:render'
|
||||||
return key
|
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
|
# activate controller
|
||||||
worker = @worker( key )
|
worker = @worker( key )
|
||||||
|
@ -224,13 +224,6 @@ class _taskManagerSingleton extends App.Controller
|
||||||
params_app['el'] = $('#content_permanent_' + key )
|
params_app['el'] = $('#content_permanent_' + key )
|
||||||
params_app['task_key'] = 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
|
if to_not_show
|
||||||
params_app['doNotLog'] = 1
|
params_app['doNotLog'] = 1
|
||||||
a = new App[callback]( params_app )
|
a = new App[callback]( params_app )
|
||||||
|
@ -359,7 +352,7 @@ class _taskManagerSingleton extends App.Controller
|
||||||
@delay(
|
@delay(
|
||||||
=>
|
=>
|
||||||
task = tasks.shift()
|
task = tasks.shift()
|
||||||
@add(task.key, task.callback, task.params, true, task.state)
|
@add(task.key, task.callback, task.params, true)
|
||||||
task_count * 300
|
task_count * 300
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,13 @@
|
||||||
<div class="avatar span1 thumbnails">
|
<div class="avatar span1 thumbnails">
|
||||||
<img class="thumbnail user-data" data-id="<%= @S('id') %>" src="<%- @S('image') %>" alt="">
|
<img class="thumbnail user-data" data-id="<%= @S('id') %>" src="<%- @S('image') %>" alt="">
|
||||||
</div>
|
</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">
|
<form class="form-stacked pull-left ticket-update">
|
||||||
<div class="form-ticket-update"></div>
|
<div class="form-ticket-update"></div>
|
||||||
<div class="form-article-update"></div>
|
<div class="form-article-update"></div>
|
||||||
|
|
|
@ -450,6 +450,11 @@ footer {
|
||||||
margin-left: 80px;
|
margin-left: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-changed {
|
||||||
|
border: 1px solid #fbeed5;
|
||||||
|
background-color: #fcf8e3;
|
||||||
|
}
|
||||||
|
|
||||||
#splash {
|
#splash {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -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 => "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 => "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 => "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 => "" )
|
#Translation.create_if_not_exists( :locale => 'de', :source => "", :target => "" )
|
||||||
|
|
||||||
# install all packages in auto_install
|
# install all packages in auto_install
|
||||||
|
|
Loading…
Reference in a new issue