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

This commit is contained in:
Martin Edenhofer 2015-02-20 14:40:51 +01:00
parent d411eae4ae
commit a56b1d31c6
7 changed files with 314 additions and 37 deletions

View file

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

View file

@ -18,9 +18,16 @@ class App.TicketZoom extends App.Controller
@navupdate '#' @navupdate '#'
@form_meta = undefined @form_meta = undefined
@ticket_id = params.ticket_id @ticket_id = params.ticket_id
@article_id = params.article_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 @key = 'ticket::' + @ticket_id
cache = App.Store.get( @key ) cache = App.Store.get( @key )
@ -71,12 +78,17 @@ class App.TicketZoom extends App.Controller
url: => url: =>
'#ticket/zoom/' + @ticket_id '#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 ) App.OnlineNotification.seen( 'Ticket', @ticket_id )
@navupdate '#' @navupdate '#'
@positionPageHeaderStart() @positionPageHeaderStart()
hide: => hide: =>
@activeState = false
@positionPageHeaderStop() @positionPageHeaderStop()
changed: => changed: =>
@ -235,9 +247,16 @@ class App.TicketZoom extends App.Controller
isCustomer: @isRole('Customer') isCustomer: @isRole('Customer')
) )
new OverviewNavigator(
el: @$('.overview-navigator')
ticket_id: @ticket.id
overview_id: @overview_id
)
new TicketTitle( new TicketTitle(
ticket: @ticket ticket: @ticket
el: @el.find('.ticket-title') overview_id: @overview_id
el: @el.find('.ticket-title')
) )
new TicketMeta( new TicketMeta(
@ -782,6 +801,73 @@ class TicketTitle extends App.Controller
release: => release: =>
App.Ticket.unsubscribe( @subscribeId ) 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 class TicketMeta extends App.Controller
constructor: -> constructor: ->
super super

View file

@ -4,19 +4,7 @@
<div class="scrollPageHeader"> <div class="scrollPageHeader">
<small><%- @C('ticket_hook') %> <span class="ticket-number"><%- @ticket.number %></span></small> <small><%- @C('ticket_hook') %> <span class="ticket-number"><%- @ticket.number %></span></small>
<div class="ticket-title"></div> <div class="ticket-title"></div>
<div class="pagination-counter"> <div class="overview-navigator"></div>
<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> </div>
<div class="page-header horizontal"> <div class="page-header horizontal">
<div class="flex vertical center"> <div class="flex vertical center">
@ -24,24 +12,9 @@
<div class="ticket-title"></div> <div class="ticket-title"></div>
<div class="ticket-meta"></div> <div class="ticket-meta"></div>
</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>
<div class="ticket-article"></div> <div class="ticket-article"></div>
<div class="ticket-edit"></div> <div class="ticket-edit"></div>
</div> </div>
</div> </div>

View file

@ -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>

View file

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

View file

@ -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

View file

@ -336,6 +336,50 @@ class TestCase < Test::Unit::TestCase
assert( true, "(#{test[:name]}) user creation failed" ) assert( true, "(#{test[:name]}) user creation failed" )
return 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' elsif action[:execute] == 'create_signature'
instance.find_elements( { :css => 'a[href="#manage"]' } )[0].click instance.find_elements( { :css => 'a[href="#manage"]' } )[0].click
instance.find_elements( { :css => 'a[href="#channels/email"]' } )[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' elsif action[:execute] == 'verify_task_attributes'
if action[:title] if action[:title]
text = instance.find_elements( { :css => '.tasks .active' } )[0].text.strip text = instance.find_elements( { :css => '.tasks .active' } )[0].text.strip
assert_equal( action[:title], text ) assert_equal( action[:title], text )
end end
return return
elsif action[:execute] == 'verify_ticket_attributes' elsif action[:execute] == 'verify_ticket_attributes'
if action[:title] if action[:title]
text = instance.find_elements( { :css => '.content.active .page-header .ticket-title-update' } )[0].text.strip 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 end
if action[:body] if action[:body]
text = instance.find_elements( { :css => '.content.active [data-name="body"]' } )[0].text.strip text = instance.find_elements( { :css => '.content.active [data-name="body"]' } )[0].text.strip
assert_equal( action[:body], text ) assert_equal( action[:body], text )
end end
return return
elsif action[:execute] == 'set_ticket_attributes' elsif action[:execute] == 'set_ticket_attributes'
@ -463,6 +507,8 @@ class TestCase < Test::Unit::TestCase
element.send_keys( action[:body] ) element.send_keys( action[:body] )
end end
return return
# create ticket
elsif action[:execute] == 'create_ticket' elsif action[:execute] == 'create_ticket'
instance.find_elements( { :css => 'a[href="#new"]' } )[0].click instance.find_elements( { :css => 'a[href="#new"]' } )[0].click
instance.find_elements( { :css => 'a[href="#ticket/create"]' } )[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" ) assert( false, "(#{test[:name]}) ticket creation failed, can't get zoom url" )
return 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' elsif action[:execute] == 'search_user'
element = instance.find_elements( { :css => '#global-search' } )[0] element = instance.find_elements( { :css => '#global-search' } )[0]
element.click element.click
@ -542,6 +640,8 @@ class TestCase < Test::Unit::TestCase
end end
assert( true, "(#{test[:name]}) user #{action[:term]} found" ) assert( true, "(#{test[:name]}) user #{action[:term]} found" )
return return
# search org
elsif action[:execute] == 'search_organization' elsif action[:execute] == 'search_organization'
element = instance.find_elements( { :css => '#global-search' } )[0] element = instance.find_elements( { :css => '#global-search' } )[0]
element.click element.click
@ -574,6 +674,8 @@ class TestCase < Test::Unit::TestCase
end end
assert( true, "(#{test[:name]}) org #{action[:term]} found" ) assert( true, "(#{test[:name]}) org #{action[:term]} found" )
return return
# search ticket
elsif action[:execute] == 'search_ticket' elsif action[:execute] == 'search_ticket'
element = instance.find_elements( { :css => '#global-search' } )[0] element = instance.find_elements( { :css => '#global-search' } )[0]
element.click element.click