1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { matchPath } from 'react-router';
6 import { ResourceKind, RESOURCE_UUID_PATTERN, extractUuidKind, COLLECTION_PDH_REGEX, PORTABLE_DATA_HASH_PATTERN } from '~/models/resource';
7 import { getProjectUrl } from '~/models/project';
8 import { getCollectionUrl } from '~/models/collection';
9 import { Config } from '~/common/config';
10 import { Session } from "~/models/session";
12 export interface FederationConfig {
14 remoteHostsConfig: { [key: string]: Config };
18 export const Routes = {
21 FED_LOGIN: '/fedtoken',
22 ADD_SESSION: '/add-session',
23 PROJECTS: `/projects/:id(${RESOURCE_UUID_PATTERN})`,
24 COLLECTIONS: `/collections/:id(${RESOURCE_UUID_PATTERN})`,
25 PROCESSES: `/processes/:id(${RESOURCE_UUID_PATTERN})`,
26 FAVORITES: '/favorites',
28 PROCESS_LOGS: `/process-logs/:id(${RESOURCE_UUID_PATTERN})`,
29 REPOSITORIES: '/repositories',
30 SHARED_WITH_ME: '/shared-with-me',
31 RUN_PROCESS: '/run-process',
32 VIRTUAL_MACHINES_ADMIN: '/virtual-machines-admin',
33 VIRTUAL_MACHINES_USER: '/virtual-machines-user',
34 WORKFLOWS: '/workflows',
35 SEARCH_RESULTS: '/search-results',
36 SSH_KEYS_ADMIN: `/ssh-keys-admin`,
37 SSH_KEYS_USER: `/ssh-keys-user`,
38 SITE_MANAGER: `/site-manager`,
39 MY_ACCOUNT: '/my-account',
40 LINK_ACCOUNT: '/link_account',
41 KEEP_SERVICES: `/keep-services`,
42 COMPUTE_NODES: `/nodes`,
44 API_CLIENT_AUTHORIZATIONS: `/api_client_authorizations`,
46 GROUP_DETAILS: `/group/:id(${RESOURCE_UUID_PATTERN})`,
48 PUBLIC_FAVORITES: '/public-favorites',
49 COLLECTIONS_CONTENT_ADDRESS: `/collections/:id(${PORTABLE_DATA_HASH_PATTERN})`,
50 ALL_PROCESSES: '/all_processes',
54 export const getResourceUrl = (uuid: string) => {
55 const kind = extractUuidKind(uuid);
57 case ResourceKind.PROJECT:
58 return getProjectUrl(uuid);
59 case ResourceKind.USER:
60 return getProjectUrl(uuid);
61 case ResourceKind.COLLECTION:
62 return getCollectionUrl(uuid);
63 case ResourceKind.PROCESS:
64 return getProcessUrl(uuid);
70 export const getNavUrl = (uuid: string, config: FederationConfig) => {
71 const path = getResourceUrl(uuid) || "";
72 const cls = uuid.substr(0, 5);
73 if (cls === config.localCluster || extractUuidKind(uuid) === ResourceKind.USER || COLLECTION_PDH_REGEX.exec(uuid)) {
75 } else if (config.remoteHostsConfig[cls]) {
77 if (config.remoteHostsConfig[cls].workbench2Url) {
78 /* NOTE: wb2 presently doesn't support passing api_token
79 to arbitrary page to set credentials, only through
80 api-token route. So for navigation to work, user needs
81 to already be logged in. In the future we want to just
82 request the records and display in the current
83 workbench instance making this redirect unnecessary. */
84 u = new URL(config.remoteHostsConfig[cls].workbench2Url);
86 u = new URL(config.remoteHostsConfig[cls].workbenchUrl);
87 u.search = "api_token=" + config.sessions.filter((s) => s.clusterId === cls)[0].token;
97 export const getProcessUrl = (uuid: string) => `/processes/${uuid}`;
99 export const getProcessLogUrl = (uuid: string) => `/process-logs/${uuid}`;
101 export const getGroupUrl = (uuid: string) => `/group/${uuid}`;
103 export interface ResourceRouteParams {
107 export const matchRootRoute = (route: string) =>
108 matchPath(route, { path: Routes.ROOT, exact: true });
110 export const matchFavoritesRoute = (route: string) =>
111 matchPath(route, { path: Routes.FAVORITES });
113 export const matchTrashRoute = (route: string) =>
114 matchPath(route, { path: Routes.TRASH });
116 export const matchAllProcessesRoute = (route: string) =>
117 matchPath(route, { path: Routes.ALL_PROCESSES });
119 export const matchProjectRoute = (route: string) =>
120 matchPath<ResourceRouteParams>(route, { path: Routes.PROJECTS });
122 export const matchCollectionRoute = (route: string) =>
123 matchPath<ResourceRouteParams>(route, { path: Routes.COLLECTIONS });
125 export const matchProcessRoute = (route: string) =>
126 matchPath<ResourceRouteParams>(route, { path: Routes.PROCESSES });
128 export const matchProcessLogRoute = (route: string) =>
129 matchPath<ResourceRouteParams>(route, { path: Routes.PROCESS_LOGS });
131 export const matchSharedWithMeRoute = (route: string) =>
132 matchPath(route, { path: Routes.SHARED_WITH_ME });
134 export const matchRunProcessRoute = (route: string) =>
135 matchPath(route, { path: Routes.RUN_PROCESS });
137 export const matchWorkflowRoute = (route: string) =>
138 matchPath<ResourceRouteParams>(route, { path: Routes.WORKFLOWS });
140 export const matchSearchResultsRoute = (route: string) =>
141 matchPath<ResourceRouteParams>(route, { path: Routes.SEARCH_RESULTS });
143 export const matchUserVirtualMachineRoute = (route: string) =>
144 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_USER });
146 export const matchAdminVirtualMachineRoute = (route: string) =>
147 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_ADMIN });
149 export const matchRepositoriesRoute = (route: string) =>
150 matchPath<ResourceRouteParams>(route, { path: Routes.REPOSITORIES });
152 export const matchSshKeysUserRoute = (route: string) =>
153 matchPath(route, { path: Routes.SSH_KEYS_USER });
155 export const matchSshKeysAdminRoute = (route: string) =>
156 matchPath(route, { path: Routes.SSH_KEYS_ADMIN });
158 export const matchSiteManagerRoute = (route: string) =>
159 matchPath(route, { path: Routes.SITE_MANAGER });
161 export const matchMyAccountRoute = (route: string) =>
162 matchPath(route, { path: Routes.MY_ACCOUNT });
164 export const matchLinkAccountRoute = (route: string) =>
165 matchPath(route, { path: Routes.LINK_ACCOUNT });
167 export const matchKeepServicesRoute = (route: string) =>
168 matchPath(route, { path: Routes.KEEP_SERVICES });
170 export const matchTokenRoute = (route: string) =>
171 matchPath(route, { path: Routes.TOKEN });
173 export const matchFedTokenRoute = (route: string) =>
174 matchPath(route, { path: Routes.FED_LOGIN });
176 export const matchUsersRoute = (route: string) =>
177 matchPath(route, { path: Routes.USERS });
179 export const matchComputeNodesRoute = (route: string) =>
180 matchPath(route, { path: Routes.COMPUTE_NODES });
182 export const matchApiClientAuthorizationsRoute = (route: string) =>
183 matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
185 export const matchGroupsRoute = (route: string) =>
186 matchPath(route, { path: Routes.GROUPS });
188 export const matchGroupDetailsRoute = (route: string) =>
189 matchPath<ResourceRouteParams>(route, { path: Routes.GROUP_DETAILS });
191 export const matchLinksRoute = (route: string) =>
192 matchPath(route, { path: Routes.LINKS });
194 export const matchPublicFavoritesRoute = (route: string) =>
195 matchPath(route, { path: Routes.PUBLIC_FAVORITES });
197 export const matchCollectionsContentAddressRoute = (route: string) =>
198 matchPath(route, { path: Routes.COLLECTIONS_CONTENT_ADDRESS });