Skip to content

Commit

Permalink
refactor(store): django pagination and query selectors
Browse files Browse the repository at this point in the history
Signed-off-by: Boaz Shuster <boaz.shuster.github@gmail.com>
  • Loading branch information
boaz0 committed Jun 28, 2020
1 parent 0e18cfb commit cfcb37e
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 124 deletions.
71 changes: 9 additions & 62 deletions src/store/costModels/selectors.ts
@@ -1,5 +1,7 @@
import { parseApiError } from 'pages/costModels/createCostModelWizard/parseError';
import { FetchStatus } from 'store/common';
import { selectPagination } from 'store/djangoUtils/pagination';
import { selectQuery } from 'store/djangoUtils/query';
import { RootState } from 'store/rootReducer';
import { stateKey } from './reducer';

Expand Down Expand Up @@ -45,69 +47,14 @@ export const currentFilterValue = (state: RootState) =>
export const currentFilterType = (state: RootState) =>
costModelsState(state).currentFilterType;

export const query = (state: RootState) => {
const payload = costModelsState(state).costModels;
if (payload === null) {
return {
ordering: null,
name: null,
source_type: null,
description: null,
offset: null,
limit: null,
};
}
const urlParams = new URLSearchParams(payload.links.first.split('?')[1]);
return {
ordering: urlParams.get('ordering'),
name: urlParams.get('name'),
source_type: urlParams.get('source_type'),
description: urlParams.get('description'),
offset: urlParams.get('offset'),
limit: urlParams.get('limit'),
};
};
export const query = selectQuery(
(state: RootState) => costModelsState(state).costModels,
['ordering', 'name', 'source_type', 'description', 'offset', 'limit']
);

export const pagination = (state: RootState) => {
const payload = costModelsState(state).costModels;
if (payload === null) {
return {
page: 1,
perPage: 1,
count: 0,
};
}

let urlParams = null;
if (payload.links.next !== null) {
urlParams = new URLSearchParams(payload.links.next.split('?')[1]);
const limit = Number(urlParams.get('limit'));
const offset = Number(urlParams.get('offset')) - limit;
return {
page: offset / limit + 1,
perPage: limit,
count: payload.meta.count,
};
}

if (payload.links.previous !== null) {
urlParams = new URLSearchParams(payload.links.previous.split('?')[1]);
const limit = Number(urlParams.get('limit'));
const offset = Number(urlParams.get('offset')) + limit;
return {
page: offset / limit + 1,
perPage: limit,
count: payload.meta.count,
};
}

urlParams = new URLSearchParams(payload.links.first.split('?')[1]);
return {
page: 1,
perPage: Number(urlParams.get('limit')),
count: payload.meta.count,
};
};
export const pagination = selectPagination(
(state: RootState) => costModelsState(state).costModels
);

export const updateProcessing = (state: RootState) =>
costModelsState(state).update.status === FetchStatus.inProgress;
Expand Down
50 changes: 50 additions & 0 deletions src/store/djangoUtils/pagination.ts
@@ -0,0 +1,50 @@
import { RootState } from 'store/rootReducer';
import { PageResults } from './types';

export const selectPagination = <T extends PageResults>(
stateProjector: (state: RootState) => T
) => {
return (state: RootState) => {
return getPagination(stateProjector(state));
};
};

export const getPagination = <T extends PageResults>(payload: T) => {
if (payload === null) {
return {
page: 1,
perPage: 1,
count: 0,
};
}

let urlParams = null;
if (payload.links.next !== null) {
urlParams = new URLSearchParams(payload.links.next.split('?')[1]);
const limit = Number(urlParams.get('limit'));
const offset = Number(urlParams.get('offset')) - limit;
return {
page: offset / limit + 1,
perPage: limit,
count: payload.meta.count,
};
}

if (payload.links.previous !== null) {
urlParams = new URLSearchParams(payload.links.previous.split('?')[1]);
const limit = Number(urlParams.get('limit'));
const offset = Number(urlParams.get('offset')) + limit;
return {
page: offset / limit + 1,
perPage: limit,
count: payload.meta.count,
};
}

urlParams = new URLSearchParams(payload.links.first.split('?')[1]);
return {
page: 1,
perPage: Number(urlParams.get('limit')),
count: payload.meta.count,
};
};
22 changes: 22 additions & 0 deletions src/store/djangoUtils/query.ts
@@ -0,0 +1,22 @@
import { RootState } from 'store/rootReducer';
import { PageResults } from './types';

export const selectQuery = <T extends PageResults>(
stateProjector: (state: RootState) => T,
keys: string[]
) => {
return (state: RootState) => {
const params = getQuery(stateProjector(state));
return keys.reduce((acc, curr) => {
return { ...acc, [curr]: params.get(curr) };
}, {});
};
};

const getQuery = <T extends PageResults>(payload: T) => {
if (payload === null) {
return new URLSearchParams();
}
const [, search] = payload.links.first.split('?');
return new URLSearchParams(search);
};
6 changes: 6 additions & 0 deletions src/store/djangoUtils/types.ts
@@ -0,0 +1,6 @@
import { PagedLinks, PagedMetaData } from 'api/api';

export interface PageResults {
meta: PagedMetaData;
links?: PagedLinks;
}
71 changes: 9 additions & 62 deletions src/store/sourceSettings/selectors.ts
@@ -1,3 +1,5 @@
import { selectPagination } from 'store/djangoUtils/pagination';
import { selectQuery } from 'store/djangoUtils/query';
import { RootState } from 'store/rootReducer';
import { stateKey } from './reducer';

Expand All @@ -21,66 +23,11 @@ export const currentFilterValue = (state: RootState) =>
export const currentFilterType = (state: RootState) =>
sourcesState(state).currentFilterType;

export const query = (state: RootState) => {
const sourcesPayload = sourcesState(state).sources;
if (sourcesPayload === null) {
return {
name: null,
type: null,
offset: null,
limit: null,
};
}
const urlParams = new URLSearchParams(
sourcesPayload.links.first.split('?')[1]
);
return {
name: urlParams.get('name'),
type: urlParams.get('type'),
offset: urlParams.get('offset'),
limit: urlParams.get('limit'),
};
};
export const query = selectQuery(
(state: RootState) => sourcesState(state).sources,
['name', 'type', 'offset', 'limit']
);

export const pagination = (state: RootState) => {
const sourcesPayload = sourcesState(state).sources;
if (sourcesPayload === null) {
return {
page: 1,
perPage: 1,
count: 0,
};
}

let urlParams = null;
if (sourcesPayload.links.next !== null) {
urlParams = new URLSearchParams(sourcesPayload.links.next.split('?')[1]);
const limit = Number(urlParams.get('limit'));
const offset = Number(urlParams.get('offset')) - limit;
return {
page: offset / limit + 1,
perPage: limit,
count: sourcesPayload.meta.count,
};
}

if (sourcesPayload.links.previous !== null) {
urlParams = new URLSearchParams(
sourcesPayload.links.previous.split('?')[1]
);
const limit = Number(urlParams.get('limit'));
const offset = Number(urlParams.get('offset')) + limit;
return {
page: offset / limit + 1,
perPage: limit,
count: sourcesPayload.meta.count,
};
}

urlParams = new URLSearchParams(sourcesPayload.links.first.split('?')[1]);
return {
page: 1,
perPage: Number(urlParams.get('limit')),
count: sourcesPayload.meta.count,
};
};
export const pagination = selectPagination(
(state: RootState) => sourcesState(state).sources
);

0 comments on commit cfcb37e

Please sign in to comment.