Browse Source

Moved to websockets.

Martin Edenhofer 12 years ago
parent
commit
b2209ff868

+ 3 - 0
Gemfile

@@ -58,3 +58,6 @@ gem 'simple-rss'
 # To use debugger
 # gem 'ruby-debug'
 
+# event machine
+gem 'eventmachine'
+gem 'em-websocket'

+ 29 - 4
app/assets/javascripts/app/controllers/_application_controller.js.coffee

@@ -2,7 +2,8 @@ class App.Controller extends Spine.Controller
   
   # add @title methode to set title
   title: (name) ->
-    $('html head title').html( Config.product_name + ' - ' + Ti(name) )
+#    $('html head title').html( Config.product_name + ' - ' + Ti(name) )
+    document.title = Config.product_name + ' - ' + Ti(name)
 
   # add @notify methode to create notification
   notify: (data) ->
@@ -545,6 +546,13 @@ class App.Controller extends Spine.Controller
   
     return newInstance
 
+  clearInterval: (interval_id) =>
+    # check global var
+    if !@intervalID
+      @intervalID = {}
+
+    clearInterval( @intervalID[interval_id] ) if @intervalID[interval_id]
+
   interval: (action, interval, interval_id) =>
     
     # check global var
@@ -778,11 +786,14 @@ class App.ControllerModal extends App.Controller
     super(options)
 
   modalShow: (params) =>
-    @el.modal({
+    defaults = {
       backdrop: true,
       keyboard: true,
-      show: true
-    })
+      show: true,
+    }
+    data = $.extend({}, defaults, params)
+    @el.modal(data)
+
     @el.bind('hidden', =>
 
       # navigate back to home page
@@ -805,3 +816,17 @@ class App.ControllerModal extends App.Controller
   submit: (e) =>
     e.preventDefault()
     @log 'You need to implement your own "submit" method!'
+
+class App.ErrorModal extends App.ControllerModal
+  constructor: ->
+    super
+    @render()
+
+  render: ->
+    @html App.view('error')(
+      message: @message
+    )
+    @modalShow(
+      backdrop: false,
+      keyboard: false,
+    )

+ 19 - 15
app/assets/javascripts/app/controllers/_dashboard/activity_stream.js.coffee

@@ -9,25 +9,29 @@ class App.DashboardActivityStream extends App.Controller
     @items = []
     
     # refresh list ever 140 sec.
-    @interval( @fetch, 1400000, 'dashboard_activity_stream' )
-    
+#    @interval( @fetch, 1400000, 'dashboard_activity_stream' )
+    @fetch()
+    Spine.bind 'activity_stream_rebuild', (data) =>
+      @log 'a_stream', data
+      @fetch()
+
   fetch: =>
     
     # use cache of first page
-    if window.LastRefresh[ 'dashboard_activity_stream' ]
-      @render( window.LastRefresh[ 'dashboard_activity_stream' ] )
+    if window.LastRefresh[ 'activity_stream' ]
+      @load( window.LastRefresh[ 'activity_stream' ] )
     
-    # get data
-    App.Com.ajax(
-      id:    'dashoard_activity_stream',
-      type:  'GET',
-      url:   '/activity_stream',
-      data:  {
-        limit: @limit,
-      }
-      processData: true,
-      success: @load
-    )
+#    # get data
+#    App.Com.ajax(
+#      id:    'dashoard_activity_stream',
+#      type:  'GET',
+#      url:   '/activity_stream',
+#      data:  {
+#        limit: @limit,
+#      }
+#      processData: true,
+#      success: @load
+#    )
     
   load: (data) =>
     items = data.activity_stream

+ 5 - 23
app/assets/javascripts/app/controllers/_dashboard/rss.js.coffee

@@ -3,36 +3,18 @@ $ = jQuery.sub()
 class App.DashboardRss extends App.Controller
   constructor: ->
     super
-    
-    
-    # refresh list ever 600 sec.
-    @interval( @fetch, 6000000, 'dashboard_rss' )
 
-  fetch: =>
+    # refresh list ever 600 sec.
+    Spine.bind 'rss_rebuild', (data) =>
+      @load(data)
 
     # use cache of first page
     if window.LastRefresh[ 'dashboard_rss' ]
-      @render( window.LastRefresh[ 'dashboard_rss' ] )
-
-    # get data
-    App.Com.ajax(
-      id:    'dashboard_rss',
-      type:  'GET',
-      url:   '/rss_fetch',
-      data:  {
-        limit: @limit,
-        url:   @url,
-      }
-      processData: true,
-      success: @load
-    )
+      @load( window.LastRefresh[ 'dashboard_rss' ] )
 
   load: (data) =>
     items = data.items || []
-    
-    # set cache
-    window.LastRefresh[ 'dashboard_rss' ] = items
-    
+    @head = data.head || '?'
     @render(items)
 
   render: (items) ->

+ 1 - 1
app/assets/javascripts/app/controllers/agent_ticket_view.js.coffee

@@ -271,7 +271,7 @@ class Index extends App.Controller
             @tickets = []
 
             # rebuild navbar with updated ticket count of overviews
-            Spine.trigger 'navupdate_remote'
+            App.WebSocket.send( event: 'navupdate_ticket_overview' )
             
             # fetch overview data again
             @fetch()

+ 6 - 11
app/assets/javascripts/app/controllers/getting_started.js.coffee

@@ -9,13 +9,12 @@ class Index extends App.Controller
 
   constructor: ->
     super
-    
+
     # set title
     @title 'Get Started'
     @navupdate '#get_started'
- 
+
     @master_user = 0
- 
 #    @render()
     @fetch()
 
@@ -43,7 +42,7 @@ class Index extends App.Controller
     )
 
   render: ->
