Fixed issue #1930 - bulk action is not executed for a pending-state.
This commit is contained in:
parent
c0e02c3d89
commit
5b0b10ce59
6 changed files with 339 additions and 59 deletions
|
@ -1162,9 +1162,10 @@ class Table extends App.Controller
|
||||||
# start organization popups
|
# start organization popups
|
||||||
@organizationPopups()
|
@organizationPopups()
|
||||||
|
|
||||||
@bulkForm = new BulkForm
|
@bulkForm = new BulkForm(
|
||||||
holder: @el
|
holder: @el
|
||||||
view: @view
|
view: @view
|
||||||
|
)
|
||||||
|
|
||||||
# start bulk action observ
|
# start bulk action observ
|
||||||
@el.append(@bulkForm.el)
|
@el.append(@bulkForm.el)
|
||||||
|
@ -1226,12 +1227,16 @@ class BulkForm extends App.Controller
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
|
|
||||||
@configure_attributes_ticket = [
|
@configure_attributes_ticket = []
|
||||||
{ name: 'state_id', display: 'State', tag: 'select', multiple: false, null: true, relation: 'TicketState', translate: true, nulloption: true, default: '' },
|
used_attributes = ['state_id', 'pending_time', 'priority_id', 'group_id', 'owner_id']
|
||||||
{ name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: true, relation: 'TicketPriority', translate: true, nulloption: true, default: '' },
|
attributesClean = App.Ticket.attributesGet('edit')
|
||||||
{ name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: true, relation: 'Group', nulloption: true },
|
for attributeName, attribute of attributesClean
|
||||||
{ name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, relation: 'User', nulloption: true }
|
if _.contains(used_attributes, attributeName)
|
||||||
]
|
localAttribute = clone(attribute)
|
||||||
|
localAttribute.nulloption = true
|
||||||
|
localAttribute.default = ''
|
||||||
|
localAttribute.null = true
|
||||||
|
@configure_attributes_ticket.push localAttribute
|
||||||
|
|
||||||
@holder = @options.holder
|
@holder = @options.holder
|
||||||
@visible = false
|
@visible = false
|
||||||
|
@ -1246,9 +1251,9 @@ class BulkForm extends App.Controller
|
||||||
App.TicketCreateCollection.unbind(@bindId)
|
App.TicketCreateCollection.unbind(@bindId)
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
@el.css 'right', App.Utils.getScrollBarWidth()
|
@el.css('right', App.Utils.getScrollBarWidth())
|
||||||
|
|
||||||
@html App.view('agent_ticket_view/bulk')()
|
@html(App.view('agent_ticket_view/bulk')())
|
||||||
|
|
||||||
handlers = @Config.get('TicketZoomFormHandler')
|
handlers = @Config.get('TicketZoomFormHandler')
|
||||||
|
|
||||||
|
@ -1304,12 +1309,15 @@ class BulkForm extends App.Controller
|
||||||
setTimeout ( => @$('.textarea.form-group textarea').focus() ), 0
|
setTimeout ( => @$('.textarea.form-group textarea').focus() ), 0
|
||||||
|
|
||||||
reset: =>
|
reset: =>
|
||||||
@$('.js-action-step').removeClass('hide')
|
@cancel()
|
||||||
@$('.js-confirm-step').addClass('hide')
|
|
||||||
|
|
||||||
if @visible
|
if @visible
|
||||||
@makeSpaceForTableRows()
|
@makeSpaceForTableRows()
|
||||||
|
|
||||||
|
cancel: =>
|
||||||
|
@$('.js-action-step').removeClass('hide')
|
||||||
|
@$('.js-confirm-step').addClass('hide')
|
||||||
|
|
||||||
show: =>
|
show: =>
|
||||||
@el.removeClass('hide')
|
@el.removeClass('hide')
|
||||||
@visible = true
|
@visible = true
|
||||||
|
@ -1325,30 +1333,84 @@ class BulkForm extends App.Controller
|
||||||
scrollParent = @holder.scrollParent()
|
scrollParent = @holder.scrollParent()
|
||||||
isScrolledToBottom = scrollParent.prop('scrollHeight') is scrollParent.scrollTop() + scrollParent.outerHeight()
|
isScrolledToBottom = scrollParent.prop('scrollHeight') is scrollParent.scrollTop() + scrollParent.outerHeight()
|
||||||
|
|
||||||
@holder.css 'margin-bottom', height
|
@holder.css('margin-bottom', height)
|
||||||
|
|
||||||
if isScrolledToBottom
|
if isScrolledToBottom
|
||||||
scrollParent.scrollTop scrollParent.prop('scrollHeight') - scrollParent.outerHeight()
|
scrollParent.scrollTop scrollParent.prop('scrollHeight') - scrollParent.outerHeight()
|
||||||
|
|
||||||
removeSpaceForTableRows: =>
|
removeSpaceForTableRows: =>
|
||||||
@holder.css 'margin-bottom', 0
|
@holder.css('margin-bottom', 0)
|
||||||
|
|
||||||
|
ticketMergeParams: (params) ->
|
||||||
|
ticketUpdate = {}
|
||||||
|
for item of params
|
||||||
|
if params[item] != '' && params[item] != null
|
||||||
|
ticketUpdate[item] = params[item]
|
||||||
|
|
||||||
|
# in case if a group is selected, set also the selected owner (maybe nobody)
|
||||||
|
if params.group_id != '' && params.group_id != null
|
||||||
|
ticketUpdate.owner_id = params.owner_id
|
||||||
|
ticketUpdate
|
||||||
|
|
||||||
submit: (e) =>
|
submit: (e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
@bulk_count = @holder.find('.table-overview').find('[name="bulk"]:checked').length
|
@bulkCount = @holder.find('.table-overview').find('[name="bulk"]:checked').length
|
||||||
@bulk_count_index = 0
|
|
||||||
@holder.find('.table-overview').find('[name="bulk"]:checked').each( (index, element) =>
|
if @bulkCount is 0
|
||||||
@log 'notice', '@bulk_count_index', @bulk_count, @bulk_count_index
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'error'
|
||||||
|
msg: App.i18n.translateContent('At least one object must be selected.')
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
ticket_ids = []
|
||||||
|
@holder.find('.table-overview').find('[name="bulk"]:checked').each( (index, element) ->
|
||||||
ticket_id = $(element).val()
|
ticket_id = $(element).val()
|
||||||
ticket = App.Ticket.find(ticket_id)
|
ticket_ids.push ticket_id
|
||||||
|
)
|
||||||
|
|
||||||
params = @formParam(e.target)
|
params = @formParam(e.target)
|
||||||
|
|
||||||
|
for ticket_id in ticket_ids
|
||||||
|
ticket = App.Ticket.find(ticket_id)
|
||||||
|
|
||||||
|
ticketUpdate = @ticketMergeParams(params)
|
||||||
|
ticket.load(ticketUpdate)
|
||||||
|
|
||||||
|
# if title is empty - ticket can't processed, set ?
|
||||||
|
if _.isEmpty(ticket.title)
|
||||||
|
ticket.title = '-'
|
||||||
|
|
||||||
|
# validate ticket
|
||||||
|
errors = ticket.validate(
|
||||||
|
screen: 'edit'
|
||||||
|
)
|
||||||
|
if errors
|
||||||
|
@log 'error', 'update', errors
|
||||||
|
errorString = ''
|
||||||
|
for key, error of errors
|
||||||
|
errorString += "#{key}: #{error}"
|
||||||
|
|
||||||
|
@formValidate(
|
||||||
|
form: e.target
|
||||||
|
errors: errors
|
||||||
|
screen: 'edit'
|
||||||
|
)
|
||||||
|
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'error'
|
||||||
|
msg: App.i18n.translateContent('Bulk action stopped %s!', errorString)
|
||||||
|
}
|
||||||
|
@cancel()
|
||||||
|
return
|
||||||
|
|
||||||
|
@bulkCountIndex = 0
|
||||||
|
for ticket_id in ticket_ids
|
||||||
|
ticket = App.Ticket.find(ticket_id)
|
||||||
|
|
||||||
# update ticket
|
# update ticket
|
||||||
ticket_update = {}
|
ticketUpdate = @ticketMergeParams(params)
|
||||||
for item of params
|
|
||||||
if params[item] != ''
|
|
||||||
ticket_update[item] = params[item]
|
|
||||||
|
|
||||||
# validate article
|
# validate article
|
||||||
if params['body']
|
if params['body']
|
||||||
|
@ -1372,7 +1434,7 @@ class BulkForm extends App.Controller
|
||||||
@formEnable(e)
|
@formEnable(e)
|
||||||
return
|
return
|
||||||
|
|
||||||
ticket.load(ticket_update)
|
ticket.load(ticketUpdate)
|
||||||
|
|
||||||
# if title is empty - ticket can't processed, set ?
|
# if title is empty - ticket can't processed, set ?
|
||||||
if _.isEmpty(ticket.title)
|
if _.isEmpty(ticket.title)
|
||||||
|
@ -1380,7 +1442,7 @@ class BulkForm extends App.Controller
|
||||||
|
|
||||||
ticket.save(
|
ticket.save(
|
||||||
done: (r) =>
|
done: (r) =>
|
||||||
@bulk_count_index++
|
@bulkCountIndex++
|
||||||
|
|
||||||
# reset form after save
|
# reset form after save
|
||||||
if article
|
if article
|
||||||
|
@ -1390,13 +1452,22 @@ class BulkForm extends App.Controller
|
||||||
)
|
)
|
||||||
|
|
||||||
# refresh view after all tickets are proceeded
|
# refresh view after all tickets are proceeded
|
||||||
if @bulk_count_index == @bulk_count
|
if @bulkCountIndex == @bulkCount
|
||||||
|
@render()
|
||||||
@hide()
|
@hide()
|
||||||
|
|
||||||
# fetch overview data again
|
# fetch overview data again
|
||||||
App.Event.trigger('overview:fetch')
|
App.Event.trigger('overview:fetch')
|
||||||
|
|
||||||
|
fail: (r) =>
|
||||||
|
@bulkCountIndex++
|
||||||
|
@log 'error', 'update ticket', r
|
||||||
|
App.Event.trigger 'notify', {
|
||||||
|
type: 'error'
|
||||||
|
msg: App.i18n.translateContent('Can\'t update Ticket %s!', ticket.number)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
)
|
|
||||||
@holder.find('.table-overview').find('[name="bulk"]:checked').prop('checked', false)
|
@holder.find('.table-overview').find('[name="bulk"]:checked').prop('checked', false)
|
||||||
App.Event.trigger 'notify', {
|
App.Event.trigger 'notify', {
|
||||||
type: 'success'
|
type: 'success'
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
- fix that place method doesn't think that the container is the window, but rather the real window is the window
|
- fix that place method doesn't think that the container is the window, but rather the real window is the window
|
||||||
- added rerender method to show correct today if task is longer open the 24 hours
|
- added rerender method to show correct today if task is longer open the 24 hours
|
||||||
- scroll into view
|
- scroll into view
|
||||||
|
- fix vertical auto position
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function(factory){
|
(function(factory){
|
||||||
|
@ -689,7 +690,9 @@
|
||||||
visualPadding = 10,
|
visualPadding = 10,
|
||||||
container = $(this.o.container),
|
container = $(this.o.container),
|
||||||
windowWidth = $(window).width(),
|
windowWidth = $(window).width(),
|
||||||
scrollTop = container.scrollTop(),
|
scrollTop = container.scrollParent().scrollTop(),
|
||||||
|
bottomEdge = container.offset().top + container.height(),
|
||||||
|
scrollHeight = container.scrollParent().prop('scrollHeight'),
|
||||||
appendOffset = container.offset();
|
appendOffset = container.offset();
|
||||||
|
|
||||||
var parentsZindex = [];
|
var parentsZindex = [];
|
||||||
|
@ -738,10 +741,10 @@
|
||||||
// auto y orientation is best-situation: top or bottom, no fudging,
|
// auto y orientation is best-situation: top or bottom, no fudging,
|
||||||
// decision based on which shows more of the calendar
|
// decision based on which shows more of the calendar
|
||||||
var yorient = this.o.orientation.y,
|
var yorient = this.o.orientation.y,
|
||||||
top_overflow;
|
space_below;
|
||||||
if (yorient === 'auto'){
|
if (yorient === 'auto'){
|
||||||
top_overflow = -scrollTop + top - calendarHeight;
|
space_below = scrollHeight - bottomEdge - scrollTop;
|
||||||
yorient = top_overflow < 0 ? 'bottom' : 'top';
|
yorient = space_below > calendarHeight ? 'bottom' : 'top';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.picker.addClass('datepicker-orient-' + yorient);
|
this.picker.addClass('datepicker-orient-' + yorient);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="u-positionOrigin" data-name="<%= @attribute.nameRaw %>">
|
<div class="control controls--date" data-name="<%= @attribute.nameRaw %>">
|
||||||
<input type="hidden" value="<%= @attribute.value %>" name="<%= @attribute.name %>">
|
<input type="hidden" value="<%= @attribute.value %>" name="<%= @attribute.name %>">
|
||||||
<input type="text" value="" class="form-control js-datepicker <%= @attribute.class %>" data-item="date">
|
<input type="text" value="" class="form-control js-datepicker <%= @attribute.class %>" data-item="date">
|
||||||
</div>
|
</div>
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="horizontal u-positionOrigin" data-name="<%= @attribute.nameRaw %>">
|
<div class="controls controls--datetime" data-name="<%= @attribute.nameRaw %>">
|
||||||
<input type="hidden" value="<%= @attribute.value %>" name="<%= @attribute.name %>">
|
<input type="hidden" value="<%= @attribute.value %>" name="<%= @attribute.name %>">
|
||||||
<input type="text" value="" class="form-control flex-shrink-horizontal js-datepicker <%= @attribute.class %>" data-item="date">
|
<input type="text" value="" class="form-control flex-shrink-horizontal js-datepicker <%= @attribute.class %>" data-item="date">
|
||||||
<div class="controls-label"><%- @T('at') %></div>
|
<div class="controls-label"><%- @T('at') %></div>
|
||||||
|
|
|
@ -1634,6 +1634,15 @@ fieldset > .form-group {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.controls--datetime {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls--date {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.controls-label {
|
.controls-label {
|
||||||
margin: 11px 10px 0;
|
margin: 11px 10px 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
@ -2980,6 +2989,11 @@ footer {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bulkAction-firstStep .has-error {
|
||||||
|
border-color: red !important;
|
||||||
|
border: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
.bulkAction-secondStep {
|
.bulkAction-secondStep {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -4570,6 +4584,11 @@ footer {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
&.datetime {
|
||||||
|
min-width: 140px;
|
||||||
|
overflow: visible; // datepicker popup needs to be visible
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group.is-changed {
|
.form-group.is-changed {
|
||||||
|
@ -4638,17 +4657,46 @@ footer {
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 28px 18px 12px;
|
padding: 28px 5px 12px 20px;
|
||||||
float: none;
|
float: none;
|
||||||
display: block;
|
display: block;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-inline .controls--select {
|
.form-inline {
|
||||||
|
.controls--datetime,
|
||||||
|
.controls--date,
|
||||||
|
.controls--select {
|
||||||
position: static;
|
position: static;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.controls--datetime {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 12px;
|
||||||
|
left: 0;
|
||||||
|
padding: 0 5px 0 20px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.controls-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
width: 70px;
|
||||||
|
line-height: inherit;
|
||||||
|
position: static;
|
||||||
|
padding: 0;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
&.time {
|
||||||
|
margin-left: 5px;
|
||||||
|
width: 38px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bulkAction-secondStep .form-group {
|
.bulkAction-secondStep .form-group {
|
||||||
min-width: 140px;
|
min-width: 140px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
require 'browser_test_helper'
|
require 'browser_test_helper'
|
||||||
|
|
||||||
class AgentTicketOverviewLevel0Test < TestCase
|
class AgentTicketOverviewLevel0Test < TestCase
|
||||||
def test_i
|
def test_bulk_close
|
||||||
@browser = browser_instance
|
@browser = browser_instance
|
||||||
login(
|
login(
|
||||||
username: 'master@example.com',
|
username: 'master@example.com',
|
||||||
|
@ -38,56 +38,63 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
)
|
)
|
||||||
|
|
||||||
click(text: 'Unassigned & Open')
|
click(text: 'Unassigned & Open')
|
||||||
sleep 8 # till overview is rendered
|
watch_for(
|
||||||
|
css: '.content.active',
|
||||||
|
value: 'overview count test #2',
|
||||||
|
)
|
||||||
|
|
||||||
# select both via bulk action
|
# select both via bulk action
|
||||||
click(
|
click(
|
||||||
css: '.active table tr td input[value="' + ticket1[:id] + '"] + .icon-checkbox.icon-unchecked',
|
css: '.content.active table tr td input[value="' + ticket1[:id] + '"] + .icon-checkbox.icon-unchecked',
|
||||||
fast: true,
|
fast: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
# scroll to reply - needed for chrome
|
# scroll to reply - needed for chrome
|
||||||
scroll_to(
|
scroll_to(
|
||||||
position: 'top',
|
position: 'top',
|
||||||
css: '.active table tr td input[value="' + ticket2[:id] + '"] + .icon-checkbox.icon-unchecked',
|
css: '.content.active table tr td input[value="' + ticket2[:id] + '"] + .icon-checkbox.icon-unchecked',
|
||||||
)
|
)
|
||||||
click(
|
click(
|
||||||
css: '.active table tr td input[value="' + ticket2[:id] + '"] + .icon-checkbox.icon-unchecked',
|
css: '.content.active table tr td input[value="' + ticket2[:id] + '"] + .icon-checkbox.icon-unchecked',
|
||||||
fast: true,
|
fast: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
exists(
|
exists(
|
||||||
css: '.active table tr td input[value="' + ticket1[:id] + '"][type="checkbox"]:checked',
|
css: '.content.active table tr td input[value="' + ticket1[:id] + '"][type="checkbox"]:checked',
|
||||||
)
|
)
|
||||||
exists(
|
exists(
|
||||||
css: '.active table tr td input[value="' + ticket2[:id] + '"][type="checkbox"]:checked',
|
css: '.content.active table tr td input[value="' + ticket2[:id] + '"][type="checkbox"]:checked',
|
||||||
)
|
)
|
||||||
|
|
||||||
# select close state & submit
|
# select close state & submit
|
||||||
select(
|
select(
|
||||||
css: '.active .bulkAction [name="state_id"]',
|
css: '.content.active .bulkAction [name="state_id"]',
|
||||||
value: 'closed',
|
value: 'closed',
|
||||||
)
|
)
|
||||||
click(
|
click(
|
||||||
css: '.active .bulkAction .js-confirm',
|
css: '.content.active .bulkAction .js-confirm',
|
||||||
)
|
)
|
||||||
click(
|
click(
|
||||||
css: '.active .bulkAction .js-submit',
|
css: '.content.active .bulkAction .js-submit',
|
||||||
|
)
|
||||||
|
|
||||||
|
watch_for_disappear(
|
||||||
|
css: '.content.active table tr td input[value="' + ticket2[:id] + '"]',
|
||||||
|
timeout: 6,
|
||||||
)
|
)
|
||||||
sleep 6
|
|
||||||
|
|
||||||
exists_not(
|
exists_not(
|
||||||
css: '.active table tr td input[value="' + ticket1[:id] + '"]',
|
css: '.content.active table tr td input[value="' + ticket1[:id] + '"]',
|
||||||
)
|
)
|
||||||
exists_not(
|
exists_not(
|
||||||
css: '.active table tr td input[value="' + ticket2[:id] + '"]',
|
css: '.content.active table tr td input[value="' + ticket2[:id] + '"]',
|
||||||
)
|
)
|
||||||
|
|
||||||
# remember current overview count
|
# remember current overview count
|
||||||
overview_counter_before = overview_counter()
|
overview_counter_before = overview_counter()
|
||||||
|
|
||||||
# click options and enable number and article count
|
# click options and enable number and article count
|
||||||
click(css: '.active [data-type="settings"]')
|
click(css: '.content.active [data-type="settings"]')
|
||||||
|
|
||||||
watch_for(
|
watch_for(
|
||||||
css: '.modal h1',
|
css: '.modal h1',
|
||||||
|
@ -116,15 +123,15 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
|
|
||||||
# check if number and article count is shown
|
# check if number and article count is shown
|
||||||
match(
|
match(
|
||||||
css: '.active table th:nth-child(3)',
|
css: '.content.active table th:nth-child(3)',
|
||||||
value: '#',
|
value: '#',
|
||||||
)
|
)
|
||||||
match(
|
match(
|
||||||
css: '.active table th:nth-child(4)',
|
css: '.content.active table th:nth-child(4)',
|
||||||
value: 'Title',
|
value: 'Title',
|
||||||
)
|
)
|
||||||
match(
|
match(
|
||||||
css: '.active table th:nth-child(7)',
|
css: '.content.active table th:nth-child(7)',
|
||||||
value: 'Article#',
|
value: 'Article#',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -134,20 +141,20 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
|
|
||||||
# check if number and article count is shown
|
# check if number and article count is shown
|
||||||
match(
|
match(
|
||||||
css: '.active table th:nth-child(3)',
|
css: '.content.active table th:nth-child(3)',
|
||||||
value: '#',
|
value: '#',
|
||||||
)
|
)
|
||||||
match(
|
match(
|
||||||
css: '.active table th:nth-child(4)',
|
css: '.content.active table th:nth-child(4)',
|
||||||
value: 'Title',
|
value: 'Title',
|
||||||
)
|
)
|
||||||
match(
|
match(
|
||||||
css: '.active table th:nth-child(7)',
|
css: '.content.active table th:nth-child(7)',
|
||||||
value: 'Article#',
|
value: 'Article#',
|
||||||
)
|
)
|
||||||
|
|
||||||
# disable number and article count
|
# disable number and article count
|
||||||
click(css: '.active [data-type="settings"]')
|
click(css: '.content.active [data-type="settings"]')
|
||||||
|
|
||||||
watch_for(
|
watch_for(
|
||||||
css: '.modal h1',
|
css: '.modal h1',
|
||||||
|
@ -164,15 +171,15 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
|
|
||||||
# check if number and article count is gone
|
# check if number and article count is gone
|
||||||
match_not(
|
match_not(
|
||||||
css: '.active table th:nth-child(3)',
|
css: '.content.active table th:nth-child(3)',
|
||||||
value: '#',
|
value: '#',
|
||||||
)
|
)
|
||||||
match(
|
match(
|
||||||
css: '.active table th:nth-child(3)',
|
css: '.content.active table th:nth-child(3)',
|
||||||
value: 'Title',
|
value: 'Title',
|
||||||
)
|
)
|
||||||
exists_not(
|
exists_not(
|
||||||
css: '.active table th:nth-child(8)',
|
css: '.content.active table th:nth-child(8)',
|
||||||
)
|
)
|
||||||
|
|
||||||
# create new ticket
|
# create new ticket
|
||||||
|
@ -211,4 +218,155 @@ class AgentTicketOverviewLevel0Test < TestCase
|
||||||
# cleanup
|
# cleanup
|
||||||
tasks_close_all()
|
tasks_close_all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_bulk_pending
|
||||||
|
@browser = browser_instance
|
||||||
|
login(
|
||||||
|
username: 'master@example.com',
|
||||||
|
password: 'test',
|
||||||
|
url: browser_url,
|
||||||
|
)
|
||||||
|
tasks_close_all()
|
||||||
|
|
||||||
|
# test bulk action
|
||||||
|
|
||||||
|
# create new ticket
|
||||||
|
ticket1 = ticket_create(
|
||||||
|
data: {
|
||||||
|
customer: 'nico',
|
||||||
|
group: 'Users',
|
||||||
|
title: 'overview count test #3',
|
||||||
|
body: 'overview count test #3',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ticket2 = ticket_create(
|
||||||
|
data: {
|
||||||
|
customer: 'nico',
|
||||||
|
group: 'Users',
|
||||||
|
title: 'overview count test #4',
|
||||||
|
body: 'overview count test #4',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
click(text: 'Overviews')
|
||||||
|
|
||||||
|
# enable full overviews
|
||||||
|
execute(
|
||||||
|
js: '$(".content.active .sidebar").css("display", "block")',
|
||||||
|
)
|
||||||
|
|
||||||
|
click(text: 'Unassigned & Open')
|
||||||
|
watch_for(
|
||||||
|
css: '.content.active',
|
||||||
|
value: 'overview count test #4',
|
||||||
|
timeout: 8,
|
||||||
|
)
|
||||||
|
|
||||||
|
# remember current overview count
|
||||||
|
overview_counter_before = overview_counter()
|
||||||
|
|
||||||
|
# select both via bulk action
|
||||||
|
click(
|
||||||
|
css: '.content.active table tr td input[value="' + ticket1[:id] + '"] + .icon-checkbox.icon-unchecked',
|
||||||
|
fast: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
# scroll to reply - needed for chrome
|
||||||
|
scroll_to(
|
||||||
|
position: 'top',
|
||||||
|
css: '.content.active table tr td input[value="' + ticket2[:id] + '"] + .icon-checkbox.icon-unchecked',
|
||||||
|
)
|
||||||
|
click(
|
||||||
|
css: '.content.active table tr td input[value="' + ticket2[:id] + '"] + .icon-checkbox.icon-unchecked',
|
||||||
|
fast: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
exists(
|
||||||
|
css: '.content.active table tr td input[value="' + ticket1[:id] + '"][type="checkbox"]:checked',
|
||||||
|
)
|
||||||
|
exists(
|
||||||
|
css: '.content.active table tr td input[value="' + ticket2[:id] + '"][type="checkbox"]:checked',
|
||||||
|
)
|
||||||
|
|
||||||
|
exists(
|
||||||
|
displayed: false,
|
||||||
|
css: '.content.active .bulkAction [data-name="pending_time"]',
|
||||||
|
)
|
||||||
|
|
||||||
|
select(
|
||||||
|
css: '.content.active .bulkAction [name="state_id"]',
|
||||||
|
value: 'pending close',
|
||||||
|
)
|
||||||
|
|
||||||
|
exists(
|
||||||
|
displayed: true,
|
||||||
|
css: '.content.active .bulkAction [data-name="pending_time"]',
|
||||||
|
)
|
||||||
|
|
||||||
|
set(
|
||||||
|
css: '.content.active .bulkAction [data-item="date"]',
|
||||||
|
value: '05/23/2088',
|
||||||
|
)
|
||||||
|
|
||||||
|
select(
|
||||||
|
css: '.content.active .bulkAction [name="group_id"]',
|
||||||
|
value: 'Users',
|
||||||
|
)
|
||||||
|
|
||||||
|
select(
|
||||||
|
css: '.content.active .bulkAction [name="owner_id"]',
|
||||||
|
value: 'Test Master Agent',
|
||||||
|
)
|
||||||
|
|
||||||
|
click(
|
||||||
|
css: '.content.active .bulkAction .js-confirm',
|
||||||
|
)
|
||||||
|
click(
|
||||||
|
css: '.content.active .bulkAction .js-submit',
|
||||||
|
)
|
||||||
|
|
||||||
|
watch_for_disappear(
|
||||||
|
css: '.content.active table tr td input[value="' + ticket2[:id] + '"]',
|
||||||
|
timeout: 12,
|
||||||
|
)
|
||||||
|
|
||||||
|
exists_not(
|
||||||
|
css: '.content.active table tr td input[value="' + ticket1[:id] + '"]',
|
||||||
|
)
|
||||||
|
exists_not(
|
||||||
|
css: '.content.active table tr td input[value="' + ticket2[:id] + '"]',
|
||||||
|
)
|
||||||
|
|
||||||
|
# get new overview count
|
||||||
|
overview_counter_new = overview_counter()
|
||||||
|
assert_equal(overview_counter_before['#ticket/view/all_unassigned'] - 2, overview_counter_new['#ticket/view/all_unassigned'])
|
||||||
|
|
||||||
|
# open ticket by search
|
||||||
|
ticket_open_by_search(
|
||||||
|
number: ticket1[:number],
|
||||||
|
)
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# close ticket
|
||||||
|
ticket_update(
|
||||||
|
data: {
|
||||||
|
state: 'closed',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# open ticket by search
|
||||||
|
ticket_open_by_search(
|
||||||
|
number: ticket2[:number],
|
||||||
|
)
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# close ticket
|
||||||
|
ticket_update(
|
||||||
|
data: {
|
||||||
|
state: 'closed',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
tasks_close_all()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue