Split of model/collections and controller.

This commit is contained in:
Martin Edenhofer 2015-11-04 17:04:17 +01:00
parent c2459ed72d
commit 812d953c1c
4 changed files with 274 additions and 198 deletions

View file

@ -3,7 +3,6 @@ class App.TicketOverview extends App.Controller
constructor: ->
super
@render()
render: ->
@ -29,7 +28,7 @@ class App.TicketOverview extends App.Controller
@activeState
url: =>
'#ticket/view/' + @view
"#ticket/view/#{@view}"
show: (params) =>
@ -77,9 +76,105 @@ class App.TicketOverview extends App.Controller
release: ->
# no
overview: (overview_id) =>
return if !@contentController
@contentController.meta(overview_id)
class Navbar extends App.Controller
elements:
'.js-tabsClone': 'clone'
'.js-tabClone': 'tabClone'
'.js-tabs': 'tabs'
'.js-tab': 'tab'
'.js-dropdown': 'dropdown'
'.js-toggle': 'dropdownToggle'
'.js-dropdownItem': 'dropdownItem'
events:
'click .js-tab': 'activate'
'click .js-dropdownItem': 'navigateTo'
'hide.bs.dropdown': 'onDropdownHide'
'show.bs.dropdown': 'onDropdownShow'
constructor: ->
super
@bindId = App.OverviewIndexCollection.bind(@render)
# rerender view, e. g. on language change
@bind 'ui:rerender', =>
@render(App.OverviewIndexCollection.get())
if @vertical
$(window).on 'resize.navbar', @autoFoldTabs
navigateTo: (event) =>
location.hash = $(event.currentTarget).attr('data-target')
onDropdownShow: =>
@dropdownToggle.addClass('active')
onDropdownHide: =>
@dropdownToggle.removeClass('active')
activate: (event) =>
@tab.removeClass('active')
$(event.currentTarget).addClass('active')
release: =>
$(window).off 'resize.navbar', @autoFoldTabs
if @bindId
App.OverviewIndexCollection.unbind(@bindId)
autoFoldTabs: =>
items = App.OverviewIndexCollection.get()
@html App.view("agent_ticket_view/navbar#{ if @vertical then '_vertical' }")
items: items
while @clone.width() > @el.width()
@tabClone.not('.hide').last().addClass('hide')
@tab.not('.hide').last().addClass('hide')
@dropdownItem.filter('.hide').last().removeClass('hide')
# if all tabs are visible
# remove dropdown and dropdown button
if @dropdownItem.filter('.hide').size() is 0
@dropdown.remove()
@dropdownToggle.remove()
active: (state) =>
@activeState = state
update: (params = {}) ->
for key, value of params
@[key] = value
@render(App.OverviewIndexCollection.get())
render: (data) =>
return if !data
# set page title
if @activeState && @view && !@vertical
for item in data
if item.link is @view
@title item.name, true
# redirect to first view
if @activeState && !@view && !@vertical
view = data[0].link
@navigate "ticket/view/#{view}", true
return
# add new views
for item in data
item.target = "#ticket/view/#{item.link}"
if item.link is @view
item.active = true
activeOverview = item
else
item.active = false
@html App.view("agent_ticket_view/navbar#{ if @vertical then '_vertical' else '' }")
items: data
if @vertical
@autoFoldTabs()
class Table extends App.Controller
events:
@ -89,34 +184,17 @@ class Table extends App.Controller
constructor: ->
super
@cache = {}
# rebuild ticket overview data
@bind 'ticket_overview_rebuild', (data) =>
#console.log('EVENT ticket_overview_rebuild', @view, data.view)
# remeber bulk attributes
@bulk = data.bulk
# fill cache
@cache[data.view] = data
# check if current view is updated
if @view is data.view
@render()
# force fetch ticket overview
@bind 'ticket_overview_fetch_force', =>
@fetch()
# force fetch ticket overview
@bind 'ticket_overview_local', =>
@render(true)
if @view
@bindId = App.OverviewCollection.bind(@view, @render)
# rerender view, e. g. on langauge change
@bind 'ui:rerender', =>
return if !@authenticate(true)
@render()
@render(App.OverviewCollection.get(@view))
release: =>
if @bindId
App.OverviewCollection.unbind(@bindId)
update: (params) =>
for key, value of params
@ -127,61 +205,26 @@ class Table extends App.Controller
return if !@view
# fetch initial data
if !@cache || !@cache[@view]
@fetch()
else
@render()
if @view
if @bindId
App.OverviewCollection.unbind(@bindId)
@bindId = App.OverviewCollection.bind(@view, @render)
fetch: =>
# init fetch via ajax, all other updates on time via websockets
@ajax(
id: 'ticket_overview_' + @view + '_' + @view_mode
type: 'GET'
url: @apiPath + '/ticket_overviews'
data:
view: @view
view_mode: @view_mode
processData: true
success: (data) =>
if data.assets
App.Collection.loadAssets( data.assets )
# remeber bulk attributes
@bulk = data.bulk
@cache[data.view] = data
@render()
)
meta: (overview_id) =>
return if !@cache
# find requested overview data
for url, data of @cache
if data.overview.id is overview_id
return data
false
render: (overview_changed = false) =>
#console.log('RENDER', @cache, @view)
return if !@cache
return if !@cache[@view]
render: (data) =>
return if !data
# use cache
overview = @cache[@view].overview
tickets_count = @cache[@view].tickets_count
ticket_ids = @cache[@view].ticket_ids
overview = data.overview
tickets_count = data.tickets_count
ticket_ids = data.ticket_ids
# use cache if no local change
if !overview_changed
App.Overview.refresh( overview, { clear: true } )
App.Overview.refresh(overview, { clear: true })
# get ticket list
ticket_list_show = []
for ticket_id in ticket_ids
ticket_list_show.push App.Ticket.fullLocal( ticket_id )
ticket_list_show.push App.Ticket.fullLocal(ticket_id)
# if customer and no ticket exists, show the following message only
if !ticket_list_show[0] && @isRole('Customer')
@ -191,7 +234,7 @@ class Table extends App.Controller
@selected = @bulkGetSelected()
# set page title
@overview = App.Overview.find( overview.id )
@overview = App.Overview.find(overview.id)
# render init page
checkbox = true
@ -513,7 +556,8 @@ class Table extends App.Controller
if @bulk_count_index == @bulk_count
# fetch overview data again
App.Event.trigger('ticket_overview_fetch_force')
App.OverviewIndexCollection.fetch()
App.OverviewCollection.fetch(@view)
)
)
@el.find('.table-overview').find('[name="bulk"]:checked').prop('checked', false)
@ -640,7 +684,7 @@ class App.OverviewSettings extends App.ControllerModal
e.preventDefault()
params = @formParam(e.target)
# check if refetch is needed
# check if re-fetch is needed
@reload_needed = false
if @overview.order.by isnt params.order.by
@overview.order.by = params.order.by
@ -660,120 +704,16 @@ class App.OverviewSettings extends App.ControllerModal
# fetch overview data again
if @reload_needed
App.Event.trigger('ticket_overview_fetch_force')
App.OverviewIndexCollection.fetch()
App.OverviewCollection.fetch(@overview.link)
else
App.Event.trigger('ticket_overview_local')
App.OverviewIndexCollection.trigger()
App.OverviewCollection.trigger(@overview.link)
# hide modal
@hide()
)
class Navbar extends App.Controller
elements:
'.js-tabsClone': 'clone'
'.js-tabClone': 'tabClone'
'.js-tabs': 'tabs'
'.js-tab': 'tab'
'.js-dropdown': 'dropdown'
'.js-toggle': 'dropdownToggle'
'.js-dropdownItem': 'dropdownItem'
events:
'click .js-tab': 'activate'
'click .js-dropdownItem': 'navigate'
'hide.bs.dropdown': 'onDropdownHide'
'show.bs.dropdown': 'onDropdownShow'
constructor: ->
super
console.log('RR', @vertical)
App.OverviewIndexCollection.bind(@render)
App.OverviewIndexCollection.fetch()
# force fetch ticket overview
#@bind 'ticket_overview_fetch_force', =>
# @fetch()
# rerender view, e. g. on langauge change
@bind 'ui:rerender', =>
@render(App.OverviewIndexCollection.get())
if @options.vertical
$(window).on 'resize.navbar', @autoFoldTabs
navigate: (event) =>
location.hash = $(event.currentTarget).attr('data-target')
onDropdownShow: =>
@dropdownToggle.addClass('active')
onDropdownHide: =>
@dropdownToggle.removeClass('active')
activate: (event) =>
@tab.removeClass('active')
$(event.currentTarget).addClass('active')
release: =>
$(window).off 'resize.navbar', @autoFoldTabs
autoFoldTabs: =>
items = App.OverviewIndexCollection.get()
@html App.view("agent_ticket_view/navbar#{ if @options.vertical then '_vertical' }")
items: items
while @clone.width() > @el.width()
@tabClone.not('.hide').last().addClass('hide')
@tab.not('.hide').last().addClass('hide')
@dropdownItem.filter('.hide').last().removeClass('hide')
# if all tabs are visible
# remove dropdown and dropdown button
if @dropdownItem.filter('.hide').size() is 0
@dropdown.remove()
@dropdownToggle.remove()
active: (state) =>
@activeState = state
update: (params = {}) ->
for key, value of params
@[key] = value
@render(App.OverviewIndexCollection.get())
render: (data) =>
return if !data
# set page title
if @activeState && @view
for item in data
if item.link is @view
@title item.name, true
# redirect to first view
if @activeState && !@view
view = data[0].link
#console.log('REDIRECT', "ticket/view/#{view}")
@navigate "ticket/view/#{view}", true
return
# add new views
for item in data
item.target = '#ticket/view/' + item.link
if item.link is @view
item.active = true
activeOverview = item
else
item.active = false
@html App.view("agent_ticket_view/navbar#{ if @options.vertical then '_vertical' else '' }")
items: data
if @options.vertical
@autoFoldTabs()
class TicketOverviewRouter extends App.ControllerPermanent
constructor: (params) ->
super

