Skip to content

Commit

Permalink
Fixing major bug in pagination with infinite scroll and two or more p…
Browse files Browse the repository at this point in the history
…ages.
  • Loading branch information
dsternlicht committed May 11, 2020
1 parent 0e8a7f4 commit 941f050
Show file tree
Hide file tree
Showing 13 changed files with 72 additions and 74 deletions.
8 changes: 4 additions & 4 deletions build/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"files": {
"main.css": "./static/css/main.4cc0f9aa.chunk.css",
"main.js": "./static/js/main.7336efbc.chunk.js",
"main.js.map": "./static/js/main.7336efbc.chunk.js.map",
"main.js": "./static/js/main.6bfcc0ad.chunk.js",
"main.js.map": "./static/js/main.6bfcc0ad.chunk.js.map",
"runtime-main.js": "./static/js/runtime-main.f1c188a0.js",
"runtime-main.js.map": "./static/js/runtime-main.f1c188a0.js.map",
"static/css/2.5dbdccff.chunk.css": "./static/css/2.5dbdccff.chunk.css",
"static/js/2.7c8c2e97.chunk.js": "./static/js/2.7c8c2e97.chunk.js",
"static/js/2.7c8c2e97.chunk.js.map": "./static/js/2.7c8c2e97.chunk.js.map",
"index.html": "./index.html",
"precache-manifest.cb860fbdcd8dbe8080de19e34af61e4a.js": "./precache-manifest.cb860fbdcd8dbe8080de19e34af61e4a.js",
"precache-manifest.1b5f585b6d711dcd919128291e36c30d.js": "./precache-manifest.1b5f585b6d711dcd919128291e36c30d.js",
"service-worker.js": "./service-worker.js",
"static/css/2.5dbdccff.chunk.css.map": "./static/css/2.5dbdccff.chunk.css.map",
"static/css/main.4cc0f9aa.chunk.css.map": "./static/css/main.4cc0f9aa.chunk.css.map",
Expand All @@ -20,6 +20,6 @@
"static/css/2.5dbdccff.chunk.css",
"static/js/2.7c8c2e97.chunk.js",
"static/css/main.4cc0f9aa.chunk.css",
"static/js/main.7336efbc.chunk.js"
"static/js/main.6bfcc0ad.chunk.js"
]
}
2 changes: 1 addition & 1 deletion build/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="manifest" href="./manifest.json"/><title>RESTool App</title><link href="./static/css/2.5dbdccff.chunk.css" rel="stylesheet"><link href="./static/css/main.4cc0f9aa.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>window.location.href.includes("dsternlicht.github.io/RESTool")&&(window.RESTool={config:{remoteUrl:"https://dsternlicht.github.io/RESTool/config.json"}})</script><script>!function(i){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],l=0,f=[];l<n.length;l++)t=n[l],Object.prototype.hasOwnProperty.call(p,t)&&p[t]&&f.push(p[t][0]),p[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(i[r]=o[r]);for(s&&s(e);f.length;)f.shift()();return c.push.apply(c,u||[]),a()}function a(){for(var e,r=0;r<c.length;r++){for(var t=c[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==p[u]&&(n=!1)}n&&(c.splice(r--,1),e=l(l.s=t[0]))}return e}var t={},p={1:0},c=[];function l(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return i[e].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.m=i,l.c=t,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(r,e){if(1&e&&(r=l(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)l.d(t,n,function(e){return r[e]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="./";var r=this.webpackJsonprestool=this.webpackJsonprestool||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;a()}([])</script><script src="./static/js/2.7c8c2e97.chunk.js"></script><script src="./static/js/main.7336efbc.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="manifest" href="./manifest.json"/><title>RESTool App</title><link href="./static/css/2.5dbdccff.chunk.css" rel="stylesheet"><link href="./static/css/main.4cc0f9aa.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(i){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],l=0,f=[];l<n.length;l++)t=n[l],Object.prototype.hasOwnProperty.call(p,t)&&p[t]&&f.push(p[t][0]),p[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(i[r]=o[r]);for(s&&s(e);f.length;)f.shift()();return c.push.apply(c,u||[]),a()}function a(){for(var e,r=0;r<c.length;r++){for(var t=c[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==p[u]&&(n=!1)}n&&(c.splice(r--,1),e=l(l.s=t[0]))}return e}var t={},p={1:0},c=[];function l(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return i[e].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.m=i,l.c=t,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(r,e){if(1&e&&(r=l(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)l.d(t,n,function(e){return r[e]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="./";var r=this.webpackJsonprestool=this.webpackJsonprestool||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;a()}([])</script><script src="./static/js/2.7c8c2e97.chunk.js"></script><script src="./static/js/main.6bfcc0ad.chunk.js"></script></body></html>
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "62a17be81a9a806c130c549a55f7efa3",
"revision": "260f7b32e62212f39f14e289c5d3762e",
"url": "./index.html"
},
{
"revision": "2c2c33ed22ea3cb20857",
"url": "./static/css/2.5dbdccff.chunk.css"
},
{
"revision": "38eb9d0d9243ccb227e2",
"revision": "da7511d8c0d5378f120f",
"url": "./static/css/main.4cc0f9aa.chunk.css"
},
{
Expand All @@ -20,8 +20,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "./static/js/2.7c8c2e97.chunk.js.LICENSE"
},
{
"revision": "38eb9d0d9243ccb227e2",
"url": "./static/js/main.7336efbc.chunk.js"
"revision": "da7511d8c0d5378f120f",
"url": "./static/js/main.6bfcc0ad.chunk.js"
},
{
"revision": "58d6219fe1f60f2fa5af",
Expand Down
2 changes: 1 addition & 1 deletion build/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");

importScripts(
"./precache-manifest.cb860fbdcd8dbe8080de19e34af61e4a.js"
"./precache-manifest.1b5f585b6d711dcd919128291e36c30d.js"
);

self.addEventListener('message', (event) => {
Expand Down
2 changes: 2 additions & 0 deletions build/static/js/main.6bfcc0ad.chunk.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions build/static/js/main.6bfcc0ad.chunk.js.map

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions build/static/js/main.7336efbc.chunk.js

This file was deleted.

1 change: 0 additions & 1 deletion build/static/js/main.7336efbc.chunk.js.map

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "restool",
"version": "2.2.0",
"version": "2.2.1",
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.4.0",
Expand Down
27 changes: 13 additions & 14 deletions src/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ function App() {
const [config, setConfig] = useState<IConfig | null>(null);
const [activePage, setActivePage] = useState<IConfigPage | null>(config?.pages?.[0] || null);
const [error, setError] = useState<string | null>(null);

const appName: string = config?.name || defaultAppName;

async function loadConfig(url?: string): Promise<void> {
try {
const windowConfig = (window as any).RESTool?.config;
Expand Down Expand Up @@ -73,19 +74,19 @@ function App() {
oldTimestamp = performance.now();

function step (newTimestamp: number) {
scrollCount += Math.PI / (scrollDuration / (newTimestamp - oldTimestamp));
scrollCount += Math.PI / (scrollDuration / (newTimestamp - oldTimestamp));

if (scrollCount >= Math.PI) {
window.scrollTo(0, 0);
}
if (scrollCount >= Math.PI) {
window.scrollTo(0, 0);
}

if (window.scrollY === 0) {
return;
}
if (window.scrollY === 0) {
return;
}

window.scrollTo(0, Math.round(cosParameter + cosParameter * Math.cos(scrollCount)));
oldTimestamp = newTimestamp;
window.requestAnimationFrame(step);
window.scrollTo(0, Math.round(cosParameter + cosParameter * Math.cos(scrollCount)));
oldTimestamp = newTimestamp;
window.requestAnimationFrame(step);
}

window.requestAnimationFrame(step);
Expand All @@ -98,16 +99,14 @@ function App() {

useEffect(() => {
const { isValid, errorMessage } = ConfigService.validateConfig(config);

if (!isValid) {
setError(errorMessage);
toast.error(errorMessage);
return;
}
return;
}, [config]);

const appName: string = config?.name || defaultAppName;

return (
<div className="restool-app">
{
Expand Down
37 changes: 17 additions & 20 deletions src/components/cards/cards.comp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ interface IProps {
}

export const Cards = ({ items, fields, callbacks, customActions, customLabels, pagination }: IProps) => {
const editLabel: string = customLabels?.buttons?.editItem || 'Edit';
const deleteLabel: string = customLabels?.buttons?.deleteItem || 'Delete';
const paginationCallbacks = {
nextPage: callbacks.getNextPage || (() => { return; }),
previousPage: callbacks.getPreviousPage || (() => { return; }),
};

function renderRow(origField: IConfigDisplayField, value: any) {
if (value && typeof value === 'object') {
return 'object';
Expand All @@ -51,9 +58,6 @@ export const Cards = ({ items, fields, callbacks, customActions, customLabels, p
}
}

const editLabel: string = customLabels?.buttons?.editItem || 'Edit';
const deleteLabel: string = customLabels?.buttons?.deleteItem || 'Delete';

function renderActions(item: any, cardIdx: number) {
return (
<div className="actions-wrapper">
Expand Down Expand Up @@ -155,26 +159,19 @@ export const Cards = ({ items, fields, callbacks, customActions, customLabels, p
);
}

const paginationCallbacks = {
nextPage: callbacks.getNextPage || (() => { return; }),
previousPage: callbacks.getPreviousPage || (() => { return; }),
}

return (
<div>
<React.Fragment>
<div className="cards-wrapper">
{items.map(renderCard)}
</div>
<div>
{
pagination &&
pagination.type === 'buttons' &&
<Pagination
callbacks={paginationCallbacks}
pagination={pagination}
></Pagination>
}
</div>
</div>
{
pagination &&
pagination.type === 'buttons' &&
<Pagination
callbacks={paginationCallbacks}
pagination={pagination}
></Pagination>
}
</React.Fragment>
)
}
37 changes: 20 additions & 17 deletions src/components/page/page.comp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,8 @@ const PageComp = ({ context }: IProps) => {
});
}

function extractQueryParams(): IConfigInputField[] {
function extractQueryParams(params: IConfigInputField[]): IConfigInputField[] {
const parsedParams = QueryString.parse(location.search);
const params = initQueryParams;
const finalQueryParams = params.map((queryParam) => {
if (typeof parsedParams[queryParam.name] !== 'undefined') {
queryParam.value = queryParam.type === 'boolean' ? (parsedParams[queryParam.name] === 'true') : decodeURIComponent(parsedParams[queryParam.name] as any);
Expand All @@ -190,9 +189,9 @@ const PageComp = ({ context }: IProps) => {
return queryParam;
});

setPagination(updateParamsToPaginationState(finalQueryParams))
setPagination(getUpdatedPaginationState(finalQueryParams))

return finalQueryParams
return finalQueryParams;
}

async function getAllRequest() {
Expand All @@ -201,6 +200,7 @@ const PageComp = ({ context }: IProps) => {
} else {
setLoading(true);
}

setError(null);

try {
Expand Down Expand Up @@ -237,7 +237,7 @@ const PageComp = ({ context }: IProps) => {

if (paginationConfig) {
const total = paginationConfig.fields?.total ? dataHelpers.extractDataByDataPath(result, paginationConfig.fields.total.dataPath) : undefined;
const newPaginationState = updateParamsToPaginationState(queryParams, total);
const newPaginationState = getUpdatedPaginationState(queryParams, total);
if (newPaginationState) {
setPagination(newPaginationState);
}
Expand Down Expand Up @@ -334,19 +334,18 @@ const PageComp = ({ context }: IProps) => {
}

function submitQueryParams(updatedParams: IConfigInputField[], reset?: boolean) {
if (loading) {
return;
}

if (reset) {
setItems([]);
remove(updatedParams, param => ['page', 'limit'].includes(param.name));
updatedParams = buildInitQueryParamsAndPaginationState(updatedParams, paginationConfig).initQueryParams;
}

setQueryParams(updatedParams);

setPagination(updateParamsToPaginationState(updatedParams))

if (loading) {
return;
}
setPagination(getUpdatedPaginationState(updatedParams));

let paramsToUrl = [...updatedParams];

Expand Down Expand Up @@ -374,10 +373,11 @@ const PageComp = ({ context }: IProps) => {
}
}

function updateParamsToPaginationState(updatedParams: IConfigInputField[], total?: number): IPaginationState | undefined {
function getUpdatedPaginationState(updatedParams: IConfigInputField[], total?: number): IPaginationState | undefined {
if (!paginationConfig) {
return undefined;
return;
}

const newState: IPaginationState = pagination ? pagination : {
type: paginationConfig.type,
page: parseInt(paginationConfig.params?.page?.value || '1'),
Expand All @@ -387,13 +387,15 @@ const PageComp = ({ context }: IProps) => {
hasNextPage: false,
sortBy: paginationConfig.params?.sortBy?.value,
};

newState.total = total || pagination?.total;
newState.page = parseInt(updatedParams.find(param => param.name === paginationConfig?.params?.page?.name)?.value) || newState.page;
newState.limit = parseInt(updatedParams.find(param => param.name === paginationConfig?.params?.limit?.name)?.value) || newState.limit;
newState.descending = updatedParams.find(param => param.name === paginationConfig?.params?.descending?.name)?.value === 'true' || newState.descending;
newState.sortBy = updatedParams.find(param => param.name === paginationConfig?.params?.sortBy?.name)?.value || newState.sortBy;
newState.hasPreviousPage = paginationHelpers.hasPreviousPage(newState.page);
newState.hasNextPage = paginationHelpers.hasNextPage(newState.page, newState.limit, newState.total);

return newState;
}

Expand Down Expand Up @@ -550,10 +552,11 @@ const PageComp = ({ context }: IProps) => {
}, [page]);

useEffect(() => {
setQueryParams(extractQueryParams());
return () => {
setItems([]);
}
const { initQueryParams, initialPagination } = buildInitQueryParamsAndPaginationState(getAllConfig?.queryParams || [], paginationConfig);

setItems([]);
setQueryParams(extractQueryParams(initQueryParams));
setPagination(initialPagination);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [activePage]);

Expand Down
17 changes: 8 additions & 9 deletions src/components/table/table.comp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ interface IProps {
}

export const Table = ({ items, fields, pagination, callbacks, customActions, customLabels }: IProps) => {
const editLabel = customLabels?.buttons?.editItem || 'Edit';
const deleteLabel = customLabels?.buttons?.deleteItem || 'Delete';
const actionColumnHeader = customLabels?.tableColumnHeaders?.actions || 'Actions';
const paginationCallbacks = {
nextPage: callbacks.getNextPage || (() => { return; }),
previousPage: callbacks.getPreviousPage || (() => { return; }),
};

function renderTableCell(origField: IConfigDisplayField, value: any) {
if (value && typeof value === 'object') {
return 'object';
Expand All @@ -48,10 +56,6 @@ export const Table = ({ items, fields, pagination, callbacks, customActions, cus
}
}

const editLabel = customLabels?.buttons?.editItem || 'Edit';
const deleteLabel = customLabels?.buttons?.deleteItem || 'Delete';
const actionColumnHeader = customLabels?.tableColumnHeaders?.actions || 'Actions';

function renderTableRow(item: any, rowIdx: number) {
return (
<tr key={`tr_${rowIdx}`}>
Expand Down Expand Up @@ -122,11 +126,6 @@ export const Table = ({ items, fields, pagination, callbacks, customActions, cus
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const paginationCallbacks = {
nextPage: callbacks.getNextPage || (() => { return; }),
previousPage: callbacks.getPreviousPage || (() => { return; }),
}

if (pagination?.type === 'infinite-scroll') {
return (
<InfiniteScroll
Expand Down

0 comments on commit 941f050

Please sign in to comment.