Добавление функции для построения url ссылок внутри приложения, добавление функции triggerLink для сервисов (#31)

This commit is contained in:
Nikolay
2020-12-28 00:26:20 +03:00
committed by GitHub
parent 27de662b5f
commit e8635972c6
6 changed files with 148 additions and 11 deletions

41
package-lock.json generated
View File

@ -8290,16 +8290,11 @@
"dev": true
},
"history": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/history/-/history-5.0.0.tgz",
"integrity": "sha512-3NyRMKIiFSJmIPdq7FxkNMJkQ7ZEtVblOQ38VtKaA0zZMW1Eo6Q6W8oDKEflr1kNNTItSnk4JMCO1deeSgbLLg==",
"requires": {
"@babel/runtime": "^7.1.2",
"loose-envify": "^1.2.0",
"resolve-pathname": "^3.0.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0",
"value-equal": "^1.0.1"
"@babel/runtime": "^7.7.6"
}
},
"hmac-drbg": {
@ -15977,6 +15972,19 @@
"tiny-warning": "^1.0.0"
},
"dependencies": {
"history": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
"requires": {
"@babel/runtime": "^7.1.2",
"loose-envify": "^1.2.0",
"resolve-pathname": "^3.0.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0",
"value-equal": "^1.0.1"
}
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@ -15996,6 +16004,21 @@
"react-router": "5.2.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0"
},
"dependencies": {
"history": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
"requires": {
"@babel/runtime": "^7.1.2",
"loose-envify": "^1.2.0",
"resolve-pathname": "^3.0.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0",
"value-equal": "^1.0.1"
}
}
}
},
"react-scripts": {

View File

@ -12,6 +12,7 @@
"axios": "^0.21.0",
"date-fns": "^2.16.1",
"fp-ts": "^2.8.5",
"history": "^5.0.0",
"lodash": "^4.17.20",
"react": "^17.0.1",
"react-dom": "^17.0.1",

View File

@ -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];

View 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`);
});
});

View 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('?');
};

View 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);
};