Fixes #2337 - Zammad stops Organization pagination after 500 entries.
This commit is contained in:
parent
5b4c7ab886
commit
3fd0609f61
30 changed files with 590 additions and 251 deletions
|
@ -138,7 +138,7 @@ class App.ControllerGenericIndex extends App.Controller
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
# fetch all
|
# fetch all
|
||||||
if !@disableInitFetch
|
if !@disableInitFetch && !@pageData.pagerAjax
|
||||||
App[ @genericObject ].fetchFull(
|
App[ @genericObject ].fetchFull(
|
||||||
->
|
->
|
||||||
clear: true
|
clear: true
|
||||||
|
@ -156,12 +156,45 @@ class App.ControllerGenericIndex extends App.Controller
|
||||||
if @subscribeId
|
if @subscribeId
|
||||||
App[ @genericObject ].unsubscribe(@subscribeId)
|
App[ @genericObject ].unsubscribe(@subscribeId)
|
||||||
|
|
||||||
|
paginate: (page) =>
|
||||||
|
return if page is @pageData.pagerSelected
|
||||||
|
@pageData.pagerSelected = page
|
||||||
|
@render()
|
||||||
|
|
||||||
render: =>
|
render: =>
|
||||||
|
if @pageData.pagerAjax
|
||||||
|
sortBy = @table?.customOrderBy || @table?.orderBy || @defaultSortBy || 'id'
|
||||||
|
orderBy = @table?.customOrderDirection || @table?.orderDirection || @defaultOrder || 'ASC'
|
||||||
|
|
||||||
|
fallbackSortBy = sortBy
|
||||||
|
fallbackOrderBy = orderBy
|
||||||
|
if sortBy isnt 'id'
|
||||||
|
fallbackSortBy = "#{sortBy}, id"
|
||||||
|
fallbackOrderBy = "#{orderBy}, ASC"
|
||||||
|
|
||||||
|
@startLoading()
|
||||||
|
App[@genericObject].indexFull(
|
||||||
|
(collection, data) =>
|
||||||
|
@pageData.pagerTotalCount = data.total_count
|
||||||
|
@stopLoading()
|
||||||
|
@renderObjects(collection)
|
||||||
|
{
|
||||||
|
refresh: false
|
||||||
|
sort_by: fallbackSortBy
|
||||||
|
order_by: fallbackOrderBy
|
||||||
|
page: @pageData.pagerSelected
|
||||||
|
per_page: @pageData.pagerPerPage
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
objects = App[@genericObject].search(
|
objects = App[@genericObject].search(
|
||||||
sortBy: @defaultSortBy || 'name'
|
sortBy: @defaultSortBy || 'name'
|
||||||
order: @defaultOrder
|
order: @defaultOrder
|
||||||
)
|
)
|
||||||
|
@renderObjects(objects)
|
||||||
|
|
||||||
|
renderObjects: (objects) =>
|
||||||
|
|
||||||
# remove ignored items from collection
|
# remove ignored items from collection
|
||||||
if @ignoreObjectIDs
|
if @ignoreObjectIDs
|
||||||
|
@ -208,10 +241,24 @@ class App.ControllerGenericIndex extends App.Controller
|
||||||
},
|
},
|
||||||
@pageData.tableExtend
|
@pageData.tableExtend
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if @pageData.pagerAjax
|
||||||
|
params = _.extend(
|
||||||
|
{
|
||||||
|
pagerAjax: @pageData.pagerAjax
|
||||||
|
pagerBaseUrl: @pageData.pagerBaseUrl
|
||||||
|
pagerSelected: @pageData.pagerSelected
|
||||||
|
pagerPerPage: @pageData.pagerPerPage
|
||||||
|
pagerTotalCount: @pageData.pagerTotalCount
|
||||||
|
sortRenderCallback: @render
|
||||||
|
},
|
||||||
|
params
|
||||||
|
)
|
||||||
|
|
||||||
if !@table
|
if !@table
|
||||||
@table = new App.ControllerTable(params)
|
@table = new App.ControllerTable(params)
|
||||||
else
|
else
|
||||||
@table.update(objects: objects)
|
@table.update(objects: objects, pagerSelected: @pageData.pagerSelected, pagerTotalCount: @pageData.pagerTotalCount)
|
||||||
|
|
||||||
edit: (id, e) =>
|
edit: (id, e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
|
@ -196,6 +196,29 @@ class App.ControllerTable extends App.Controller
|
||||||
App.QueueManager.run('tableRender')
|
App.QueueManager.run('tableRender')
|
||||||
|
|
||||||
renderPager: (el, find = false) =>
|
renderPager: (el, find = false) =>
|
||||||
|
if @pagerAjax
|
||||||
|
@renderPagerAjax(el, find)
|
||||||
|
else
|
||||||
|
@renderPagerStatic(el, find)
|
||||||
|
|
||||||
|
renderPagerAjax: (el, find = false) =>
|
||||||
|
pages = parseInt((@pagerTotalCount - 1) / @pagerPerPage)
|
||||||
|
if pages < 1
|
||||||
|
if find
|
||||||
|
el.find('.js-pager').html('')
|
||||||
|
else
|
||||||
|
el.filter('.js-pager').html('')
|
||||||
|
return
|
||||||
|
pager = App.view('generic/table_pager')(
|
||||||
|
page: @pagerSelected - 1
|
||||||
|
pages: pages
|
||||||
|
)
|
||||||
|
if find
|
||||||
|
el.find('.js-pager').html(pager)
|
||||||
|
else
|
||||||
|
el.filter('.js-pager').html(pager)
|
||||||
|
|
||||||
|
renderPagerStatic: (el, find = false) =>
|
||||||
pages = parseInt(((@objects.length - 1) / @shownPerPage))
|
pages = parseInt(((@objects.length - 1) / @shownPerPage))
|
||||||
if pages < 1
|
if pages < 1
|
||||||
if find
|
if find
|
||||||
|
@ -214,6 +237,11 @@ class App.ControllerTable extends App.Controller
|
||||||
|
|
||||||
render: =>
|
render: =>
|
||||||
@setMaxPage()
|
@setMaxPage()
|
||||||
|
|
||||||
|
# always render pager in case of ajax pagination
|
||||||
|
if @pagerTotalCount
|
||||||
|
@renderPager(@el, true)
|
||||||
|
|
||||||
if @renderState is undefined
|
if @renderState is undefined
|
||||||
|
|
||||||
# check if table is empty
|
# check if table is empty
|
||||||
|
@ -451,11 +479,14 @@ class App.ControllerTable extends App.Controller
|
||||||
container.delegate('.js-page', 'click', (e) =>
|
container.delegate('.js-page', 'click', (e) =>
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
page = $(e.currentTarget).attr 'data-page'
|
page = $(e.currentTarget).attr 'data-page'
|
||||||
render = =>
|
if @pagerAjax
|
||||||
@shownPage = page
|
@navigate "#{@pagerBaseUrl}#{(parseInt(page) + 1)}"
|
||||||
@renderTableFull()
|
else
|
||||||
App.QueueManager.add('tableRender', render)
|
render = =>
|
||||||
App.QueueManager.run('tableRender')
|
@shownPage = page
|
||||||
|
@renderTableFull()
|
||||||
|
App.QueueManager.add('tableRender', render)
|
||||||
|
App.QueueManager.run('tableRender')
|
||||||
)
|
)
|
||||||
|
|
||||||
@el.html(container)
|
@el.html(container)
|
||||||
|
@ -660,6 +691,19 @@ class App.ControllerTable extends App.Controller
|
||||||
@lastOrderDirection = orderDirection
|
@lastOrderDirection = orderDirection
|
||||||
@lastOrderBy = orderBy
|
@lastOrderBy = orderBy
|
||||||
|
|
||||||
|
# sorting for ajax pagination will be made in the backend
|
||||||
|
# so we only set the arrow for the sort direction
|
||||||
|
if @pagerAjax
|
||||||
|
for header in @headers
|
||||||
|
if header.name is orderBy || "#{header.name}_id" is orderBy || header.name is "#{orderBy}_id"
|
||||||
|
if orderDirection is 'DESC'
|
||||||
|
header.sortOrderIcon = ['arrow-down', 'table-sort-arrow']
|
||||||
|
else
|
||||||
|
header.sortOrderIcon = ['arrow-up', 'table-sort-arrow']
|
||||||
|
else
|
||||||
|
header.sortOrderIcon = undefined
|
||||||
|
return
|
||||||
|
|
||||||
# Underscore's sortBy cannot deal with null values, so we replace null values with a place holder string
|
# Underscore's sortBy cannot deal with null values, so we replace null values with a place holder string
|
||||||
sortBy = (list, iteratee) ->
|
sortBy = (list, iteratee) ->
|
||||||
_.sortBy(
|
_.sortBy(
|
||||||
|
@ -964,6 +1008,10 @@ class App.ControllerTable extends App.Controller
|
||||||
sortByColumn: (event) =>
|
sortByColumn: (event) =>
|
||||||
column = $(event.currentTarget).closest('[data-column-key]').attr('data-column-key')
|
column = $(event.currentTarget).closest('[data-column-key]').attr('data-column-key')
|
||||||
|
|
||||||
|
# for ajax pagination we only accept valid attributes for sorting
|
||||||
|
if @model && @pagerAjax
|
||||||
|
return if !@attributesList[column]
|
||||||
|
|
||||||
orderBy = @customOrderBy || @orderBy
|
orderBy = @customOrderBy || @orderBy
|
||||||
orderDirection = @customOrderDirection || @orderDirection
|
orderDirection = @customOrderDirection || @orderDirection
|
||||||
|
|
||||||
|
@ -988,6 +1036,10 @@ class App.ControllerTable extends App.Controller
|
||||||
render = =>
|
render = =>
|
||||||
@renderTableFull(false, skipHeadersResize: true)
|
@renderTableFull(false, skipHeadersResize: true)
|
||||||
App.QueueManager.add('tableRender', render)
|
App.QueueManager.add('tableRender', render)
|
||||||
|
|
||||||
|
if @sortRenderCallback
|
||||||
|
App.QueueManager.add('tableRender', @sortRenderCallback)
|
||||||
|
|
||||||
App.QueueManager.run('tableRender')
|
App.QueueManager.run('tableRender')
|
||||||
|
|
||||||
preferencesStore: (type, key, value) ->
|
preferencesStore: (type, key, value) ->
|
||||||
|
|
|
@ -8,10 +8,15 @@ class Index extends App.ControllerSubContent
|
||||||
el: @el
|
el: @el
|
||||||
id: @id
|
id: @id
|
||||||
genericObject: 'Group'
|
genericObject: 'Group'
|
||||||
|
defaultSortBy: 'name'
|
||||||
pageData:
|
pageData:
|
||||||
home: 'groups'
|
home: 'groups'
|
||||||
object: 'Group'
|
object: 'Group'
|
||||||
objects: 'Groups'
|
objects: 'Groups'
|
||||||
|
pagerAjax: true
|
||||||
|
pagerBaseUrl: '#manage/groups/'
|
||||||
|
pagerSelected: ( @page || 1 )
|
||||||
|
pagerPerPage: 150
|
||||||
navupdate: '#groups'
|
navupdate: '#groups'
|
||||||
notes: [
|
notes: [
|
||||||
'Groups are ...'
|
'Groups are ...'
|
||||||
|
@ -22,4 +27,11 @@ class Index extends App.ControllerSubContent
|
||||||
container: @el.closest('.content')
|
container: @el.closest('.content')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
show: (params) =>
|
||||||
|
for key, value of params
|
||||||
|
if key isnt 'el' && key isnt 'shown' && key isnt 'match'
|
||||||
|
@[key] = value
|
||||||
|
|
||||||
|
@genericController.paginate( @page || 1 )
|
||||||
|
|
||||||
App.Config.set('Group', { prio: 1500, name: 'Groups', parent: '#manage', target: '#manage/groups', controller: Index, permission: ['admin.group'] }, 'NavBarAdmin')
|
App.Config.set('Group', { prio: 1500, name: 'Groups', parent: '#manage', target: '#manage/groups', controller: Index, permission: ['admin.group'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -13,6 +13,10 @@ class Index extends App.ControllerSubContent
|
||||||
home: 'Jobs'
|
home: 'Jobs'
|
||||||
object: 'Scheduler'
|
object: 'Scheduler'
|
||||||
objects: 'Schedulers'
|
objects: 'Schedulers'
|
||||||
|
pagerAjax: true
|
||||||
|
pagerBaseUrl: '#manage/job/'
|
||||||
|
pagerSelected: ( @page || 1 )
|
||||||
|
pagerPerPage: 150
|
||||||
navupdate: '#Jobs'
|
navupdate: '#Jobs'
|
||||||
notes: [
|
notes: [
|
||||||
'Scheduler are ...'
|
'Scheduler are ...'
|
||||||
|
@ -24,4 +28,11 @@ class Index extends App.ControllerSubContent
|
||||||
large: true
|
large: true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
show: (params) =>
|
||||||
|
for key, value of params
|
||||||
|
if key isnt 'el' && key isnt 'shown' && key isnt 'match'
|
||||||
|
@[key] = value
|
||||||
|
|
||||||
|
@genericController.paginate( @page || 1 )
|
||||||
|
|
||||||
App.Config.set('Job', { prio: 3400, name: 'Scheduler', parent: '#manage', target: '#manage/job', controller: Index, permission: ['admin.scheduler'] }, 'NavBarAdmin')
|
App.Config.set('Job', { prio: 3400, name: 'Scheduler', parent: '#manage', target: '#manage/job', controller: Index, permission: ['admin.scheduler'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -8,10 +8,15 @@ class Index extends App.ControllerSubContent
|
||||||
el: @el
|
el: @el
|
||||||
id: @id
|
id: @id
|
||||||
genericObject: 'Macro'
|
genericObject: 'Macro'
|
||||||
|
defaultSortBy: 'name'
|
||||||
pageData:
|
pageData:
|
||||||
home: 'macros'
|
home: 'macros'
|
||||||
object: 'Macro'
|
object: 'Macro'
|
||||||
objects: 'Macros'
|
objects: 'Macros'
|
||||||
|
pagerAjax: true
|
||||||
|
pagerBaseUrl: '#manage/macros/'
|
||||||
|
pagerSelected: ( @page || 1 )
|
||||||
|
pagerPerPage: 150
|
||||||
navupdate: '#macros'
|
navupdate: '#macros'
|
||||||
notes: [
|
notes: [
|
||||||
'Text modules are ...'
|
'Text modules are ...'
|
||||||
|
@ -22,4 +27,11 @@ class Index extends App.ControllerSubContent
|
||||||
container: @el.closest('.content')
|
container: @el.closest('.content')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
show: (params) =>
|
||||||
|
for key, value of params
|
||||||
|
if key isnt 'el' && key isnt 'shown' && key isnt 'match'
|
||||||
|
@[key] = value
|
||||||
|
|
||||||
|
@genericController.paginate( @page || 1 )
|
||||||
|
|
||||||
App.Config.set('Macros', { prio: 2310, name: 'Macros', parent: '#manage', target: '#manage/macros', controller: Index, permission: ['admin.macro'] }, 'NavBarAdmin')
|
App.Config.set('Macros', { prio: 2310, name: 'Macros', parent: '#manage', target: '#manage/macros', controller: Index, permission: ['admin.macro'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -21,6 +21,7 @@ class ManageRouter extends App.ControllerPermanent
|
||||||
|
|
||||||
App.Config.set('manage', ManageRouter, 'Routes')
|
App.Config.set('manage', ManageRouter, 'Routes')
|
||||||
App.Config.set('manage/:target', ManageRouter, 'Routes')
|
App.Config.set('manage/:target', ManageRouter, 'Routes')
|
||||||
|
App.Config.set('manage/:target/:page', ManageRouter, 'Routes')
|
||||||
App.Config.set('settings/:target', ManageRouter, 'Routes')
|
App.Config.set('settings/:target', ManageRouter, 'Routes')
|
||||||
App.Config.set('channels/:target', ManageRouter, 'Routes')
|
App.Config.set('channels/:target', ManageRouter, 'Routes')
|
||||||
App.Config.set('channels/:target/:channel_id', ManageRouter, 'Routes')
|
App.Config.set('channels/:target/:channel_id', ManageRouter, 'Routes')
|
||||||
|
|
|
@ -13,10 +13,15 @@ class Index extends App.ControllerSubContent
|
||||||
baseUrl: '/api/v1/organizations'
|
baseUrl: '/api/v1/organizations'
|
||||||
container: @el.closest('.content')
|
container: @el.closest('.content')
|
||||||
)
|
)
|
||||||
|
defaultSortBy: 'name'
|
||||||
pageData:
|
pageData:
|
||||||
home: 'organizations'
|
home: 'organizations'
|
||||||
object: 'Organization'
|
object: 'Organization'
|
||||||
objects: 'Organizations'
|
objects: 'Organizations'
|
||||||
|
pagerAjax: true
|
||||||
|
pagerBaseUrl: '#manage/organizations/'
|
||||||
|
pagerSelected: ( @page || 1 )
|
||||||
|
pagerPerPage: 150
|
||||||
navupdate: '#organizations'
|
navupdate: '#organizations'
|
||||||
notes: [
|
notes: [
|
||||||
'Organizations are for any person in the system. Agents (Owners, Resposbiles, ...) and Customers.'
|
'Organizations are for any person in the system. Agents (Owners, Resposbiles, ...) and Customers.'
|
||||||
|
@ -28,4 +33,12 @@ class Index extends App.ControllerSubContent
|
||||||
container: @el.closest('.content')
|
container: @el.closest('.content')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
show: (params) =>
|
||||||
|
for key, value of params
|
||||||
|
if key isnt 'el' && key isnt 'shown' && key isnt 'match'
|
||||||
|
@[key] = value
|
||||||
|
|
||||||
|
@genericController.paginate( @page || 1 )
|
||||||
|
|
||||||
|
|
||||||
App.Config.set('Organization', { prio: 2000, name: 'Organizations', parent: '#manage', target: '#manage/organizations', controller: Index, permission: ['admin.organization'] }, 'NavBarAdmin')
|
App.Config.set('Organization', { prio: 2000, name: 'Organizations', parent: '#manage', target: '#manage/organizations', controller: Index, permission: ['admin.organization'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -8,10 +8,15 @@ class Index extends App.ControllerSubContent
|
||||||
el: @el
|
el: @el
|
||||||
id: @id
|
id: @id
|
||||||
genericObject: 'ReportProfile'
|
genericObject: 'ReportProfile'
|
||||||
|
defaultSortBy: 'name'
|
||||||
pageData:
|
pageData:
|
||||||
home: 'report_profiles'
|
home: 'report_profiles'
|
||||||
object: 'Report Profile'
|
object: 'Report Profile'
|
||||||
objects: 'Report Profiles'
|
objects: 'Report Profiles'
|
||||||
|
pagerAjax: true
|
||||||
|
pagerBaseUrl: '#manage/report_profiles/'
|
||||||
|
pagerSelected: ( @page || 1 )
|
||||||
|
pagerPerPage: 150
|
||||||
navupdate: '#report_profiles'
|
navupdate: '#report_profiles'
|
||||||
notes: [
|
notes: [
|
||||||
# 'Report Profile are ...'
|
# 'Report Profile are ...'
|
||||||
|
@ -22,4 +27,11 @@ class Index extends App.ControllerSubContent
|
||||||
container: @el.closest('.content')
|
container: @el.closest('.content')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
show: (params) =>
|
||||||
|
for key, value of params
|
||||||
|
if key isnt 'el' && key isnt 'shown' && key isnt 'match'
|
||||||
|
@[key] = value
|
||||||
|
|
||||||
|
@genericController.paginate( @page || 1 )
|
||||||
|
|
||||||
App.Config.set('ReportProfile', { prio: 8000, name: 'Report Profiles', parent: '#manage', target: '#manage/report_profiles', controller: Index, permission: ['admin.report_profile'] }, 'NavBarAdmin')
|
App.Config.set('ReportProfile', { prio: 8000, name: 'Report Profiles', parent: '#manage', target: '#manage/report_profiles', controller: Index, permission: ['admin.report_profile'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -8,10 +8,15 @@ class Index extends App.ControllerSubContent
|
||||||
el: @el
|
el: @el
|
||||||
id: @id
|
id: @id
|
||||||
genericObject: 'Role'
|
genericObject: 'Role'
|
||||||
|
defaultSortBy: 'name'
|
||||||
pageData:
|
pageData:
|
||||||
home: 'roles'
|
home: 'roles'
|
||||||
object: 'Role'
|
object: 'Role'
|
||||||
objects: 'Roles'
|
objects: 'Roles'
|
||||||
|
pagerAjax: true
|
||||||
|
pagerBaseUrl: '#manage/roles/'
|
||||||
|
pagerSelected: ( @page || 1 )
|
||||||
|
pagerPerPage: 150
|
||||||
navupdate: '#roles'
|
navupdate: '#roles'
|
||||||
notes: [
|
notes: [
|
||||||
'Roles are ...'
|
'Roles are ...'
|
||||||
|
@ -22,4 +27,11 @@ class Index extends App.ControllerSubContent
|
||||||
container: @el.closest('.content')
|
container: @el.closest('.content')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
show: (params) =>
|
||||||
|
for key, value of params
|
||||||
|
if key isnt 'el' && key isnt 'shown' && key isnt 'match'
|
||||||
|
@[key] = value
|
||||||
|
|
||||||
|
@genericController.paginate( @page || 1 )
|
||||||
|
|
||||||
App.Config.set('Role', { prio: 1600, name: 'Roles', parent: '#manage', target: '#manage/roles', controller: Index, permission: ['admin.role'] }, 'NavBarAdmin')
|
App.Config.set('Role', { prio: 1600, name: 'Roles', parent: '#manage', target: '#manage/roles', controller: Index, permission: ['admin.role'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -8,6 +8,7 @@ class Index extends App.ControllerSubContent
|
||||||
el: @el
|
el: @el
|
||||||
id: @id
|
id: @id
|
||||||
genericObject: 'TextModule'
|
genericObject: 'TextModule'
|
||||||
|
defaultSortBy: 'name'
|
||||||
importCallback: ->
|
importCallback: ->
|
||||||
new App.Import(
|
new App.Import(
|
||||||
baseUrl: '/api/v1/text_modules'
|
baseUrl: '/api/v1/text_modules'
|
||||||
|
@ -18,6 +19,10 @@ class Index extends App.ControllerSubContent
|
||||||
home: 'text_modules'
|
home: 'text_modules'
|
||||||
object: 'TextModule'
|
object: 'TextModule'
|
||||||
objects: 'Text modules'
|
objects: 'Text modules'
|
||||||
|
pagerAjax: true
|
||||||
|
pagerBaseUrl: '#manage/text_modules/'
|
||||||
|
pagerSelected: ( @page || 1 )
|
||||||
|
pagerPerPage: 150
|
||||||
navupdate: '#text_modules'
|
navupdate: '#text_modules'
|
||||||
notes: [
|
notes: [
|
||||||
'Text modules are ...'
|
'Text modules are ...'
|
||||||
|
@ -29,4 +34,11 @@ class Index extends App.ControllerSubContent
|
||||||
container: @el.closest('.content')
|
container: @el.closest('.content')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
show: (params) =>
|
||||||
|
for key, value of params
|
||||||
|
if key isnt 'el' && key isnt 'shown' && key isnt 'match'
|
||||||
|
@[key] = value
|
||||||
|
|
||||||
|
@genericController.paginate( @page || 1 )
|
||||||
|
|
||||||
App.Config.set('TextModule', { prio: 2300, name: 'Text modules', parent: '#manage', target: '#manage/text_modules', controller: Index, permission: ['admin.text_module'] }, 'NavBarAdmin')
|
App.Config.set('TextModule', { prio: 2300, name: 'Text modules', parent: '#manage', target: '#manage/text_modules', controller: Index, permission: ['admin.text_module'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -13,6 +13,10 @@ class Index extends App.ControllerSubContent
|
||||||
home: 'triggers'
|
home: 'triggers'
|
||||||
object: 'Trigger'
|
object: 'Trigger'
|
||||||
objects: 'Triggers'
|
objects: 'Triggers'
|
||||||
|
pagerAjax: true
|
||||||
|
pagerBaseUrl: '#manage/trigger/'
|
||||||
|
pagerSelected: ( @page || 1 )
|
||||||
|
pagerPerPage: 150
|
||||||
navupdate: '#triggers'
|
navupdate: '#triggers'
|
||||||
notes: [
|
notes: [
|
||||||
'Triggers are ...'
|
'Triggers are ...'
|
||||||
|
@ -24,4 +28,11 @@ class Index extends App.ControllerSubContent
|
||||||
veryLarge: true
|
veryLarge: true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
show: (params) =>
|
||||||
|
for key, value of params
|
||||||
|
if key isnt 'el' && key isnt 'shown' && key isnt 'match'
|
||||||
|
@[key] = value
|
||||||
|
|
||||||
|
@genericController.paginate( @page || 1 )
|
||||||
|
|
||||||
App.Config.set('Trigger', { prio: 3300, name: 'Trigger', parent: '#manage', target: '#manage/trigger', controller: Index, permission: ['admin.trigger'] }, 'NavBarAdmin')
|
App.Config.set('Trigger', { prio: 3300, name: 'Trigger', parent: '#manage', target: '#manage/trigger', controller: Index, permission: ['admin.trigger'] }, 'NavBarAdmin')
|
||||||
|
|
|
@ -621,6 +621,74 @@ set new attributes of model (remove already available attributes)
|
||||||
App.Log.error('Model', statusText, error, url)
|
App.Log.error('Model', statusText, error, url)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
index full collection (with assets)
|
||||||
|
|
||||||
|
App.Model.indexFull(@callback)
|
||||||
|
|
||||||
|
App.Model.indexFull(
|
||||||
|
@callback
|
||||||
|
page: 1
|
||||||
|
per_page: 10
|
||||||
|
sort_by: 'name'
|
||||||
|
order_by: 'ASC'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
@indexFull: (callback, params = {}) ->
|
||||||
|
url = "#{@url}?full=true"
|
||||||
|
for key in ['page', 'per_page', 'sort_by', 'order_by']
|
||||||
|
continue if !params[key]
|
||||||
|
url += "&#{key}=#{params[key]}"
|
||||||
|
|
||||||
|
App.Log.debug('Model', "indexFull collection #{@className}", url)
|
||||||
|
|
||||||
|
# request already active, queue callback
|
||||||
|
queueManagerName = "#{@className}::indexFull"
|
||||||
|
|
||||||
|
if params.refresh is undefined
|
||||||
|
params.refresh = true
|
||||||
|
|
||||||
|
App.Ajax.request(
|
||||||
|
type: 'GET'
|
||||||
|
url: url
|
||||||
|
processData: true,
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
App.Log.debug('Model', "got indexFull collection #{@className}", data)
|
||||||
|
|
||||||
|
recordIds = data.record_ids
|
||||||
|
if data.record_ids is undefined
|
||||||
|
recordIds = data[ @className.toLowerCase() + '_ids' ]
|
||||||
|
|
||||||
|
# full / load assets
|
||||||
|
if data.assets
|
||||||
|
App.Collection.loadAssets(data.assets, targetModel: @className)
|
||||||
|
|
||||||
|
# if no record_ids are found, no initial render is fired
|
||||||
|
if data.record_ids && _.isEmpty(data.record_ids) && params.refresh
|
||||||
|
App[@className].trigger('refresh', [])
|
||||||
|
|
||||||
|
# find / load object
|
||||||
|
else if params.refresh
|
||||||
|
App[@className].refresh(data)
|
||||||
|
|
||||||
|
if callback
|
||||||
|
localCallback = =>
|
||||||
|
collection = []
|
||||||
|
for id in recordIds
|
||||||
|
collection.push App[@className].find(id)
|
||||||
|
callback(collection, data)
|
||||||
|
App.QueueManager.add(queueManagerName, localCallback)
|
||||||
|
|
||||||
|
App.QueueManager.run(queueManagerName)
|
||||||
|
|
||||||
|
error: (xhr, statusText, error) =>
|
||||||
|
@indexFullActive = false
|
||||||
|
App.Log.error('Model', statusText, error, url)
|
||||||
|
)
|
||||||
|
|
||||||
@_bindsEmpty: ->
|
@_bindsEmpty: ->
|
||||||
if @SUBSCRIPTION_ITEM
|
if @SUBSCRIPTION_ITEM
|
||||||
for id, keys of @SUBSCRIPTION_ITEM
|
for id, keys of @SUBSCRIPTION_ITEM
|
||||||
|
@ -667,8 +735,9 @@ set new attributes of model (remove already available attributes)
|
||||||
|
|
||||||
# just show this values in result, all filters need to match to get shown
|
# just show this values in result, all filters need to match to get shown
|
||||||
filter:
|
filter:
|
||||||
some_attribute1: ['only_this_value1', 'only_that_value1']
|
|
||||||
some_attribute2: ['only_this_value2', 'only_that_value2']
|
# check single value
|
||||||
|
some_attribute1: 'only_this_value1'
|
||||||
|
|
||||||
# just show this values in result, all filters need to match to get shown
|
# just show this values in result, all filters need to match to get shown
|
||||||
filterExtended:
|
filterExtended:
|
||||||
|
|
|
@ -105,7 +105,12 @@ module ApplicationController::RendersModels
|
||||||
per_page = (params[:per_page] || 500).to_i
|
per_page = (params[:per_page] || 500).to_i
|
||||||
offset = (page - 1) * per_page
|
offset = (page - 1) * per_page
|
||||||
|
|
||||||
generic_objects = object.order(id: :asc).offset(offset).limit(per_page)
|
sql_helper = ::SqlHelper.new(object: object)
|
||||||
|
sort_by = sql_helper.get_sort_by(params, 'id')
|
||||||
|
order_by = sql_helper.get_order_by(params, 'ASC')
|
||||||
|
order_sql = sql_helper.get_order(sort_by, order_by)
|
||||||
|
|
||||||
|
generic_objects = object.order(Arel.sql(order_sql)).offset(offset).limit(per_page)
|
||||||
|
|
||||||
if response_expand?
|
if response_expand?
|
||||||
list = []
|
list = []
|
||||||
|
@ -124,8 +129,9 @@ module ApplicationController::RendersModels
|
||||||
assets = item.assets(assets)
|
assets = item.assets(assets)
|
||||||
end
|
end
|
||||||
render json: {
|
render json: {
|
||||||
record_ids: item_ids,
|
record_ids: item_ids,
|
||||||
assets: assets,
|
assets: assets,
|
||||||
|
total_count: object.count
|
||||||
}, status: :ok
|
}, status: :ok
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,48 +48,7 @@ curl http://localhost/api/v1/organizations -v -u #{login}:#{password}
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
offset = 0
|
model_index_render(policy_scope(Organization), params)
|
||||||
per_page = 500
|
|
||||||
|
|
||||||
if params[:page] && params[:per_page]
|
|
||||||
offset = (params[:page].to_i - 1) * params[:per_page].to_i
|
|
||||||
per_page = params[:per_page].to_i
|
|
||||||
end
|
|
||||||
|
|
||||||
if per_page > 500
|
|
||||||
per_page = 500
|
|
||||||
end
|
|
||||||
|
|
||||||
organizations = policy_scope(Organization).order(id: :asc).offset(offset).limit(per_page)
|
|
||||||
|
|
||||||
if response_expand?
|
|
||||||
list = []
|
|
||||||
organizations.each do |organization|
|
|
||||||
list.push organization.attributes_with_association_names
|
|
||||||
end
|
|
||||||
render json: list, status: :ok
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if response_full?
|
|
||||||
assets = {}
|
|
||||||
item_ids = []
|
|
||||||
organizations.each do |item|
|
|
||||||
item_ids.push item.id
|
|
||||||
assets = item.assets(assets)
|
|
||||||
end
|
|
||||||
render json: {
|
|
||||||
record_ids: item_ids,
|
|
||||||
assets: assets,
|
|
||||||
}, status: :ok
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
list = []
|
|
||||||
organizations.each do |organization|
|
|
||||||
list.push organization.attributes_with_association_ids
|
|
||||||
end
|
|
||||||
render json: list
|
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
|
||||||
module HasSearchSortable
|
|
||||||
extend ActiveSupport::Concern
|
|
||||||
|
|
||||||
# methods defined here are going to extend the class, not the instance of it
|
|
||||||
class_methods do
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
This function will check the params for the "sort_by" attribute
|
|
||||||
and validate its values.
|
|
||||||
|
|
||||||
sort_by = search_get_sort_by(params, default)
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
sort_by = [
|
|
||||||
'created_at',
|
|
||||||
'updated_at',
|
|
||||||
]
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def search_get_sort_by(params, default)
|
|
||||||
sort_by = []
|
|
||||||
if params[:sort_by].present? && params[:sort_by].is_a?(String)
|
|
||||||
params[:sort_by] = [params[:sort_by]]
|
|
||||||
elsif params[:sort_by].blank?
|
|
||||||
params[:sort_by] = []
|
|
||||||
end
|
|
||||||
|
|
||||||
# check order
|
|
||||||
params[:sort_by].each do |value|
|
|
||||||
|
|
||||||
# only accept values which are set for the db schema
|
|
||||||
raise "Found invalid column '#{value}' for sorting." if columns_hash[value].blank?
|
|
||||||
|
|
||||||
sort_by.push(value)
|
|
||||||
end
|
|
||||||
|
|
||||||
if sort_by.blank?
|
|
||||||
if default.is_a?(Array)
|
|
||||||
sort_by = default
|
|
||||||
else
|
|
||||||
sort_by.push(default)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
sort_by
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
This function will check the params for the "order_by" attribute
|
|
||||||
and validate its values.
|
|
||||||
|
|
||||||
order_by = search_get_order_by(params, default)
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
order_by = [
|
|
||||||
'asc',
|
|
||||||
'desc',
|
|
||||||
]
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def search_get_order_by(params, default)
|
|
||||||
order_by = []
|
|
||||||
if params[:order_by].present? && params[:order_by].is_a?(String)
|
|
||||||
params[:order_by] = [ params[:order_by] ]
|
|
||||||
elsif params[:order_by].blank?
|
|
||||||
params[:order_by] = []
|
|
||||||
end
|
|
||||||
|
|
||||||
# check order
|
|
||||||
params[:order_by].each do |value|
|
|
||||||
raise "Found invalid order by value #{value}. Please use 'asc' or 'desc'." if !value.match?(/\A(asc|desc)\z/i)
|
|
||||||
|
|
||||||
order_by.push(value.downcase)
|
|
||||||
end
|
|
||||||
|
|
||||||
if order_by.blank?
|
|
||||||
if default.is_a?(Array)
|
|
||||||
order_by = default
|
|
||||||
else
|
|
||||||
order_by.push(default)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
order_by
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
This function will use the evaluated values for sort_by and
|
|
||||||
order_by to generate the ORDER-SELECT sql statement for the sorting
|
|
||||||
of the result.
|
|
||||||
|
|
||||||
sort_by = [ 'created_at', 'updated_at' ]
|
|
||||||
order_by = [ 'asc', 'desc' ]
|
|
||||||
default = 'tickets.created_at'
|
|
||||||
|
|
||||||
sql = search_get_order_select_sql(sort_by, order_by, default)
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
sql = 'tickets.created_at, tickets.updated_at'
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def search_get_order_select_sql(sort_by, order_by, default)
|
|
||||||
sql = []
|
|
||||||
|
|
||||||
sort_by.each_with_index do |value, index|
|
|
||||||
next if value.blank?
|
|
||||||
next if order_by[index].blank?
|
|
||||||
|
|
||||||
sql.push( "#{ActiveRecord::Base.connection.quote_table_name(table_name)}.#{ActiveRecord::Base.connection.quote_column_name(value)}" )
|
|
||||||
end
|
|
||||||
|
|
||||||
if sql.blank?
|
|
||||||
sql.push("#{ActiveRecord::Base.connection.quote_table_name(table_name)}.#{ActiveRecord::Base.connection.quote_column_name(default)}")
|
|
||||||
end
|
|
||||||
|
|
||||||
sql.join(', ')
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
This function will use the evaluated values for sort_by and
|
|
||||||
order_by to generate the ORDER- sql statement for the sorting
|
|
||||||
of the result.
|
|
||||||
|
|
||||||
sort_by = [ 'created_at', 'updated_at' ]
|
|
||||||
order_by = [ 'asc', 'desc' ]
|
|
||||||
default = 'tickets.created_at DESC'
|
|
||||||
|
|
||||||
sql = search_get_order_sql(sort_by, order_by, default)
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
sql = 'tickets.created_at ASC, tickets.updated_at DESC'
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def search_get_order_sql(sort_by, order_by, default)
|
|
||||||
sql = []
|
|
||||||
|
|
||||||
sort_by.each_with_index do |value, index|
|
|
||||||
next if value.blank?
|
|
||||||
next if order_by[index].blank?
|
|
||||||
|
|
||||||
sql.push( "#{ActiveRecord::Base.connection.quote_table_name(table_name)}.#{ActiveRecord::Base.connection.quote_column_name(value)} #{order_by[index]}" )
|
|
||||||
end
|
|
||||||
|
|
||||||
if sql.blank?
|
|
||||||
sql.push("#{ActiveRecord::Base.connection.quote_table_name(table_name)}.#{ActiveRecord::Base.connection.quote_column_name(default)}")
|
|
||||||
end
|
|
||||||
|
|
||||||
sql.join(', ')
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -2,21 +2,19 @@ class KnowledgeBase
|
||||||
module Search
|
module Search
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
|
||||||
include HasSearchSortable
|
|
||||||
end
|
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
def search(params)
|
def search(params)
|
||||||
current_user = params[:current_user]
|
current_user = params[:current_user]
|
||||||
# enable search only for agents and admins
|
# enable search only for agents and admins
|
||||||
return [] if !search_preferences(current_user)
|
return [] if !search_preferences(current_user)
|
||||||
|
|
||||||
|
sql_helper = ::SqlHelper.new(object: self)
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
limit: params[:limit] || 10,
|
limit: params[:limit] || 10,
|
||||||
from: params[:offset] || 0,
|
from: params[:offset] || 0,
|
||||||
sort_by: search_get_sort_by(params, 'updated_at'),
|
sort_by: sql_helper.get_sort_by(params, 'updated_at'),
|
||||||
order_by: search_get_order_by(params, 'desc'),
|
order_by: sql_helper.get_order_by(params, 'desc'),
|
||||||
user: current_user
|
user: current_user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +39,9 @@ class KnowledgeBase
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_sql(query, kb_locales, options)
|
def search_sql(query, kb_locales, options)
|
||||||
table_name = arel_table.name
|
table_name = arel_table.name
|
||||||
order_sql = search_get_order_sql(options[:sort_by], options[:order_by], "#{table_name}.updated_at ASC")
|
sql_helper = ::SqlHelper.new(object: self)
|
||||||
|
order_sql = sql_helper.get_order(options[:sort_by], options[:order_by], "#{table_name}.updated_at ASC")
|
||||||
|
|
||||||
# - stip out * we already search for *query* -
|
# - stip out * we already search for *query* -
|
||||||
query.delete! '*'
|
query.delete! '*'
|
||||||
|
|
|
@ -4,10 +4,6 @@ class Organization
|
||||||
module Search
|
module Search
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
|
||||||
include HasSearchSortable
|
|
||||||
end
|
|
||||||
|
|
||||||
# methods defined here are going to extend the class, not the instance of it
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
class_methods do
|
class_methods do
|
||||||
|
|
||||||
|
@ -72,11 +68,13 @@ returns
|
||||||
offset = params[:offset] || 0
|
offset = params[:offset] || 0
|
||||||
current_user = params[:current_user]
|
current_user = params[:current_user]
|
||||||
|
|
||||||
|
sql_helper = ::SqlHelper.new(object: self)
|
||||||
|
|
||||||
# check sort - positions related to order by
|
# check sort - positions related to order by
|
||||||
sort_by = search_get_sort_by(params, %w[active updated_at])
|
sort_by = sql_helper.get_sort_by(params, %w[active updated_at])
|
||||||
|
|
||||||
# check order - positions related to sort by
|
# check order - positions related to sort by
|
||||||
order_by = search_get_order_by(params, %w[desc desc])
|
order_by = sql_helper.get_order_by(params, %w[desc desc])
|
||||||
|
|
||||||
# enable search only for agents and admins
|
# enable search only for agents and admins
|
||||||
return [] if !search_preferences(current_user)
|
return [] if !search_preferences(current_user)
|
||||||
|
@ -97,8 +95,8 @@ returns
|
||||||
return organizations
|
return organizations
|
||||||
end
|
end
|
||||||
|
|
||||||
order_select_sql = search_get_order_select_sql(sort_by, order_by, 'organizations.updated_at')
|
order_select_sql = sql_helper.get_order_select(sort_by, order_by, 'organizations.updated_at')
|
||||||
order_sql = search_get_order_sql(sort_by, order_by, 'organizations.updated_at ASC')
|
order_sql = sql_helper.get_order(sort_by, order_by, 'organizations.updated_at ASC')
|
||||||
|
|
||||||
# fallback do sql query
|
# fallback do sql query
|
||||||
# - stip out * we already search for *query* -
|
# - stip out * we already search for *query* -
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
module Ticket::Search
|
module Ticket::Search
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
|
||||||
include HasSearchSortable
|
|
||||||
end
|
|
||||||
|
|
||||||
# methods defined here are going to extend the class, not the instance of it
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
class_methods do
|
class_methods do
|
||||||
|
|
||||||
|
@ -119,11 +115,13 @@ returns
|
||||||
full = true
|
full = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sql_helper = ::SqlHelper.new(object: self)
|
||||||
|
|
||||||
# check sort
|
# check sort
|
||||||
sort_by = search_get_sort_by(params, 'updated_at')
|
sort_by = sql_helper.get_sort_by(params, 'updated_at')
|
||||||
|
|
||||||
# check order
|
# check order
|
||||||
order_by = search_get_order_by(params, 'desc')
|
order_by = sql_helper.get_order_by(params, 'desc')
|
||||||
|
|
||||||
# try search index backend
|
# try search index backend
|
||||||
if condition.blank? && SearchIndexBackend.enabled?
|
if condition.blank? && SearchIndexBackend.enabled?
|
||||||
|
@ -197,8 +195,8 @@ returns
|
||||||
# do query
|
# do query
|
||||||
# - stip out * we already search for *query* -
|
# - stip out * we already search for *query* -
|
||||||
|
|
||||||
order_select_sql = search_get_order_select_sql(sort_by, order_by, 'tickets.updated_at')
|
order_select_sql = sql_helper.get_order_select(sort_by, order_by, 'tickets.updated_at')
|
||||||
order_sql = search_get_order_sql(sort_by, order_by, 'tickets.updated_at DESC')
|
order_sql = sql_helper.get_order(sort_by, order_by, 'tickets.updated_at DESC')
|
||||||
if query
|
if query
|
||||||
query.delete! '*'
|
query.delete! '*'
|
||||||
tickets_all = Ticket.select("DISTINCT(tickets.id), #{order_select_sql}")
|
tickets_all = Ticket.select("DISTINCT(tickets.id), #{order_select_sql}")
|
||||||
|
|
|
@ -4,10 +4,6 @@ class User
|
||||||
module Search
|
module Search
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
|
||||||
include HasSearchSortable
|
|
||||||
end
|
|
||||||
|
|
||||||
# methods defined here are going to extend the class, not the instance of it
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
class_methods do
|
class_methods do
|
||||||
|
|
||||||
|
@ -83,11 +79,13 @@ returns
|
||||||
offset = params[:offset] || 0
|
offset = params[:offset] || 0
|
||||||
current_user = params[:current_user]
|
current_user = params[:current_user]
|
||||||
|
|
||||||
|
sql_helper = ::SqlHelper.new(object: self)
|
||||||
|
|
||||||
# check sort - positions related to order by
|
# check sort - positions related to order by
|
||||||
sort_by = search_get_sort_by(params, %w[active updated_at])
|
sort_by = sql_helper.get_sort_by(params, %w[active updated_at])
|
||||||
|
|
||||||
# check order - positions related to sort by
|
# check order - positions related to sort by
|
||||||
order_by = search_get_order_by(params, %w[desc desc])
|
order_by = sql_helper.get_order_by(params, %w[desc desc])
|
||||||
|
|
||||||
# enable search only for agents and admins
|
# enable search only for agents and admins
|
||||||
return [] if !search_preferences(current_user)
|
return [] if !search_preferences(current_user)
|
||||||
|
@ -129,7 +127,7 @@ returns
|
||||||
return users
|
return users
|
||||||
end
|
end
|
||||||
|
|
||||||
order_sql = search_get_order_sql(sort_by, order_by, 'users.updated_at DESC')
|
order_sql = sql_helper.get_order(sort_by, order_by, 'users.updated_at DESC')
|
||||||
|
|
||||||
# fallback do sql query
|
# fallback do sql query
|
||||||
# - stip out * we already search for *query* -
|
# - stip out * we already search for *query* -
|
||||||
|
|
172
lib/sql_helper.rb
Normal file
172
lib/sql_helper.rb
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class SqlHelper
|
||||||
|
|
||||||
|
def initialize(object:)
|
||||||
|
@object = object
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_param_key(key, params)
|
||||||
|
sort_by = []
|
||||||
|
if params[key].present? && params[key].is_a?(String)
|
||||||
|
params[key] = params[key].split(/\s*,\s*/)
|
||||||
|
elsif params[key].blank?
|
||||||
|
params[key] = []
|
||||||
|
end
|
||||||
|
|
||||||
|
sort_by
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
This function will check the params for the "sort_by" attribute
|
||||||
|
and validate its values.
|
||||||
|
|
||||||
|
sql_helper = SqlHelper.new(object: Ticket)
|
||||||
|
sort_by = sql_helper.get_sort_by(params, default)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
sort_by = [
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def get_sort_by(params, default = nil)
|
||||||
|
sort_by = get_param_key(:sort_by, params)
|
||||||
|
|
||||||
|
# check order
|
||||||
|
params[:sort_by].each do |value|
|
||||||
|
|
||||||
|
# only accept values which are set for the db schema
|
||||||
|
raise "Found invalid column '#{value}' for sorting." if @object.columns_hash[value].blank?
|
||||||
|
|
||||||
|
sort_by.push(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
if sort_by.blank? && default.present?
|
||||||
|
if default.is_a?(Array)
|
||||||
|
sort_by = default
|
||||||
|
else
|
||||||
|
sort_by.push(default)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sort_by
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
This function will check the params for the "order_by" attribute
|
||||||
|
and validate its values.
|
||||||
|
|
||||||
|
sql_helper = SqlHelper.new(object: Ticket)
|
||||||
|
order_by = sql_helper.get_order_by(params, default)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
order_by = [
|
||||||
|
'asc',
|
||||||
|
'desc',
|
||||||
|
]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def get_order_by(params, default = nil)
|
||||||
|
order_by = get_param_key(:order_by, params)
|
||||||
|
|
||||||
|
# check order
|
||||||
|
params[:order_by].each do |value|
|
||||||
|
raise "Found invalid order by value #{value}. Please use 'asc' or 'desc'." if !value.match?(/\A(asc|desc)\z/i)
|
||||||
|
|
||||||
|
order_by.push(value.downcase)
|
||||||
|
end
|
||||||
|
|
||||||
|
if order_by.blank? && default.present?
|
||||||
|
if default.is_a?(Array)
|
||||||
|
order_by = default
|
||||||
|
else
|
||||||
|
order_by.push(default)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
order_by
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_sql_order_default(sql, default)
|
||||||
|
if sql.blank? && default.present?
|
||||||
|
sql.push("#{ActiveRecord::Base.connection.quote_table_name(@object.table_name)}.#{ActiveRecord::Base.connection.quote_column_name(default)}")
|
||||||
|
end
|
||||||
|
sql
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
This function will use the evaluated values for sort_by and
|
||||||
|
order_by to generate the ORDER-SELECT sql statement for the sorting
|
||||||
|
of the result.
|
||||||
|
|
||||||
|
sort_by = [ 'created_at', 'updated_at' ]
|
||||||
|
order_by = [ 'asc', 'desc' ]
|
||||||
|
default = 'tickets.created_at'
|
||||||
|
|
||||||
|
sql_helper = SqlHelper.new(object: Ticket)
|
||||||
|
sql = sql_helper.get_order_select(sort_by, order_by, default)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
sql = 'tickets.created_at, tickets.updated_at'
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def get_order_select(sort_by, order_by, default = nil)
|
||||||
|
sql = []
|
||||||
|
|
||||||
|
sort_by.each_with_index do |value, index|
|
||||||
|
next if value.blank?
|
||||||
|
next if order_by[index].blank?
|
||||||
|
|
||||||
|
sql.push( "#{ActiveRecord::Base.connection.quote_table_name(@object.table_name)}.#{ActiveRecord::Base.connection.quote_column_name(value)}" )
|
||||||
|
end
|
||||||
|
|
||||||
|
sql = set_sql_order_default(sql, default)
|
||||||
|
|
||||||
|
sql.join(', ')
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
This function will use the evaluated values for sort_by and
|
||||||
|
order_by to generate the ORDER- sql statement for the sorting
|
||||||
|
of the result.
|
||||||
|
|
||||||
|
sort_by = [ 'created_at', 'updated_at' ]
|
||||||
|
order_by = [ 'asc', 'desc' ]
|
||||||
|
default = 'tickets.created_at DESC'
|
||||||
|
|
||||||
|
sql_helper = SqlHelper.new(object: Ticket)
|
||||||
|
sql = sql_helper.get_order(sort_by, order_by, default)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
sql = 'tickets.created_at ASC, tickets.updated_at DESC'
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def get_order(sort_by, order_by, default = nil)
|
||||||
|
sql = []
|
||||||
|
|
||||||
|
sort_by.each_with_index do |value, index|
|
||||||
|
next if value.blank?
|
||||||
|
next if order_by[index].blank?
|
||||||
|
|
||||||
|
sql.push( "#{ActiveRecord::Base.connection.quote_table_name(@object.table_name)}.#{ActiveRecord::Base.connection.quote_column_name(value)} #{order_by[index]}" )
|
||||||
|
end
|
||||||
|
|
||||||
|
sql = set_sql_order_default(sql, default)
|
||||||
|
|
||||||
|
sql.join(', ')
|
||||||
|
end
|
||||||
|
end
|
8
spec/factories/report/profile.rb
Normal file
8
spec/factories/report/profile.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :'report/profile', aliases: %i[report_profile] do
|
||||||
|
sequence(:name) { |n| "Report #{n}" }
|
||||||
|
active { true }
|
||||||
|
created_by_id { 1 }
|
||||||
|
updated_by_id { 1 }
|
||||||
|
end
|
||||||
|
end
|
45
spec/system/examples/pagination_examples.rb
Normal file
45
spec/system/examples/pagination_examples.rb
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
RSpec.shared_examples 'pagination' do |model:, klass:, path:, sort_by: :name|
|
||||||
|
def prepare(model)
|
||||||
|
create_list(model, 500)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does paginate' do
|
||||||
|
prepare(model)
|
||||||
|
visit path
|
||||||
|
refresh # more stability
|
||||||
|
expect(page).to have_css('.js-pager', wait: 10)
|
||||||
|
|
||||||
|
class_page1 = klass.order(sort_by => :asc, id: :asc).offset(50).first
|
||||||
|
expect(page).to have_text(class_page1.name, wait: 10)
|
||||||
|
|
||||||
|
page.first('.js-page', text: '2').click
|
||||||
|
await_empty_ajax_queue
|
||||||
|
|
||||||
|
class_page2 = klass.order(sort_by => :asc, id: :asc).offset(175).first
|
||||||
|
expect(page).to have_text(class_page2.name, wait: 10)
|
||||||
|
|
||||||
|
page.first('.js-page', text: '3').click
|
||||||
|
await_empty_ajax_queue
|
||||||
|
|
||||||
|
class_page3 = klass.order(sort_by => :asc, id: :asc).offset(325).first
|
||||||
|
expect(page).to have_text(class_page3.name, wait: 10)
|
||||||
|
|
||||||
|
page.first('.js-page', text: '4').click
|
||||||
|
await_empty_ajax_queue
|
||||||
|
|
||||||
|
class_page4 = klass.order(sort_by => :asc, id: :asc).offset(475).first
|
||||||
|
expect(page).to have_text(class_page4.name, wait: 10)
|
||||||
|
|
||||||
|
page.first('.js-page', text: '1').click
|
||||||
|
await_empty_ajax_queue
|
||||||
|
|
||||||
|
page.first('.js-tableHead[data-column-key=name]').click
|
||||||
|
await_empty_ajax_queue
|
||||||
|
expect(page).to have_text(class_page1.name, wait: 10)
|
||||||
|
|
||||||
|
page.first('.js-tableHead[data-column-key=name]').click
|
||||||
|
await_empty_ajax_queue
|
||||||
|
class_last = klass.order(sort_by => :desc).first
|
||||||
|
expect(page).to have_text(class_last.name, wait: 10)
|
||||||
|
end
|
||||||
|
end
|
8
spec/system/manage/groups_spec.rb
Normal file
8
spec/system/manage/groups_spec.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
require 'system/examples/pagination_examples'
|
||||||
|
|
||||||
|
RSpec.describe 'Manage > Groups', type: :system do
|
||||||
|
context 'ajax pagination' do
|
||||||
|
include_examples 'pagination', model: :group, klass: Group, path: 'manage/groups'
|
||||||
|
end
|
||||||
|
end
|
8
spec/system/manage/jobs_spec.rb
Normal file
8
spec/system/manage/jobs_spec.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
require 'system/examples/pagination_examples'
|
||||||
|
|
||||||
|
RSpec.describe 'Manage > Job', type: :system do
|
||||||
|
context 'ajax pagination' do
|
||||||
|
include_examples 'pagination', model: :job, klass: Job, path: 'manage/job'
|
||||||
|
end
|
||||||
|
end
|
8
spec/system/manage/macros_spec.rb
Normal file
8
spec/system/manage/macros_spec.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
require 'system/examples/pagination_examples'
|
||||||
|
|
||||||
|
RSpec.describe 'Manage > Macro', type: :system do
|
||||||
|
context 'ajax pagination' do
|
||||||
|
include_examples 'pagination', model: :macro, klass: Macro, path: 'manage/macros'
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,5 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
require 'system/examples/pagination_examples'
|
||||||
|
|
||||||
RSpec.describe 'Manage > Organizations', type: :system do
|
RSpec.describe 'Manage > Organizations', type: :system do
|
||||||
|
|
||||||
|
@ -48,4 +49,8 @@ RSpec.describe 'Manage > Organizations', type: :system do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'ajax pagination' do
|
||||||
|
include_examples 'pagination', model: :organization, klass: Organization, path: 'manage/organizations'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
8
spec/system/manage/report_profiles_spec.rb
Normal file
8
spec/system/manage/report_profiles_spec.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
require 'system/examples/pagination_examples'
|
||||||
|
|
||||||
|
RSpec.describe 'Manage > Report Profiles', type: :system do
|
||||||
|
context 'ajax pagination' do
|
||||||
|
include_examples 'pagination', model: :report_profile, klass: Report::Profile, path: 'manage/report_profiles'
|
||||||
|
end
|
||||||
|
end
|
8
spec/system/manage/roles_spec.rb
Normal file
8
spec/system/manage/roles_spec.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
require 'system/examples/pagination_examples'
|
||||||
|
|
||||||
|
RSpec.describe 'Manage > Role', type: :system do
|
||||||
|
context 'ajax pagination' do
|
||||||
|
include_examples 'pagination', model: :role, klass: Role, path: 'manage/roles'
|
||||||
|
end
|
||||||
|
end
|
8
spec/system/manage/text_modules_spec.rb
Normal file
8
spec/system/manage/text_modules_spec.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
require 'system/examples/pagination_examples'
|
||||||
|
|
||||||
|
RSpec.describe 'Manage > Text Module', type: :system do
|
||||||
|
context 'ajax pagination' do
|
||||||
|
include_examples 'pagination', model: :text_module, klass: TextModule, path: 'manage/text_modules'
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,5 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
require 'system/examples/pagination_examples'
|
||||||
|
|
||||||
RSpec.describe 'Manage > Trigger', type: :system do
|
RSpec.describe 'Manage > Trigger', type: :system do
|
||||||
|
|
||||||
|
@ -57,4 +58,8 @@ RSpec.describe 'Manage > Trigger', type: :system do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'ajax pagination' do
|
||||||
|
include_examples 'pagination', model: :trigger, klass: Trigger, path: 'manage/trigger'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue