Revert "Revert "Added group by direction feature to Overviews""

This reverts commit d02edbfc3b.
This commit is contained in:
Billy Zhou 2018-07-12 15:18:39 +08:00
parent 2e4b7128f1
commit 09313ed326
9 changed files with 269 additions and 4 deletions

View file

@ -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 = []

View file

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

View file

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

View file

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

View file

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

View file

@ -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() {

View file

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

View file

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

View file

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