-    
+
     # check authentication, redirect to login if master user already exists
     if !@master_user && !@authenticate()
       @navigate '#login'
@@ -59,7 +58,7 @@ class Index extends App.Controller
   submit: (e) ->
     e.preventDefault()
     @params = @formParam(e.target)
-    
+
     # if no login is given, use emails as fallback
     if !@params.login && @params.email
       @params.login = @params.email
@@ -102,28 +101,24 @@ class Index extends App.Controller
 
           # rerender page    
           @render()
-          
 #      error: =>
 #        @modalHide()
     )
 
-
   relogin: (data, status, xhr) =>
     @log 'login:success', data
 
     # login check
     App.Auth.loginCheck()
-  
+
     # add notify
     Spine.trigger 'notify:removeall'
 #      @notify
 #        type: 'success',
 #        msg: 'Thanks for joining. Email sent to "' + @params.email + '". Please verify your email address.'
-      
+
     @el.find('.master_user').fadeOut('slow', =>
       @el.find('.agent_user').fadeIn()
     )
 
-
-    
 Config.Routes['getting_started'] = Index

+ 15 - 11
app/assets/javascripts/app/controllers/login.js.coffee

@@ -3,7 +3,7 @@ $ = jQuery.sub()
 class Index extends App.Controller
   events:
     'submit #login': 'login',
-    
+
   constructor: ->
     super
     @title 'Sign in'
@@ -37,12 +37,12 @@ class Index extends App.Controller
     for key, provider of auth_provider_all
       if Config[provider.config] is true || Config[provider.config] is "true"
         auth_providers.push provider
-    
+
     @html App.view('login')(
       item:           data,
       auth_providers: auth_providers,
     )
-    
+
     # set focus
     if !$(@el).find('[name="username"]').val()
       $(@el).find('[name="username"]').focus()
@@ -55,17 +55,17 @@ class Index extends App.Controller
   login: (e) ->
     e.preventDefault()
     params = @formParam(e.target)
-    
+
     # remember username
     @username = params['username']
-    
+
     # session create with login/password
     App.Auth.login(
       data:    params,
       success: @success
       error:   @error,
     )
- 
+
   success: (data, status, xhr) =>
     @log 'login:success', data
 
@@ -85,10 +85,14 @@ class Index extends App.Controller
     for key, value of data.default_collections
       App[key].refresh( value, options: { clear: true } )
 
