Implemented poc of issue #57 - Keep inactive tickets/cases in a task bar.

This commit is contained in:
Martin Edenhofer 2013-04-18 01:42:00 +02:00
parent e41c964be9
commit 8ec3f8acec
33 changed files with 222 additions and 80 deletions

View file

@ -309,6 +309,17 @@ class App.Controller extends Spine.Controller
ws_send: (data) ->
App.Event.trigger( 'ws:send', JSON.stringify(data) )
class App.ControllerPermanent extends App.Controller
constructor: ->
super
$('#content_permanent').show()
@el.find('#content').empty()
class App.ControllerContent extends App.Controller
constructor: ->
super
$('#content_permanent').hide()
class App.ControllerModal extends App.Controller
className: 'modal hide fade',
tag: 'div',

View file

@ -106,7 +106,7 @@ class App.ControllerGenericEdit extends App.ControllerModal
ui.modalHide()
)
class App.ControllerGenericIndex extends App.Controller
class App.ControllerGenericIndex extends App.ControllerContent
events:
'click [data-type=edit]': 'edit'
'click [data-type=destroy]': 'destroy'
@ -195,7 +195,7 @@ class App.ControllerGenericIndex extends App.Controller
genericObject: @genericObject
)
class App.ControllerLevel2 extends App.Controller
class App.ControllerLevel2 extends App.ControllerContent
events:
'click [data-toggle="tabnav"]': 'toggle',

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
events:
'click .customer_new': 'userNew'
'submit form': 'submit'

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
events:
'click [data-type=edit]': 'zoom'
'click [data-type=settings]': 'settings'

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class TicketZoom extends App.Controller
events:
'click .submit': 'update'
'click [data-type=reply]': 'reply'
@ -34,7 +32,11 @@ class Index extends App.Controller
@load(cache)
update = =>
@fetch( @ticket_id, false)
@interval( update, 30000, 'zoom_check', 'page' )
@interval( update, 30000, @key, 'ticket_zoom' )
release: =>
@clearInterval( @key, 'ticket_zoom' )
@el.remove()
fetch: (ticket_id, force) ->
@ -143,7 +145,7 @@ class Index extends App.Controller
)
new App.ControllerForm(
el: @el.find('#form-ticket-update')
el: @el.find('[data-id="form-ticket-update"]')
form_id: @form_id
model:
configure_attributes: @configure_attributes_ticket
@ -153,7 +155,7 @@ class Index extends App.Controller
)
new App.ControllerForm(
el: @el.find('#form-article-update')
el: @el.find('[data-id="form-article-update"]')
form_id: @form_id
model:
configure_attributes: @configure_attributes_article
@ -184,7 +186,7 @@ class Index extends App.Controller
# start customer info controller
if !@isRole('Customer')
new App.UserInfo(
el: @el.find('#customer_info')
el: @el.find('[data-id="customer_info"]')
user_id: @ticket.customer_id
ticket: @ticket
)
@ -192,7 +194,7 @@ class Index extends App.Controller
# start action controller
if !@isRole('Customer')
new TicketActionRow(
el: @el.find('#action_info')
el: @el.find('[data-id="action_info"]')
ticket: @ticket
zoom: @
)
@ -200,7 +202,7 @@ class Index extends App.Controller
# start tag controller
if !@isRole('Customer')
new App.TagWidget(
el: @el.find('#tag_info')
el: @el.find('[data-id="tag_info"]')
object_type: 'Ticket'
object: @ticket
)
@ -208,7 +210,7 @@ class Index extends App.Controller
# start link info controller
if !@isRole('Customer')
new App.LinkInfo(
el: @el.find('#link_info')
el: @el.find('[data-id="link_info"]')
object_type: 'Ticket'
object: @ticket
)
@ -216,7 +218,7 @@ class Index extends App.Controller
# show text module UI
if !@isRole('Customer')
new App.TextModuleUI(
el: @el.find('#text_module')
el: @el.find('[data-id="text_module"]')
data:
ticket: @ticket
)
@ -580,6 +582,12 @@ class TicketActionRow extends App.Controller
e.preventDefault()
new App.TicketCustomer( ticket_id: @ticket.id, zoom: @zoom )
App.Config.set( 'ticket/zoom/:ticket_id', Index, 'Routes' )
App.Config.set( 'ticket/zoom/:ticket_id/nav/:nav', Index, 'Routes' )
App.Config.set( 'ticket/zoom/:ticket_id/:article_id', Index, 'Routes' )
class TicketZoomRouter extends App.ControllerPermanent
constructor: (params) ->
super
@log 'zoom router', params
App.TaskManager.add( 'Ticket', @ticket_id, { callback: TicketZoom } )
App.Config.set( 'ticket/zoom/:ticket_id', TicketZoomRouter, 'Routes' )
App.Config.set( 'ticket/zoom/:ticket_id/nav/:nav', TicketZoomRouter, 'Routes' )
App.Config.set( 'ticket/zoom/:ticket_id/:article_id', TicketZoomRouter, 'Routes' )

View file

@ -1,5 +1,3 @@
$ = jQuery.sub()
class Index extends App.ControllerLevel2
# toggleable: true
toggleable: false

View file

@ -1,5 +1,3 @@
$ = jQuery.sub()
class App.ChatWidget extends App.Controller
events:
'submit #chat_form': 'submitMessage'

View file

@ -0,0 +1,7 @@
class App.ContentPermanentWidget extends App.ControllerPermanent
className: 'container aaa'
constructor: ->
super
App.Config.set( 'content_permanent', App.ContentPermanentWidget, 'Widgets' )

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
events:
'submit form': 'submit',
'click .submit': 'submit',
@ -112,7 +110,6 @@ class Index extends App.Controller
# generate form
configure_attributes = [
# { name: 'customer_id', display: 'Customer', tag: 'autocompletion', type: 'text', limit: 100, null: false, relation: 'User', class: 'span7', autocapitalize: false, help: 'Select the customer of the Ticket or create one.', link: '<a href="" class="customer_new">&raquo;</a>', callback: @userInfo },
{ name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: groupFilter, nulloption: true, relation: 'Group', default: defaults['group_id'], class: 'span7', },
# { name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, filter: @edit_form, nulloption: true, relation: 'User', default: defaults['owner_id'], class: 'span7', },
{ name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 100, null: false, default: defaults['subject'], class: 'span7', },
@ -120,7 +117,7 @@ class Index extends App.Controller
# { name: 'ticket_state_id', display: 'State', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketState', default: defaults['ticket_state_id'], translate: true, class: 'medium' },
# { name: 'ticket_priority_id', display: 'Priority', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketPriority', default: defaults['ticket_priority_id'], translate: true, class: 'medium' },
]
@html App.view('agent_ticket_create')( head: 'New Ticket' )
@html App.view('customer_ticket_create')( head: 'New Ticket' )
new App.ControllerForm(
el: @el.find('#form_create')
@ -146,7 +143,6 @@ class Index extends App.Controller
# get params
params = @formParam(e.target)
@log 'CustomerTicketCreate', 'notice', 'params', params
# set customer id
params.customer_id = @Session.get('id')
@ -183,7 +179,6 @@ class Index extends App.Controller
ticket_article_sender_id: sender.id
form_id: @form_id
}
# console.log('params', params)
object.load(params)

View file

@ -1,4 +1,4 @@
class Index extends App.Controller
class Index extends App.ControllerContent
constructor: ->
super

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
constructor: ->
super

View file

@ -1,5 +1,3 @@
$ = jQuery.sub()
class App.LinkInfo extends App.Controller
events:
'click [data-type=add]': 'add',

View file

@ -1,4 +1,4 @@
class Index extends App.Controller
class Index extends App.ControllerContent
events:
'submit #login': 'login',

View file

@ -1,4 +1,4 @@
class Index extends App.Controller
class Index extends App.ControllerContent
constructor: ->
super
@signout()

View file

@ -6,7 +6,7 @@ $.fn.item = ->
elementID or= $(@).parents('[data-id]').data('id')
Note.find(elementID)
class Index extends App.Controller
class Index extends App.ControllerContent
events:
'click [data-type=network-new]': 'network_new'
'click [data-type=network-edit]': 'network_edit'

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
constructor: ->
super

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
constructor: ->
super

View file

@ -1,4 +1,4 @@
class Index extends App.Controller
class Index extends App.ControllerContent
events:
'click .action': 'action'

View file

@ -1,4 +1,4 @@
class Index extends App.Controller
class Index extends App.ControllerContent
className: 'container'
events:
@ -66,7 +66,7 @@ class Index extends App.Controller
App.Config.set( 'reset_password', Index, 'Routes' )
class Verify extends App.Controller
class Verify extends App.ControllerContent
className: 'container'
events:

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
constructor: ->
super

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
className: 'container signup'
events:

View file

@ -1,4 +1,4 @@
class Index extends App.Controller
class Index extends App.ControllerContent
constructor: ->
super

View file

@ -0,0 +1,42 @@
class App.TaskWidget extends App.Controller
events:
'click [data-type="close"]': 'remove'
constructor: ->
super
@render()
# rerender view
App.Event.bind 'ui:rerender', (data) =>
@render()
# rebuild chat widget
App.Event.bind 'auth', (user) =>
App.TaskManager.reset()
@el.html('')
render: ->
return if _.isEmpty( @Session.all() )
tasks = App.TaskManager.all()
item_list = []
for key, task of tasks
item = {}
item.key = key
item.data = App[task.type].find( task.type_id )
item_list.push item
@html App.view('task_widget')(
item_list: item_list
)
remove: (e) =>
e.preventDefault()
key = $(e.target).parent().data('id')
App.TaskManager.remove( key )
@render()
if _.isEmpty( App.TaskManager.all() )
@navigate '#'
App.Config.set( 'task', App.TaskWidget, 'Widgets' )

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
constructor: ->
super

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
constructor: ->
super

View file

@ -1,6 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
class Index extends App.ControllerContent
constructor: ->
super
@ -30,5 +28,4 @@ class Index extends App.Controller
)
App.Config.set( 'users', Index, 'Routes' )
App.Config.set( 'User', { prio: 1000, parent: '#admin', name: 'Users', target: '#users', role: ['Admin'] }, 'NavBar' )

