Last active
January 23, 2020 18:32
-
-
Save volkovasystems/b7b5b472fb72f305d653abc5af854aae to your computer and use it in GitHub Desktop.
recompute-page-data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
const truly = require( "truly" ); | |
const resolvePageData = require( "./resolve-page-data.js" ); | |
const recomputePageData = function recomputePageData( pageData ){ | |
pageData = resolvePageData( pageData ); | |
const listCount = pageData.listCount; | |
let pageIndex = pageData.pageIndex; | |
let pageCount = pageData.pageCount; | |
let pageSize = pageData.pageSize; | |
let lastPageSize = pageData.lastPageSize; | |
if( | |
listCount <= 0 | |
){ | |
return pageData; | |
} | |
/*; | |
@note: | |
If either pageCount or pageSize | |
has value then use it to re-compute the other. | |
@end-note | |
*/ | |
if( | |
( | |
truly( pageSize ) | |
&& pageSize > 0 | |
) | |
|| ( | |
truly( pageCount ) | |
&& pageCount > 0 | |
) | |
){ | |
if( | |
truly( pageSize ) | |
&& pageSize > 0 | |
&& pageCount <= 0 | |
){ | |
pageCount = ( | |
Math | |
.floor( | |
listCount | |
/ pageSize | |
) | |
); | |
} | |
if( | |
truly( pageCount ) | |
&& pageCount > 0 | |
&& pageSize <= 0 | |
){ | |
pageSize = ( | |
Math | |
.floor( | |
listCount | |
/ pageCount | |
) | |
); | |
} | |
} | |
else{ | |
/*; | |
@note: | |
This is the default basic partition distribution algorithm. | |
If both pageCount and pageSize has no value | |
then use this algorithm as reference. | |
This is based on the formula, square root of list count, | |
the result is the partition distribution factor that | |
can be used to get the partition distribution size | |
and both value is a good balance between page count and page size. | |
@end-note | |
@todo-note: | |
Provide extension here to let the developer | |
inject their own partition distribution algorithm. | |
@end-todo-note | |
*/ | |
const partitionFactor = ( | |
Math | |
.floor( | |
Math | |
.sqrt( | |
listCount | |
) | |
) | |
); | |
const partitionSize = ( | |
Math | |
.floor( | |
listCount | |
/ partitionFactor | |
) | |
); | |
pageSize = ( | |
pageSize | |
|| ( | |
Math | |
.min( | |
partitionFactor, | |
partitionSize | |
) | |
) | |
); | |
pageCount = ( | |
pageCount | |
|| ( | |
Math | |
.max( | |
partitionFactor, | |
partitionSize | |
) | |
) | |
); | |
} | |
/*; | |
@note: | |
Any partition distribution algorithm | |
is useless for list count less than | |
the minimum threshold. | |
@end-note | |
@todo-note: | |
Add extension here to provide developer | |
to specify their own minimum threshold. | |
@end-todo-note | |
*/ | |
if( | |
pageSize > listCount | |
|| ( | |
listCount <= 10 | |
&& pageSize <= 10 | |
) | |
){ | |
pageSize = listCount; | |
pageCount = 1; | |
} | |
/*; | |
@todo-note: | |
Add handler here to check if pageCount | |
and pageSize is weirdly larger than listCount. | |
@end-todo-note | |
*/ | |
/*; | |
@note: | |
Resolve for last page size. | |
Page count should include the last page size. | |
If the product of page count and page size | |
is equal to list count then last page size is zero. | |
If the product of page count and page size | |
is less than list count then the remaining | |
size is the value of last page size | |
and page count is incremented. | |
If the product of page count and page size | |
is greater than list count then re-compute | |
for last page size by getting the difference of list count | |
and product of page count less 1 and page size. | |
@end-note | |
*/ | |
const computedListCount = ( | |
pageCount | |
* pageSize | |
); | |
if( | |
computedListCount == listCount | |
){ | |
lastPageSize = 0; | |
} | |
else if( | |
computedListCount < listCount | |
){ | |
lastPageSize = ( | |
listCount | |
- computedListCount | |
); | |
pageCount++; | |
} | |
else if( | |
computedListCount > listCount | |
){ | |
lastPageSize = ( | |
listCount | |
- ( | |
( | |
pageCount | |
- 1 | |
) | |
* pageSize | |
) | |
); | |
} | |
/*; | |
@note: | |
We will apply roll over logic on pagination. | |
if the pageIndex is greater than pageCount | |
@end-note | |
@todo-note: | |
Add extension here to provide developer | |
to inject their own handler if | |
page index is greater than page count. | |
@end-todo-note | |
*/ | |
if( | |
pageIndex > pageCount | |
){ | |
pageIndex = 1; | |
} | |
pageData.pageIndex = pageIndex; | |
pageData.pageCount = pageCount; | |
pageData.pageSize = pageSize; | |
pageData.lastPageSize = lastPageSize; | |
/*; | |
@note: | |
These are extended features | |
to support array slicing. | |
@end-note | |
*/ | |
pageData.startIndex = ( | |
( | |
pageIndex | |
- 1 | |
) | |
* pageSize | |
); | |
pageData.endIndex = ( | |
pageData.startIndex | |
+ pageSize | |
); | |
if( | |
pageIndex === pageCount | |
&& lastPageSize > 0 | |
){ | |
pageData.endIndex = ( | |
pageData.startIndex | |
+ lastPageSize | |
); | |
} | |
/*; | |
@note: | |
This is extended feature to | |
resolve between pageSize | |
and lastPageSize when pageIndex changes. | |
@end-note | |
*/ | |
pageData.currentPageSize = ( | |
pageData.endIndex | |
- pageData.startIndex | |
); | |
return pageData; | |
}; | |
module.exports = recomputePageData; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment