Добавление функции для построения url ссылок внутри приложения, добавление функции triggerLink для сервисов (#31)
This commit is contained in:
41
package-lock.json
generated
41
package-lock.json
generated
@ -8290,16 +8290,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"history": {
|
"history": {
|
||||||
"version": "4.10.1",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/history/-/history-5.0.0.tgz",
|
||||||
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
|
"integrity": "sha512-3NyRMKIiFSJmIPdq7FxkNMJkQ7ZEtVblOQ38VtKaA0zZMW1Eo6Q6W8oDKEflr1kNNTItSnk4JMCO1deeSgbLLg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.1.2",
|
"@babel/runtime": "^7.7.6"
|
||||||
"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"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hmac-drbg": {
|
"hmac-drbg": {
|
||||||
@ -15977,6 +15972,19 @@
|
|||||||
"tiny-warning": "^1.0.0"
|
"tiny-warning": "^1.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"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": {
|
"react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
@ -15996,6 +16004,21 @@
|
|||||||
"react-router": "5.2.0",
|
"react-router": "5.2.0",
|
||||||
"tiny-invariant": "^1.0.2",
|
"tiny-invariant": "^1.0.2",
|
||||||
"tiny-warning": "^1.0.0"
|
"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": {
|
"react-scripts": {
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
"axios": "^0.21.0",
|
"axios": "^0.21.0",
|
||||||
"date-fns": "^2.16.1",
|
"date-fns": "^2.16.1",
|
||||||
"fp-ts": "^2.8.5",
|
"fp-ts": "^2.8.5",
|
||||||
|
"history": "^5.0.0",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
|
|||||||
@ -10,7 +10,8 @@ import SearchIcon from '@material-ui/icons/Search';
|
|||||||
import {Avatar} from '@material-ui/core';
|
import {Avatar} from '@material-ui/core';
|
||||||
import {useParams} from '_hooks/useParams';
|
import {useParams} from '_hooks/useParams';
|
||||||
import {PageType} from '_enums/common';
|
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';
|
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 history = useHistory();
|
||||||
|
|
||||||
const handleGoRoot = () => {
|
const handleGoRoot = () => {
|
||||||
history.push(ROUTES.MAIN);
|
history.push(buildPath({pageType: PageType.Main}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const title = PAGE_TITLE[pageType];
|
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