mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-03 14:57:22 +03:00
Move more non-shared components to shlink-web-component
This commit is contained in:
parent
bc11e568b9
commit
c73a592fd1
11 changed files with 28 additions and 43 deletions
|
@ -9,10 +9,10 @@ import { useEffect, useState } from 'react';
|
||||||
import { Button, FormGroup, Input, Row } from 'reactstrap';
|
import { Button, FormGroup, Input, Row } from 'reactstrap';
|
||||||
import type { InputType } from 'reactstrap/types/lib/Input';
|
import type { InputType } from 'reactstrap/types/lib/Input';
|
||||||
import { Checkbox } from '../../src/utils/Checkbox';
|
import { Checkbox } from '../../src/utils/Checkbox';
|
||||||
import { IconInput } from '../../src/utils/IconInput';
|
|
||||||
import { SimpleCard } from '../../src/utils/SimpleCard';
|
import { SimpleCard } from '../../src/utils/SimpleCard';
|
||||||
import type { DomainSelectorProps } from '../domains/DomainSelector';
|
import type { DomainSelectorProps } from '../domains/DomainSelector';
|
||||||
import type { TagsSelectorProps } from '../tags/helpers/TagsSelector';
|
import type { TagsSelectorProps } from '../tags/helpers/TagsSelector';
|
||||||
|
import { IconInput } from '../utils/components/IconInput';
|
||||||
import type { DateTimeInputProps } from '../utils/dates/DateTimeInput';
|
import type { DateTimeInputProps } from '../utils/dates/DateTimeInput';
|
||||||
import { DateTimeInput } from '../utils/dates/DateTimeInput';
|
import { DateTimeInput } from '../utils/dates/DateTimeInput';
|
||||||
import { formatIsoDate } from '../utils/dates/helpers/date';
|
import { formatIsoDate } from '../utils/dates/helpers/date';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { isEmpty, pipe } from 'ramda';
|
import { isEmpty, pipe } from 'ramda';
|
||||||
import { useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { orderToString, stringToOrder } from '../../../src/utils/helpers/ordering';
|
import { orderToString, stringToOrder } from '../../../src/utils/helpers/ordering';
|
||||||
import type { TagsFilteringMode } from '../../api-contract';
|
import type { TagsFilteringMode } from '../../api-contract';
|
||||||
|
@ -57,7 +57,7 @@ export const useShortUrlsQuery = (): [ShortUrlsFiltering, ToFirstPage] => {
|
||||||
),
|
),
|
||||||
[search],
|
[search],
|
||||||
);
|
);
|
||||||
const toFirstPageWithExtra = (extra: Partial<ShortUrlsFiltering>) => {
|
const toFirstPageWithExtra = useCallback((extra: Partial<ShortUrlsFiltering>) => {
|
||||||
const merged = { ...filtering, ...extra };
|
const merged = { ...filtering, ...extra };
|
||||||
const { orderBy, tags, excludeBots, excludeMaxVisitsReached, excludePastValidUntil, ...mergedFiltering } = merged;
|
const { orderBy, tags, excludeBots, excludeMaxVisitsReached, excludePastValidUntil, ...mergedFiltering } = merged;
|
||||||
const query: ShortUrlsQuery = {
|
const query: ShortUrlsQuery = {
|
||||||
|
@ -72,7 +72,7 @@ export const useShortUrlsQuery = (): [ShortUrlsFiltering, ToFirstPage] => {
|
||||||
const queryString = isEmpty(stringifiedQuery) ? '' : `?${stringifiedQuery}`;
|
const queryString = isEmpty(stringifiedQuery) ? '' : `?${stringifiedQuery}`;
|
||||||
|
|
||||||
navigate(`${routesPrefix}/list-short-urls/1${queryString}`);
|
navigate(`${routesPrefix}/list-short-urls/1${queryString}`);
|
||||||
};
|
}, [filtering, navigate, routesPrefix]);
|
||||||
|
|
||||||
return [filtering, toFirstPageWithExtra];
|
return [filtering, toFirstPageWithExtra];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@import './mixins/vertical-align';
|
@import '../../../src/utils/mixins/vertical-align';
|
||||||
@import './base';
|
@import '../../../src/utils/base';
|
||||||
|
|
||||||
.icon-input-container {
|
.icon-input-container {
|
||||||
position: relative;
|
position: relative;
|
|
@ -4,7 +4,7 @@ import classNames from 'classnames';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import type { InputProps } from 'reactstrap';
|
import type { InputProps } from 'reactstrap';
|
||||||
import { Input } from 'reactstrap';
|
import { Input } from 'reactstrap';
|
||||||
import { useElementRef } from './helpers/hooks';
|
import { useElementRef } from '../../../src/utils/helpers/hooks';
|
||||||
import './IconInput.scss';
|
import './IconInput.scss';
|
||||||
|
|
||||||
type IconInputProps = InputProps & {
|
type IconInputProps = InputProps & {
|
|
@ -1,7 +1,7 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { DropdownItem } from 'reactstrap';
|
import { DropdownItem } from 'reactstrap';
|
||||||
import { DropdownBtn } from '../../../src/utils/DropdownBtn';
|
import { DropdownBtn } from '../../../src/utils/DropdownBtn';
|
||||||
import { useEffectExceptFirstTime } from '../../../src/utils/helpers/hooks';
|
import { useEffectExceptFirstTime } from '../helpers/hooks';
|
||||||
import { DateIntervalDropdownItems } from './DateIntervalDropdownItems';
|
import { DateIntervalDropdownItems } from './DateIntervalDropdownItems';
|
||||||
import { DateRangeRow } from './DateRangeRow';
|
import { DateRangeRow } from './DateRangeRow';
|
||||||
import type {
|
import type {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { format, formatISO, isBefore, isEqual, isWithinInterval, parse, parseISO as stdParseISO } from 'date-fns';
|
import { format, formatISO, isBefore, isEqual, isWithinInterval, parse, parseISO as stdParseISO } from 'date-fns';
|
||||||
import type { OptionalString } from '../../../../src/utils/utils';
|
|
||||||
|
|
||||||
export const STANDARD_DATE_FORMAT = 'yyyy-MM-dd';
|
export const STANDARD_DATE_FORMAT = 'yyyy-MM-dd';
|
||||||
|
|
||||||
|
@ -13,7 +12,7 @@ export const now = () => new Date();
|
||||||
|
|
||||||
export const isDateObject = (date: DateOrString): date is Date => typeof date !== 'string';
|
export const isDateObject = (date: DateOrString): date is Date => typeof date !== 'string';
|
||||||
|
|
||||||
const formatDateFromFormat = (date?: NullableDate, theFormat?: string): OptionalString => {
|
const formatDateFromFormat = (date?: NullableDate, theFormat?: string): string | null | undefined => {
|
||||||
if (!date || !isDateObject(date)) {
|
if (!date || !isDateObject(date)) {
|
||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { DependencyList, EffectCallback } from 'react';
|
import type { DependencyList, EffectCallback } from 'react';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useSwipeable as useReactSwipeable } from 'react-swipeable';
|
import { useSwipeable as useReactSwipeable } from 'react-swipeable';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { parseQuery, stringifyQuery } from './query';
|
import { parseQuery, stringifyQuery } from './query';
|
||||||
|
@ -28,13 +28,6 @@ export const useTimeoutToggle = (
|
||||||
return [flag, callback];
|
return [flag, callback];
|
||||||
};
|
};
|
||||||
|
|
||||||
type ToggleResult = [boolean, () => void, () => void, () => void];
|
|
||||||
|
|
||||||
export const useToggle = (initialValue = false): ToggleResult => {
|
|
||||||
const [flag, setFlag] = useState<boolean>(initialValue);
|
|
||||||
return [flag, () => setFlag(!flag), () => setFlag(true), () => setFlag(false)];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useSwipeable = (showSidebar: () => void, hideSidebar: () => void) => {
|
export const useSwipeable = (showSidebar: () => void, hideSidebar: () => void) => {
|
||||||
const swipeMenuIfNoModalExists = (callback: () => void) => (e: any) => {
|
const swipeMenuIfNoModalExists = (callback: () => void) => (e: any) => {
|
||||||
const swippedOnVisitsTable = (e.event.composedPath() as HTMLElement[]).some(
|
const swippedOnVisitsTable = (e.event.composedPath() as HTMLElement[]).some(
|
||||||
|
@ -83,9 +76,11 @@ export const useGoBack = () => {
|
||||||
return () => navigate(-1);
|
return () => navigate(-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useParsedQuery = <T>(): T => {
|
type ToggleResult = [boolean, () => void, () => void, () => void];
|
||||||
const { search } = useLocation();
|
|
||||||
return parseQuery<T>(search);
|
export const useToggle = (initialValue = false): ToggleResult => {
|
||||||
|
const [flag, setFlag] = useState<boolean>(initialValue);
|
||||||
|
return [flag, () => setFlag(!flag), () => setFlag(true), () => setFlag(false)];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useDomId = (): string => {
|
export const useDomId = (): string => {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import type { PayloadAction, PrepareAction } from '@reduxjs/toolkit';
|
import type { PayloadAction, PrepareAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
import { mergeDeepRight } from 'ramda';
|
import { mergeDeepRight } from 'ramda';
|
||||||
import type { ShortUrlsOrder } from '../../../shlink-web-component/short-urls/data';
|
import type { Settings } from '../../../shlink-web-component';
|
||||||
import type { Settings } from '../../../shlink-web-component/utils/settings';
|
|
||||||
|
type ShortUrlsOrder = Exclude<Exclude<Settings['shortUrlsList'], undefined>['defaultOrdering'], undefined>;
|
||||||
|
|
||||||
export const DEFAULT_SHORT_URLS_ORDERING: ShortUrlsOrder = {
|
export const DEFAULT_SHORT_URLS_ORDERING: ShortUrlsOrder = {
|
||||||
field: 'dateCreated',
|
field: 'dateCreated',
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import type { DependencyList, EffectCallback } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { parseQuery } from '../../../shlink-web-component/utils/helpers/query';
|
import { parseQuery } from '../../../shlink-web-component/utils/helpers/query';
|
||||||
|
@ -27,22 +26,6 @@ export const useTimeoutToggle = (
|
||||||
return [flag, callback];
|
return [flag, callback];
|
||||||
};
|
};
|
||||||
|
|
||||||
type ToggleResult = [boolean, () => void, () => void, () => void];
|
|
||||||
|
|
||||||
export const useToggle = (initialValue = false): ToggleResult => {
|
|
||||||
const [flag, setFlag] = useState<boolean>(initialValue);
|
|
||||||
return [flag, () => setFlag(!flag), () => setFlag(true), () => setFlag(false)];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useEffectExceptFirstTime = (callback: EffectCallback, deps: DependencyList): void => {
|
|
||||||
const isFirstLoad = useRef(true);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
!isFirstLoad.current && callback();
|
|
||||||
isFirstLoad.current = false;
|
|
||||||
}, deps);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useGoBack = () => {
|
export const useGoBack = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
return () => navigate(-1);
|
return () => navigate(-1);
|
||||||
|
@ -53,6 +36,13 @@ export const useParsedQuery = <T>(): T => {
|
||||||
return parseQuery<T>(search);
|
return parseQuery<T>(search);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ToggleResult = [boolean, () => void, () => void, () => void];
|
||||||
|
|
||||||
|
export const useToggle = (initialValue = false): ToggleResult => {
|
||||||
|
const [flag, setFlag] = useState<boolean>(initialValue);
|
||||||
|
return [flag, () => setFlag(!flag), () => setFlag(true), () => setFlag(false)];
|
||||||
|
};
|
||||||
|
|
||||||
export const useDomId = (): string => {
|
export const useDomId = (): string => {
|
||||||
const { current: id } = useRef(`dom-${uuid()}`);
|
const { current: id } = useRef(`dom-${uuid()}`);
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -22,7 +22,7 @@ export const determineOrderDir = <T extends string = string>(
|
||||||
return currentOrderDir ? newOrderMap[currentOrderDir] : 'ASC';
|
return currentOrderDir ? newOrderMap[currentOrderDir] : 'ASC';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sortList = <List>(list: List[], { field, dir }: Order<Partial<keyof List>>) => (
|
export const sortList = <List>(list: List[], { field, dir }: Order<keyof List>) => (
|
||||||
!field || !dir ? list : list.sort((a, b) => {
|
!field || !dir ? list : list.sort((a, b) => {
|
||||||
const greaterThan = dir === 'ASC' ? 1 : -1;
|
const greaterThan = dir === 'ASC' ? 1 : -1;
|
||||||
const smallerThan = dir === 'ASC' ? -1 : 1;
|
const smallerThan = dir === 'ASC' ? -1 : 1;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type { IconProp } from '@fortawesome/fontawesome-svg-core';
|
import type { IconProp } from '@fortawesome/fontawesome-svg-core';
|
||||||
import { faAppleAlt, faCalendar, faTable } from '@fortawesome/free-solid-svg-icons';
|
import { faAppleAlt, faCalendar, faTable } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { screen } from '@testing-library/react';
|
import { screen } from '@testing-library/react';
|
||||||
import { IconInput } from '../../src/utils/IconInput';
|
import { IconInput } from '../../shlink-web-component/utils/components/IconInput';
|
||||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||||
|
|
||||||
describe('<IconInput />', () => {
|
describe('<IconInput />', () => {
|
||||||
|
|
Loading…
Reference in a new issue