View file

@ -5,32 +5,43 @@ class App.TicketZoomOverviewNavigator extends App.Controller
constructor: ->
super
return if !@overview_id
# rebuild overview navigator if overview has changed
@bind 'ticket_overview_rebuild', (data) =>
execute = =>
@render()
@delay(execute, 1600, 'overview-navigator')
lateUpdate = =>
@delay(@render, 2600, 'overview-navigator')
@overview = App.Overview.find(@overview_id)
@bindId = App.OverviewCollection.bind(@overview.link, lateUpdate, false)
@render()
render: (overview) =>
release: =>
App.OverviewCollection.unbind(@bindId)
render: =>
if !@overview_id
@html('')
return
# get overview data
worker = App.TaskManager.worker( 'TicketOverview' )
return if !worker
overview = worker.overview(@overview_id)
overview = App.OverviewCollection.get(@overview.link)
return if !overview
current_position = 0
found = false
next = false
previous = false
for ticket_id in overview.ticket_ids
current_position += 1
next = overview.ticket_ids[current_position]
previous = overview.ticket_ids[current_position-2]
break if ticket_id is @ticket_id
if ticket_id is @ticket_id
found = true
break
if !found
@html('')
return
# get next/previous ticket
if next

View file

@ -0,0 +1,103 @@
class App.OverviewCollection
_instance = undefined # Must be declared here to force the closure on the class
@get: (view) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.get(view)
@bind: (view, callback, init) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.bind(view, callback, init)
@unbind: (counter) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.unbind(counter)
@fetch: (view) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.fetch(view)
@trigger: (view) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.trigger(view)
# The actual Singleton class
class _Singleton
constructor: ->
@overview = {}
@callbacks = {}
@fetchActive = {}
@counter = 0
# websocket updates
App.Event.bind 'ticket_overview_rebuild', (data) =>
if !@overview[data.view]
@overview[data.view] = {}
# proccess assets, delete them later
if data.assets
App.Collection.loadAssets( data.assets )
delete data.assets
@overview[data.view] = data
@callback(data.view, data)
get: (view) ->
@overview[view]
bind: (view, callback, init = true) ->
@counter += 1
@callbacks[@counter] =
view: view
callback: callback
# start init call if needed
if init
if @overview[view] is undefined
@fetch(view)
else
@callback(view, @overview[view])
@counter
unbind: (counter) ->
delete @callbacks[counter]
fetch: (view) =>
return if @fetchActive[view]
@fetchActive[view] = true
App.Ajax.request(
id: 'ticket_overview_' + view
type: 'GET',
url: App.Config.get('api_path') + '/ticket_overviews',
data:
view: view
processData: true,
success: (data) =>
@fetchActive[view] = false
# proccess assets, delete them later
if data.assets
App.Collection.loadAssets( data.assets )
delete data.assets
@overview[data.view] = data
@callback(view, data)
error: =>
@fetchActive[view] = false
)
trigger: (view) =>
@callback(view, @get(view))
callback: (view, data) =>
for counter, meta of @callbacks
if meta.view is view
meta.callback(data)

View file

@ -16,6 +16,11 @@ class App.OverviewIndexCollection
_instance ?= new _Singleton
_instance.unbind(callback)
@trigger: ->
if _instance == undefined
_instance ?= new _Singleton
_instance.trigger()
@fetch: ->
if _instance == undefined
_instance ?= new _Singleton
@ -26,14 +31,25 @@ class _Singleton
constructor: ->
@callbacks = {}
@counter = 0
# websocket updates
App.Event.bind 'ticket_overview_index', (data) =>
@overview_index = data
@callback(data)
get: ->
@overview_index
bind: (callback) ->
bind: (callback, init = true) ->
@counter += 1
# start init call if needed
if init
if @overview_index is undefined
@fetch()
else
@callback(@overview_index)
@callbacks[@counter] = callback
unbind: (callback) ->
@ -52,8 +68,14 @@ class _Singleton
success: (data) =>
@fetchActive = false
@overview_index = data
for counter, callback of @callbacks
callback(data)
@callback(data)
error: =>
@fetchActive = false
)
trigger: =>
@callback(@get())
callback: (data) =>
for counter, callback of @callbacks
callback(data)