Fixed issue #1681 - Unable to re-order overviews in admin interface with over 100 overviews.
This commit is contained in:
parent
ce1135a55c
commit
7599e8e17a
12 changed files with 503 additions and 66 deletions
|
@ -148,24 +148,26 @@ class App.ControllerGenericIndex extends App.Controller
|
||||||
return item
|
return item
|
||||||
)
|
)
|
||||||
|
|
||||||
# show description button, only if content exists
|
if !@table
|
||||||
showDescription = false
|
|
||||||
if App[ @genericObject ].description && !_.isEmpty(objects)
|
|
||||||
showDescription = true
|
|
||||||
|
|
||||||
@html App.view('generic/admin/index')(
|
# show description button, only if content exists
|
||||||
head: @pageData.objects
|
showDescription = false
|
||||||
notes: @pageData.notes
|
if App[ @genericObject ].description && !_.isEmpty(objects)
|
||||||
buttons: @pageData.buttons
|
showDescription = true
|
||||||
menus: @pageData.menus
|
|
||||||
showDescription: showDescription
|
|
||||||
)
|
|
||||||
|
|
||||||
# show description in content if no no content exists
|
@html App.view('generic/admin/index')(
|
||||||
if _.isEmpty(objects) && App[ @genericObject ].description
|
head: @pageData.objects
|
||||||
description = marked(App[ @genericObject ].description)
|
notes: @pageData.notes
|
||||||
@$('.table-overview').html(description)
|
buttons: @pageData.buttons
|
||||||
return
|
menus: @pageData.menus
|
||||||
|
showDescription: showDescription
|
||||||
|
)
|
||||||
|
|
||||||
|
# show description in content if no no content exists
|
||||||
|
if _.isEmpty(objects) && App[ @genericObject ].description
|
||||||
|
description = marked(App[ @genericObject ].description)
|
||||||
|
@$('.table-overview').html(description)
|
||||||
|
return
|
||||||
|
|
||||||
# append content table
|
# append content table
|
||||||
params = _.extend(
|
params = _.extend(
|
||||||
|
@ -184,7 +186,10 @@ class App.ControllerGenericIndex extends App.Controller
|
||||||
},
|
},
|
||||||
@pageData.tableExtend
|
@pageData.tableExtend
|
||||||
)
|
)
|
||||||
new App.ControllerTable(params)
|
if !@table
|
||||||
|
@table = new App.ControllerTable(params)
|
||||||
|
else
|
||||||
|
@table.update(objects: objects)
|
||||||
|
|
||||||
edit: (id, e) =>
|
edit: (id, e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
|
@ -23,17 +23,22 @@ class Index extends App.ControllerSubContent
|
||||||
]
|
]
|
||||||
container: @el.closest('.content')
|
container: @el.closest('.content')
|
||||||
large: true
|
large: true
|
||||||
dndCallback: =>
|
dndCallback: (e, item) =>
|
||||||
items = @el.find('table > tbody > tr')
|
items = @el.find('table > tbody > tr')
|
||||||
order = []
|
prios = []
|
||||||
prio = 0
|
prio = 0
|
||||||
for item in items
|
for item in items
|
||||||
prio += 1
|
prio += 1
|
||||||
id = $(item).data('id')
|
id = $(item).data('id')
|
||||||
overview = App.Overview.find(id)
|
prios.push [id, prio]
|
||||||
if overview.prio isnt prio
|
|
||||||
overview.prio = prio
|
@ajax(
|
||||||
overview.save()
|
id: 'overview_prio'
|
||||||
|
type: 'POST'
|
||||||
|
url: "#{@apiPath}/overviews_prio"
|
||||||
|
processData: true
|
||||||
|
data: JSON.stringify(prios: prios)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
App.Config.set('Overview', { prio: 2300, name: 'Overviews', parent: '#manage', target: '#manage/overviews', controller: Index, permission: ['admin.overview'] }, 'NavBarAdmin')
|
App.Config.set('Overview', { prio: 2300, name: 'Overviews', parent: '#manage', target: '#manage/overviews', controller: Index, permission: ['admin.overview'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -387,15 +387,17 @@ set new attributes of model (remove already available attributes)
|
||||||
=>
|
=>
|
||||||
return if _.isEmpty(@SUBSCRIPTION_COLLECTION)
|
return if _.isEmpty(@SUBSCRIPTION_COLLECTION)
|
||||||
App.Log.debug('Model', "server notify collection change #{@className}")
|
App.Log.debug('Model', "server notify collection change #{@className}")
|
||||||
@fetchFull(
|
callback = =>
|
||||||
->
|
@fetchFull(
|
||||||
clear: true
|
->
|
||||||
)
|
clear: true
|
||||||
|
)
|
||||||
|
App.Delay.set(callback, 200, "full-#{@className}")
|
||||||
|
|
||||||
"Collection::Subscribe::#{@className}"
|
"Collection::Subscribe::#{@className}"
|
||||||
)
|
)
|
||||||
|
|
||||||
key = @className + '-' + Math.floor( Math.random() * 99999 )
|
key = "#{@className}-#{Math.floor(Math.random() * 99999)}"
|
||||||
@SUBSCRIPTION_COLLECTION[key] = callback
|
@SUBSCRIPTION_COLLECTION[key] = callback
|
||||||
|
|
||||||
# fetch init collection
|
# fetch init collection
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class App.Overview extends App.Model
|
class App.Overview extends App.Model
|
||||||
@configure 'Overview', 'name', 'prio', 'condition', 'order', 'group_by', 'view', 'user_ids', 'organization_shared', 'role_ids', 'order', 'group_by', 'active', 'updated_at'
|
@configure 'Overview', 'name', 'prio', 'condition', 'order', 'group_by', 'view', 'user_ids', 'organization_shared', 'role_ids', 'active'
|
||||||
@extend Spine.Model.Ajax
|
@extend Spine.Model.Ajax
|
||||||
@url: @apiPath + '/overviews'
|
@url: @apiPath + '/overviews'
|
||||||
@configure_attributes = [
|
@configure_attributes = [
|
||||||
|
|
|
@ -30,7 +30,7 @@ Example:
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Resource:
|
Resource:
|
||||||
GET /api/v1/overviews.json
|
GET /api/v1/overviews
|
||||||
|
|
||||||
Response:
|
Response:
|
||||||
[
|
[
|
||||||
|
@ -47,7 +47,7 @@ Response:
|
||||||
]
|
]
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password}
|
curl http://localhost/api/v1/overviews -v -u #{login}:#{password}
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password}
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Resource:
|
Resource:
|
||||||
GET /api/v1/overviews/#{id}.json
|
GET /api/v1/overviews/#{id}
|
||||||
|
|
||||||
Response:
|
Response:
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ Response:
|
||||||
}
|
}
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/overviews/#{id}.json -v -u #{login}:#{password}
|
curl http://localhost/api/v1/overviews/#{id} -v -u #{login}:#{password}
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ curl http://localhost/api/v1/overviews/#{id}.json -v -u #{login}:#{password}
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Resource:
|
Resource:
|
||||||
POST /api/v1/overviews.json
|
POST /api/v1/overviews
|
||||||
|
|
||||||
Payload:
|
Payload:
|
||||||
{
|
{
|
||||||
|
@ -101,7 +101,7 @@ Response:
|
||||||
}
|
}
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}'
|
curl http://localhost/api/v1/overviews -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}'
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Conte
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Resource:
|
Resource:
|
||||||
PUT /api/v1/overviews/{id}.json
|
PUT /api/v1/overviews/{id}
|
||||||
|
|
||||||
Payload:
|
Payload:
|
||||||
{
|
{
|
||||||
|
@ -134,7 +134,7 @@ Response:
|
||||||
}
|
}
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}'
|
curl http://localhost/api/v1/overviews -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}'
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
|
@ -145,17 +145,55 @@ curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Conte
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
Resource:
|
Resource:
|
||||||
DELETE /api/v1/overviews/{id}.json
|
DELETE /api/v1/overviews/{id}
|
||||||
|
|
||||||
Response:
|
Response:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
curl http://localhost/api/v1/overviews/#{id}.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X DELETE
|
curl http://localhost/api/v1/overviews/#{id} -v -u #{login}:#{password} -H "Content-Type: application/json" -X DELETE
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
model_destroy_render(Overview, params)
|
model_destroy_render(Overview, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
Resource:
|
||||||
|
POST /api/v1/overviews_prio
|
||||||
|
|
||||||
|
Payload:
|
||||||
|
{
|
||||||
|
"prios": [
|
||||||
|
[overview_id, prio],
|
||||||
|
[overview_id, prio],
|
||||||
|
[overview_id, prio],
|
||||||
|
[overview_id, prio],
|
||||||
|
[overview_id, prio]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Response:
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
}
|
||||||
|
|
||||||
|
Test:
|
||||||
|
curl http://localhost/api/v1/overviews_prio -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"prios": [ [1,1], [44,2] ]}'
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def prio
|
||||||
|
Overview.without_callback(:update, :before, :rearrangement) do
|
||||||
|
params[:prios].each do |overview_prio|
|
||||||
|
overview = Overview.find(overview_prio[0])
|
||||||
|
next if overview.prio == overview_prio[1]
|
||||||
|
overview.prio = overview_prio[1]
|
||||||
|
overview.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render json: { success: true }, status: :ok
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -75,12 +75,12 @@ get assets and record_ids of selector
|
||||||
attribute_ref_class = models[attribute_class][:reflections][reflection].klass
|
attribute_ref_class = models[attribute_class][:reflections][reflection].klass
|
||||||
if content['value'].instance_of?(Array)
|
if content['value'].instance_of?(Array)
|
||||||
content['value'].each do |item_id|
|
content['value'].each do |item_id|
|
||||||
attribute_object = attribute_ref_class.find_by(id: item_id)
|
next if item_id.blank?
|
||||||
if attribute_object
|
attribute_object = attribute_ref_class.lookup(id: item_id)
|
||||||
assets = attribute_object.assets(assets)
|
next if !attribute_object
|
||||||
end
|
assets = attribute_object.assets(assets)
|
||||||
end
|
end
|
||||||
else
|
elsif content['value'].present?
|
||||||
attribute_object = attribute_ref_class.find_by(id: content['value'])
|
attribute_object = attribute_ref_class.find_by(id: content['value'])
|
||||||
if attribute_object
|
if attribute_object
|
||||||
assets = attribute_object.assets(assets)
|
assets = attribute_object.assets(assets)
|
||||||
|
@ -138,11 +138,11 @@ get assets of object list
|
||||||
require item['object'].to_filename
|
require item['object'].to_filename
|
||||||
record = Kernel.const_get(item['object']).find(item['o_id'])
|
record = Kernel.const_get(item['object']).find(item['o_id'])
|
||||||
assets = record.assets(assets)
|
assets = record.assets(assets)
|
||||||
if item['created_by_id']
|
if item['created_by_id'].present?
|
||||||
user = User.find(item['created_by_id'])
|
user = User.find(item['created_by_id'])
|
||||||
assets = user.assets(assets)
|
assets = user.assets(assets)
|
||||||
end
|
end
|
||||||
if item['updated_by_id']
|
if item['updated_by_id'].present?
|
||||||
user = User.find(item['updated_by_id'])
|
user = User.find(item['updated_by_id'])
|
||||||
assets = user.assets(assets)
|
assets = user.assets(assets)
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,26 +17,47 @@ class Overview < ApplicationModel
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|
||||||
before_create :fill_link_on_create, :fill_prio
|
before_create :fill_link_on_create, :fill_prio
|
||||||
before_update :fill_link_on_update
|
before_update :fill_link_on_update, :rearrangement
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def rearrangement
|
||||||
|
return true if !changes['prio']
|
||||||
|
prio = 0
|
||||||
|
Overview.all.order(prio: :asc, updated_at: :desc).pluck(:id).each do |overview_id|
|
||||||
|
prio += 1
|
||||||
|
next if id == overview_id
|
||||||
|
Overview.without_callback(:update, :before, :rearrangement) do
|
||||||
|
overview = Overview.find(overview_id)
|
||||||
|
next if overview.prio == prio
|
||||||
|
overview.prio = prio
|
||||||
|
overview.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def fill_prio
|
def fill_prio
|
||||||
return true if prio
|
return true if prio.present?
|
||||||
self.prio = 9999
|
self.prio = Overview.count + 1
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def fill_link_on_create
|
def fill_link_on_create
|
||||||
return true if link.present?
|
self.link = if link.present?
|
||||||
self.link = link_name(name)
|
link_name(link)
|
||||||
|
else
|
||||||
|
link_name(name)
|
||||||
|
end
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def fill_link_on_update
|
def fill_link_on_update
|
||||||
return true if !changes['name']
|
return true if !changes['name'] && !changes['link']
|
||||||
return true if changes['link']
|
self.link = if link.present?
|
||||||
self.link = link_name(name)
|
link_name(link)
|
||||||
|
else
|
||||||
|
link_name(name)
|
||||||
|
end
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -50,12 +71,16 @@ class Overview < ApplicationModel
|
||||||
local_link = id || rand(999)
|
local_link = id || rand(999)
|
||||||
end
|
end
|
||||||
check = true
|
check = true
|
||||||
|
count = 0
|
||||||
|
local_lookup_link = local_link
|
||||||
while check
|
while check
|
||||||
exists = Overview.find_by(link: local_link)
|
count += 1
|
||||||
if exists&.id != id
|
exists = Overview.find_by(link: local_lookup_link)
|
||||||
local_link = "#{local_link}_#{rand(999)}"
|
if exists && exists.id != id # rubocop:disable Style/SafeNavigation
|
||||||
|
local_lookup_link = "#{local_link}_#{count}"
|
||||||
else
|
else
|
||||||
check = false
|
check = false
|
||||||
|
local_link = local_lookup_link
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local_link
|
local_link
|
||||||
|
|
|
@ -40,9 +40,7 @@ returns
|
||||||
next if !user
|
next if !user
|
||||||
data = user.assets(data)
|
data = user.assets(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
data = assets_of_selector('condition', data)
|
data = assets_of_selector('condition', data)
|
||||||
|
|
||||||
end
|
end
|
||||||
%w[created_by_id updated_by_id].each do |local_user_id|
|
%w[created_by_id updated_by_id].each do |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
|
|
|
@ -7,5 +7,6 @@ Zammad::Application.routes.draw do
|
||||||
match api_path + '/overviews', to: 'overviews#create', via: :post
|
match api_path + '/overviews', to: 'overviews#create', via: :post
|
||||||
match api_path + '/overviews/:id', to: 'overviews#update', via: :put
|
match api_path + '/overviews/:id', to: 'overviews#update', via: :put
|
||||||
match api_path + '/overviews/:id', to: 'overviews#destroy', via: :delete
|
match api_path + '/overviews/:id', to: 'overviews#destroy', via: :delete
|
||||||
|
match api_path + '/overviews_prio', to: 'overviews#prio', via: :post
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,8 @@ fill your database with demo records
|
||||||
customers: 1000,
|
customers: 1000,
|
||||||
groups: 20,
|
groups: 20,
|
||||||
organizations: 40,
|
organizations: 40,
|
||||||
tickets: 100
|
overviews: 5,
|
||||||
|
tickets: 100,
|
||||||
)
|
)
|
||||||
|
|
||||||
or if you only want to create 100 tickets
|
or if you only want to create 100 tickets
|
||||||
|
@ -25,6 +26,7 @@ or if you only want to create 100 tickets
|
||||||
customers = params[:customers] || 0
|
customers = params[:customers] || 0
|
||||||
groups = params[:groups] || 0
|
groups = params[:groups] || 0
|
||||||
organizations = params[:organizations] || 0
|
organizations = params[:organizations] || 0
|
||||||
|
overviews = params[:overviews] || 0
|
||||||
tickets = params[:tickets] || 0
|
tickets = params[:tickets] || 0
|
||||||
|
|
||||||
puts 'load db with:'
|
puts 'load db with:'
|
||||||
|
@ -32,6 +34,7 @@ or if you only want to create 100 tickets
|
||||||
puts " customers:#{customers}"
|
puts " customers:#{customers}"
|
||||||
puts " groups:#{groups}"
|
puts " groups:#{groups}"
|
||||||
puts " organizations:#{organizations}"
|
puts " organizations:#{organizations}"
|
||||||
|
puts " overviews:#{overviews}"
|
||||||
puts " tickets:#{tickets}"
|
puts " tickets:#{tickets}"
|
||||||
|
|
||||||
# set current user
|
# set current user
|
||||||
|
@ -39,7 +42,7 @@ or if you only want to create 100 tickets
|
||||||
|
|
||||||
# organizations
|
# organizations
|
||||||
organization_pool = []
|
organization_pool = []
|
||||||
if organizations && !organizations.zero?
|
if !organizations.zero?
|
||||||
(1..organizations).each do
|
(1..organizations).each do
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
organization = Organization.create!(name: "FillOrganization::#{rand(999_999)}", active: true)
|
organization = Organization.create!(name: "FillOrganization::#{rand(999_999)}", active: true)
|
||||||
|
@ -53,7 +56,7 @@ or if you only want to create 100 tickets
|
||||||
|
|
||||||
# create agents
|
# create agents
|
||||||
agent_pool = []
|
agent_pool = []
|
||||||
if agents && !agents.zero?
|
if !agents.zero?
|
||||||
roles = Role.where(name: [ 'Agent'])
|
roles = Role.where(name: [ 'Agent'])
|
||||||
groups_all = Group.all
|
groups_all = Group.all
|
||||||
|
|
||||||
|
@ -81,7 +84,7 @@ or if you only want to create 100 tickets
|
||||||
|
|
||||||
# create customer
|
# create customer
|
||||||
customer_pool = []
|
customer_pool = []
|
||||||
if customers && !customers.zero?
|
if !customers.zero?
|
||||||
roles = Role.where(name: [ 'Customer'])
|
roles = Role.where(name: [ 'Customer'])
|
||||||
groups_all = Group.all
|
groups_all = Group.all
|
||||||
|
|
||||||
|
@ -113,7 +116,7 @@ or if you only want to create 100 tickets
|
||||||
|
|
||||||
# create groups
|
# create groups
|
||||||
group_pool = []
|
group_pool = []
|
||||||
if groups && !groups.zero?
|
if !groups.zero?
|
||||||
|
|
||||||
(1..groups).each do
|
(1..groups).each do
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
|
@ -133,6 +136,35 @@ or if you only want to create 100 tickets
|
||||||
puts " take #{group_pool.length} groups"
|
puts " take #{group_pool.length} groups"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# create overviews
|
||||||
|
if !overviews.zero?
|
||||||
|
(1..overviews).each do
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
overview = Overview.create!(
|
||||||
|
name: "Filloverview::#{rand(999_999)}",
|
||||||
|
role_ids: [Role.find_by(name: 'Agent').id],
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: Ticket::State.by_category(:work_on_all).pluck(:id),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'ASC',
|
||||||
|
},
|
||||||
|
view: {
|
||||||
|
d: %w[title customer group state owner created_at],
|
||||||
|
s: %w[title customer group state owner created_at],
|
||||||
|
m: %w[number title customer group state owner created_at],
|
||||||
|
view_mode_default: 's',
|
||||||
|
},
|
||||||
|
active: true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# create tickets
|
# create tickets
|
||||||
priority_pool = Ticket::Priority.all
|
priority_pool = Ticket::Priority.all
|
||||||
state_pool = Ticket::State.all
|
state_pool = Ticket::State.all
|
||||||
|
|
179
test/controllers/overviews_controller_test.rb
Normal file
179
test/controllers/overviews_controller_test.rb
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class OverviewsControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
setup do
|
||||||
|
|
||||||
|
# set accept header
|
||||||
|
@headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
|
||||||
|
|
||||||
|
# create agent
|
||||||
|
roles = Role.where(name: %w[Admin Agent])
|
||||||
|
groups = Group.all
|
||||||
|
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
@admin = User.create_or_update(
|
||||||
|
login: 'tickets-admin',
|
||||||
|
firstname: 'Tickets',
|
||||||
|
lastname: 'Admin',
|
||||||
|
email: 'tickets-admin@example.com',
|
||||||
|
password: 'adminpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: groups,
|
||||||
|
)
|
||||||
|
|
||||||
|
# create agent
|
||||||
|
roles = Role.where(name: 'Agent')
|
||||||
|
@agent = User.create_or_update(
|
||||||
|
login: 'tickets-agent@example.com',
|
||||||
|
firstname: 'Tickets',
|
||||||
|
lastname: 'Agent',
|
||||||
|
email: 'tickets-agent@example.com',
|
||||||
|
password: 'agentpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: Group.all,
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'no permissions' do
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent', 'agentpw')
|
||||||
|
|
||||||
|
params = {
|
||||||
|
name: 'Overview2',
|
||||||
|
link: 'my_overview',
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: [1, 2, 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
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(401)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
assert_equal('authentication failed', result['error'])
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'create overviews' do
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-admin', 'adminpw')
|
||||||
|
|
||||||
|
params = {
|
||||||
|
name: 'Overview2',
|
||||||
|
link: 'my_overview',
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: [1, 2, 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
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'])
|
||||||
|
|
||||||
|
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_1', result['link'])
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'set mass prio' do
|
||||||
|
overview1 = Overview.create!(
|
||||||
|
name: 'Overview1',
|
||||||
|
link: 'my_overview',
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: [1, 2, 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
prio: 1,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
overview2 = Overview.create!(
|
||||||
|
name: 'Overview2',
|
||||||
|
link: 'my_overview',
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: [1, 2, 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
prio: 2,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-admin', 'adminpw')
|
||||||
|
params = {
|
||||||
|
prios: [
|
||||||
|
[overview2.id, 1],
|
||||||
|
[overview1.id, 2],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
post '/api/v1/overviews_prio', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
assert_equal(true, result['success'])
|
||||||
|
|
||||||
|
overview1.reload
|
||||||
|
overview2.reload
|
||||||
|
|
||||||
|
assert_equal(2, overview1.prio)
|
||||||
|
assert_equal(1, overview2.prio)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -28,7 +28,7 @@ class OverviewTest < ActiveSupport::TestCase
|
||||||
overview.destroy!
|
overview.destroy!
|
||||||
|
|
||||||
overview = Overview.create!(
|
overview = Overview.create!(
|
||||||
name: 'My assigned Tickets',
|
name: 'My assigned Tickets 2',
|
||||||
condition: {
|
condition: {
|
||||||
'ticket.state_id' => {
|
'ticket.state_id' => {
|
||||||
operator: 'is',
|
operator: 'is',
|
||||||
|
@ -46,7 +46,7 @@ class OverviewTest < ActiveSupport::TestCase
|
||||||
view_mode_default: 's',
|
view_mode_default: 's',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
assert_equal(overview.link, 'my_assigned_tickets')
|
assert_equal(overview.link, 'my_assigned_tickets_2')
|
||||||
overview.destroy!
|
overview.destroy!
|
||||||
|
|
||||||
overview = Overview.create!(
|
overview = Overview.create!(
|
||||||
|
@ -210,6 +210,158 @@ class OverviewTest < ActiveSupport::TestCase
|
||||||
assert_equal(overview.link, 'my_overview2')
|
assert_equal(overview.link, 'my_overview2')
|
||||||
|
|
||||||
overview.destroy!
|
overview.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'same url' do
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
|
||||||
|
overview1 = Overview.create!(
|
||||||
|
name: 'My own assigned Tickets',
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: [1, 2, 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert_equal(overview1.link, 'my_own_assigned_tickets')
|
||||||
|
|
||||||
|
overview2 = Overview.create!(
|
||||||
|
name: 'My own assigned Tickets',
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: [1, 2, 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert_equal(overview2.link, 'my_own_assigned_tickets_1')
|
||||||
|
|
||||||
|
overview3 = Overview.create!(
|
||||||
|
name: 'My own assigned Tickets',
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: [1, 2, 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert_equal(overview3.link, 'my_own_assigned_tickets_2')
|
||||||
|
|
||||||
|
overview1.destroy!
|
||||||
|
overview2.destroy!
|
||||||
|
overview3.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'priority rearrangement' do
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
|
||||||
|
overview1 = Overview.create!(
|
||||||
|
name: 'Overview1',
|
||||||
|
link: 'my_overview',
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: [1, 2, 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
prio: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
overview2 = Overview.create!(
|
||||||
|
name: 'Overview2',
|
||||||
|
link: 'my_overview',
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: [1, 2, 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
prio: 2,
|
||||||
|
)
|
||||||
|
|
||||||
|
overview3 = Overview.create!(
|
||||||
|
name: 'Overview3',
|
||||||
|
link: 'my_overview',
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => {
|
||||||
|
operator: 'is',
|
||||||
|
value: [1, 2, 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
by: 'created_at',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
prio: 3,
|
||||||
|
)
|
||||||
|
|
||||||
|
overview2.prio = 3
|
||||||
|
overview2.save!
|
||||||
|
|
||||||
|
overviews = Overview.all.order(prio: :asc).pluck(:id)
|
||||||
|
assert_equal(overview1.id, overviews[0])
|
||||||
|
assert_equal(overview3.id, overviews[1])
|
||||||
|
assert_equal(overview2.id, overviews[2])
|
||||||
|
|
||||||
|
overview1.destroy!
|
||||||
|
overview2.destroy!
|
||||||
|
overview3.destroy!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue