-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathroutes.ts
133 lines (108 loc) · 4.14 KB
/
routes.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import type {Location} from 'history';
import isEmpty from 'lodash/isEmpty';
import {compile} from 'path-to-regexp';
import qs from 'qs';
import type {QueryParamConfig} from 'use-query-params';
import {StringParam} from 'use-query-params';
import {backend, clusterName, webVersion} from './store';
export const CLUSTERS = 'clusters';
export const CLUSTER = 'cluster';
export const TENANT = 'tenant';
export const NODE = 'node';
export const PDISK = 'pDisk';
export const VDISK = 'vDisk';
export const STORAGE_GROUP = 'storageGroup';
export const TABLET = 'tablet';
const routes = {
clusters: `/${CLUSTERS}`,
cluster: `/${CLUSTER}/:activeTab?`,
tenant: `/${TENANT}`,
node: `/${NODE}/:id/:activeTab?`,
pDisk: `/${PDISK}`,
vDisk: `/${VDISK}`,
storageGroup: `/${STORAGE_GROUP}`,
tablet: `/${TABLET}/:id`,
auth: `/auth`,
} as const;
export default routes;
export const parseQuery = (location: Location) => {
return qs.parse(location.search, {
ignoreQueryPrefix: true,
});
};
const prepareRoute = (route: string) => {
let preparedRoute = route;
const portRegExp = /:\d{3,5}/g;
const portMatch = route.match(portRegExp);
// if port exists in route we escape port to avoid errors in function compile()
// compile(preparedRoute) parses prepared root by symbol ":"
// if we pass raw route and there is a port in route, compile()
// will try to parse the port and throw an error
if (portMatch) {
const port = portMatch[0];
preparedRoute = route.replace(portRegExp, ':\\' + port.slice(1));
}
return preparedRoute;
};
type Query = AnyRecord;
export function createHref(
route: string,
params?: Record<string, string | number | undefined>,
query: Query = {},
) {
let extendedQuery = query;
const isBackendInQuery = 'backend' in query && Boolean(query.backend);
if (backend && !isBackendInQuery && webVersion) {
extendedQuery = {...query, backend};
}
const isClusterNameInQuery = 'clusterName' in query && Boolean(query.clusterName);
if (clusterName && !isClusterNameInQuery && webVersion) {
extendedQuery = {...extendedQuery, clusterName};
}
const search = isEmpty(extendedQuery)
? ''
: `?${qs.stringify(extendedQuery, {encode: false, arrayFormat: 'repeat'})}`;
const preparedRoute = prepareRoute(route);
return `${compile(preparedRoute)(params)}${search}`;
}
// embedded version could be located in some folder (e.g. host/some_folder/app_router_path)
// window.location has the full pathname, while location from router ignores path to project
// this navigation assumes page reloading
export const createExternalUILink = (query = {}) =>
createHref(window.location.pathname, undefined, query);
export function getLocationObjectFromHref(href: string) {
const {pathname, search, hash} = new URL(href, 'http://localhost');
return {pathname, search, hash};
}
// ==== Get page path functions ====
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type QueryParamsTypeFromQueryObject<T extends Record<string, QueryParamConfig<any, any>>> = {
[QueryParamName in keyof T]?: Parameters<T[QueryParamName]['encode']>[0];
};
export function getPDiskPagePath(
pDiskId: string | number,
nodeId: string | number,
query: Query = {},
) {
return createHref(routes.pDisk, undefined, {...query, nodeId, pDiskId});
}
export function getVDiskPagePath(
vDiskSlotId: string | number,
pDiskId: string | number,
nodeId: string | number,
query: Query = {},
) {
return createHref(routes.vDisk, undefined, {...query, nodeId, pDiskId, vDiskSlotId});
}
export function getStorageGroupPath(groupId: string | number, query: Query = {}) {
return createHref(routes.storageGroup, undefined, {...query, groupId});
}
export const tabletPageQueryParams = {
database: StringParam,
clusterName: StringParam,
activeTab: StringParam,
} as const;
type TabletPageQuery = QueryParamsTypeFromQueryObject<typeof tabletPageQueryParams>;
export function getTabletPagePath(tabletId: string | number, query: TabletPageQuery = {}) {
return createHref(routes.tablet, {id: tabletId}, {...query});
}