Refactored many helpers to Typescript

This commit is contained in:
Alejandro Celaya 2020-08-22 18:32:48 +02:00
parent 7c67fa4149
commit 62df46d648
18 changed files with 145 additions and 113 deletions

15
package-lock.json generated
View file

@ -3090,6 +3090,12 @@
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
"dev": true
},
"@types/geojson": {
"version": "7946.0.7",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz",
"integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==",
"dev": true
},
"@types/glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
@ -3299,6 +3305,15 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
"@types/leaflet": {
"version": "1.5.17",
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.5.17.tgz",
"integrity": "sha512-2XYq9k6kNjhNI7PaTz8Rdxcc8Vzwu97OaS9CtcrTxnTSxFUGwjlGjTDvhTLJU+JRSfZ4lBwGcl0SjZHALdVr6g==",
"dev": true,
"requires": {
"@types/geojson": "*"
}
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",

View file

@ -78,6 +78,7 @@
"@types/classnames": "^2.2.10",
"@types/enzyme": "^3.10.5",
"@types/jest": "^26.0.10",
"@types/leaflet": "^1.5.17",
"@types/moment": "^2.13.0",
"@types/ramda": "^0.27.14",
"@types/react": "^16.9.46",

View file

@ -6,7 +6,7 @@ import { homepage } from '../package.json';
import registerServiceWorker from './registerServiceWorker';
import container from './container';
import store from './container/store';
import { fixLeafletIcons } from './utils/utils';
import { fixLeafletIcons } from './utils/helpers/leaflet';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'react-datepicker/dist/react-datepicker.css';
import 'leaflet/dist/leaflet.css';

View file

@ -10,4 +10,4 @@ const formatDateFromFormat = (date?: NullableDate, format?: string): NullableDat
export const formatDate = (format = 'YYYY-MM-DD') => (date?: NullableDate) => formatDateFromFormat(date, format);
export const formatIsoDate = (date: NullableDate) => formatDateFromFormat(date, undefined);
export const formatIsoDate = (date?: NullableDate) => formatDateFromFormat(date, undefined);

View file

@ -0,0 +1,16 @@
// TODO Migrate this file to Typescript
import L from 'leaflet';
import marker2x from 'leaflet/dist/images/marker-icon-2x.png';
import marker from 'leaflet/dist/images/marker-icon.png';
import markerShadow from 'leaflet/dist/images/marker-shadow.png';
export const fixLeafletIcons = () => {
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl: marker2x,
iconUrl: marker,
shadowUrl: markerShadow,
});
};

View file

@ -1,8 +0,0 @@
const TEN_ROUNDING_NUMBER = 10;
const { ceil } = Math;
const formatter = new Intl.NumberFormat('en-US');
export const prettify = (number) => formatter.format(number);
export const roundTen = (number) => ceil(number / TEN_ROUNDING_NUMBER) * TEN_ROUNDING_NUMBER;

View file

@ -0,0 +1,7 @@
const TEN_ROUNDING_NUMBER = 10;
const { ceil } = Math;
const formatter = new Intl.NumberFormat('en-US');
export const prettify = (number: number) => formatter.format(number);
export const roundTen = (number: number) => ceil(number / TEN_ROUNDING_NUMBER) * TEN_ROUNDING_NUMBER;

View file

@ -1,27 +0,0 @@
import { max, min, range } from 'ramda';
export const ELLIPSIS = '...';
export const progressivePagination = (currentPage, pageCount) => {
const delta = 2;
const pages = range(
max(delta, currentPage - delta),
min(pageCount - 1, currentPage + delta) + 1,
);
if (currentPage - delta > delta) {
pages.unshift(ELLIPSIS);
}
if (currentPage + delta < pageCount - 1) {
pages.push(ELLIPSIS);
}
pages.unshift(1);
pages.push(pageCount);
return pages;
};
export const keyForPage = (pageNumber, index) => pageNumber !== ELLIPSIS ? pageNumber : `${pageNumber}_${index}`;
export const isPageDisabled = (pageNumber) => pageNumber === ELLIPSIS;

View file

@ -0,0 +1,29 @@
import { max, min, range } from 'ramda';
export const ELLIPSIS = '...';
type NumberOrEllipsis = number | '...';
export const progressivePagination = (currentPage: number, pageCount: number): NumberOrEllipsis[] => {
const delta = 2;
const pages: NumberOrEllipsis[] = range(
max(delta, currentPage - delta),
min(pageCount - 1, currentPage + delta) + 1,
);
if (currentPage - delta > delta) {
pages.unshift(ELLIPSIS);
}
if (currentPage + delta < pageCount - 1) {
pages.push(ELLIPSIS);
}
pages.unshift(1);
pages.push(pageCount);
return pages;
};
export const keyForPage = (pageNumber: NumberOrEllipsis, index: number) => pageNumber !== ELLIPSIS ? pageNumber : `${pageNumber}_${index}`;
export const isPageDisabled = (pageNumber: NumberOrEllipsis) => pageNumber === ELLIPSIS;

View file

@ -1,27 +0,0 @@
import { compare } from 'compare-versions';
import { identity, memoizeWith } from 'ramda';
import { hasValue } from '../utils';
export const versionMatch = (versionToMatch, { maxVersion, minVersion }) => {
if (!hasValue(versionToMatch)) {
return false;
}
const matchesMinVersion = !minVersion || compare(versionToMatch, minVersion, '>=');
const matchesMaxVersion = !maxVersion || compare(versionToMatch, maxVersion, '<=');
return !!(matchesMaxVersion && matchesMinVersion);
};
const versionIsValidSemVer = memoizeWith(identity, (version) => {
try {
return compare(version, version, '=');
} catch (e) {
return false;
}
});
export const versionToPrintable = (version) => !versionIsValidSemVer(version) ? version : `v${version}`;
export const versionToSemVer = (defaultValue = 'latest') =>
(version) => versionIsValidSemVer(version) ? version : defaultValue;

View file

@ -0,0 +1,32 @@
import { compare } from 'compare-versions';
import { identity, memoizeWith } from 'ramda';
import { Empty, hasValue } from '../utils';
export interface Versions {
maxVersion?: string;
minVersion?: string;
}
export const versionMatch = (versionToMatch: string | Empty, { maxVersion, minVersion }: Versions): boolean => {
if (!hasValue(versionToMatch)) {
return false;
}
const matchesMinVersion = !minVersion || compare(versionToMatch, minVersion, '>=');
const matchesMaxVersion = !maxVersion || compare(versionToMatch, maxVersion, '<=');
return matchesMaxVersion && matchesMinVersion;
};
const versionIsValidSemVer = memoizeWith(identity, (version: string) => {
try {
return compare(version, version, '=');
} catch (e) {
return false;
}
});
export const versionToPrintable = (version: string) => !versionIsValidSemVer(version) ? version : `v${version}`;
export const versionToSemVer = (defaultValue = 'latest') =>
(version: string) => versionIsValidSemVer(version) ? version : defaultValue;

View file

@ -1,32 +0,0 @@
import L from 'leaflet';
import marker2x from 'leaflet/dist/images/marker-icon-2x.png';
import marker from 'leaflet/dist/images/marker-icon.png';
import markerShadow from 'leaflet/dist/images/marker-shadow.png';
import { isEmpty, isNil, range } from 'ramda';
export const determineOrderDir = (clickedField, currentOrderField, currentOrderDir) => {
if (currentOrderField !== clickedField) {
return 'ASC';
}
const newOrderMap = {
ASC: 'DESC',
DESC: undefined,
};
return currentOrderDir ? newOrderMap[currentOrderDir] : 'ASC';
};
export const fixLeafletIcons = () => {
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl: marker2x,
iconUrl: marker,
shadowUrl: markerShadow,
});
};
export const rangeOf = (size, mappingFn, startAt = 1) => range(startAt, size + 1).map(mappingFn);
export const hasValue = (value) => !isNil(value) && !isEmpty(value);

23
src/utils/utils.ts Normal file
View file

@ -0,0 +1,23 @@
import { isEmpty, isNil, range } from 'ramda';
export type OrderDir = 'ASC' | 'DESC' | undefined;
export const determineOrderDir = (currentField: string, newField: string, currentOrderDir: OrderDir): OrderDir => {
if (currentField !== newField) {
return 'ASC';
}
const newOrderMap: Record<'ASC' | 'DESC', OrderDir> = {
ASC: 'DESC',
DESC: undefined,
};
return currentOrderDir ? newOrderMap[currentOrderDir] : 'ASC';
};
export const rangeOf = <T>(size: number, mappingFn: (value: number) => T, startAt = 1): T[] =>
range(startAt, size + 1).map(mappingFn);
export type Empty = null | undefined | '' | never[];
export const hasValue = <T>(value: T | Empty): value is T => !isNil(value) && !isEmpty(value);

View file

@ -0,0 +1,19 @@
import L from 'leaflet';
import marker2x from 'leaflet/dist/images/marker-icon-2x.png';
import marker from 'leaflet/dist/images/marker-icon.png';
import markerShadow from 'leaflet/dist/images/marker-shadow.png';
import { fixLeafletIcons } from '../../../src/utils/helpers/leaflet';
describe('leaflet', () => {
describe('fixLeafletIcons', () => {
it('updates icons used by leaflet', () => {
fixLeafletIcons();
const { iconRetinaUrl, iconUrl, shadowUrl } = L.Icon.Default.prototype.options;
expect(iconRetinaUrl).toEqual(marker2x);
expect(iconUrl).toEqual(marker);
expect(shadowUrl).toEqual(markerShadow);
});
});
});

View file

@ -1,8 +1,4 @@
import L from 'leaflet';
import marker2x from 'leaflet/dist/images/marker-icon-2x.png';
import marker from 'leaflet/dist/images/marker-icon.png';
import markerShadow from 'leaflet/dist/images/marker-shadow.png';
import { determineOrderDir, fixLeafletIcons, rangeOf } from '../../src/utils/utils';
import { determineOrderDir, rangeOf } from '../../src/utils/utils';
describe('utils', () => {
describe('determineOrderDir', () => {
@ -27,18 +23,6 @@ describe('utils', () => {
});
});
describe('fixLeafletIcons', () => {
it('updates icons used by leaflet', () => {
fixLeafletIcons();
const { iconRetinaUrl, iconUrl, shadowUrl } = L.Icon.Default.prototype.options;
expect(iconRetinaUrl).toEqual(marker2x);
expect(iconUrl).toEqual(marker);
expect(shadowUrl).toEqual(markerShadow);
});
});
describe('rangeOf', () => {
const func = (i) => `result_${i}`;
const size = 5;