Moved to new memory management, http://blog.alexmaccaw.com/jswebapps-memory-management
This commit is contained in:
parent
2f5f231246
commit
91d3bb8965
19 changed files with 225 additions and 231 deletions
|
@ -9,10 +9,16 @@ class App.Controller extends Spine.Controller
|
||||||
|
|
||||||
super
|
super
|
||||||
|
|
||||||
|
# apply to release controller on dom remove
|
||||||
|
@el.on('remove', @release)
|
||||||
|
|
||||||
# create shortcuts
|
# create shortcuts
|
||||||
@Config = App.Config
|
@Config = App.Config
|
||||||
@Session = App.Session
|
@Session = App.Session
|
||||||
|
|
||||||
|
release: =>
|
||||||
|
# release custom bindings after it got removed from dom
|
||||||
|
|
||||||
# add @title methode to set title
|
# add @title methode to set title
|
||||||
title: (name) ->
|
title: (name) ->
|
||||||
# $('html head title').html( @Config.get(product_name) + ' - ' + App.i18n.translateInline(name) )
|
# $('html head title').html( @Config.get(product_name) + ' - ' + App.i18n.translateInline(name) )
|
||||||
|
|
|
@ -112,22 +112,7 @@ class App.ControllerGenericIndex extends App.ControllerContent
|
||||||
@navupdate @pageData.navupdate
|
@navupdate @pageData.navupdate
|
||||||
|
|
||||||
# bind render after a change is done
|
# bind render after a change is done
|
||||||
App.Collection.observe(
|
@subscribeId = App[ @genericObject ].subscribe(@render)
|
||||||
level: 'page',
|
|
||||||
collections: [
|
|
||||||
{
|
|
||||||
collection: @genericObject,
|
|
||||||
event: 'refresh change',
|
|
||||||
callback: @render,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
)
|
|
||||||
App.Event.bind(
|
|
||||||
@genericObject+ ':created ' + @genericObject + ':updated ' + @genericObject + ':destroy'
|
|
||||||
=>
|
|
||||||
App[ @genericObject ].fetch()
|
|
||||||
'page'
|
|
||||||
)
|
|
||||||
|
|
||||||
App[ @genericObject ].bind 'ajaxError', (rec, msg) =>
|
App[ @genericObject ].bind 'ajaxError', (rec, msg) =>
|
||||||
@log 'error', 'ajax', msg.status
|
@log 'error', 'ajax', msg.status
|
||||||
|
@ -143,6 +128,9 @@ class App.ControllerGenericIndex extends App.ControllerContent
|
||||||
# fetch all
|
# fetch all
|
||||||
App[ @genericObject ].fetch()
|
App[ @genericObject ].fetch()
|
||||||
|
|
||||||
|
release: =>
|
||||||
|
App[ @genericObject ].unsubscribe(@subscribeId)
|
||||||
|
|
||||||
render: =>
|
render: =>
|
||||||
|
|
||||||
objects = App.Collection.all(
|
objects = App.Collection.all(
|
||||||
|
|
|
@ -80,10 +80,7 @@ class App.TicketCreate extends App.Controller
|
||||||
return true
|
return true
|
||||||
|
|
||||||
release: =>
|
release: =>
|
||||||
# @clearInterval( @key, 'ticket_zoom' )
|
|
||||||
@el.remove()
|
|
||||||
@clearInterval( @id, @auto_save_key )
|
@clearInterval( @id, @auto_save_key )
|
||||||
@textModule.release()
|
|
||||||
|
|
||||||
autosave: =>
|
autosave: =>
|
||||||
@auto_save_key = 'create' + @type + @id
|
@auto_save_key = 'create' + @type + @id
|
||||||
|
@ -203,15 +200,15 @@ class App.TicketCreate extends App.Controller
|
||||||
|
|
||||||
# show template UI
|
# show template UI
|
||||||
new App.TemplateUI(
|
new App.TemplateUI(
|
||||||
el: @el.find('[data-id="ticket_template"]'),
|
el: @el.find('[data-id="ticket_template"]')
|
||||||
template_id: template['id'],
|
template_id: template['id']
|
||||||
)
|
)
|
||||||
|
|
||||||
@formDefault = @formParam( @el.find('.ticket-create') )
|
@formDefault = @formParam( @el.find('.ticket-create') )
|
||||||
|
|
||||||
# show text module UI
|
# show text module UI
|
||||||
@textModule = new App.TextModuleUI(
|
@textModule = new App.TextModuleUI(
|
||||||
el: @el.find('.ticket-create')
|
el: @el.find('.ticket-create').find('textarea')
|
||||||
)
|
)
|
||||||
|
|
||||||
localUserInfo: (params) =>
|
localUserInfo: (params) =>
|
||||||
|
|
|
@ -34,7 +34,7 @@ class App.TicketHistory extends App.ControllerModal
|
||||||
App.Collection.load( type: 'HistoryAttribute', data: data.history_attributes )
|
App.Collection.load( type: 'HistoryAttribute', data: data.history_attributes )
|
||||||
|
|
||||||
# load history collections
|
# load history collections
|
||||||
App.Collection.deleteAll( 'History' )
|
App.History.deleteAll()
|
||||||
App.Collection.load( type: 'History', data: data.history )
|
App.Collection.load( type: 'History', data: data.history )
|
||||||
|
|
||||||
# render page
|
# render page
|
||||||
|
|
|
@ -86,19 +86,6 @@ class Index extends App.ControllerContent
|
||||||
@log 'notice', 'refetch...', record
|
@log 'notice', 'refetch...', record
|
||||||
@fetch()
|
@fetch()
|
||||||
|
|
||||||
# # bind render after a change is done
|
|
||||||
# App.Collection.observe(
|
|
||||||
# level: 'page',
|
|
||||||
# collections: [
|
|
||||||
# {
|
|
||||||
# collection: @genericObject,
|
|
||||||
# event: 'refresh change',
|
|
||||||
# callback: @render,
|
|
||||||
# },
|
|
||||||
# ],
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
@ticket_list_show = []
|
@ticket_list_show = []
|
||||||
for ticket_id in @ticket_list
|
for ticket_id in @ticket_list
|
||||||
@ticket_list_show.push App.Collection.find( 'Ticket', ticket_id )
|
@ticket_list_show.push App.Collection.find( 'Ticket', ticket_id )
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class App.TaskWidget extends App.Controller
|
class App.TaskWidget extends App.Controller
|
||||||
events:
|
events:
|
||||||
'click [data-type="close"]': 'remove'
|
'click [data-type="close"]': 'remove'
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
|
|
|
@ -6,22 +6,10 @@ class App.TemplateUI extends App.Controller
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
|
@subscribeId = App.Template.subscribe(@render, initFetch: true )
|
||||||
|
|
||||||
# fetch item on demand
|
release: =>
|
||||||
fetch_needed = 1
|
App.Template.unsubscribe(@subscribeId)
|
||||||
if App.Collection.count( 'Template' ) > 0
|
|
||||||
fetch_needed = 0
|
|
||||||
@render()
|
|
||||||
|
|
||||||
if fetch_needed
|
|
||||||
@reload()
|
|
||||||
|
|
||||||
reload: =>
|
|
||||||
App.Template.bind 'refresh', =>
|
|
||||||
@log 'notice', 'loading...'
|
|
||||||
@render()
|
|
||||||
App.Template.unbind 'refresh'
|
|
||||||
App.Collection.fetch( 'Template' )
|
|
||||||
|
|
||||||
render: =>
|
render: =>
|
||||||
@configure_attributes = [
|
@configure_attributes = [
|
||||||
|
@ -30,16 +18,16 @@ class App.TemplateUI extends App.Controller
|
||||||
|
|
||||||
template = {}
|
template = {}
|
||||||
if @template_id
|
if @template_id
|
||||||
template = App.Collection.find( 'Template', @template_id )
|
template = App.Template.find( @template_id )
|
||||||
|
|
||||||
# insert data
|
# insert data
|
||||||
@html App.view('template_widget')(
|
@html App.view('template_widget')(
|
||||||
template: template,
|
template: template,
|
||||||
)
|
)
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @el.find('#form-template'),
|
el: @el.find('#form-template')
|
||||||
model: { configure_attributes: @configure_attributes, className: '' },
|
model: { configure_attributes: @configure_attributes, className: '' }
|
||||||
autofocus: false,
|
autofocus: false
|
||||||
)
|
)
|
||||||
|
|
||||||
delete: (e) =>
|
delete: (e) =>
|
||||||
|
@ -47,7 +35,7 @@ class App.TemplateUI extends App.Controller
|
||||||
|
|
||||||
# get params
|
# get params
|
||||||
params = @formParam(e.target)
|
params = @formParam(e.target)
|
||||||
template = App.Collection.find( 'Template', params['template_id'] )
|
template = App.Template.find( params['template_id'] )
|
||||||
if confirm('Sure?')
|
if confirm('Sure?')
|
||||||
template.destroy()
|
template.destroy()
|
||||||
@template_id = undefined
|
@template_id = undefined
|
||||||
|
@ -59,7 +47,7 @@ class App.TemplateUI extends App.Controller
|
||||||
# get params
|
# get params
|
||||||
params = @formParam(e.target)
|
params = @formParam(e.target)
|
||||||
|
|
||||||
template = App.Collection.find( 'Template', params['template_id'] )
|
template = App.Template.find( params['template_id'] )
|
||||||
App.Event.trigger 'ticket_create_rerender', template.attributes()
|
App.Event.trigger 'ticket_create_rerender', template.attributes()
|
||||||
|
|
||||||
create: (e) =>
|
create: (e) =>
|
||||||
|
|
|
@ -10,36 +10,23 @@ class App.TextModuleUI extends App.Controller
|
||||||
.text("(" + e.keywords + ")").end()
|
.text("(" + e.keywords + ")").end()
|
||||||
element.append(template)
|
element.append(template)
|
||||||
|
|
||||||
@el.find('textarea').sew(
|
@el.parent().find('textarea').sew(
|
||||||
values: @reload()
|
values: @reload(@data)
|
||||||
token: '::'
|
token: '::'
|
||||||
elementFactory: elementFactory
|
elementFactory: elementFactory
|
||||||
)
|
)
|
||||||
|
|
||||||
App.TextModule.bind(
|
@subscribeId = App.TextModule.subscribe(@update, initFetch: true )
|
||||||
'refresh change'
|
|
||||||
=>
|
|
||||||
@reload()
|
|
||||||
)
|
|
||||||
|
|
||||||
# subscribe and reload data / fetch new data if triggered
|
|
||||||
@bindLevel = 'TextModule-' + Math.floor( Math.random() * 99999 )
|
|
||||||
App.Event.bind(
|
|
||||||
'TextModule:updated TextModule:created TextModule:destroy'
|
|
||||||
=>
|
|
||||||
App.TextModule.fetch()
|
|
||||||
@bindLevel
|
|
||||||
)
|
|
||||||
|
|
||||||
# fetch init collection
|
|
||||||
App.TextModule.fetch()
|
|
||||||
|
|
||||||
release: =>
|
release: =>
|
||||||
App.Event.unbindLevel(@bindLevel)
|
App.TextModule.unsubscribe(@subscribeId)
|
||||||
|
|
||||||
reload: (data = false) =>
|
reload: (data = false) =>
|
||||||
if data
|
if data
|
||||||
@lastData = data
|
@lastData = data
|
||||||
|
@update()
|
||||||
|
|
||||||
|
update: =>
|
||||||
all = App.TextModule.all()
|
all = App.TextModule.all()
|
||||||
values = [{val: '-', keywords: '-'}]
|
values = [{val: '-', keywords: '-'}]
|
||||||
ui = @lastData || @
|
ui = @lastData || @
|
||||||
|
@ -51,7 +38,7 @@ class App.TextModuleUI extends App.Controller
|
||||||
try
|
try
|
||||||
key = eval (varString)
|
key = eval (varString)
|
||||||
catch error
|
catch error
|
||||||
console.log( "tag replacement: " + error )
|
#console.log( "tag replacement: " + error )
|
||||||
key = ''
|
key = ''
|
||||||
return key
|
return key
|
||||||
)
|
)
|
||||||
|
@ -62,10 +49,10 @@ class App.TextModuleUI extends App.Controller
|
||||||
values.shift()
|
values.shift()
|
||||||
|
|
||||||
# set new data
|
# set new data
|
||||||
if @el.find('textarea')[0]
|
if @el[0]
|
||||||
if $(@el.find('textarea')[0]).data()
|
if $(@el[0]).data()
|
||||||
if $(@el.find('textarea')[0]).data().plugin_sew
|
if $(@el[0]).data().plugin_sew
|
||||||
$(@el.find('textarea')[0]).data().plugin_sew.options.values = values
|
$(@el[0]).data().plugin_sew.options.values = values
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
@ -82,7 +69,7 @@ class App.TextModuleUIOld extends App.Controller
|
||||||
|
|
||||||
# fetch item on demand
|
# fetch item on demand
|
||||||
fetch_needed = 1
|
fetch_needed = 1
|
||||||
if App.Collection.count( 'TextModule' ) > 0
|
if App.TextModule.count() > 0
|
||||||
fetch_needed = 0
|
fetch_needed = 0
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
|
@ -94,7 +81,7 @@ class App.TextModuleUIOld extends App.Controller
|
||||||
@log 'notice', 'loading....'
|
@log 'notice', 'loading....'
|
||||||
@render()
|
@render()
|
||||||
App.TextModule.unbind 'refresh'
|
App.TextModule.unbind 'refresh'
|
||||||
App.Collection.fetch( 'TextModule' )
|
App.TextModule.fetch()
|
||||||
|
|
||||||
render: =>
|
render: =>
|
||||||
|
|
||||||
|
|
|
@ -58,25 +58,8 @@ class App.TicketZoom extends App.Controller
|
||||||
return true
|
return true
|
||||||
|
|
||||||
release: =>
|
release: =>
|
||||||
@textModule.release()
|
|
||||||
App.Event.unbindLevel 'ticket-zoom-' + @ticket_id
|
App.Event.unbindLevel 'ticket-zoom-' + @ticket_id
|
||||||
@clearInterval( @key, 'ticket_zoom' )
|
@clearInterval( @key, 'ticket_zoom' )
|
||||||
@el.remove()
|
|
||||||
|
|
||||||
autosave: =>
|
|
||||||
@auto_save_key = 'zoom' + @id
|
|
||||||
|
|
||||||
@autosaveLast = _.clone( @formDefault )
|
|
||||||
update = =>
|
|
||||||
currentData = @formParam( @el.find('.ticket-update') )
|
|
||||||
diff = difference( @autosaveLast, currentData )
|
|
||||||
if !@autosaveLast || ( diff && !_.isEmpty( diff ) )
|
|
||||||
@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) ->
|
fetch: (ticket_id, force) ->
|
||||||
|
|
||||||
|
@ -156,7 +139,6 @@ class App.TicketZoom extends App.Controller
|
||||||
|
|
||||||
# update taskbar with new meta data
|
# update taskbar with new meta data
|
||||||
App.Event.trigger 'task:render'
|
App.Event.trigger 'task:render'
|
||||||
|
|
||||||
if !@renderDone
|
if !@renderDone
|
||||||
@renderDone = true
|
@renderDone = true
|
||||||
@html App.view('ticket_zoom')(
|
@html App.view('ticket_zoom')(
|
||||||
|
@ -185,8 +167,8 @@ class App.TicketZoom extends App.Controller
|
||||||
|
|
||||||
# show text module UI
|
# show text module UI
|
||||||
if !@isRole('Customer')
|
if !@isRole('Customer')
|
||||||
@textModule = new App.TextModuleUI(
|
new App.TextModuleUI(
|
||||||
el: @el
|
el: @el.find('textarea')
|
||||||
data:
|
data:
|
||||||
ticket: @ticket
|
ticket: @ticket
|
||||||
)
|
)
|
||||||
|
@ -235,6 +217,7 @@ class App.TicketZoom extends App.Controller
|
||||||
# show ticket action row
|
# show ticket action row
|
||||||
new TicketAction(
|
new TicketAction(
|
||||||
ticket: @ticket
|
ticket: @ticket
|
||||||
|
task_key: @task_key
|
||||||
el: @el.find('.ticket-action')
|
el: @el.find('.ticket-action')
|
||||||
ui: @
|
ui: @
|
||||||
)
|
)
|
||||||
|
@ -337,6 +320,9 @@ class Edit extends App.Controller
|
||||||
super
|
super
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
|
release: =>
|
||||||
|
@autosaveStop()
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
|
|
||||||
ticket = App.Collection.find( 'Ticket', @ticket.id )
|
ticket = App.Collection.find( 'Ticket', @ticket.id )
|
||||||
|
@ -431,13 +417,32 @@ class Edit extends App.Controller
|
||||||
@ui.formDefault = @formParam( @el.find('.ticket-update') )
|
@ui.formDefault = @formParam( @el.find('.ticket-update') )
|
||||||
|
|
||||||
# start auto save
|
# start auto save
|
||||||
@ui.autosave()
|
@autosaveStart()
|
||||||
|
|
||||||
# enable user popups
|
# enable user popups
|
||||||
@userPopups()
|
@userPopups()
|
||||||
|
|
||||||
|
autosaveStop: =>
|
||||||
|
@clearInterval( @ticket.id, @auto_save_key )
|
||||||
|
|
||||||
|
autosaveStart: =>
|
||||||
|
@auto_save_key = 'zoom' + @ticket.id
|
||||||
|
|
||||||
|
@autosaveLast = _.clone( @ui.formDefault )
|
||||||
|
update = =>
|
||||||
|
currentData = @formParam( @el.find('.ticket-update') )
|
||||||
|
diff = difference( @autosaveLast, currentData )
|
||||||
|
if !@autosaveLast || ( diff && !_.isEmpty( diff ) )
|
||||||
|
@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, @ticket.id, @auto_save_key )
|
||||||
|
|
||||||
update: (e) =>
|
update: (e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
@autosaveStop()
|
||||||
params = @formParam(e.target)
|
params = @formParam(e.target)
|
||||||
|
|
||||||
ticket = App.Collection.find( 'Ticket', @ticket.id )
|
ticket = App.Collection.find( 'Ticket', @ticket.id )
|
||||||
|
@ -477,7 +482,10 @@ class Edit extends App.Controller
|
||||||
attachmentTranslated = App.i18n.translateContent('Attachment')
|
attachmentTranslated = App.i18n.translateContent('Attachment')
|
||||||
attachmentTranslatedRegExp = new RegExp( attachmentTranslated, 'i' )
|
attachmentTranslatedRegExp = new RegExp( attachmentTranslated, 'i' )
|
||||||
if params['body'].match(/attachment/i) || params['body'].match( attachmentTranslatedRegExp )
|
if params['body'].match(/attachment/i) || params['body'].match( attachmentTranslatedRegExp )
|
||||||
return if !confirm( App.i18n.translateContent('You use attachment in text but no attachment is attached. Do you want to continue?') )
|
if !confirm( App.i18n.translateContent('You use attachment in text but no attachment is attached. Do you want to continue?') )
|
||||||
|
return
|
||||||
|
else
|
||||||
|
@autosaveStart()
|
||||||
|
|
||||||
ticket.load( ticket_update )
|
ticket.load( ticket_update )
|
||||||
@log 'notice', 'update ticket', ticket_update, ticket
|
@log 'notice', 'update ticket', ticket_update, ticket
|
||||||
|
@ -489,6 +497,7 @@ class Edit extends App.Controller
|
||||||
if errors
|
if errors
|
||||||
@log 'error', 'update', errors
|
@log 'error', 'update', errors
|
||||||
@formEnable(e)
|
@formEnable(e)
|
||||||
|
@autosaveStart()
|
||||||
|
|
||||||
ticket.save(
|
ticket.save(
|
||||||
success: (r) =>
|
success: (r) =>
|
||||||
|
|
|
@ -6,14 +6,23 @@ class App.UserInfo extends App.Controller
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
|
|
||||||
|
# show user
|
||||||
callback = (user) =>
|
callback = (user) =>
|
||||||
@render(user)
|
@render(user)
|
||||||
if @callback
|
if @callback
|
||||||
@callback(user)
|
@callback(user)
|
||||||
|
|
||||||
App.Collection.find( 'User', @user_id, callback )
|
# subscribe and reload data / fetch new data if triggered
|
||||||
|
@subscribeId = user.subscribe(@render)
|
||||||
|
|
||||||
|
App.User.retrieve( @user_id, callback )
|
||||||
|
|
||||||
|
release: =>
|
||||||
|
App.User.unsubscribe(@subscribeId)
|
||||||
|
|
||||||
render: (user) =>
|
render: (user) =>
|
||||||
|
if !user
|
||||||
|
user = @u
|
||||||
|
|
||||||
# get display data
|
# get display data
|
||||||
data = []
|
data = []
|
||||||
|
|
|
@ -19,51 +19,16 @@ class App.Collection
|
||||||
_instance ?= new _collectionSingleton
|
_instance ?= new _collectionSingleton
|
||||||
_instance.find( type, id, callback, force )
|
_instance.find( type, id, callback, force )
|
||||||
|
|
||||||
@get: ( args ) ->
|
|
||||||
if _instance == undefined
|
|
||||||
_instance ?= new _collectionSingleton
|
|
||||||
_instance.get( args )
|
|
||||||
|
|
||||||
@all: ( args ) ->
|
@all: ( args ) ->
|
||||||
if _instance == undefined
|
if _instance == undefined
|
||||||
_instance ?= new _collectionSingleton
|
_instance ?= new _collectionSingleton
|
||||||
_instance.all( args )
|
_instance.all( args )
|
||||||
|
|
||||||
@deleteAll: ( type ) ->
|
|
||||||
if _instance == undefined
|
|
||||||
_instance ?= new _collectionSingleton
|
|
||||||
_instance.deleteAll( type )
|
|
||||||
|
|
||||||
@findByAttribute: ( type, key, value ) ->
|
@findByAttribute: ( type, key, value ) ->
|
||||||
if _instance == undefined
|
if _instance == undefined
|
||||||
_instance ?= new _collectionSingleton
|
_instance ?= new _collectionSingleton
|
||||||
_instance.findByAttribute( type, key, value )
|
_instance.findByAttribute( type, key, value )
|
||||||
|
|
||||||
@count: ( type ) ->
|
|
||||||
if _instance == undefined
|
|
||||||
_instance ?= new _collectionSingleton
|
|
||||||
_instance.count( type )
|
|
||||||
|
|
||||||
@fetch: ( type ) ->
|
|
||||||
if _instance == undefined
|
|
||||||
_instance ?= new _collectionSingleton
|
|
||||||
_instance.fetch( type )
|
|
||||||
|
|
||||||
@observe: (args) ->
|
|
||||||
if _instance == undefined
|
|
||||||
_instance ?= new _collectionSingleton
|
|
||||||
_instance.observe(args)
|
|
||||||
|
|
||||||
@observeUnbindLevel: (level) ->
|
|
||||||
if _instance == undefined
|
|
||||||
_instance ?= new _collectionSingleton
|
|
||||||
_instance.observeUnbindLevel(level)
|
|
||||||
|
|
||||||
@_observeStats: ->
|
|
||||||
if _instance == undefined
|
|
||||||
_instance ?= new _collectionSingleton
|
|
||||||
_instance._observeStats()
|
|
||||||
|
|
||||||
class _collectionSingleton extends Spine.Module
|
class _collectionSingleton extends Spine.Module
|
||||||
@include App.LogInclude
|
@include App.LogInclude
|
||||||
|
|
||||||
|
@ -263,14 +228,6 @@ class _collectionSingleton extends Spine.Module
|
||||||
else
|
else
|
||||||
return data
|
return data
|
||||||
|
|
||||||
get: (params) ->
|
|
||||||
if !App[ params.type ]
|
|
||||||
@log 'error', 'get', 'no such collection', params
|
|
||||||
return
|
|
||||||
|
|
||||||
@log 'debug', 'get', params
|
|
||||||
App[ params.type ].refresh( object, options: { clear: true } )
|
|
||||||
|
|
||||||
all: (params) ->
|
all: (params) ->
|
||||||
if !App[ params.type ]
|
if !App[ params.type ]
|
||||||
@log 'error', 'all', 'no such collection', params
|
@log 'error', 'all', 'no such collection', params
|
||||||
|
@ -296,9 +253,6 @@ class _collectionSingleton extends Spine.Module
|
||||||
|
|
||||||
return all_complied
|
return all_complied
|
||||||
|
|
||||||
deleteAll: (type) ->
|
|
||||||
App[type].deleteAll()
|
|
||||||
|
|
||||||
findByAttribute: ( type, key, value ) ->
|
findByAttribute: ( type, key, value ) ->
|
||||||
if !App[type]
|
if !App[type]
|
||||||
@log 'error', 'findByAttribute', 'no such collection', type, key, value
|
@log 'error', 'findByAttribute', 'no such collection', type, key, value
|
||||||
|
@ -309,18 +263,6 @@ class _collectionSingleton extends Spine.Module
|
||||||
return
|
return
|
||||||
item
|
item
|
||||||
|
|
||||||
count: ( type ) ->
|
|
||||||
if !App[type]
|
|
||||||
@log 'error', 'count', 'no such collection', type, key, value
|
|
||||||
return
|
|
||||||
App[type].count()
|
|
||||||
|
|
||||||
fetch: ( type ) ->
|
|
||||||
if !App[type]
|
|
||||||
@log 'error', 'fetch', 'no such collection', type, key, value
|
|
||||||
return
|
|
||||||
App[type].fetch()
|
|
||||||
|
|
||||||
_sortBy: ( collection, attribute ) ->
|
_sortBy: ( collection, attribute ) ->
|
||||||
_.sortBy( collection, (item) ->
|
_.sortBy( collection, (item) ->
|
||||||
return '' if item[ attribute ] is undefined || item[ attribute ] is null
|
return '' if item[ attribute ] is undefined || item[ attribute ] is null
|
||||||
|
@ -365,33 +307,3 @@ class _collectionSingleton extends Spine.Module
|
||||||
)
|
)
|
||||||
return collection
|
return collection
|
||||||
|
|
||||||
observeUnbindLevel: (level) ->
|
|
||||||
return if !@observeCurrent
|
|
||||||
return if !@observeCurrent[level]
|
|
||||||
for observers in @observeCurrent[level]
|
|
||||||
@_observeUnbind( observers )
|
|
||||||
@observeCurrent[level] = []
|
|
||||||
|
|
||||||
observe: (data) ->
|
|
||||||
if !@observeCurrent
|
|
||||||
@observeCurrent = {}
|
|
||||||
|
|
||||||
if !@observeCurrent[ data.level ]
|
|
||||||
@observeCurrent[ data.level ] = []
|
|
||||||
|
|
||||||
@observeCurrent[ data.level ].push data.collections
|
|
||||||
for observe in data.collections
|
|
||||||
events = observe.event.split(' ')
|
|
||||||
for event in events
|
|
||||||
if App[ observe.collection ]
|
|
||||||
App[ observe.collection ].bind( event, observe.callback )
|
|
||||||
|
|
||||||
_observeUnbind: (observers) ->
|
|
||||||
for observe in observers
|
|
||||||
events = observe.event.split(' ')
|
|
||||||
for event in events
|
|
||||||
if App[ observe.collection ]
|
|
||||||
App[ observe.collection ].unbind( event, observe.callback )
|
|
||||||
|
|
||||||
_observeStats: ->
|
|
||||||
@observeCurrent
|
|
||||||
|
|
|
@ -59,9 +59,6 @@ class App.Content extends App.Controller
|
||||||
|
|
||||||
@log 'notice', 'execute page controller', route, params
|
@log 'notice', 'execute page controller', route, params
|
||||||
|
|
||||||
# remove observers for page
|
|
||||||
App.Collection.observeUnbindLevel('page')
|
|
||||||
|
|
||||||
# remove events for page
|
# remove events for page
|
||||||
App.Event.unbindLevel('page')
|
App.Event.unbindLevel('page')
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,9 @@ class _taskManagerSingleton extends App.Controller
|
||||||
|
|
||||||
get: ( key ) =>
|
get: ( key ) =>
|
||||||
for task in @allTasks
|
for task in @allTasks
|
||||||
return task if task.key is key
|
if task.key is key
|
||||||
|
return task
|
||||||
|
# return task if task.key is key
|
||||||
return
|
return
|
||||||
# throw "No such task with '#{key}'"
|
# throw "No such task with '#{key}'"
|
||||||
|
|
||||||
|
@ -249,10 +251,23 @@ class _taskManagerSingleton extends App.Controller
|
||||||
if !task
|
if !task
|
||||||
throw "No such task with '#{key}' to remove"
|
throw "No such task with '#{key}' to remove"
|
||||||
|
|
||||||
worker = @worker( key )
|
allTasks = _.filter(
|
||||||
if worker && worker.release
|
@allTasks
|
||||||
worker.release()
|
(taskLocal) ->
|
||||||
|
return task if task.key isnt taskLocal.key
|
||||||
|
return
|
||||||
|
)
|
||||||
|
@allTasks = allTasks || []
|
||||||
|
|
||||||
|
$('#content_permanent_' + key ).html('')
|
||||||
|
$('#content_permanent_' + key ).remove()
|
||||||
|
|
||||||
delete @workersStarted[ key ]
|
delete @workersStarted[ key ]
|
||||||
|
delete @workers[ key ]
|
||||||
|
|
||||||
|
App.Event.trigger 'task:render'
|
||||||
|
|
||||||
|
# destroy in backend
|
||||||
@taskDestroy(task)
|
@taskDestroy(task)
|
||||||
|
|
||||||
notify: ( key ) =>
|
notify: ( key ) =>
|
||||||
|
@ -277,10 +292,11 @@ class _taskManagerSingleton extends App.Controller
|
||||||
|
|
||||||
# release tasks
|
# release tasks
|
||||||
for task in @allTasks
|
for task in @allTasks
|
||||||
worker = @worker( task.key )
|
$('#content_permanent_' + task.key ).html('')
|
||||||
if worker && worker.release
|
$('#content_permanent_' + task.key ).remove()
|
||||||
worker.release()
|
|
||||||
delete @workersStarted[ task.key ]
|
delete @workersStarted[ task.key ]
|
||||||
|
delete @workers[ task.key ]
|
||||||
|
|
||||||
# clear instance vars
|
# clear instance vars
|
||||||
@tasksToUpdate = {}
|
@tasksToUpdate = {}
|
||||||
|
@ -324,14 +340,6 @@ class _taskManagerSingleton extends App.Controller
|
||||||
)
|
)
|
||||||
|
|
||||||
taskDestroy: (task) ->
|
taskDestroy: (task) ->
|
||||||
allTasks = _.filter(
|
|
||||||
@allTasks
|
|
||||||
(taskLocal) ->
|
|
||||||
return task if task.key isnt taskLocal.key
|
|
||||||
return
|
|
||||||
)
|
|
||||||
@allTasks = allTasks || []
|
|
||||||
App.Event.trigger 'task:render'
|
|
||||||
|
|
||||||
# check if update is still in process
|
# check if update is still in process
|
||||||
if @tasksToUpdate[ task.key ] is 'inProgress'
|
if @tasksToUpdate[ task.key ] is 'inProgress'
|
||||||
|
|
|
@ -87,3 +87,105 @@ class App.Model extends Spine.Model
|
||||||
return true if typeof @id is 'number' # in case of real database id
|
return true if typeof @id is 'number' # in case of real database id
|
||||||
return true if @id[0] isnt 'c'
|
return true if @id[0] isnt 'c'
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
@retrieve: ( id, callback, force ) ->
|
||||||
|
if !force && App[ @className ].exists( id )
|
||||||
|
data = App[ @className ].find( id )
|
||||||
|
# data = @_fillUp( @className, data )
|
||||||
|
if callback
|
||||||
|
callback( data )
|
||||||
|
return data
|
||||||
|
else
|
||||||
|
if force
|
||||||
|
console.log 'debug', 'find forced to load!', @className, id
|
||||||
|
else
|
||||||
|
console.log 'debug', 'find not loaded!', @className, id
|
||||||
|
if callback
|
||||||
|
|
||||||
|
# execute callback if record got loaded
|
||||||
|
col = @
|
||||||
|
App[ @className ].one 'refresh', (record) ->
|
||||||
|
delay = =>
|
||||||
|
data = App[ @className ].find( id )
|
||||||
|
if callback
|
||||||
|
callback( data )
|
||||||
|
window.setTimeout(delay, 200)
|
||||||
|
|
||||||
|
# fetch object
|
||||||
|
console.log 'debug', 'loading..' + @className + '..', id
|
||||||
|
App[ @className ].fetch( id: id )
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
@subscribe: (callback, param = {}) ->
|
||||||
|
if !@SUBSCRIPTION_COLLECTION
|
||||||
|
@SUBSCRIPTION_COLLECTION = {}
|
||||||
|
|
||||||
|
# subscribe and render data / fetch new data if triggered
|
||||||
|
@bind(
|
||||||
|
'refresh change'
|
||||||
|
=>
|
||||||
|
for key, callbackSingle of @SUBSCRIPTION_COLLECTION
|
||||||
|
callbackSingle()
|
||||||
|
)
|
||||||
|
|
||||||
|
# trigger deleteAll() and fetch() on network notify
|
||||||
|
events = "#{@className}:created #{@className}:updated #{@className}:destroy"
|
||||||
|
App.Event.bind(
|
||||||
|
events
|
||||||
|
=>
|
||||||
|
@deleteAll()
|
||||||
|
# callbacks = =>
|
||||||
|
# for key, callbackSingle of @SUBSCRIPTION_COLLECTION
|
||||||
|
# callbackSingle()
|
||||||
|
# @one 'refresh', (collection) =>
|
||||||
|
# callbacks(collection)
|
||||||
|
@fetch()
|
||||||
|
|
||||||
|
'Collection::Subscribe::' + @className
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
key = @className + '-' + Math.floor( Math.random() * 99999 )
|
||||||
|
@SUBSCRIPTION_COLLECTION[key] = callback
|
||||||
|
|
||||||
|
# fetch init collection
|
||||||
|
if param['initFetch'] is true
|
||||||
|
@one 'refresh', (collection) =>
|
||||||
|
callback(collection)
|
||||||
|
@fetch()
|
||||||
|
|
||||||
|
return key
|
||||||
|
|
||||||
|
subscribe: (callback) ->
|
||||||
|
if !App[ @constructor.className ]['SUBSCRIPTION_ITEM']
|
||||||
|
App[ @constructor.className ]['SUBSCRIPTION_ITEM'] = {}
|
||||||
|
if !App[ @constructor.className ]['SUBSCRIPTION_ITEM'][@id]
|
||||||
|
App[ @constructor.className ]['SUBSCRIPTION_ITEM'][@id] = {}
|
||||||
|
|
||||||
|
events = "#{@constructor.className}:created #{@constructor.className}:updated #{@constructor.className}:destroy"
|
||||||
|
App.Event.bind(
|
||||||
|
events
|
||||||
|
(record) =>
|
||||||
|
if @id.toString() is record.id.toString()
|
||||||
|
App[ @constructor.className ].one 'refresh', (record) =>
|
||||||
|
user = App[ @constructor.className ].find(@id)
|
||||||
|
for key, callback of App[ @constructor.className ]['SUBSCRIPTION_ITEM'][@id]
|
||||||
|
callback(user)
|
||||||
|
App[ @constructor.className ].fetch( id: @id )
|
||||||
|
'Item::Subscribe::' + @constructor.className
|
||||||
|
)
|
||||||
|
|
||||||
|
key = @constructor.className + '-' + Math.floor( Math.random() * 99999 )
|
||||||
|
App[ @constructor.className ]['SUBSCRIPTION_ITEM'][@id][key] = callback
|
||||||
|
return key
|
||||||
|
|
||||||
|
@unsubscribe: (data) ->
|
||||||
|
if @SUBSCRIPTION_ITEM
|
||||||
|
for id, keys of @SUBSCRIPTION_ITEM
|
||||||
|
if keys[data]
|
||||||
|
delete keys[data]
|
||||||
|
|
||||||
|
if @SUBSCRIPTION_COLLECTION
|
||||||
|
if @SUBSCRIPTION_COLLECTION[data]
|
||||||
|
delete @SUBSCRIPTION_COLLECTION[data]
|
||||||
|
|
|
@ -31,13 +31,10 @@ module ExtraCollection
|
||||||
if !user.is_role('Customer')
|
if !user.is_role('Customer')
|
||||||
|
|
||||||
# all signatures
|
# all signatures
|
||||||
collections['Signature'] = Signature.all
|
collections['Signature'] = Signature.all
|
||||||
|
|
||||||
# all email addresses
|
# all email addresses
|
||||||
collections['EmailAddress'] = EmailAddress.all
|
collections['EmailAddress'] = EmailAddress.all
|
||||||
|
|
||||||
# all templates
|
|
||||||
collections['Template'] = Template.all
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ curl http://localhost/api/templates.json -v -u #{login}:#{password}
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
return if deny_if_not_role('Agent')
|
||||||
model_index_render(Template, params)
|
model_index_render(Template, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -68,6 +69,7 @@ curl http://localhost/api/templates/#{id}.json -v -u #{login}:#{password}
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
return if deny_if_not_role('Agent')
|
||||||
model_show_render(Template, params)
|
model_show_render(Template, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -95,6 +97,7 @@ curl http://localhost/api/templates.json -v -u #{login}:#{password} -H "Content-
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
return if deny_if_not_role('Agent')
|
||||||
model_create_render(Template, params)
|
model_create_render(Template, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -122,6 +125,7 @@ curl http://localhost/api/templates.json -v -u #{login}:#{password} -H "Content-
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
return if deny_if_not_role('Agent')
|
||||||
model_update_render(Template, params)
|
model_update_render(Template, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -139,6 +143,7 @@ curl http://localhost/api/templates.json -v -u #{login}:#{password} -H "Content-
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
return if deny_if_not_role('Agent')
|
||||||
model_destory_render(Template, params)
|
model_destory_render(Template, params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -318,10 +318,7 @@ curl http://localhost/api/users/2.json -v -u #{login}:#{password} -H "Content-Ty
|
||||||
|
|
||||||
# DELETE /api/users/1
|
# DELETE /api/users/1
|
||||||
def destroy
|
def destroy
|
||||||
if !is_role('Admin')
|
return if deny_if_not_role('Admin')
|
||||||
response_access_deny
|
|
||||||
return
|
|
||||||
end
|
|
||||||
model_destory_render(User, params)
|
model_destory_render(User, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Template < ApplicationModel
|
class Template < ApplicationModel
|
||||||
store :options
|
store :options
|
||||||
validates :name, :presence => true
|
validates :name, :presence => true
|
||||||
|
after_create :notify_clients_after_create
|
||||||
|
after_update :notify_clients_after_update
|
||||||
|
after_destroy :notify_clients_after_destroy
|
||||||
end
|
end
|
||||||
|
|
|
@ -172,6 +172,7 @@ class TestCase < Test::Unit::TestCase
|
||||||
|
|
||||||
def browser_element_action(test, action, instance)
|
def browser_element_action(test, action, instance)
|
||||||
#puts "NOTICE: " + action.inspect
|
#puts "NOTICE: " + action.inspect
|
||||||
|
sleep 0.2
|
||||||
if action[:css]
|
if action[:css]
|
||||||
if action[:css].match '###stack###'
|
if action[:css].match '###stack###'
|
||||||
action[:css].gsub! '###stack###', @stack
|
action[:css].gsub! '###stack###', @stack
|
||||||
|
@ -221,7 +222,8 @@ class TestCase < Test::Unit::TestCase
|
||||||
elsif action[:element] == :alert
|
elsif action[:element] == :alert
|
||||||
element = instance.switch_to.alert
|
element = instance.switch_to.alert
|
||||||
elsif action[:execute] == 'close_all_tasks'
|
elsif action[:execute] == 'close_all_tasks'
|
||||||
while true
|
# while true
|
||||||
|
for i in 1..100
|
||||||
begin
|
begin
|
||||||
element = instance.find_element( { :css => '.taskbar [data-type="close"]' } )
|
element = instance.find_element( { :css => '.taskbar [data-type="close"]' } )
|
||||||
if element
|
if element
|
||||||
|
|
Loading…
Reference in a new issue