Skip to content

Commit

Permalink
More speed-up for TestCase filtering on the TestPlan view page
Browse files Browse the repository at this point in the history
building upon the previous change we now either show or hide rows on
screen depending on what the actual result set is.

When the rows which match the filter are less than the ones which don't
we display only them. Else we display everything and hide the rows which
don't match the filter. This always results in the minimum number of
display updates.

For the extreme scenario where 990/1000 rows match is_automated=false this
provides 30x improvement!

WARNING: for scenarios which are not on the extreme case, yet still
result in 100s of rows that need to be displayed this commit does not
offer any optimization compared to the previous one!
  • Loading branch information
atodorov committed Nov 14, 2024
1 parent 800a3e3 commit 7b7bf96
Showing 1 changed file with 45 additions and 6 deletions.
51 changes: 45 additions & 6 deletions tcms/testplans/static/testplans/js/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,47 @@ function getSelectedTestCases () {
return tcIds
}

// returns 2 arrays with selectors that need to be either shown or hidden
// return values will be used as multiple-selector for jQuery
// see https://api.jquery.com/multiple-selector/
function findSelectorsToShowAndHide (inputData, filterBy, filterValue) {
const hideMe = []
const showMe = []

inputData.forEach(function (element) {
if (element[filterBy] !== undefined && element[filterBy].toString().toLowerCase().indexOf(filterValue) > -1) {
showMe.push(`[data-testcase-pk=${element.id}]`)
} else {
hideMe.push(`[data-testcase-pk=${element.id}]`)
}
})

return {
hide: hideMe,
show: showMe
}
}

// update the screen in one swoop trying to perform
// as little display updates as possible
function showOrHideMultipleRows (rootSelector, rows) {
// initial state is that everything is hidden

if (rows.show.length <= rows.hide.length) {
$(rows.show.join(',')).show()
} else {
/* eslint-disable indent */
$('body')
.find(rootSelector)
.show()
.end()
.find(rows.hide.join(','))
.hide()
.end()
/* eslint-enable */
}
}

function filterTestCasesByProperty (planId, testCases, filterBy, filterValue) {
// no input => show all rows
if (filterValue.trim().length === 0) {
Expand All @@ -697,24 +738,22 @@ function filterTestCasesByProperty (planId, testCases, filterBy, filterValue) {

$('.js-testcase-row').hide()

// see https://api.jquery.com/multiple-selector/
const showOnly = []
if (filterBy === 'component' || filterBy === 'tag') {
const query = { plan: planId }
query[`${filterBy}__name__icontains`] = filterValue

jsonRPC('TestCase.filter', query, function (filtered) {
// hide again if a previous async request showed something else
$('.js-testcase-row').hide()

const showOnly = []
filtered.forEach(tc => showOnly.push(`[data-testcase-pk=${tc.id}]`))

$(showOnly.join(',')).show()
})
} else {
testCases.filter(function (tc) {
return (tc[filterBy] !== undefined && tc[filterBy].toString().toLowerCase().indexOf(filterValue) > -1)
}).forEach(tc => showOnly.push(`[data-testcase-pk=${tc.id}]`))
const rows = findSelectorsToShowAndHide(testCases, filterBy, filterValue)

$(showOnly.join(',')).show()
showOrHideMultipleRows('.js-testcase-row', rows)
}
}

0 comments on commit 7b7bf96

Please sign in to comment.