This commit is contained in:
Martin Edenhofer 2013-07-23 18:45:28 +02:00
parent 2f5f231246
commit 91d3bb8965
19 changed files with 225 additions and 231 deletions

View file

@ -9,10 +9,16 @@ class App.Controller extends Spine.Controller
super
# apply to release controller on dom remove
@el.on('remove', @release)
# create shortcuts
@Config = App.Config
@Session = App.Session
release: =>
# release custom bindings after it got removed from dom
# add @title methode to set title
title: (name) ->
# $('html head title').html( @Config.get(product_name) + ' - ' + App.i18n.translateInline(name) )

View file

@ -112,22 +112,7 @@ class App.ControllerGenericIndex extends App.ControllerContent
@navupdate @pageData.navupdate
# bind render after a change is done
App.Collection.observe(
level: 'page',
collections: [
{
collection: @genericObject,
event: 'refresh change',
callback: @render,
},
],
)
App.Event.bind(
@genericObject+ ':created ' + @genericObject + ':updated ' + @genericObject + ':destroy'
=>
App[ @genericObject ].fetch()
'page'
)
@subscribeId = App[ @genericObject ].subscribe(@render)
App[ @genericObject ].bind 'ajaxError', (rec, msg) =>
@log 'error', 'ajax', msg.status
@ -143,6 +128,9 @@ class App.ControllerGenericIndex extends App.ControllerContent
# fetch all
App[ @genericObject ].fetch()
release: =>
App[ @genericObject ].unsubscribe(@subscribeId)
render: =>
objects = App.Collection.all(

View file

@ -80,10 +80,7 @@ class App.TicketCreate extends App.Controller
return true
release: =>
# @clearInterval( @key, 'ticket_zoom' )
@el.remove()
@clearInterval( @id, @auto_save_key )
@textModule.release()
autosave: =>
@auto_save_key = 'create' + @type + @id
@ -203,15 +200,15 @@ class App.TicketCreate extends App.Controller
# show template UI
new App.TemplateUI(
el: @el.find('[data-id="ticket_template"]'),
template_id: template['id'],
el: @el.find('[data-id="ticket_template"]')
template_id: template['id']
)
@formDefault = @formParam( @el.find('.ticket-create') )
# show text module UI
@textModule = new App.TextModuleUI(
el: @el.find('.ticket-create')
el: @el.find('.ticket-create').find('textarea')
)
localUserInfo: (params) =>

View file

@ -34,7 +34,7 @@ class App.TicketHistory extends App.ControllerModal
App.Collection.load( type: 'HistoryAttribute', data: data.history_attributes )
# load history collections
App.Collection.deleteAll( 'History' )
App.History.deleteAll()
App.Collection.load( type: 'History', data: data.history )
# render page

View file

@ -86,19 +86,6 @@ class Index extends App.ControllerContent
@log 'notice', 'refetch...', record
@fetch()
# # bind render after a change is done
# App.Collection.observe(
# level: 'page',
# collections: [
# {
# collection: @genericObject,
# event: 'refresh change',
# callback: @render,
# },
# ],
# )
@ticket_list_show = []
for ticket_id in @ticket_list
@ticket_list_show.push App.Collection.find( 'Ticket', ticket_id )

View file

@ -1,6 +1,6 @@
class App.TaskWidget extends App.Controller
events:
'click [data-type="close"]': 'remove'
'click [data-type="close"]': 'remove'
constructor: ->
super

View file

@ -6,22 +6,10 @@ class App.TemplateUI extends App.Controller
constructor: ->
super
@subscribeId = App.Template.subscribe(@render, initFetch: true )
# fetch item on demand
fetch_needed = 1
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' )
release: =>
App.Template.unsubscribe(@subscribeId)
render: =>
@configure_attributes = [
@ -30,16 +18,16 @@ class App.TemplateUI extends App.Controller
template = {}
if @template_id
template = App.Collection.find( 'Template', @template_id )
template = App.Template.find( @template_id )
# insert data
@html App.view('template_widget')(
template: template,
)
new App.ControllerForm(
el: @el.find('#form-template'),
model: { configure_attributes: @configure_attributes, className: '' },
autofocus: false,
el: @el.find('#form-template')
model: { configure_attributes: @configure_attributes, className: '' }
autofocus: false
)
delete: (e) =>
@ -47,7 +35,7 @@ class App.TemplateUI extends App.Controller
# get params
params = @formParam(e.target)
template = App.Collection.find( 'Template', params['template_id'] )
template = App.Template.find( params['template_id'] )
if confirm('Sure?')
template.destroy()
@template_id = undefined
@ -59,7 +47,7 @@ class App.TemplateUI extends App.Controller
# get params
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()
create: (e) =>

View file

@ -10,36 +10,23 @@ class App.TextModuleUI extends App.Controller
.text("(" + e.keywords + ")").end()
element.append(template)
@el.find('textarea').sew(
values: @reload()
token: '::'
elementFactory: elementFactory
@el.parent().find('textarea').sew(
values: @reload(@data)
token: '::'
elementFactory: elementFactory
)
App.TextModule.bind(
'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()
@subscribeId = App.TextModule.subscribe(@update, initFetch: true )
release: =>
App.Event.unbindLevel(@bindLevel)
App.TextModule.unsubscribe(@subscribeId)
reload: (data = false) =>
if data
@lastData = data
@update()
update: =>
all = App.TextModule.all()
values = [{val: '-', keywords: '-'}]
ui = @lastData || @
@ -51,7 +38,7 @@ class App.TextModuleUI extends App.Controller
try
key = eval (varString)
catch error
console.log( "tag replacement: " + error )
#console.log( "tag replacement: " + error )
key = ''
return key
)
@ -62,10 +49,10 @@ class App.TextModuleUI extends App.Controller
values.shift()
# set new data
if @el.find('textarea')[0]
if $(@el.find('textarea')[0]).data()
if $(@el.find('textarea')[0]).data().plugin_sew
$(@el.find('textarea')[0]).data().plugin_sew.options.values = values
if @el[0]
if $(@el[0]).data()
if $(@el[0]).data().plugin_sew
$(@el[0]).data().plugin_sew.options.values = values
return values
@ -82,7 +69,7 @@ class App.TextModuleUIOld extends App.Controller
# fetch item on demand
fetch_needed = 1
if App.Collection.count( 'TextModule' ) > 0
if App.TextModule.count() > 0
fetch_needed = 0
@render()
@ -94,7 +81,7 @@ class App.TextModuleUIOld extends App.Controller
@log 'notice', 'loading....'
@render()
App.TextModule.unbind 'refresh'
App.Collection.fetch( 'TextModule' )
App.TextModule.fetch()
render: =>

View file

@ -58,25 +58,8 @@ class App.TicketZoom extends App.Controller
return true
release: =>
@textModule.release()
App.Event.unbindLevel 'ticket-zoom-' + @ticket_id
@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) ->
@ -156,7 +139,6 @@ class App.TicketZoom extends App.Controller
# update taskbar with new meta data
App.Event.trigger 'task:render'
if !@renderDone
@renderDone = true
@html App.view('ticket_zoom')(
@ -185,8 +167,8 @@ class App.TicketZoom extends App.Controller
# show text module UI
if !@isRole('Customer')
@textModule = new App.TextModuleUI(
el: @el
new App.TextModuleUI(
el: @el.find('textarea')
data:
ticket: @ticket
)
@ -235,6 +217,7 @@ class App.TicketZoom extends App.Controller
# show ticket action row
new TicketAction(
ticket: @ticket
task_key: @task_key
el: @el.find('.ticket-action')
ui: @
)
@ -337,6 +320,9 @@ class Edit extends App.Controller
super
@render()
release: =>
@autosaveStop()
render: ->
ticket = App.Collection.find( 'Ticket', @ticket.id )
@ -431,13 +417,32 @@ class Edit extends App.Controller
@ui.formDefault = @formParam( @el.find('.ticket-update') )
# start auto save
@ui.autosave()
@autosaveStart()
# enable user popups
@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) =>
e.preventDefault()
@autosaveStop()
params = @formParam(e.target)
ticket = App.Collection.find( 'Ticket', @ticket.id )
@ -477,7 +482,10 @@ class Edit extends App.Controller
attachmentTranslated = App.i18n.translateContent('Attachment')
attachmentTranslatedRegExp = new RegExp( attachmentTranslated, 'i' )
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 )
@log 'notice', 'update ticket', ticket_update, ticket
@ -489,6 +497,7 @@ class Edit extends App.Controller
if errors
@log 'error', 'update', errors
@formEnable(e)
@autosaveStart()
ticket.save(
success: (r) =>

View file

@ -6,14 +6,23 @@ class App.UserInfo extends App.Controller
constructor: ->
super
# show user
callback = (user) =>
@render(user)
if @callback
@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) =>
if !user
user = @u
# get display data
data = []

View file

@ -19,51 +19,16 @@ class App.Collection
_instance ?= new _collectionSingleton
_instance.find( type, id, callback, force )
@get: ( args ) ->
if _instance == undefined
_instance ?= new _collectionSingleton
_instance.get( args )
@all: ( args ) ->
if _instance == undefined
_instance ?= new _collectionSingleton
_instance.all( args )
@deleteAll: ( type ) ->
if _instance == undefined
_instance ?= new _collectionSingleton
_instance.deleteAll( type )
@findByAttribute: ( type, key, value ) ->
if _instance == undefined
_instance ?= new _collectionSingleton
_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
@include App.LogInclude
@ -263,14 +228,6 @@ class _collectionSingleton extends Spine.Module
else
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) ->
if !App[ params.type ]
@log 'error', 'all', 'no such collection', params
@ -296,9 +253,6 @@ class _collectionSingleton extends Spine.Module
return all_complied
deleteAll: (type) ->
App[type].deleteAll()
findByAttribute: ( type, key, value ) ->
if !App[type]
@log 'error', 'findByAttribute', 'no such collection', type, key, value
@ -309,18 +263,6 @@ class _collectionSingleton extends Spine.Module
return
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, (item) ->
return '' if item[ attribute ] is undefined || item[ attribute ] is null
@ -365,33 +307,3 @@ class _collectionSingleton extends Spine.Module
)
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