View file

@ -113,12 +113,19 @@ class App.Auth
@_logout: (data) ->
App.Log.log 'Auth', 'notice', '_logout'
# empty session
App.Session.init()
# update websocket auth info
App.WebSocket.auth()
# clear store
App.Store.clear('all')
# rebuild navbar
App.Event.trigger( 'auth' )
App.Event.trigger( 'ui:rerender' )
@_loginError: (xhr, statusText, error) ->
App.Log.log 'Auth', 'notice', '_loginError:error'
@ -129,4 +136,8 @@ class App.Auth
App.WebSocket.auth()
# clear store
App.Store.clear('all')
App.Store.clear('all')
# rebuild navbar
App.Event.trigger( 'auth' )
App.Event.trigger( 'ui:rerender' )

View file

@ -1,5 +1,3 @@
$ = jQuery.sub()
class App.i18n
_instance = undefined

View file

@ -1,4 +1,3 @@
class App.Run extends App.Controller
constructor: ->
super

View file

@ -0,0 +1,72 @@
class App.TaskManager
_instance = undefined
@init: ->
_instance ?= new _Singleton
@all: ->
if _instance == undefined
_instance ?= new _Singleton
_instance.all()
@add: ( type, type_id, params ) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.add( type, type_id, params )
@remove: ( key ) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.remove( key )
@reset: ->
if _instance == undefined
_instance ?= new _Singleton
_instance.reset()
class _Singleton extends Spine.Module
@include App.Log
constructor: ->
@tasks = {}
@task_count = 0
all: ->
@tasks
add: ( type, type_id, params ) ->
for key, task of @tasks
if task.type is type && task.type_id is type_id
$('#content').empty()
$('.content_permanent').hide()
$('#content_permanent_' + key ).show()
return key
@task_count++
$('#content').empty()
$('#content_permanent').append('<div id="content_permanent_' + @task_count + '" class="content_permanent"></div>')
$('.content_permanent').hide()
$('#content_permanent_' + @task_count ).show()
a = new params.callback( el: $('#content_permanent_' + @task_count ), ticket_id: type_id )
task =
type: type
type_id: type_id
params: params
worker: a
@tasks[@task_count] = task
App.Event.trigger 'ui:rerender'
@task_count
remove: ( key ) =>
if @tasks[key]
console.log('rrrelease', @tasks[key], @tasks[key].worker)
@tasks[key].worker.release()
delete @tasks[key]
App.Event.trigger 'ui:rerender'
reset: =>
@tasks = {}
App.Event.trigger 'ui:rerender'

