Improved ticket update (take response and show changes without additional ajax request).

This commit is contained in:
Martin Edenhofer 2016-09-04 23:24:19 +02:00
parent d5c8fa3348
commit 71a2a26ea8
5 changed files with 137 additions and 91 deletions

View file

@ -44,44 +44,25 @@ class App.TicketZoom extends App.Controller
return if data.id.toString() isnt @ticket_id.toString()
# check if we already have the request queued
#@log 'notice', 'TRY', @ticket_id, new Date(data.updated_at), new Date(@ticketUpdatedAtLastCallRequested)
@fetchMayBe(data, true)
#@log 'notice', 'TRY', @ticket_id, new Date(data.updated_at), new Date(@ticketUpdatedAtLastCall)
@fetchMayBe(data)
)
fetchStart: =>
if @fetchIsRunning
@fetchIsRunningAgain = true
return false
@fetchIsRunning = true
true
fetchDone: =>
@fetchIsRunning = false
if @fetchIsRunningAgain
@fetchIsRunningAgain = false
@fetch()
fetchMayBe: (data, delay = true) =>
if @ticketUpdatedAtLastCallRequested
if new Date(data.updated_at).getTime() is new Date(@ticketUpdatedAtLastCallRequested).getTime()
@log 'debug', 'no fetch, current ticket already there or requested'
fetchMayBe: (data) =>
if @ticketUpdatedAtLastCall
if new Date(data.updated_at).getTime() is new Date(@ticketUpdatedAtLastCall).getTime()
@log('debug', 'no fetch, current ticket already there or requested')
return
if new Date(data.updated_at).getTime() < new Date(@ticketUpdatedAtLastCallRequested).getTime()
@log 'debug', 'no fetch, current ticket already newser or requested'
if new Date(data.updated_at).getTime() < new Date(@ticketUpdatedAtLastCall).getTime()
@log('debug', 'no fetch, current ticket already newser or requested')
return
@ticketUpdatedAtLastCallRequested = data.updated_at
if delay isnt true
@fetch()
return
fetchDelayed = =>
@fetch()
@delay(fetchDelayed, 1200, "ticket-zoom-#{@ticket_id}")
fetch: =>
return if !@Session.get()
return if !@fetchStart()
# get data
@ajax(
@ -90,22 +71,20 @@ class App.TicketZoom extends App.Controller
url: "#{@apiPath}/tickets/#{@ticket_id}?all=true"
processData: true
success: (data, status, xhr) =>
@fetchDone()
# check if ticket has changed
newTicketRaw = data.assets.Ticket[@ticket_id]
if @ticketUpdatedAtLastCallDone
if @ticketUpdatedAtLastCall
# return if ticket hasnt changed
return if @ticketUpdatedAtLastCallDone is newTicketRaw.updated_at
return if @ticketUpdatedAtLastCall is newTicketRaw.updated_at
# notify if ticket changed not by my self
if newTicketRaw.updated_by_id isnt @Session.get('id')
App.TaskManager.notify(@task_key)
# remember current data
@ticketUpdatedAtLastCallRequested = newTicketRaw.updated_at
@ticketUpdatedAtLastCallDone = newTicketRaw.updated_at
@ticketUpdatedAtLastCall = newTicketRaw.updated_at
@load(data)
App.SessionStorage.set(@key, data)
@ -115,7 +94,6 @@ class App.TicketZoom extends App.Controller
@recentView('Ticket', @ticket_id)
error: (xhr) =>
@fetchDone()
statusText = xhr.statusText
status = xhr.status
@ -127,7 +105,7 @@ class App.TicketZoom extends App.Controller
@renderDone = false
# if ticket is already loaded, ignore status "0" - network issues e. g. temp. not connection
if @ticketUpdatedAtLastCallRequested && status is 0
if @ticketUpdatedAtLastCall && status is 0
console.log('network issues e. g. temp. not connection', status, statusText, detail)
return
@ -174,6 +152,9 @@ class App.TicketZoom extends App.Controller
@ticket = App.Ticket.fullLocal(@ticket_id)
@ticket.article = undefined
# remember current data
@ticketUpdatedAtLastCall = @ticket.updated_at
# render page
@render()
@ -714,28 +695,34 @@ class App.TicketZoom extends App.Controller
ticket.article = article
# submit changes
ui = @
ticket.save(
done: (r) ->
@ajax(
id: "ticket_update_#{ticket.id}"
type: 'PUT'
url: "#{App.Ticket.url}/#{ticket.id}?all=true"
data: JSON.stringify(ticket.attributes())
processData: true
success: (data) =>
App.SessionStorage.set(@key, data)
@load(data)
# reset article - should not be resubmited on next ticket update
ticket.article = undefined
# reset form after save
ui.reset()
@reset()
if taskAction is 'closeNextInOverview'
if ui.overview_id
if @overview_id
current_position = 0
overview = App.Overview.find(ui.overview_id)
overview = App.Overview.find(@overview_id)
list = App.OverviewListCollection.get(overview.link)
for ticket in list.tickets
current_position += 1
if ticket.id is ui.ticket_id
if ticket.id is @ticket_id
next = list.tickets[current_position]
if next
# close task
App.TaskManager.remove(ui.task_key)
App.TaskManager.remove(@task_key)
# open task via task manager to get overview information
App.TaskManager.execute(
@ -743,34 +730,31 @@ class App.TicketZoom extends App.Controller
controller: 'TicketZoom'
params:
ticket_id: next.id
overview_id: ui.overview_id
overview_id: @overview_id
show: true
)
ui.navigate "ticket/zoom/#{next.id}"
@navigate "ticket/zoom/#{next.id}"
return
# fallback, close task
taskAction = 'closeTab'
if taskAction is 'closeTab'
App.TaskManager.remove(ui.task_key)
App.TaskManager.remove(@task_key)
nextTaskUrl = App.TaskManager.nextTaskUrl()
if nextTaskUrl
ui.navigate nextTaskUrl
@navigate nextTaskUrl
return
ui.navigate '#'
@navigate '#'
return
ui.autosaveStart()
ui.muteTask()
ui.fetchMayBe({ id: @id, updated_at: @updated_at }, true)
# enable form
ui.formEnable(e)
@autosaveStart()
@muteTask()
@formEnable(e)
App.Event.trigger('overview:fetch')
fail: (settings, details) =>
error: (settings, details) =>
App.Event.trigger 'notify', {
type: 'error'
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to update!')

View file

@ -15,8 +15,8 @@ class ApplicationController < ActionController::Base
:model_index_render
skip_before_action :verify_authenticity_token
before_action :set_interface_handle, :set_user, :session_update, :user_device_check, :cors_preflight_check
after_action :trigger_events, :http_log, :set_access_control_headers
before_action :transaction_begin, :set_user, :session_update, :user_device_check, :cors_preflight_check
after_action :transaction_end, :http_log, :set_access_control_headers
rescue_from StandardError, with: :server_error
rescue_from ExecJS::RuntimeError, with: :server_error
@ -58,13 +58,15 @@ class ApplicationController < ActionController::Base
private
def set_interface_handle
def transaction_begin
ApplicationHandleInfo.current = 'application_server'
PushMessages.init
end
# execute events
def trigger_events
def transaction_end
Observer::Transaction.commit
PushMessages.finish
ActiveSupport::Dependencies::Reference.clear!
end
# Finds the User with the ID stored in the session with the key

View file

@ -161,12 +161,17 @@ class TicketsController < ApplicationController
end
if params[:expand]
result = ticket.attributes_with_relation_names
result = ticket.reload.attributes_with_relation_names
render json: result, status: :created
return
end
render json: ticket, status: :created
if params[:all]
render json: ticket_all(ticket.reload)
return
end
render json: ticket.reload, status: :created
end
# PUT /api/v1/tickets/1
@ -193,12 +198,17 @@ class TicketsController < ApplicationController
end
if params[:expand]
result = ticket.attributes_with_relation_names
result = ticket.reload.attributes_with_relation_names
render json: result, status: :ok
return
end
render json: ticket, status: :ok
if params[:all]
render json: ticket_all(ticket.reload)
return
end
render json: ticket.reload, status: :ok
end
# DELETE /api/v1/tickets/1

View file

@ -477,21 +477,34 @@ returns
end
def cache_delete
keys = []
# delete by id caches
key = "#{self.class}::#{id}"
Cache.delete(key)
keys.push "#{self.class}::#{id}"
# delete by id with attributes_with_associations caches
key = "#{self.class}::aws::#{id}"
Cache.delete(key)
keys.push "#{self.class}::aws::#{id}"
# delete by name caches
if self[:name]
keys.push "#{self.class}::#{name}"
end
# delete by login caches
if self[:login]
keys.push "#{self.class}::#{login}"
end
keys.each { |key|
Cache.delete(key)
}
# delete old name / login caches
if changed?
if changes.key?('name')
name = changes['name'][0]
key = "#{self.class}::#{name}"
Cache.delete(key.to_s)
Cache.delete(key)
end
if changes.key?('login')
name = changes['login'][0]
@ -500,16 +513,6 @@ returns
end
end
# delete by name caches
if self[:name]
key = "#{self.class}::#{self.name}"
Cache.delete(key)
end
# delete by login caches
return if !self[:login]
Cache.delete("#{self.class}::#{login}")
end
def self.cache_set(data_id, data)
@ -922,9 +925,12 @@ class OwnModel < ApplicationModel
logger.debug "#{self.class.name}.find(#{id}) notify created " + created_at.to_s
class_name = self.class.name
class_name.gsub!(/::/, '')
Sessions.broadcast(
event: class_name + ':create',
data: { id: id, updated_at: updated_at }
PushMessages.send(
message: {
event: class_name + ':create',
data: { id: id, updated_at: updated_at }
},
type: 'authenticated',
)
end
@ -951,9 +957,12 @@ class OwnModel < ApplicationModel
logger.debug "#{self.class.name}.find(#{id}) notify UPDATED " + updated_at.to_s
class_name = self.class.name
class_name.gsub!(/::/, '')
Sessions.broadcast(
event: class_name + ':update',
data: { id: id, updated_at: updated_at }
PushMessages.send(
message: {
event: class_name + ':update',
data: { id: id, updated_at: updated_at }
},
type: 'authenticated',
)
end
@ -980,9 +989,12 @@ class OwnModel < ApplicationModel
logger.debug "#{self.class.name}.find(#{id}) notify TOUCH " + updated_at.to_s
class_name = self.class.name
class_name.gsub!(/::/, '')
Sessions.broadcast(
event: class_name + ':touch',
data: { id: id, updated_at: updated_at }
PushMessages.send(
message: {
event: class_name + ':touch',
data: { id: id, updated_at: updated_at }
},
type: 'authenticated',
)
end
@ -1008,9 +1020,12 @@ class OwnModel < ApplicationModel
logger.debug "#{self.class.name}.find(#{id}) notify DESTOY " + updated_at.to_s
class_name = self.class.name
class_name.gsub!(/::/, '')
Sessions.broadcast(
event: class_name + ':destroy',
data: { id: id, updated_at: updated_at }
PushMessages.send(
message: {
event: class_name + ':destroy',
data: { id: id, updated_at: updated_at }
},
type: 'authenticated',
)
end

35
lib/push_messages.rb Normal file
View file

@ -0,0 +1,35 @@
module PushMessages
def self.enabled?
return true if Thread.current[:push_messages].class == Array
false
end
def self.init
Thread.current[:push_messages] = []
end
def self.send(data)
if !PushMessages.enabled?
Sessions.broadcast(
data[:message],
data[:type],
data[:current_user_id],
)
return true
end
Thread.current[:push_messages].push data
end
def self.finish
Thread.current[:push_messages].each { |data|
Sessions.broadcast(
data[:message],
data[:type],
data[:current_user_id],
)
}
Thread.current[:push_messages] = nil
end
end