+    # rebuild navbar with user data
     Spine.trigger 'navrebuild', data.session
 
-    # rebuild navbar with updated ticket count of overviews
-    Spine.trigger 'navupdate_remote'
+    # update websocked auth info
+    App.WebSocket.auth()
+
+    # rebuild navbar with ticket overview counter
+    App.WebSocket.send( event: 'navupdate_ticket_overview' )
 
     # add notify
     Spine.trigger 'notify:removeall'
@@ -100,7 +104,7 @@ class Index extends App.Controller
     # redirect to #
     if window.Config['requested_url'] isnt ''
       @navigate window.Config['requested_url']
-      
+
       # reset
       window.Config['requested_url'] = ''
     else
@@ -108,14 +112,14 @@ class Index extends App.Controller
 
   error: (xhr, statusText, error) =>
     console.log 'login:error'
-    
+
     # add notify
     Spine.trigger 'notify:removeall'
     Spine.trigger 'notify', {
       type: 'error',
       msg: T('Wrong Username and Password combination.'), 
     }
-    
+
     # rerender login page
     @render(
       username: @username

+ 3 - 4
app/assets/javascripts/app/controllers/logout.js.coffee

@@ -4,11 +4,10 @@ class Index extends Spine.Controller
 
   constructor: ->
     super
-
     @signout()
-  
+
   signout: ->
-    
+
     # remove remote session
     App.Auth.logout()
 
@@ -17,7 +16,7 @@ class Index extends Spine.Controller
     window.Session = {}
     @log 'Session', window.Session
     Spine.trigger 'navrebuild'
-    
+
     # redirect to login 
     @navigate 'login'
 

+ 85 - 127
app/assets/javascripts/app/controllers/navigation.js.coffee

@@ -5,36 +5,47 @@ class App.Navigation extends App.Controller
     super
     @log 'nav...'
     @render()
-    
-    sync_ticket_overview = =>
-      @interval( @ticket_overview, 30000, 'nav_ticket_overview' )
 
-    sync_recent_viewed = =>
-      @interval( @recent_viewed, 40000, 'nav_recent_viewed' )
-    
+    # update selected item
     Spine.bind 'navupdate', (data) =>
       @update(arguments[0])
-    
+
+    # rebuild nav bar with given user data
     Spine.bind 'navrebuild', (user) =>
       @log 'navbarrebuild', user
       @render(user)
 
-    Spine.bind 'navupdate_remote', (user) =>
-      @log 'navupdate_remote'
-      @delay( sync_ticket_overview, 500 )
-      @delay( sync_recent_viewed, 1000 )
-    
-    # rerender if new overview data is there
-    @delay( sync_ticket_overview, 800 )
-    @delay( sync_recent_viewed, 1000 )
-    
+    # rebuild ticket overview data
+    Spine.bind 'navupdate_ticket_overview', (data) =>
+      @ticket_overview_build(data)
+
+    # rebuild recent viewd data
+    Spine.bind 'update_recent_viewed', (data) =>
+      @recent_viewed_build(data)
+
   render: (user) ->
     nav_left  = @getItems( navbar: Config.NavBar )
     nav_right = @getItems( navbar: Config.NavBarRight )
 
+    # get open tabs to repopen on rerender
+    open_tab = {}
+    @el.find('.open').children('a').each( (i,d) =>
+      href = $(d).attr('href')
+      open_tab[href] = true
+    )
+
+    # get active tabs to reactivate on rerender
+    active_tab = {}
+    @el.find('.active').children('a').each( (i,d) =>
+      href = $(d).attr('href')
+      active_tab[href] = true
+    )
+    
     @html App.view('navigation')(
       navbar_left:  nav_left,
       navbar_right: nav_right,
+      open_tab:     open_tab,
+      active_tab:   active_tab,
       user:         user,
     )
 
@@ -119,118 +130,65 @@ class App.Navigation extends App.Controller
     
   update: (url) =>
     @el.find('li').removeClass('active')
-#    if url isnt '#'
     @el.find("[href=\"#{url}\"]").parents('li').addClass('active')
-#      @el.find("[href*=\"#{url}\"]").parents('li').addClass('active')
 
-  # get data
-  ticket_overview: =>
+  ticket_overview_build: (data) =>
 
-    # do no load and rerender if sub-menu is open
-    open = @el.find('.open').val()
-    if open isnt undefined
-      return
-    
-    # do no load and rerender if user is not logged in
-    if !window.Session['id']
-      return
-
-    # only of lod request is already done
-
-    if !@req_overview
-      @req_overview = App.Com.ajax(
-        id:    'navbar_ticket_overviews',
-        type:  'GET',
-        url:   '/ticket_overviews',
-        data:  {},
-        processData: true,
-        success: (data, status, xhr) =>
-  
-          # remove old views
-          for key of Config.NavBar
-            if Config.NavBar[key].parent is '#ticket/view'
-              delete Config.NavBar[key]
-  
-          # add new views
-          for item in data
-            Config.NavBar['TicketOverview' + item.url] = {
-              prio:   item.prio,
-              parent: '#ticket/view',
-              name:   item.name,
-              count:  item.count,
-              target: '#ticket/view/' + item.url,
-              role:   ['Agent'],
-            }
-  
-          # rebuild navbar
-          Spine.trigger 'navrebuild', window.Session
-
-          # reset ajax call
-          @req_overview = undefined
-      )
-
-  # get data
-  recent_viewed: =>
+    # remove old views
+    for key of Config.NavBar
+      if Config.NavBar[key].parent is '#ticket/view'
+        delete Config.NavBar[key]
 
-    # do no load and rerender if sub-menu is open
-    open = @el.find('.open').val()
-    if open isnt undefined
-      return
-    
-    # do no load and rerender if user is not logged in
-    if !window.Session['id']
-      return
-
-    # only of lod request is already done
-    if !@req_recent_viewed
-      @req_recent_viewed = App.Com.ajax(
-        id:    'navbar_recent_viewed',
-        type:  'GET',
-        url:   '/recent_viewed',
-        data:  {
-          limit: 5,
-        }
-        processData: true,
-        success: (data, status, xhr) =>
-  
-          items = data.recent_viewed
-  
-          # load user collection
-          @loadCollection( type: 'User', data: data.users )
-  
-          # load ticket collection
-          @loadCollection( type: 'Ticket', data: data.tickets )
-  
-          # remove old views
-          for key of Config.NavBarRight
-            if Config.NavBarRight[key].parent is '#current_user'
-              part = Config.NavBarRight[key].target.split '::'
-              if part is 'RecendViewed'
-                delete Config.NavBarRight[key]
-  
-          # add new views
-          prio = 5000
-          for item in items
-            divider   = false
-            navheader = false
-            if prio is 5000
-              divider   = true
-              navheader = 'Recent Viewed'
-            ticket = App.Ticket.find(item.o_id)
-            prio++
-            Config.NavBarRight['RecendViewed::' + ticket.id] = {
-              prio:      prio,
-              parent:    '#current_user',
-              name:      item.history_object.name + ' (' + ticket.title + ')',
-              target:    '#ticket/zoom/' + ticket.id,
-              role:      ['Agent'],
-              divider:   divider,
-              navheader: navheader
-            }
-  
-          # rebuild navbar
-          Spine.trigger 'navrebuild', window.Session
-
-          # reset ajax call
-          @req_recent_viewed = undefined
-      )
+    # add new views
+    for item in data
+      Config.NavBar['TicketOverview' + item.url] = {
+        prio:   item.prio,
+        parent: '#ticket/view',
+        name:   item.name,
+        count:  item.count,
+        target: '#ticket/view/' + item.url,
+        role:   ['Agent'],
+      }
+
+    # rebuild navbar
+    Spine.trigger 'navrebuild', window.Session
+
+  recent_viewed_build: (data) =>
+
+    items = data.recent_viewed
+
+    # load user collection
+    @loadCollection( type: 'User', data: data.users )
+
+    # load ticket collection
+    @loadCollection( type: 'Ticket', data: data.tickets )
+
+    # remove old views
+    for key of Config.NavBarRight
+      if Config.NavBarRight[key].parent is '#current_user'
+        part = key.split '::'
+        if part[0] is 'RecendViewed'
+          delete Config.NavBarRight[key]
+
+    # add new views
+    prio = 8000
+    for item in items
+      divider   = false
+      navheader = false
+      if prio is 8000
+        divider   = true
+        navheader = 'Recent Viewed'
+      ticket = App.Ticket.find(item.o_id)
+      prio++
+      Config.NavBarRight['RecendViewed::' + ticket.id + '-' + prio ] = {
+        prio:      prio,
+        parent:    '#current_user',
+        name:      item.history_object.name + ' (' + ticket.title + ')',
+        target:    '#ticket/zoom/' + ticket.id,
+        role:      ['Agent'],
+        divider:   divider,
+        navheader: navheader
+      }
+
+    # rebuild navbar
+    Spine.trigger 'navrebuild', window.Session

+ 22 - 28
app/assets/javascripts/app/index.js.coffee

@@ -11,6 +11,7 @@
 #= require ./lib/bootstrap-popover.js
 #= require ./lib/bootstrap-modal.js
 #= require ./lib/bootstrap-tab.js
+#= require ./lib/bootstrap-transition.js
 
 #= require ./lib/underscore.coffee
 #= require ./lib/ba-linkify.js
@@ -23,6 +24,7 @@
 #not_used= require_tree ./lib
 #= require_self
 #= require ./lib/ajax.js.coffee
+#= require ./lib/websocket.js.coffee
 #= require ./lib/auth.js.coffee
 #= require ./lib/i18n.js.coffee
 #= require_tree ./models
@@ -57,13 +59,15 @@ Config2.set( 'a', 123)
 console.log '1112222', Config2.get( 'a')
 ###
 
-
 class App.Run extends Spine.Controller
   constructor: ->
     super
-    @log 'RUN app'#, @
+    @log 'RUN app'
     @el = $('#app')
 
+    # create web socket connection
+    App.WebSocket.connect()
+
     # init of i18n
     new App.i18n
 
@@ -84,27 +88,6 @@ class App.Run extends Spine.Controller
       window.Session['UISelection'] = @getSelected() + ''
     )
 
