Revert "Revert "Added group by direction feature to Overviews""
This reverts commit d02edbfc3b
.
This commit is contained in:
parent
2e4b7128f1
commit
09313ed326
9 changed files with 269 additions and 4 deletions
|
@ -113,6 +113,7 @@ class App.ControllerTable extends App.Controller
|
|||
radio: false
|
||||
renderState: undefined
|
||||
groupBy: undefined
|
||||
groupDirection: undefined
|
||||
|
||||
shownPerPage: 150
|
||||
shownPage: 0
|
||||
|
@ -771,6 +772,9 @@ class App.ControllerTable extends App.Controller
|
|||
for key of groupObjects
|
||||
groupsSorted.push key
|
||||
groupsSorted = groupsSorted.sort()
|
||||
# Reverse the sorted groups depending on the groupDirection
|
||||
if @groupDirection == 'DESC'
|
||||
groupsSorted.reverse()
|
||||
|
||||
# get new order
|
||||
localObjects = []
|
||||
|
|
|
@ -969,6 +969,7 @@ class Table extends App.Controller
|
|||
overviewAttributes: @overview.view.s
|
||||
objects: ticketListShow
|
||||
groupBy: @overview.group_by
|
||||
groupDirection: @overview.group_direction
|
||||
orderBy: @overview.order.by
|
||||
orderDirection: @overview.order.direction
|
||||
)
|
||||
|
@ -1134,6 +1135,7 @@ class Table extends App.Controller
|
|||
objects: ticketListShow
|
||||
checkbox: checkbox
|
||||
groupBy: @overview.group_by
|
||||
groupDirection: @overview.group_direction
|
||||
orderBy: @overview.order.by
|
||||
orderDirection: @overview.order.direction
|
||||
class: 'table--light'
|
||||
|
@ -1529,7 +1531,7 @@ class App.OverviewSettings extends App.ControllerModal
|
|||
},
|
||||
{
|
||||
name: 'order::direction'
|
||||
display: 'Direction'
|
||||
display: 'Order by Direction'
|
||||
tag: 'select'
|
||||
default: @overview.order.direction
|
||||
null: false
|
||||
|
@ -1547,7 +1549,18 @@ class App.OverviewSettings extends App.ControllerModal
|
|||
nulloption: true
|
||||
translate: true
|
||||
options: App.Overview.groupByAttributes()
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'group_direction'
|
||||
display: 'Group by Direction'
|
||||
tag: 'select'
|
||||
default: @overview.group_direction
|
||||
null: false
|
||||
translate: true
|
||||
options:
|
||||
ASC: 'up'
|
||||
DESC: 'down'
|
||||
},)
|
||||
|
||||
controller = new App.ControllerForm(
|
||||
model: { configure_attributes: @configure_attributes_article }
|
||||
|
@ -1572,6 +1585,10 @@ class App.OverviewSettings extends App.ControllerModal
|
|||
@overview.order.direction = params.order.direction
|
||||
@reload_needed = true
|
||||
|
||||
if @overview.group_direction isnt params.group_direction
|
||||
@overview.group_direction = params.group_direction
|
||||
@reload_needed = true
|
||||
|
||||
for key, value of params.view
|
||||
@overview.view[key] = value
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class App.Overview extends App.Model
|
||||
@configure 'Overview', 'name', 'prio', 'condition', 'order', 'group_by', 'view', 'user_ids', 'organization_shared', 'role_ids', 'active'
|
||||
@configure 'Overview', 'name', 'prio', 'condition', 'order', 'group_by', 'group_direction', 'view', 'user_ids', 'organization_shared', 'role_ids', 'active'
|
||||
@extend Spine.Model.Ajax
|
||||
@url: @apiPath + '/overviews'
|
||||
@configure_attributes = [
|
||||
|
@ -29,7 +29,7 @@ class App.Overview extends App.Model
|
|||
},
|
||||
{
|
||||
name: 'order::direction'
|
||||
display: 'Direction'
|
||||
display: 'Order by Direction'
|
||||
tag: 'select'
|
||||
default: 'down'
|
||||
null: false
|
||||
|
@ -53,6 +53,17 @@ class App.Overview extends App.Model
|
|||
group: 'Group'
|
||||
owner: 'Owner'
|
||||
},
|
||||
{
|
||||
name: 'group_direction'
|
||||
display: 'Group by Direction'
|
||||
tag: 'select'
|
||||
default: 'down'
|
||||
null: false
|
||||
translate: true
|
||||
options:
|
||||
ASC: 'up'
|
||||
DESC: 'down'
|
||||
},
|
||||
{ name: 'active', display: 'Active', tag: 'active', default: true },
|
||||
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
|
||||
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
||||
|
|
|
@ -237,6 +237,7 @@ class CreateTicket < ActiveRecord::Migration[4.2]
|
|||
t.column :condition, :text, limit: 500.kilobytes + 1, null: false
|
||||
t.column :order, :string, limit: 2500, null: false
|
||||
t.column :group_by, :string, limit: 250, null: true
|
||||
t.column :group_direction, :string, limit: 250, null: true
|
||||
t.column :organization_shared, :boolean, null: false, default: false
|
||||
t.column :out_of_office, :boolean, null: false, default: false
|
||||
t.column :view, :string, limit: 1000, null: false
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
class AddGroupDirectionToOverviews < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
# return if it's a new setup
|
||||
return if !Setting.find_by(name: 'system_init_done')
|
||||
|
||||
add_column :overviews, :group_direction, :string, limit: 250, null: true
|
||||
end
|
||||
end
|
|
@ -355,6 +355,39 @@ test('table test', function() {
|
|||
el.find('tbody > tr:nth-child(5) > td:nth-child(1) label').click()
|
||||
equal(el.find('tbody > tr:nth-child(5) > td:nth-child(1) input').prop('checked'), true, 'check row 5')
|
||||
equal(el.find('tbody > tr:nth-child(5) > td:nth-child(1) input').val(), '1', 'check row 5')
|
||||
|
||||
|
||||
$('#table').append('<hr><h1>table Group By Direction DESC</h1><div id="table6"></div>')
|
||||
el = $('#table6')
|
||||
var clickCheckbox = function (id, checked, e) {
|
||||
console.log('clickCheckbox', id, checked, e.target)
|
||||
};
|
||||
new App.ControllerTable({
|
||||
el: el,
|
||||
overview: ['number', 'title', 'owner', 'customer', 'priority', 'group', 'state', 'created_at'],
|
||||
model: App.Ticket,
|
||||
objects: App.Ticket.search({sortBy:'created_at', order: 'DESC'}),
|
||||
groupBy: 'priority',
|
||||
groupDirection: 'DESC',
|
||||
})
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:nth-child(1)').text().trim(), '2 normal', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:nth-child(1)').text().trim(), '1 niedrig', 'check row 3')
|
||||
|
||||
$('#table').append('<hr><h1>table Group By Direction ASC</h1><div id="table7"></div>')
|
||||
el = $('#table7')
|
||||
var clickCheckbox = function (id, checked, e) {
|
||||
console.log('clickCheckbox', id, checked, e.target)
|
||||
};
|
||||
new App.ControllerTable({
|
||||
el: el,
|
||||
overview: ['number', 'title', 'owner', 'customer', 'priority', 'group', 'state', 'created_at'],
|
||||
model: App.Ticket,
|
||||
objects: App.Ticket.search({sortBy:'created_at', order: 'DESC'}),
|
||||
groupBy: 'priority',
|
||||
groupDirection: 'ASC',
|
||||
})
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:nth-child(1)').text().trim(), '1 niedrig', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(4) > td:nth-child(1)').text().trim(), '2 normal', 'check row 4')
|
||||
});
|
||||
|
||||
test('table test 2.1', function() {
|
||||
|
|
|
@ -38,4 +38,106 @@ class AdminOverviewTest < TestCase
|
|||
)
|
||||
end
|
||||
|
||||
def test_overview_group_by_direction
|
||||
name = "overview_#{rand(99_999_999)}"
|
||||
ticket_titles = (1..3).map { |i| "Priority #{i} ticket" }
|
||||
|
||||
@browser = instance = browser_instance
|
||||
login(
|
||||
username: 'master@example.com',
|
||||
password: 'test',
|
||||
url: browser_url,
|
||||
)
|
||||
tasks_close_all()
|
||||
|
||||
ticket_create(
|
||||
data: {
|
||||
customer: 'nico',
|
||||
group: 'Users',
|
||||
title: 'Priority 1 ticket',
|
||||
body: 'some body 123äöü',
|
||||
priority: '1 low',
|
||||
},
|
||||
)
|
||||
|
||||
ticket_create(
|
||||
data: {
|
||||
customer: 'nico',
|
||||
group: 'Users',
|
||||
title: 'Priority 2 ticket',
|
||||
body: 'some body 123äöü',
|
||||
priority: '2 normal',
|
||||
},
|
||||
)
|
||||
|
||||
ticket_create(
|
||||
data: {
|
||||
customer: 'nico',
|
||||
group: 'Users',
|
||||
title: 'Priority 3 ticket',
|
||||
body: 'some body 123äöü',
|
||||
priority: '3 high',
|
||||
},
|
||||
)
|
||||
|
||||
# Add new overview to sort groups from high to low
|
||||
overview_create(
|
||||
data: {
|
||||
name: name,
|
||||
roles: ['Agent'],
|
||||
selector: {
|
||||
'State' => 'open',
|
||||
},
|
||||
'order::direction' => 'down',
|
||||
group_by: 'Priority',
|
||||
group_direction: 'down',
|
||||
}
|
||||
)
|
||||
|
||||
click(
|
||||
browser: instance,
|
||||
css: 'a[href="#ticket/view"]',
|
||||
mute_log: true,
|
||||
)
|
||||
click(
|
||||
browser: instance,
|
||||
css: "div.overview-header a[href='#ticket/view/#{name}']",
|
||||
mute_log: true,
|
||||
)
|
||||
|
||||
# Sort the tickets according to their onscreen Y location
|
||||
tickets_low_to_high = ticket_titles.map do |title|
|
||||
[title,
|
||||
get_location( css: "td[title='#{title}']").y]
|
||||
end
|
||||
tickets_low_to_high = tickets_low_to_high.sort_by { |x| -x[1] }.map { |x| x[0] }
|
||||
assert_equal(ticket_titles, tickets_low_to_high)
|
||||
|
||||
# Update overview to sort groups from low to high
|
||||
overview_update(
|
||||
data: {
|
||||
name: name,
|
||||
group_direction: 'up',
|
||||
}
|
||||
)
|
||||
|
||||
click(
|
||||
browser: instance,
|
||||
css: 'a[href="#ticket/view"]',
|
||||
mute_log: true,
|
||||
)
|
||||
click(
|
||||
browser: instance,
|
||||
css: "div.overview-header a[href='#ticket/view/#{name}']",
|
||||
mute_log: true,
|
||||
)
|
||||
|
||||
# Sort the tickets according to their onscreen Y location
|
||||
tickets_high_to_low = ticket_titles.map do |title|
|
||||
[title,
|
||||
get_location( css: "td[title='#{title}']").y]
|
||||
end
|
||||
tickets_high_to_low = tickets_high_to_low.sort_by { |x| x[1] }.map { |x| x[0] }
|
||||
assert_equal(ticket_titles, tickets_high_to_low)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1018,6 +1018,40 @@ class TestCase < Test::Unit::TestCase
|
|||
|
||||
=begin
|
||||
|
||||
Get the on-screen pixel coordinates of a given DOM element. Can be used to compare
|
||||
the relative location of table rows before and after sort, for example.
|
||||
|
||||
Returns a Selenium::WebDriver::Point object. Use result.x and result.y to access
|
||||
its X and Y coordinates respectively.
|
||||
|
||||
get_location(
|
||||
browser: browser1,
|
||||
css: '.some_class',
|
||||
)
|
||||
|
||||
=end
|
||||
|
||||
def get_location(params)
|
||||
switch_window_focus(params)
|
||||
log('exists', params)
|
||||
|
||||
instance = params[:browser] || @browser
|
||||
if params[:css]
|
||||
query = { css: params[:css] }
|
||||
end
|
||||
if params[:xpath]
|
||||
query = { xpath: params[:xpath] }
|
||||
end
|
||||
if !instance.find_elements(query)[0]
|
||||
screenshot(browser: instance, comment: 'exists_failed')
|
||||
raise "#{query} dosn't exist, but should"
|
||||
end
|
||||
|
||||
instance.find_elements(query)[0].location
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
set type of task (closeTab, closeNextInOverview, stayOnTab)
|
||||
|
||||
task_type(
|
||||
|
@ -1735,6 +1769,15 @@ wait untill text in selector disabppears
|
|||
)
|
||||
end
|
||||
|
||||
if data[:group_direction]
|
||||
select(
|
||||
browser: instance,
|
||||
css: '.modal select[name="group_direction"]',
|
||||
value: data[:group_direction],
|
||||
mute_log: true,
|
||||
)
|
||||
end
|
||||
|
||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||
modal_disappear(browser: instance)
|
||||
11.times do
|
||||
|
@ -1839,6 +1882,15 @@ wait untill text in selector disabppears
|
|||
)
|
||||
end
|
||||
|
||||
if data[:group_direction]
|
||||
select(
|
||||
browser: instance,
|
||||
css: '.modal select[name="group_direction"]',
|
||||
value: data[:group_direction],
|
||||
mute_log: true,
|
||||
)
|
||||
end
|
||||
|
||||
instance.find_elements(css: '.modal button.js-submit')[0].click
|
||||
modal_disappear(browser: instance)
|
||||
11.times do
|
||||
|
|
|
@ -181,4 +181,41 @@ class OverviewsControllerTest < ActionDispatch::IntegrationTest
|
|||
assert_equal(1, overview2.prio)
|
||||
end
|
||||
|
||||
test 'create an overview with group_by direction' do
|
||||
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-admin', 'adminpw')
|
||||
|
||||
params = {
|
||||
name: 'Overview2',
|
||||
link: 'my_overview',
|
||||
roles: Role.where(name: 'Agent').pluck(:name),
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
group_by: 'priority',
|
||||
group_direction: 'ASC',
|
||||
view: {
|
||||
d: %w[title customer state created_at],
|
||||
s: %w[number title customer state created_at],
|
||||
m: %w[number title customer state created_at],
|
||||
view_mode_default: 's',
|
||||
},
|
||||
}
|
||||
|
||||
post '/api/v1/overviews', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
|
||||
assert_response(201)
|
||||
result = JSON.parse(@response.body)
|
||||
assert_equal(Hash, result.class)
|
||||
assert_equal('Overview2', result['name'])
|
||||
assert_equal('my_overview', result['link'])
|
||||
assert_equal('priority', result['group_by'])
|
||||
assert_equal('ASC', result['group_direction'])
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue