mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-03-03 14:21:49 +00:00
Updated to airbnb coding styles
This commit is contained in:
@@ -15,7 +15,7 @@ export interface DropdownBtnProps {
|
||||
export const DropdownBtn: FC<DropdownBtnProps> = (
|
||||
{ text, disabled = false, className = '', children, dropdownClassName, right = false, minWidth },
|
||||
) => {
|
||||
const [ isOpen, toggle ] = useToggle();
|
||||
const [isOpen, toggle] = useToggle();
|
||||
const toggleClasses = `dropdown-btn__toggle btn-block ${className}`;
|
||||
const style = { minWidth: minWidth && `${minWidth}px` };
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ export function OrderingDropdown<T extends string = string>(
|
||||
end={right}
|
||||
className={classNames('w-100', { 'ordering-dropdown__menu--link': !isButton })}
|
||||
>
|
||||
{toPairs(items).map(([ fieldKey, fieldValue ]) => (
|
||||
{toPairs(items).map(([fieldKey, fieldValue]) => (
|
||||
<DropdownItem key={fieldKey} active={order.field === fieldKey} onClick={handleItemClick(fieldKey as T)}>
|
||||
{fieldValue}
|
||||
{order.field === fieldKey && (
|
||||
|
||||
@@ -16,7 +16,7 @@ interface SearchFieldProps {
|
||||
}
|
||||
|
||||
const SearchField = ({ onChange, className, large = true, noBorder = false, initialValue = '' }: SearchFieldProps) => {
|
||||
const [ searchTerm, setSearchTerm ] = useState(initialValue);
|
||||
const [searchTerm, setSearchTerm] = useState(initialValue);
|
||||
|
||||
const resetTimer = () => {
|
||||
timer && clearTimeout(timer);
|
||||
|
||||
@@ -25,8 +25,8 @@ export const DateRangeSelector = (
|
||||
{ onDatesChange, initialDateRange, defaultText, disabled, updatable = false }: DateRangeSelectorProps,
|
||||
) => {
|
||||
const initialIntervalIsRange = rangeIsInterval(initialDateRange);
|
||||
const [ activeInterval, setActiveInterval ] = useState(initialIntervalIsRange ? initialDateRange : undefined);
|
||||
const [ activeDateRange, setActiveDateRange ] = useState(initialIntervalIsRange ? undefined : initialDateRange);
|
||||
const [activeInterval, setActiveInterval] = useState(initialIntervalIsRange ? initialDateRange : undefined);
|
||||
const [activeDateRange, setActiveDateRange] = useState(initialIntervalIsRange ? undefined : initialDateRange);
|
||||
|
||||
const updateDateRange = (dateRange: DateRange) => {
|
||||
setActiveInterval(dateRangeIsEmpty(dateRange) ? 'all' : undefined);
|
||||
@@ -44,7 +44,7 @@ export const DateRangeSelector = (
|
||||
|
||||
isDateInterval && updateInterval(initialDateRange);
|
||||
initialDateRange && !isDateInterval && updateDateRange(initialDateRange);
|
||||
}, [ initialDateRange ]);
|
||||
}, [initialDateRange]);
|
||||
|
||||
return (
|
||||
<DropdownBtn disabled={disabled} text={rangeOrIntervalToString(activeInterval ?? activeDateRange) ?? defaultText}>
|
||||
|
||||
@@ -88,13 +88,13 @@ export const dateToMatchingInterval = (date: DateOrString): DateInterval => {
|
||||
const theDate: Date = parseISO(date);
|
||||
|
||||
return cond<never, DateInterval>([
|
||||
[ () => isBeforeOrEqual(startOfDay(new Date()), theDate), () => 'today' ],
|
||||
[ () => isBeforeOrEqual(startOfDaysAgo(1), theDate), () => 'yesterday' ],
|
||||
[ () => isBeforeOrEqual(startOfDaysAgo(7), theDate), () => 'last7Days' ],
|
||||
[ () => isBeforeOrEqual(startOfDaysAgo(30), theDate), () => 'last30Days' ],
|
||||
[ () => isBeforeOrEqual(startOfDaysAgo(90), theDate), () => 'last90Days' ],
|
||||
[ () => isBeforeOrEqual(startOfDaysAgo(180), theDate), () => 'last180Days' ],
|
||||
[ () => isBeforeOrEqual(startOfDaysAgo(365), theDate), () => 'last365Days' ],
|
||||
[ T, () => 'all' ],
|
||||
[() => isBeforeOrEqual(startOfDay(new Date()), theDate), () => 'today'],
|
||||
[() => isBeforeOrEqual(startOfDaysAgo(1), theDate), () => 'yesterday'],
|
||||
[() => isBeforeOrEqual(startOfDaysAgo(7), theDate), () => 'last7Days'],
|
||||
[() => isBeforeOrEqual(startOfDaysAgo(30), theDate), () => 'last30Days'],
|
||||
[() => isBeforeOrEqual(startOfDaysAgo(90), theDate), () => 'last90Days'],
|
||||
[() => isBeforeOrEqual(startOfDaysAgo(180), theDate), () => 'last180Days'],
|
||||
[() => isBeforeOrEqual(startOfDaysAgo(365), theDate), () => 'last365Days'],
|
||||
[T, () => 'all'],
|
||||
])();
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ import { LabeledFormGroup } from './LabeledFormGroup';
|
||||
export interface InputFormGroupProps {
|
||||
value: string;
|
||||
onChange: (newValue: string) => void;
|
||||
id?: string;
|
||||
type?: InputType;
|
||||
required?: boolean;
|
||||
placeholder?: string;
|
||||
|
||||
@@ -7,6 +7,7 @@ interface LabeledFormGroupProps {
|
||||
labelClassName?: string;
|
||||
}
|
||||
|
||||
/* eslint-disable jsx-a11y/label-has-associated-control */
|
||||
export const LabeledFormGroup: FC<LabeledFormGroupProps> = (
|
||||
{ children, label, className = '', labelClassName = '', noMargin = false },
|
||||
) => (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ActiveElement, ChartEvent, ChartType, TooltipItem } from 'chart.js';
|
||||
import { prettify } from './numbers';
|
||||
|
||||
export const pointerOnHover = ({ native }: ChartEvent, [ firstElement ]: ActiveElement[]) => {
|
||||
export const pointerOnHover = ({ native }: ChartEvent, [firstElement]: ActiveElement[]) => {
|
||||
if (!native?.target) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -15,15 +15,15 @@ const formatDateFromFormat = (date?: NullableDate, theFormat?: string): Optional
|
||||
return theFormat ? format(date, theFormat) : formatISO(date);
|
||||
};
|
||||
|
||||
export const formatDate = (format = 'yyyy-MM-dd') => (date?: NullableDate) => formatDateFromFormat(date, format);
|
||||
export const formatDate = (theFormat = 'yyyy-MM-dd') => (date?: NullableDate) => formatDateFromFormat(date, theFormat);
|
||||
|
||||
export const formatIsoDate = (date?: NullableDate) => formatDateFromFormat(date, undefined);
|
||||
|
||||
export const formatInternational = formatDate();
|
||||
|
||||
export const parseDate = (date: string, format: string) => parse(date, format, new Date());
|
||||
export const parseDate = (date: string, theFormat: string) => parse(date, theFormat, new Date());
|
||||
|
||||
export const parseISO = (date: DateOrString): Date => isDateObject(date) ? date : stdParseISO(date);
|
||||
export const parseISO = (date: DateOrString): Date => (isDateObject(date) ? date : stdParseISO(date));
|
||||
|
||||
export const isBetween = (date: DateOrString, start?: DateOrString, end?: DateOrString): boolean => {
|
||||
try {
|
||||
|
||||
@@ -5,27 +5,15 @@ const serverMatchesVersions = (versions: Versions) => (selectedServer: SelectedS
|
||||
isReachableServer(selectedServer) && versionMatch(selectedServer.version, versions);
|
||||
|
||||
export const supportsQrCodeSizeInQuery = serverMatchesVersions({ minVersion: '2.5.0' });
|
||||
|
||||
export const supportsShortUrlTitle = serverMatchesVersions({ minVersion: '2.6.0' });
|
||||
|
||||
export const supportsOrphanVisits = supportsShortUrlTitle;
|
||||
|
||||
export const supportsQrCodeMargin = supportsShortUrlTitle;
|
||||
|
||||
export const supportsTagsInPatch = supportsShortUrlTitle;
|
||||
|
||||
export const supportsBotVisits = serverMatchesVersions({ minVersion: '2.7.0' });
|
||||
|
||||
export const supportsCrawlableVisits = supportsBotVisits;
|
||||
|
||||
export const supportsQrErrorCorrection = serverMatchesVersions({ minVersion: '2.8.0' });
|
||||
|
||||
export const supportsDomainRedirects = supportsQrErrorCorrection;
|
||||
|
||||
export const supportsForwardQuery = serverMatchesVersions({ minVersion: '2.9.0' });
|
||||
|
||||
export const supportsDefaultDomainRedirectsEdition = serverMatchesVersions({ minVersion: '2.10.0' });
|
||||
|
||||
export const supportsNonOrphanVisits = serverMatchesVersions({ minVersion: '3.0.0' });
|
||||
|
||||
export const supportsAllTagsFiltering = supportsNonOrphanVisits;
|
||||
|
||||
@@ -10,7 +10,7 @@ export const saveUrl = ({ document }: Window, url: string, filename: string) =>
|
||||
};
|
||||
|
||||
export const saveCsv = (window: Window, csv: string, filename: string) => {
|
||||
const blob = new Blob([ csv ], { type: 'text/csv;charset=utf-8;' });
|
||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
saveUrl(window, url, filename);
|
||||
|
||||
@@ -11,7 +11,7 @@ export const useStateFlagTimeout = (
|
||||
setTimeout: (callback: Function, timeout: number) => number,
|
||||
clearTimeout: (timer: number) => void,
|
||||
): StateFlagTimeout => (initialValue = false, delay = DEFAULT_DELAY) => {
|
||||
const [ flag, setFlag ] = useState<boolean>(initialValue);
|
||||
const [flag, setFlag] = useState<boolean>(initialValue);
|
||||
const timeout = useRef<number | undefined>(undefined);
|
||||
const callback = () => {
|
||||
setFlag(!initialValue);
|
||||
@@ -23,15 +23,15 @@ export const useStateFlagTimeout = (
|
||||
timeout.current = setTimeout(() => setFlag(initialValue), delay);
|
||||
};
|
||||
|
||||
return [ flag, callback ];
|
||||
return [flag, callback];
|
||||
};
|
||||
|
||||
type ToggleResult = [ boolean, () => void, () => void, () => void ];
|
||||
|
||||
export const useToggle = (initialValue = false): ToggleResult => {
|
||||
const [ flag, setFlag ] = useState<boolean>(initialValue);
|
||||
const [flag, setFlag] = useState<boolean>(initialValue);
|
||||
|
||||
return [ flag, () => setFlag(!flag), () => setFlag(true), () => setFlag(false) ];
|
||||
return [flag, () => setFlag(!flag), () => setFlag(true), () => setFlag(false)];
|
||||
};
|
||||
|
||||
export const useSwipeable = (showSidebar: () => void, hideSidebar: () => void) => {
|
||||
@@ -55,17 +55,17 @@ export const useSwipeable = (showSidebar: () => void, hideSidebar: () => void) =
|
||||
};
|
||||
|
||||
export const useQueryState = <T>(paramName: string, initialState: T): [ T, (newValue: T) => void ] => {
|
||||
const [ value, setValue ] = useState(initialState);
|
||||
const setValueWithLocation = (value: T) => {
|
||||
const [value, setValue] = useState(initialState);
|
||||
const setValueWithLocation = (valueToSet: T) => {
|
||||
const { location, history } = window;
|
||||
const query = parseQuery<any>(location.search);
|
||||
|
||||
query[paramName] = value;
|
||||
query[paramName] = valueToSet;
|
||||
history.pushState(null, '', `${location.pathname}?${stringifyQuery(query)}`);
|
||||
setValue(value);
|
||||
setValue(valueToSet);
|
||||
};
|
||||
|
||||
return [ value, setValueWithLocation ];
|
||||
return [value, setValueWithLocation];
|
||||
};
|
||||
|
||||
export const useEffectExceptFirstTime = (callback: EffectCallback, deps: DependencyList): void => {
|
||||
|
||||
@@ -4,7 +4,7 @@ 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 as any)._getIconUrl;
|
||||
delete (L.Icon.Default.prototype as any)._getIconUrl; // eslint-disable-line no-underscore-dangle
|
||||
|
||||
L.Icon.Default.mergeOptions({
|
||||
iconRetinaUrl: marker2x,
|
||||
|
||||
@@ -22,20 +22,20 @@ export const determineOrderDir = <T extends string = string>(
|
||||
return currentOrderDir ? newOrderMap[currentOrderDir] : 'ASC';
|
||||
};
|
||||
|
||||
export const sortList = <List>(list: List[], { field, dir }: Order<Partial<keyof List>>) => !field || !dir
|
||||
? list
|
||||
: list.sort((a, b) => {
|
||||
export const sortList = <List>(list: List[], { field, dir }: Order<Partial<keyof List>>) => (
|
||||
!field || !dir ? list : list.sort((a, b) => {
|
||||
const greaterThan = dir === 'ASC' ? 1 : -1;
|
||||
const smallerThan = dir === 'ASC' ? -1 : 1;
|
||||
|
||||
return a[field] > b[field] ? greaterThan : smallerThan;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
export const orderToString = <T>(order: Order<T>): string | undefined =>
|
||||
order.dir ? `${order.field}-${order.dir}` : undefined;
|
||||
export const orderToString = <T>(order: Order<T>): string | undefined => (
|
||||
order.dir ? `${order.field}-${order.dir}` : undefined
|
||||
);
|
||||
|
||||
export const stringToOrder = <T>(order: string): Order<T> => {
|
||||
const [ field, dir ] = order.split('-') as [ T | undefined, OrderDir | undefined ];
|
||||
|
||||
const [field, dir] = order.split('-') as [ T | undefined, OrderDir | undefined ];
|
||||
return { field, dir };
|
||||
};
|
||||
|
||||
@@ -30,7 +30,10 @@ export const progressivePagination = (currentPage: number, pageCount: number): N
|
||||
|
||||
export const pageIsEllipsis = (pageNumber: NumberOrEllipsis): pageNumber is Ellipsis => pageNumber === ELLIPSIS;
|
||||
|
||||
export const prettifyPageNumber = (pageNumber: NumberOrEllipsis): string =>
|
||||
pageIsEllipsis(pageNumber) ? pageNumber : prettify(pageNumber);
|
||||
export const prettifyPageNumber = (pageNumber: NumberOrEllipsis): string => (
|
||||
pageIsEllipsis(pageNumber) ? pageNumber : prettify(pageNumber)
|
||||
);
|
||||
|
||||
export const keyForPage = (pageNumber: NumberOrEllipsis, index: number) => !pageIsEllipsis(pageNumber) ? `${pageNumber}` : `${pageNumber}_${index}`;
|
||||
export const keyForPage = (pageNumber: NumberOrEllipsis, index: number) => (
|
||||
!pageIsEllipsis(pageNumber) ? `${pageNumber}` : `${pageNumber}_${index}`
|
||||
);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
export const forceUpdate = async () => {
|
||||
const registrations = await navigator.serviceWorker?.getRegistrations() ?? [];
|
||||
|
||||
for (const registration of registrations) {
|
||||
const { waiting } = registration;
|
||||
|
||||
registrations.forEach(({ waiting }) => {
|
||||
waiting?.addEventListener('statechange', (event) => {
|
||||
if ((event.target as any)?.state === 'activated') {
|
||||
window.location.reload();
|
||||
@@ -12,5 +10,5 @@ export const forceUpdate = async () => {
|
||||
|
||||
// The logic that makes skipWaiting to be called when this message is posted is in service-worker.ts
|
||||
waiting?.postMessage({ type: 'SKIP_WAITING' });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export const replaceAuthorityFromUri = (uri: string, newAuthority: string): string => {
|
||||
const [ schema, rest ] = uri.split('://');
|
||||
const [ , ...pathParts ] = rest.split('/');
|
||||
const [schema, rest] = uri.split('://');
|
||||
const [, ...pathParts] = rest.split('/');
|
||||
const normalizedPath = pathParts.length ? `/${pathParts.join('/')}` : '';
|
||||
|
||||
return `${schema}://${newAuthority}${normalizedPath}`;
|
||||
|
||||
@@ -34,7 +34,7 @@ const versionIsValidSemVer = memoizeWith(identity, (version: string): version is
|
||||
}
|
||||
});
|
||||
|
||||
export const versionToPrintable = (version: string) => !versionIsValidSemVer(version) ? version : `v${version}`;
|
||||
export const versionToPrintable = (version: string) => (!versionIsValidSemVer(version) ? version : `v${version}`);
|
||||
|
||||
export const versionToSemVer = (defaultValue: SemVer = 'latest') =>
|
||||
(version: string): SemVer => versionIsValidSemVer(version) ? version : defaultValue;
|
||||
(version: string): SemVer => (versionIsValidSemVer(version) ? version : defaultValue);
|
||||
|
||||
@@ -25,6 +25,6 @@ export type RecursivePartial<T> = {
|
||||
[P in keyof T]?: RecursivePartial<T[P]>;
|
||||
};
|
||||
|
||||
export const nonEmptyValueOrNull = <T>(value: T): T | null => isEmpty(value) ? null : value;
|
||||
export const nonEmptyValueOrNull = <T>(value: T): T | null => (isEmpty(value) ? null : value);
|
||||
|
||||
export const capitalize = <T extends string>(value: T): string => `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
|
||||
|
||||
Reference in New Issue
Block a user