-#    @ws = new WebSocket("ws://localhost:3001/");
-  
-    # Set event handlers.
-#    @ws.onopen = ->
-#      console.log("onopen")
-
-#    @ws.onmessage = (e) ->
-      # e.data contains received string.
-#      console.log("onmessage: " + e.data)
-#      eval e.data
-
-#    Spine.bind 'ws:send', (data) =>
-#      @log 'ws:send', data
-#      @ws.send(data);
-
-#    @ws.onclose = ->
-#      console.log("onclose")
-
-#    @ws.onerror = ->
-#      console.log("onerror")
-      
   getSelected: ->
     text = '';
     if window.getSelection
@@ -125,24 +108,35 @@ class App.Content extends Spine.Controller
     for route, callback of Config.Routes
       do (route, callback) =>
         @route(route, (params) ->
+
+          # remember current controller
           Config['ActiveController'] = route
-          Spine.trigger( 'ws:send', JSON.stringify( { action: 'active_controller', controller: route, params: params } ) )
+
+          # send current controller
+          params_only = {}
+          for i of params
+            if typeof params[i] isnt 'object'
+              params_only[i] = params[i]
+          App.WebSocket.send(
+            action:     'active_controller',
+            controller: route,
+            params:     params_only,
+          )
 
           # unbind in controller area
           @el.unbind()
           @el.undelegate()
- 
+
           # remove waypoints
           $('footer').waypoint('remove')
- 
+
           params.el = @el
-          params.auth = @auth
           new callback( params )
 
           # scroll to top
 #          window.scrollTo(0,0)
         )
 
-    Spine.Route.setup()    
+    Spine.Route.setup()
 
 window.App = App

Some files were not shown because too many files changed in this diff