diff --git a/app/assets/javascripts/app/controllers/ticket_overview.js.coffee b/app/assets/javascripts/app/controllers/ticket_overview.js.coffee
index 659721058..de9f03134 100644
--- a/app/assets/javascripts/app/controllers/ticket_overview.js.coffee
+++ b/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
diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee
index e58f439b0..9844ecb52 100644
--- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee
+++ b/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
diff --git a/app/assets/javascripts/app/views/ticket_zoom.jst.eco b/app/assets/javascripts/app/views/ticket_zoom.jst.eco
index ac6160cc8..f37bfa1a9 100644
--- a/app/assets/javascripts/app/views/ticket_zoom.jst.eco
+++ b/app/assets/javascripts/app/views/ticket_zoom.jst.eco
@@ -4,19 +4,7 @@
-
-
-
diff --git a/app/assets/javascripts/app/views/ticket_zoom/overview_navigator.jst.eco b/app/assets/javascripts/app/views/ticket_zoom/overview_navigator.jst.eco
new file mode 100644
index 000000000..684cf91f7
--- /dev/null
+++ b/app/assets/javascripts/app/views/ticket_zoom/overview_navigator.jst.eco
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/app/assets/stylesheets/zammad.css.scss b/app/assets/stylesheets/zammad.css.scss
index a6a9464e5..6fcb98950 100644
--- a/app/assets/stylesheets/zammad.css.scss
+++ b/app/assets/stylesheets/zammad.css.scss
@@ -5079,6 +5079,10 @@ label + .wizard-buttonList {
}
+.overview-navigator {
+ display: inherit;
+}
+
/*
----------------
diff --git a/test/browser/agent_ticket_overview_level0_test.rb b/test/browser/agent_ticket_overview_level0_test.rb
new file mode 100644
index 000000000..e59d536bd
--- /dev/null
+++ b/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
diff --git a/test/browser_test_helper.rb b/test/browser_test_helper.rb
index 82522f43f..35216d0b6 100644
--- a/test/browser_test_helper.rb
+++ b/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