View file

@ -59,9 +59,6 @@ class App.Content extends App.Controller
@log 'notice', 'execute page controller', route, params
# remove observers for page
App.Collection.observeUnbindLevel('page')
# remove events for page
App.Event.unbindLevel('page')

View file

@ -232,7 +232,9 @@ class _taskManagerSingleton extends App.Controller
get: ( key ) =>
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
# throw "No such task with '#{key}'"
@ -249,10 +251,23 @@ class _taskManagerSingleton extends App.Controller
if !task
throw "No such task with '#{key}' to remove"
worker = @worker( key )
if worker && worker.release
worker.release()
allTasks = _.filter(
@allTasks
(taskLocal) ->
return task if task.key isnt taskLocal.key
return
)
@allTasks = allTasks || []
$('#content_permanent_' + key ).html('')
$('#content_permanent_' + key ).remove()
delete @workersStarted[ key ]
delete @workers[ key ]
App.Event.trigger 'task:render'
# destroy in backend
@taskDestroy(task)
notify: ( key ) =>
@ -277,10 +292,11 @@ class _taskManagerSingleton extends App.Controller
# release tasks
for task in @allTasks
worker = @worker( task.key )
if worker && worker.release
worker.release()
$('#content_permanent_' + task.key ).html('')
$('#content_permanent_' + task.key ).remove()
delete @workersStarted[ task.key ]
delete @workers[ task.key ]
# clear instance vars
@tasksToUpdate = {}
@ -324,14 +340,6 @@ class _taskManagerSingleton extends App.Controller
)
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
if @tasksToUpdate[ task.key ] is 'inProgress'

View file

@ -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 @id[0] isnt 'c'
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]

View file

@ -31,13 +31,10 @@ module ExtraCollection
if !user.is_role('Customer')
# all signatures
collections['Signature'] = Signature.all
collections['Signature'] = Signature.all
# all email addresses
collections['EmailAddress'] = EmailAddress.all
# all templates
collections['Template'] = Template.all
collections['EmailAddress'] = EmailAddress.all
end
end

View file

@ -47,6 +47,7 @@ curl http://localhost/api/templates.json -v -u #{login}:#{password}
=end
def index
return if deny_if_not_role('Agent')
model_index_render(Template, params)
end
@ -68,6 +69,7 @@ curl http://localhost/api/templates/#{id}.json -v -u #{login}:#{password}
=end
def show
return if deny_if_not_role('Agent')
model_show_render(Template, params)
end
@ -95,6 +97,7 @@ curl http://localhost/api/templates.json -v -u #{login}:#{password} -H "Content-
=end
def create
return if deny_if_not_role('Agent')
model_create_render(Template, params)
end
@ -122,6 +125,7 @@ curl http://localhost/api/templates.json -v -u #{login}:#{password} -H "Content-
=end
def update
return if deny_if_not_role('Agent')
model_update_render(Template, params)
end
@ -139,6 +143,7 @@ curl http://localhost/api/templates.json -v -u #{login}:#{password} -H "Content-
=end
def destroy
return if deny_if_not_role('Agent')
model_destory_render(Template, params)
end
end

View file

@ -318,10 +318,7 @@ curl http://localhost/api/users/2.json -v -u #{login}:#{password} -H "Content-Ty
# DELETE /api/users/1
def destroy
if !is_role('Admin')
response_access_deny
return
end
return if deny_if_not_role('Admin')
model_destory_render(User, params)
end

View file

@ -1,6 +1,9 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
class Template < ApplicationModel
store :options
validates :name, :presence => true
store :options
validates :name, :presence => true
after_create :notify_clients_after_create
after_update :notify_clients_after_update
after_destroy :notify_clients_after_destroy
end

View file

@ -172,6 +172,7 @@ class TestCase < Test::Unit::TestCase
def browser_element_action(test, action, instance)
#puts "NOTICE: " + action.inspect
sleep 0.2
if action[:css]
if action[:css].match '###stack###'
action[:css].gsub! '###stack###', @stack
@ -221,7 +222,8 @@ class TestCase < Test::Unit::TestCase
elsif action[:element] == :alert
element = instance.switch_to.alert
elsif action[:execute] == 'close_all_tasks'
while true
# while true
for i in 1..100
begin
element = instance.find_element( { :css => '.taskbar [data-type="close"]' } )
if element