diff --git a/app/assets/javascripts/app/controllers/_dashboard/ticket.js.coffee b/app/assets/javascripts/app/controllers/_dashboard/ticket.js.coffee index 81d9580cb..cbd90d78b 100644 --- a/app/assets/javascripts/app/controllers/_dashboard/ticket.js.coffee +++ b/app/assets/javascripts/app/controllers/_dashboard/ticket.js.coffee @@ -6,7 +6,6 @@ class App.DashboardTicket extends App.Controller constructor: -> super @start_page = 1 - @navupdate '#' # set new key @key = 'ticket_overview_' + @view diff --git a/app/assets/javascripts/app/controllers/dashboard.js.coffee b/app/assets/javascripts/app/controllers/dashboard.js.coffee index 009b71b1b..0550d6ed4 100644 --- a/app/assets/javascripts/app/controllers/dashboard.js.coffee +++ b/app/assets/javascripts/app/controllers/dashboard.js.coffee @@ -2,7 +2,7 @@ class Index extends App.ControllerContent constructor: -> super - + # check authentication return if !@authenticate() @@ -88,3 +88,5 @@ class Index extends App.ControllerContent @el.find( '#sortable-sidebar' ).sortable( dndOptions ) App.Config.set( 'dashboard', Index, 'Routes' ) +App.Config.set( 'Dashboard', { prio: 100, parent: '', name: 'Dashboard', target: '#dashboard', role: ['Agent'], class: 'dashboard' }, 'NavBar' ) + diff --git a/app/assets/javascripts/app/controllers/navigation.js.coffee b/app/assets/javascripts/app/controllers/navigation.js.coffee index 5c798cdea..3b8ff03ce 100644 --- a/app/assets/javascripts/app/controllers/navigation.js.coffee +++ b/app/assets/javascripts/app/controllers/navigation.js.coffee @@ -1,6 +1,6 @@ class App.Navigation extends App.Controller className: 'navigation flex vertical' - + constructor: -> super @render() @@ -210,6 +210,11 @@ class App.Navigation extends App.Controller @delay( searchFunction, 220, 'search' ) ) + + if !@taskBar + @taskBar = true + new App.TaskbarWidget( el: @el.find('.tasks') ) + getItems: (data) -> navbar = _.values(data.navbar) diff --git a/app/assets/javascripts/app/controllers/task_widget.js.coffee b/app/assets/javascripts/app/controllers/task_widget.js.coffee deleted file mode 100644 index 2a8153d32..000000000 --- a/app/assets/javascripts/app/controllers/task_widget.js.coffee +++ /dev/null @@ -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' ) diff --git a/app/assets/javascripts/app/controllers/taskbar_widget.js.coffee b/app/assets/javascripts/app/controllers/taskbar_widget.js.coffee new file mode 100644 index 000000000..b97041a91 --- /dev/null +++ b/app/assets/javascripts/app/controllers/taskbar_widget.js.coffee @@ -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) diff --git a/app/assets/javascripts/app/controllers/ticket_overview.js.coffee b/app/assets/javascripts/app/controllers/ticket_overview.js.coffee index a8e093367..d826b6c62 100644 --- a/app/assets/javascripts/app/controllers/ticket_overview.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_overview.js.coffee @@ -673,4 +673,4 @@ App.Config.set( 'ticket/view', Index, 'Routes' ) App.Config.set( 'ticket/view/:view', Index, 'Routes' ) #App.Config.set( 'ticket/view/:view/:position/:direction', Router, 'Routes' ) -App.Config.set( 'TicketOverview', { prio: 1000, parent: '', name: 'Overviews', target: '#ticket/view', role: ['Agent', 'Customer'] }, 'NavBar' ) +App.Config.set( 'TicketOverview', { prio: 1000, parent: '', name: 'Overviews', target: '#ticket/view', role: ['Agent', 'Customer'], class: 'overviews' }, 'NavBar' ) diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index dd652b8e8..678557dc4 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -5,8 +5,6 @@ class App.TicketZoom extends App.Controller # check authentication return if !@authenticate() - @navupdate '#' - @edit_form = undefined @ticket_id = params.ticket_id @article_id = params.article_id @@ -41,6 +39,7 @@ class App.TicketZoom extends App.Controller @ticket = App.Ticket.retrieve( @ticket.id ) meta.head = @ticket.title meta.title = '#' + @ticket.number + ' - ' + @ticket.title + meta.class = "level-#{@ticket.priority_id}" meta url: => diff --git a/app/assets/javascripts/app/controllers/user_zoom.js.coffee b/app/assets/javascripts/app/controllers/user_zoom.js.coffee index a23b33403..8b13bdfaa 100644 --- a/app/assets/javascripts/app/controllers/user_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/user_zoom.js.coffee @@ -5,8 +5,6 @@ class App.UserZoom extends App.Controller # check authentication return if !@authenticate() - @navupdate '#' - start = (user) => @user = user @render() @@ -17,6 +15,8 @@ class App.UserZoom extends App.Controller meta = url: @url() id: @user_id + class: "level-1" + if @user meta.head = @user.displayName() meta.title = @user.displayName() diff --git a/app/assets/javascripts/app/controllers/widget/maintenance.js.coffee b/app/assets/javascripts/app/controllers/widget/maintenance.js.coffee index 125a5f127..53aae0fff 100644 --- a/app/assets/javascripts/app/controllers/widget/maintenance.js.coffee +++ b/app/assets/javascripts/app/controllers/widget/maintenance.js.coffee @@ -31,4 +31,4 @@ class Message extends App.ControllerModal forceReload: message.reload ) -App.Config.set( 'maintenance', Widget, 'Widgets' ) +App.Config.set( 'maintenance', Widget, 'Widgets' ) \ No newline at end of file diff --git a/app/assets/javascripts/app/controllers/widget/session_taken_over.js.coffee b/app/assets/javascripts/app/controllers/widget/session_taken_over.js.coffee new file mode 100644 index 000000000..a52156b8d --- /dev/null +++ b/app/assets/javascripts/app/controllers/widget/session_taken_over.js.coffee @@ -0,0 +1,54 @@ +class Widget extends App.Controller + + constructor: -> + super + @bind() + + bind: -> + + # 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() + ) + 'maintenance' + ) + + # 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() + 'maintenance' + ) + +App.Config.set( 'session_taken_over', Widget, 'Widgets' ) \ No newline at end of file diff --git a/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee b/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee index f8cf74c4e..b8092aee0 100644 --- a/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee @@ -147,7 +147,7 @@ class _taskManagerSingleton extends App.Controller # create div for permanent content if !$("#content_permanent")[0] - $('#app section').append('
') + $('#app').append('
') # empty static content if task is shown if active diff --git a/app/assets/javascripts/app/views/navigation.jst.eco b/app/assets/javascripts/app/views/navigation.jst.eco index 7d0dcb21b..b2419848e 100644 --- a/app/assets/javascripts/app/views/navigation.jst.eco +++ b/app/assets/javascripts/app/views/navigation.jst.eco @@ -7,67 +7,9 @@ <% else: %> -
  • <%- @T( item.name ) %>
  • +
  • <%- @T( item.name ) %>
  • <% end %> <% end %> -
  • Customers
  • +
  • Customers
  • -
    -
    -
    -
    Klischee nicht sauber ausgearbeitet
    -
    -
    -
    -
    -
    -
    -
    Probleme mit Siebdruck
    -
    -
    -
    -
    -
    -
    -
    Programmfehler
    -
    -
    -
    -
    -
    -
    -
    Tonerstaub unter Glasplatte
    -
    -
    -
    -
    -
    -
    -
    Programmfehler
    -
    -
    -
    -
    -
    -
    -
    Super Service!
    -
    -
    -
    -
    -
    -
    -
    Probleme mit Siebdruck
    -
    -
    -
    -
    -
    -
    -
    Programmfehler
    -
    -
    -
    -
    -
    -
    -
    Tonerstaub unter Glasplatte
    -
    -
    -
    -
    -
    -
    -
    Programmfehler
    -
    -
    -
    -
    -
    -
    -
    Super Service!
    -
    -
    -
    -
    -
    -
    -
    Probleme mit Siebdruck
    -
    -
    -
    -
    -
    -
    -
    Programmfehler
    -
    -
    -
    -
    -
    -
    -
    Tonerstaub unter Glasplatte
    -
    -
    -
    -
    -
    -
    -
    Programmfehler
    -
    -
    -
    -
    -
    -
    -
    Super Service!
    -
    -
    -
    -
    -
    - - - +
    <% if !_.isEmpty(@user): %>