Moved to new task bar.

This commit is contained in:
Martin Edenhofer 2014-07-12 15:19:35 +02:00
parent f11a12f98e
commit 6db776e722
6 changed files with 157 additions and 393 deletions

View file

@ -1,6 +1,6 @@
class App.Navigation extends App.Controller class App.Navigation extends App.Controller
className: 'navigation flex vertical' className: 'navigation flex vertical'
constructor: -> constructor: ->
super super
@render() @render()
@ -201,6 +201,11 @@ class App.Navigation extends App.Controller
@delay( searchFunction, 220, 'search' ) @delay( searchFunction, 220, 'search' )
) )
if !@taskBar
@taskBar = true
new App.TaskbarWidget( el: @el.find('.tasks') )
getItems: (data) -> getItems: (data) ->
navbar = _.values(data.navbar) navbar = _.values(data.navbar)

View file

@ -1,261 +0,0 @@
class App.TaskWidget extends App.Controller
constructor: ->
super
@render()
# render on generic ui call
@bind 'ui:rerender', => @render()
# render on login
@bind 'auth:login', => @render()
# reset current tasks on logout
@bind 'auth:logout', => @el.html('')
# only do take over check after spool messages are finised
App.Event.bind(
'spool:sent'
=>
@spoolSent = true
# broadcast to other browser instance
App.WebSocket.send(
action: 'broadcast'
event: 'session:takeover'
spool: true
recipient:
user_id: [ App.Session.get( 'id' ) ]
data:
taskbar_id: App.TaskManager.TaskbarId()
)
'task'
)
# session take over message
App.Event.bind(
'session:takeover'
(data) =>
# only if spool messages are already sent
return if !@spoolSent
# check if error message is already shown
if !@error
# only if new client id isnt own client id
if data.taskbar_id isnt App.TaskManager.TaskbarId()
@error = new App.SessionMessage(
title: 'Session'
message: 'Session taken over... please reload page or work with other browser window.'
keyboard: false
backdrop: true
close: true
button: 'Reload application'
forceReload: true
)
@disconnectClient()
'task'
)
render: ->
return if _.isEmpty( @Session.all() )
@html App.view('task_widget')(
taskBarActions: @_getTaskActions()
)
@el.find('.taskbar-items').html('')
new Taskbar(
el: @el.find('.taskbar-items')
)
_getTaskActions: ->
roles = App.Session.get( 'roles' )
navbar = _.values( @Config.get( 'TaskActions' ) )
level1 = []
for item in navbar
if typeof item.callback is 'function'
data = item.callback() || {}
for key, value of data
item[key] = value
if !item.parent
match = 0
if !item.role
match = 1
if !roles && item.role
match = _.include( item.role, 'Anybody' )
if roles
for role in roles
if !match
match = _.include( item.role, role.name )
if match
level1.push item
level1
class Taskbar extends App.Controller
events:
'click [data-type="close"]': 'remove'
constructor: ->
super
@render()
# on window resize
resizeTasksDelay = =>
App.Delay.set( @resizeTasks, 60, 'resizeTasks', 'task' )
$(window).off( 'resize.taskbar' ).on( 'resize.taskbar', resizeTasksDelay )
# render view
@bind 'task:render', => @render()
# reset current tasks on logout
@bind 'auth:logout', => @el.html('')
render: ->
return if _.isEmpty( @Session.all() )
tasks = App.TaskManager.all()
item_list = []
for task in tasks
# collect meta data of task for task bar item
data =
url: '#'
id: false
title: App.i18n.translateInline('Loading...')
head: App.i18n.translateInline('Loading...')
worker = App.TaskManager.worker( task.key )
if worker
meta = worker.meta()
# apply meta data of controller
if meta
for key, value of meta
data[key] = value
# collect new task bar items
item = {}
item.task = task
item.data = data
item_list.push item
# set title
if task.active
@title data.title
@html App.view('task_widget_tasks')(
item_list: item_list
)
@resizeTasks()
dndOptions =
tolerance: 'pointer'
distance: 15
opacity: 0.6
forcePlaceholderSize: true
items: '> a'
update: =>
items = @el.find('> a')
order = []
for item in items
key = $(item).data('key')
if !key
throw "No such key attributes found for task item"
order.push key
App.TaskManager.reorder( order )
@el.sortable( dndOptions )
remove: (e, key = false, force = false) =>
e.preventDefault()
if !key
key = $(e.target).parent().data('key')
if !key
throw "No such key attributes found for task item"
# check if input has changed
worker = App.TaskManager.worker( key )
if !force && worker && worker.changed
if worker.changed()
new Remove(
key: key
ui: @
)
return
# check if active task is closed
currentTask = App.TaskManager.get( key )
tasks = App.TaskManager.all()
active_is_closed = false
for task in tasks
if currentTask.active && task.key is key
active_is_closed = true
# remove task
App.TaskManager.remove( key )
@resizeTasks()
# navigate to next task if needed
tasks = App.TaskManager.all()
if active_is_closed && !_.isEmpty( tasks )
task_last = undefined
for task in tasks
task_last = task
if task_last
worker = App.TaskManager.worker( task_last.key )
if worker
@navigate worker.url()
return
if _.isEmpty( tasks )
@navigate '#'
resizeTasks: ->
width = $('#task .taskbar-items').width()# - $('#task .taskbar-new').width() - 200
task_count = App.TaskManager.all().length
task_size = ( width / task_count ) - 40
elementsOversize = 0
elementsOversizeLeftTotal = 0
$('#task .task').each(
(position, element) ->
widthTask = $(element).width()
if widthTask > task_size
elementsOversize++
else
elementsOversizeLeftTotal += task_size - widthTask
)
addOversize = elementsOversizeLeftTotal / elementsOversize
task_size += addOversize
if task_size < 40
$('#task .task').css('max-width', '40px')
else if task_size < 130
$('#task .task').css('max-width', task_size + 'px')
else
$('#task .task').css('max-width', '130px')
class Remove extends App.ControllerModal
constructor: ->
super
@render()
render: ->
@html App.view('modal')(
title: 'Confirm'
message: 'Tab has changed, you really want to close it?'
close: true
button: 'Close'
)
@modalShow(
backdrop: true,
keyboard: true,
)
submit: (e) =>
@modalHide()
@ui.remove(e, @key, true)
App.Config.set( 'task', App.TaskWidget, 'Widgets' )

View file

@ -0,0 +1,136 @@
class App.TaskbarWidget extends App.Controller
events:
'click [data-type="close"]': 'remove'
constructor: ->
super
@render()
# render on generic ui call
@bind 'ui:rerender', => @render()
# render view
@bind 'task:render', => @render()
# render on login
@bind 'auth:login', => @render()
# reset current tasks on logout
@bind 'auth:logout', => @render()
render: ->
return if _.isEmpty( @Session.all() )
tasks = App.TaskManager.all()
item_list = []
for task in tasks
# collect meta data of task for task bar item
data =
url: '#'
id: false
title: App.i18n.translateInline('Loading...')
head: App.i18n.translateInline('Loading...')
worker = App.TaskManager.worker( task.key )
if worker
meta = worker.meta()
# apply meta data of controller
if meta
for key, value of meta
data[key] = value
# collect new task bar items
item = {}
item.task = task
item.data = data
item_list.push item
# set title
if task.active
@title data.title
@html App.view('task_widget_tasks')(
item_list: item_list
)
dndOptions =
tolerance: 'pointer'
distance: 15
opacity: 0.6
forcePlaceholderSize: true
items: '> a'
update: =>
items = @el.find('> a')
order = []
for item in items
key = $(item).data('key')
if !key
throw "No such key attributes found for task item"
order.push key
App.TaskManager.reorder( order )
@el.sortable( dndOptions )
remove: (e, key = false, force = false) =>
e.preventDefault()
if !key
key = $(e.target).parent().parent().data('key')
if !key
throw "No such key attributes found for task item"
# check if input has changed
worker = App.TaskManager.worker( key )
if !force && worker && worker.changed
if worker.changed()
new Remove(
key: key
ui: @
)
return
# check if active task is closed
currentTask = App.TaskManager.get( key )
tasks = App.TaskManager.all()
active_is_closed = false
for task in tasks
if currentTask.active && task.key is key
active_is_closed = true
# remove task
App.TaskManager.remove( key )
# navigate to next task if needed
tasks = App.TaskManager.all()
if active_is_closed && !_.isEmpty( tasks )
task_last = undefined
for task in tasks
task_last = task
if task_last
worker = App.TaskManager.worker( task_last.key )
if worker
@navigate worker.url()
return
if _.isEmpty( tasks )
@navigate '#'
class Remove extends App.ControllerModal
constructor: ->
super
@render()
render: ->
@html App.view('modal')(
title: 'Confirm'
message: 'Tab has changed, you really want to close it?'
close: true
button: 'Close'
)
@modalShow(
backdrop: true,
keyboard: true,
)
submit: (e) =>
@modalHide()
@ui.remove(e, @key, true)

View file

@ -147,7 +147,7 @@ class _taskManagerSingleton extends App.Controller
# create div for permanent content # create div for permanent content
if !$("#content_permanent")[0] if !$("#content_permanent")[0]
$('#app section').append('<div id="content_permanent" class="content"></div>') $('#app').append('<div id="content_permanent" class="content"></div>')
# empty static content if task is shown # empty static content if task is shown
if active if active

View file

@ -2,22 +2,16 @@
<input id="global-search" class="flex" type="search" autocomplete="off"> <input id="global-search" class="flex" type="search" autocomplete="off">
<div class="logo" title="<%- @C( 'product_name' ) %>"></div> <div class="logo" title="<%- @C( 'product_name' ) %>"></div>
<ul id="global-search-result" class="dropdown-menu" role="menu"> <ul id="global-search-result" class="dropdown-menu" role="menu">
<li class="divider" style="padding: 2px 10px; height: auto; margin: 4px 0px;">Ticket</li> <li class="divider" style="padding: 2px 10px; height: auto; margin: 4px 0px;">Ticket</li>
<li><a href="#ticket/zoom/1" class="ticket-popover" data-id="1" data-original-title="" title="">#10001 - Welcome to Zammad! - 5 d 19 h</a></li> <li><a href="#ticket/zoom/1" class="ticket-popover" data-id="1" data-original-title="" title="">#10001 - Welcome to Zammad! - 5 d 19 h</a></li>
<li class="divider" style="padding: 2px 10px; height: auto; margin: 4px 0px;">User</li> <li class="divider" style="padding: 2px 10px; height: auto; margin: 4px 0px;">User</li>
<li><a href="#user/zoom/2" class="user-popover" data-id="2" data-original-title="" title="">Nicole Braun</a></li> <li><a href="#user/zoom/2" class="user-popover" data-id="2" data-original-title="" title="">Nicole Braun</a></li>
</ul> </ul>
</form> </form>
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li class="dashboard active"><a href="#">Dashboard</a></li>
<% for item in @navbar_left: %> <% for item in @navbar_left: %>
<% if item.child: %> <% if item.child: %>
<li class="dropdown <% if @open_tab[item.target] : %>open<% end %>"> <li class="dropdown <% if @open_tab[item.target] : %>open<% end %>">
@ -35,130 +29,14 @@
</ul> </ul>
</li> </li>
<% else: %> <% else: %>
<li class="overviews <% if @active_tab[item.target] : %>active<% end %>"><a href="<%= item.target %>"><%- @T( item.name ) %></a></li> <li class="<%= item.class %> <% if @active_tab[item.target] : %>active<% end %>"><a href="<%= item.target %>"><%- @T( item.name ) %></a></li>
<% end %> <% end %>
<% end %> <% end %>
<li class="customers"><a href="#">Customers</a></li> <li class="customers"><a href="#to_somewhere">Customers</a></li>
</ul> </ul>
<div class="tasks flex"> <div class="tasks flex"></div>
<div class="task level-1 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Klischee nicht sauber ausgearbeitet</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-2 horizontal center">
<div class="modified priority icon"></div>
<div class="name contain-text flex">Probleme mit Siebdruck</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-3 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Programmfehler</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-2 horizontal center">
<div class="modified priority icon"></div>
<div class="name contain-text flex">Tonerstaub unter Glasplatte</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-1 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Programmfehler</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-1 horizontal center">
<div class="modified priority icon"></div>
<div class="name contain-text flex">Super Service!</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-2 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Probleme mit Siebdruck</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-3 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Programmfehler</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-2 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Tonerstaub unter Glasplatte</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-1 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Programmfehler</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-1 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Super Service!</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-2 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Probleme mit Siebdruck</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-3 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Programmfehler</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-2 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Tonerstaub unter Glasplatte</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-1 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Programmfehler</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
<div class="task level-1 horizontal center">
<div class="priority icon"></div>
<div class="name contain-text flex">Super Service!</div>
<div class="close-task button horizontal centered">
<div class="close-task icon"></div>
</div>
</div>
</div>
<script>
$('.task').click(function(){ $(this).toggleClass('active') })
</script>
<!-- <div class="spinner"></div> --> <!-- <div class="spinner"></div> -->
<% if !_.isEmpty(@user): %> <% if !_.isEmpty(@user): %>

View file

@ -1,3 +1,9 @@
<% for item in @item_list: %> <% for item in @item_list: %>
<a href="<%- item.data.url %>" title="<%= item.data.title %>" class="btn btn-small <% if item.task.active: %>active btn-primary<% else if item.task.notify: %>active btn-warning<% else: %>btn-default<% end %>" data-key="<%- item.task.key %>"><span class="task"><%= item.data.head %></span><span data-type="close" class="glyphicon glyphicon-remove-circle" title="<%- @T('close') %>"></a> <a href="<%- item.data.url %>" title="<%= item.data.title %>" class="task <%= item.data.class %> horizontal center <% if item.task.active: %>active<% end %>" data-key="<%- item.task.key %>">
<% end %> <div class="priority icon <% if item.task.notify: %>modified<% end %>"></div>
<div class="name contain-text flex"><%= item.data.head %></div>
<div class="close-task button horizontal centered">
<div class="close-task icon" title="<%- @T('close') %>" data-type="close"></div>
</div>
</a>
<% end %>