Browse Source

Added overview navigation in ticket zoom. Added overview browser tests.

Martin Edenhofer 10 years ago
parent
commit
a56b1d31c6

+ 24 - 0
app/assets/javascripts/app/controllers/ticket_overview.js.coffee

@@ -69,6 +69,10 @@ class App.TicketOverview extends App.Controller
   release: =>
     # no
 
+  overview: (overview_id) =>
+    return if !@contentController
+    @contentController.overview(overview_id)
+
 class Table extends App.Controller
   events:
     'click [data-type=edit]':     'zoom'
@@ -126,7 +130,17 @@ class Table extends App.Controller
         @render()
       )
 
+  overview: (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: ->
+    console.log('RENDER', @cache, @view)
     return if !@cache
     return if !@cache[@view]
 
@@ -204,7 +218,17 @@ class Table extends App.Controller
       @el.find('.table-overview').append(table)
     else
       openTicket = (id,e) =>
+
+        # open ticket via task manager to provide task with overview info
         ticket = App.Ticket.fullLocal(id)
+        App.TaskManager.execute(
+          key:        'Ticket-' + ticket.id
+          controller: 'TicketZoom'
+          params:
+            ticket_id:   ticket.id
+            overview_id: overview.id
+          show:       true
+        )
         @navigate ticket.uiUrl()
       callbackTicketTitleAdd = (value, object, attribute, attributes, refObject) =>
         attribute.title = object.title

+ 92 - 6
app/assets/javascripts/app/controllers/ticket_zoom.js.coffee

@@ -18,9 +18,16 @@ class App.TicketZoom extends App.Controller
 
     @navupdate '#'
 
-    @form_meta  = undefined
-    @ticket_id  = params.ticket_id
-    @article_id = params.article_id
+    @form_meta   = undefined
+    @ticket_id   = params.ticket_id
+    @article_id  = params.article_id
+
+    # if we are in init task startup, ognore overview_dd
+    if !params.init
+      @overview_id = params.overview_id
+    else
+      @overview_id = false
+    console.log('C OVERVIEW_ID', params.overview_id)
 
     @key = 'ticket::' + @ticket_id
     cache = App.Store.get( @key )
@@ -71,12 +78,17 @@ class App.TicketZoom extends App.Controller
   url: =>
     '#ticket/zoom/' + @ticket_id
 
-  show: =>
+  show: (params) =>
+    return if @activeState
+    @activeState = true
+    console.log('S OVERVIEW_ID', params.overview_id)
+
     App.OnlineNotification.seen( 'Ticket', @ticket_id )
     @navupdate '#'
     @positionPageHeaderStart()
 
   hide: =>
+    @activeState = false
     @positionPageHeaderStop()
 
   changed: =>
@@ -235,9 +247,16 @@ class App.TicketZoom extends App.Controller
         isCustomer: @isRole('Customer')
       )
 
