Добавление функции для построения url ссылок внутри приложения, добавление функции triggerLink для сервисов (#31)
This commit is contained in:
@ -10,7 +10,8 @@ import SearchIcon from '@material-ui/icons/Search';
|
||||
import {Avatar} from '@material-ui/core';
|
||||
import {useParams} from '_hooks/useParams';
|
||||
import {PageType} from '_enums/common';
|
||||
import {PAGE_TITLE, ROUTES} from '_consts/common';
|
||||
import {PAGE_TITLE} from '_consts/common';
|
||||
import {buildPath} from '../../../core/utils/buildPath';
|
||||
|
||||
const NO_NAME_AVATAR = 'https://d.newsweek.com/en/full/425257/02-10-putin-economy.jpg';
|
||||
|
||||
@ -33,7 +34,7 @@ const TopMenu: React.FC = () => {
|
||||
const history = useHistory();
|
||||
|
||||
const handleGoRoot = () => {
|
||||
history.push(ROUTES.MAIN);
|
||||
history.push(buildPath({pageType: PageType.Main}));
|
||||
};
|
||||
|
||||
const title = PAGE_TITLE[pageType];
|
||||
|
||||
56
src/core/utils/__test__/buildPath.test.ts
Normal file
56
src/core/utils/__test__/buildPath.test.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import {PageType} from '../../enums/common';
|
||||
import {buildPath, BuildPathOptions} from '../buildPath';
|
||||
|
||||
describe('buildPath', () => {
|
||||
it('Путь до страницы', () => {
|
||||
const options: BuildPathOptions = {
|
||||
pageType: PageType.Tags
|
||||
};
|
||||
expect(buildPath(options)).toBe(`/${PageType.Tags}`);
|
||||
});
|
||||
|
||||
it('Путь с route параметрами', () => {
|
||||
const options: BuildPathOptions = {
|
||||
pageType: PageType.Tags,
|
||||
params: ['mode', '/id', 'fine'],
|
||||
};
|
||||
expect(buildPath(options)).toBe(`/${PageType.Tags}/mode/id/fine`);
|
||||
});
|
||||
|
||||
it('Путь c query', () => {
|
||||
const options: BuildPathOptions = {
|
||||
pageType: PageType.Tags,
|
||||
query: {
|
||||
foo: 'bar',
|
||||
},
|
||||
};
|
||||
expect(buildPath(options)).toBe(`/${PageType.Tags}?foo=bar`);
|
||||
});
|
||||
|
||||
it('Путь c query значениями undefined', () => {
|
||||
const options: BuildPathOptions = {
|
||||
pageType: PageType.Tags,
|
||||
query: {
|
||||
foo: undefined,
|
||||
},
|
||||
};
|
||||
expect(buildPath(options)).toBe(`/${PageType.Tags}?foo=`);
|
||||
});
|
||||
|
||||
it('Старые query должны быть затерты', () => {
|
||||
const options: BuildPathOptions = {
|
||||
pageType: PageType.Tags,
|
||||
};
|
||||
history.pushState(null, '', '/name?like=true');
|
||||
expect(buildPath(options)).toBe(`/${PageType.Tags}`);
|
||||
});
|
||||
|
||||
it('Старые query должны остаться в url', () => {
|
||||
const options: BuildPathOptions = {
|
||||
pageType: PageType.Tags,
|
||||
withQuery: true,
|
||||
};
|
||||
history.pushState(null, '', '/name?like=true');
|
||||
expect(buildPath(options)).toBe(`/${PageType.Tags}?like=true`);
|
||||
});
|
||||
});
|
||||
23
src/core/utils/buildPath.ts
Normal file
23
src/core/utils/buildPath.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import {decode, ParsedUrlQueryInput, stringify} from 'querystring';
|
||||
import {PageType} from '../enums/common';
|
||||
|
||||
export type BuildPathOptions = {
|
||||
pageType: PageType;
|
||||
params?: Array<string>;
|
||||
query?: ParsedUrlQueryInput;
|
||||
withQuery?: boolean,
|
||||
};
|
||||
|
||||
const makePath = (params: Array<string>) => params.map(param => {
|
||||
return param.startsWith('/') ? param.slice(1) : param;
|
||||
}).join('/');
|
||||
|
||||
export const buildPath = ({pageType, params, query, withQuery}: BuildPathOptions) => {
|
||||
const path = makePath([pageType, ...(params ?? [])]);
|
||||
const previousQuery = decode(location.search.slice(1));
|
||||
const stringifyQuery = stringify({
|
||||
...(withQuery ? previousQuery : {}),
|
||||
...query,
|
||||
});
|
||||
return [`/${path}`, stringifyQuery].filter(Boolean).join('?');
|
||||
};
|
||||
33
src/core/utils/triggerLink.ts
Normal file
33
src/core/utils/triggerLink.ts
Normal file
@ -0,0 +1,33 @@
|
||||
type Options = {
|
||||
download?: boolean | string;
|
||||
target?: '_self' | '_blank';
|
||||
};
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
target: '_self',
|
||||
download: false,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Использование этой функции требуется для открытия ссылок в новых
|
||||
* вкладках из методов сервиса. Внутри компонентов его не используем.
|
||||
*/
|
||||
export const triggerLink = (link: string, options?: Options) => {
|
||||
const finalOptions = {
|
||||
...DEFAULT_OPTIONS,
|
||||
...options
|
||||
};
|
||||
|
||||
const a = document.createElement('a');
|
||||
a.href = link;
|
||||
a.target = finalOptions.target;
|
||||
|
||||
if (finalOptions.download === true) {
|
||||
a.download = 'yes';
|
||||
} else if (typeof finalOptions.download === 'string') {
|
||||
a.download = finalOptions.download;
|
||||
}
|
||||
|
||||
a.dispatchEvent(new MouseEvent('click'));
|
||||
document.removeChild(a);
|
||||
};
|
||||
Reference in New Issue
Block a user