View file

@ -83,8 +83,8 @@
</div>
<div class="span8 well-muted article-message">
<form class="form-stacked pull-left">
<div id="form-ticket-update"></div>
<div id="form-article-update"></div>
<div data-id="form-ticket-update"></div>
<div data-id="form-article-update"></div>
<button type="submit" class="btn btn-primary submit"><%- @T( 'Submit' ) %></button>
</form>
</div>
@ -93,11 +93,11 @@
</div>
<div class="span3">
<div id="customer_info"></div>
<div id="action_info"></div>
<div id="tag_info"></div>
<div id="link_info"></div>
<div id="text_module"></div>
<div data-id="customer_info"></div>
<div data-id="action_info"></div>
<div data-id="tag_info"></div>
<div data-id="link_info"></div>
<div data-id="text_module"></div>
</div>
</div>

View file

@ -0,0 +1,5 @@
<div class="well" style="position: fixed; top: 40px; width: 100%; padding: 5px;">
<% for item in @item_list: %>
<span class="label label-success" data-id="<%- item.key %>"><span class="task"><a style="color: #ffffff;" href="#ticket/zoom/<%- item.data.id %>" title="<%= item.data.title %>"><%= item.data.title %></a></span> <a href="#" data-type="close" class="icon-remove-circle" title="<%- @T('close') %>"></a></span>
<% end %>
</div>

View file

@ -1,5 +1,5 @@
body {
padding-top:50px;
padding-top:74px;
font-size: 13px;
}
@ -47,6 +47,17 @@ table th, table td {
white-space: nowrap;
}
.task {
display: inline-block;
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.task > a:hover {
text-decoration: none;
}
.max-size-scroll {
max-height: 240px;
overflow-y: scroll;
@ -87,6 +98,16 @@ h4 {
padding: 10px 12px 10px;
}
/*
.container,
*/
.navbar-static-top .container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container {
width: 96%;
min-width: 940px;
}
/*
* bootstrap changes
*/