+      new OverviewNavigator(
+        el:          @$('.overview-navigator')
+        ticket_id:   @ticket.id
+        overview_id: @overview_id
+      )
+
       new TicketTitle(
-        ticket: @ticket
-        el:     @el.find('.ticket-title')
+        ticket:      @ticket
+        overview_id: @overview_id
+        el:          @el.find('.ticket-title')
       )
 
       new TicketMeta(
@@ -782,6 +801,73 @@ class TicketTitle extends App.Controller
   release: =>
     App.Ticket.unsubscribe( @subscribeId )
 
+class OverviewNavigator extends App.Controller
+  events:
+    'click a': 'open'
+
+  constructor: ->
+    super
+
+    # rebuild overview navigator if overview has changed
+    @bind 'ticket_overview_rebuild', (data) =>
+      execute = =>
+        @render()
+      @delay(execute, 600, 'overview-navigator')
+
+    @render()
+
+  render: (overview) =>
+    console.log('RENDER OverviewNavigator', @overview_id)
+    if !@overview_id
+      @html('')
+      return
+
+    # get overview data
+    worker = App.TaskManager.worker( 'TicketOverview' )
+    return if !worker
+    overview = worker.overview(@overview_id)
+    return if !overview
+    current_position = 0
+    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
+
+    # get next/previous ticket
+    if next
+      next = App.Ticket.find(next)
+    if previous
+      previous = App.Ticket.find(previous)
+
+    @html App.view('ticket_zoom/overview_navigator')(
+      title:            overview.overview.name
+      total_count:      overview.tickets_count
+      current_position: current_position
+      next:             next
+      previous:         previous
+    )
+
+  open: (e) =>
+    e.preventDefault()
+    id  = $(e.target).data('id')
+    url = $(e.target).attr('href')
+    if !id
+      id  = $(e.target).closest('a').data('id')
+      url = $(e.target).closest('a').attr('href')
+    console.log('id', id, 'url', url)
+    App.TaskManager.execute(
+      key:        'Ticket-' + id
+      controller: 'TicketZoom'
+      params:
+        ticket_id:   id
+        overview_id: @overview_id
+      show:       true
+    )
+    @navigate url
+
 class TicketMeta extends App.Controller
   constructor: ->
     super

+ 1 - 28
app/assets/javascripts/app/views/ticket_zoom.jst.eco

@@ -4,19 +4,7 @@
       <div class="scrollPageHeader">
         <small><%- @C('ticket_hook') %> <span class="ticket-number"><%- @ticket.number %></span></small>
         <div class="ticket-title"></div>
-        <div class="pagination-counter">
-          <span class="pagination-item-current">1</span>/<span class="pagination-total-items">36</span>
-        </div>
-        <ul class="pagination">
-          <li>
-            <a class="centered" href="#" data-from="<%= @items_from - @items_per_page %>" data-type="page">
-              <span class="left arrow icon"></span>
-            </a>
-          <li>
-            <a class="centered" href="#" data-from="<%= @items_from + @items_per_page %>" data-type="page">
-              <span class="right arrow icon"></span>
-            </a>
-        </ul>
+        <div class="overview-navigator"></div>
       </div>
       <div class="page-header horizontal">
         <div class="flex vertical center">
@@ -24,24 +12,9 @@
           <div class="ticket-title"></div>
           <div class="ticket-meta"></div>
         </div>
-        <div class="page-header-meta">
-          <% if @C( 'LastOverview' ) && @nav: %>
-            <div class="pull-right">
-              <span class="pagination-count"><%= @C( 'LastOverviewPosition' ) %>/<%= @C( 'LastOverviewTotal' ) %></span>
-              <% base_url ="#ticket/view/#{ @C('LastOverview') }/#{ @C('LastOverviewPosition') }/" %>
-              <ul class="pagination pagination-sm">
-                <li class="<% if @C('LastOverviewPosition') <= 1: %>disabled<% end %>"><a href="<%- base_url %>previous" title="<%- @Ti( 'previous Ticket in Overview' ) %>">«</a></li>
-                <li class="<% if @C('LastOverviewPosition') is @C('LastOverviewTotal'): %>disabled<% end %>"><a href="<%- base_url %>next" title="<%- @Ti( 'next Ticket in Overview' ) %>">»</a></li>
-              </ul>
-            </div>
-          <% end %>
-        </div>
       </div>
-
       <div class="ticket-article"></div>
-
       <div class="ticket-edit"></div>
-
     </div>
   </div>
 

+ 14 - 0
app/assets/javascripts/app/views/ticket_zoom/overview_navigator.jst.eco

@@ -0,0 +1,14 @@
+<div class="pagination-counter" title="<%- @T(@title) %>">
+  <span class="pagination-item-current"><%= @current_position %></span>/<span class="pagination-total-items"><%= @total_count %></span>
+</div>
+<ul class="pagination">
+  <li <% if !@previous: %>class="disabled"<% end %> title="<%- @Ti( 'previous in Overview' ) %>">
+    <a class="centered" href="<% if @previous: %><%- @previous.uiUrl() %><% end %>" data-id="<% if @previous: %><%- @previous.id %><% end %>">
+      <span class="left arrow icon"></span>
+    </a>
+  <li <% if !@next: %>class="disabled"<% end %> title="<%- @Ti( 'next in Overview' ) %>">
+    <a class="centered" href="<% if @next: %><%- @next.uiUrl() %><% end %>" data-id="<% if @next: %><%- @next.id %><% end %>">
+      <span class="right arrow icon"></span>
+    <% if @next: %>
+    </a>
+</ul>

+ 4 - 0
app/assets/stylesheets/zammad.css.scss

@@ -5079,6 +5079,10 @@ label + .wizard-buttonList {
 }
 
 
+.overview-navigator {
+  display: inherit;
+}
+
 /*
 
   ----------------

+ 74 - 0
test/browser/agent_ticket_overview_level0_test.rb

@@ -0,0 +1,74 @@
+# encoding: utf-8
+require 'browser_test_helper'
+
+class AgentTicketOverviewLevel0Test < TestCase
+  def test_I
+    tests = [
+      {
+        :name     => 'verify overview count',
+        :action   => [
+          {
+            :execute => 'close_all_tasks',
+          },
+
+          # remember it ticket count in overview
+          {
+            :execute => 'overview_count_remember',
+          },
+
+          # create new open ticket
+          {
+            :execute => 'create_ticket',
+            :group   => 'Users',
+            :subject => 'some subject 123äöü',
+            :body    => 'some body 123äöü - with closed tab',
+          },
+
+          # remember ticket for later
+          {
+            :execute      => 'match',
+            :css          => '.active .page-header .ticket-number',
+            :value        => '^(.*)$',
+            :no_quote     => true,
+            :match_result => true,
+          },
+          {
+            :execute => 'wait',
+            :value   => 5,
+          },
+
+          # check new ticket count of open tickets in overview
+          {
+            :execute => 'overview_count_verify',
+            :data    => {
+              '#ticket/view/all_unassigned' => 1,
+            },
+          },
+
+          # close ticket
+          {
+            :execute => 'search_ticket',
+            :number  => '###stack###',
+          },
+          {
+            :execute => 'update_ticket',
+            :state   => 'closed',
+          },
+          {
+            :execute => 'wait',
+            :value   => 5,
+          },
+
+          # verify new open tickets in overview
+          {
+            :execute => 'overview_count_verify',
+            :data    => {
+              '#ticket/view/all_unassigned' => 0,
+            },
+          },
+        ],
+      },
+    ]
+    browser_signle_test_with_login(tests, { :username => 'master@example.com' })
+  end
+end

+ 105 - 3
test/browser_test_helper.rb

@@ -336,6 +336,50 @@ class TestCase < Test::Unit::TestCase
       assert( true, "(#{test[:name]}) user creation failed" )
       return
 
+    elsif action[:execute] == 'overview_count_remember'
+      instance.find_elements( { :css => '#navigation li.overviews a' } )[0].click
+      sleep 2
+      overviews = {}
+      instance.find_elements( { :css => '.content.active .sidebar a[href]' } ).each {|element|
+        url = element.attribute('href')
+        url.gsub!(/(http|https):\/\/.+?\/(.+?)$/, "\\2")
+        overviews[url] = 0
+        #puts url.inspect
+        #puts element.inspect
+      }
+      overviews.each {|url, value|
+        count = instance.find_elements( { :css => ".content.active .sidebar a[href=\"#{url}\"] .badge" } )[0].text
+        overviews[url] = count
+      }
+      @overview_count_remember = overviews
+      assert( !overviews.empty?, "(#{test[:name]}) overview_count_remember" )
+      return
+    elsif action[:execute] == 'overview_count_verify'
+      instance.find_elements( { :css => '#navigation li.overviews a' } )[0].click
+      sleep 2
+      overviews = {}
+      instance.find_elements( { :css => '.content.active .sidebar a[href]' } ).each {|element|
+        url = element.attribute('href')
+        url.gsub!(/(http|https):\/\/.+?\/(.+?)$/, "\\2")
+        overviews[url] = 0
+      }
+      overviews.each {|url, value|
+        count = instance.find_elements( { :css => ".content.active .sidebar a[href=\"#{url}\"] .badge" } )[0].text
+        overviews[url] = count
+      }
+      #puts "ov #{overviews.inspect}"
+      #puts "@ov #{@overview_count_remember.inspect}"
+      #puts "data #{action[:data].inspect}"
+      action[:data].each {|url,count|
+        if @overview_count_remember.has_key?(url)
+          count_is     = overviews[url].to_i
+          count_should = @overview_count_remember[url].to_i + count.to_i
+          assert_equal( count_should, count_is, "(#{test[:name]}) expected count of url #{url} is different overview_count_remember" )
+        else
+          assert( false, "(#{test[:name]}) no url #{url} exists in overview_count_remember" )
+        end
+      }
+      return
     elsif action[:execute] == 'create_signature'
       instance.find_elements( { :css => 'a[href="#manage"]' } )[0].click
       instance.find_elements( { :css => 'a[href="#channels/email"]' } )[0].click
@@ -415,17 +459,17 @@ class TestCase < Test::Unit::TestCase
     elsif action[:execute] == 'verify_task_attributes'
       if action[:title]
         text = instance.find_elements( { :css => '.tasks .active' } )[0].text.strip
-        assert_equal( action[:title], text  )
+        assert_equal( action[:title], text )
       end
       return
     elsif action[:execute] == 'verify_ticket_attributes'
       if action[:title]
         text = instance.find_elements( { :css => '.content.active .page-header .ticket-title-update' } )[0].text.strip
-        assert_equal( action[:title], text  )
+        assert_equal( action[:title], text )
       end
       if action[:body]
         text = instance.find_elements( { :css => '.content.active [data-name="body"]' } )[0].text.strip
-        assert_equal( action[:body], text  )
+        assert_equal( action[:body], text )
       end
       return
     elsif action[:execute] == 'set_ticket_attributes'
@@ -463,6 +507,8 @@ class TestCase < Test::Unit::TestCase
         element.send_keys( action[:body] )
       end
       return
+
+    # create ticket
     elsif action[:execute] == 'create_ticket'
       instance.find_elements( { :css => 'a[href="#new"]' } )[0].click
       instance.find_elements( { :css => 'a[href="#ticket/create"]' } )[0].click
@@ -525,6 +571,58 @@ class TestCase < Test::Unit::TestCase
       }
       assert( false, "(#{test[:name]}) ticket creation failed, can't get zoom url" )
       return
+
+    # udpate ticket
+    elsif action[:execute] == 'update_ticket'
+
+      if action[:group]
+        element = instance.find_elements( { :css => '.active .sidebar select[name="group_id"]' } )[0]
+        dropdown = Selenium::WebDriver::Support::Select.new(element)
+        dropdown.select_by( :text, action[:group])
+        sleep 0.2
+      end
+
+      if action[:state]
+        element = instance.find_elements( { :css => '.active .sidebar select[name="state_id"]' } )[0]
+        dropdown = Selenium::WebDriver::Support::Select.new(element)
+        dropdown.select_by( :text, action[:state])
+        sleep 0.2
+      end
+
+      found = nil
+      (1..5).each {|loop|
+        if !found
+          text = instance.find_elements( { :css => '.content.active .js-reset' } )[0].text
+          if text =~ /(Discard your unsaved changes.|Verwerfen der)/
+            assert( true, "(#{test[:name]}) discard message found" )
+            found = true
+          end
+          sleep 1
+        end
+      }
+      if !found
+        assert( false, "(#{test[:name]}) no discard message found" )
+      end
+
+      if action[:do_not_submit]
+        assert( true, "(#{test[:name]}) ticket updated without submit" )
+        return
+      end
+
+      instance.find_elements( { :css => '.content.active button.js-submit' } )[0].click
+
+      (1..10).each {|loop|
+        text = instance.find_elements( { :css => '.content.active .js-reset' } )[0].text
+        if !text || text.empty?
+          assert( true, "(#{test[:name]}) ticket updated" )
+          return
+        end
+        sleep 1
+      }
+      assert( false, "(#{test[:name]}) unable to update ticket" )
+      return
+
+    # search user
     elsif action[:execute] == 'search_user'
       element = instance.find_elements( { :css => '#global-search' } )[0]
       element.click
@@ -542,6 +640,8 @@ class TestCase < Test::Unit::TestCase
       end
       assert( true, "(#{test[:name]}) user #{action[:term]} found" )
       return
+
+    # search org
     elsif action[:execute] == 'search_organization'
       element = instance.find_elements( { :css => '#global-search' } )[0]
       element.click
@@ -574,6 +674,8 @@ class TestCase < Test::Unit::TestCase
       end
       assert( true, "(#{test[:name]}) org #{action[:term]} found" )
       return
+
+    # search ticket
     elsif action[:execute] == 'search_ticket'
       element = instance.find_elements( { :css => '#global-search' } )[0]
       element.click