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`,
43 USER_PROFILE: `/user/:id(${RESOURCE_UUID_PATTERN})`,
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.substring(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 const getUserProfileUrl = (uuid: string) => `/user/${uuid}`;
105 export interface ResourceRouteParams {
109 export const matchRootRoute = (route: string) =>
110 matchPath(route, { path: Routes.ROOT, exact: true });
112 export const matchFavoritesRoute = (route: string) =>
113 matchPath(route, { path: Routes.FAVORITES });
115 export const matchTrashRoute = (route: string) =>
116 matchPath(route, { path: Routes.TRASH });
118 export const matchAllProcessesRoute = (route: string) =>
119 matchPath(route, { path: Routes.ALL_PROCESSES });
121 export const matchProjectRoute = (route: string) =>
122 matchPath<ResourceRouteParams>(route, { path: Routes.PROJECTS });
124 export const matchCollectionRoute = (route: string) =>
125 matchPath<ResourceRouteParams>(route, { path: Routes.COLLECTIONS });
127 export const matchProcessRoute = (route: string) =>
128 matchPath<ResourceRouteParams>(route, { path: Routes.PROCESSES });
130 export const matchProcessLogRoute = (route: string) =>
131 matchPath<ResourceRouteParams>(route, { path: Routes.PROCESS_LOGS });
133 export const matchSharedWithMeRoute = (route: string) =>
134 matchPath(route, { path: Routes.SHARED_WITH_ME });
136 export const matchRunProcessRoute = (route: string) =>
137 matchPath(route, { path: Routes.RUN_PROCESS });
139 export const matchWorkflowRoute = (route: string) =>
140 matchPath<ResourceRouteParams>(route, { path: Routes.WORKFLOWS });
142 export const matchSearchResultsRoute = (route: string) =>
143 matchPath<ResourceRouteParams>(route, { path: Routes.SEARCH_RESULTS });
145 export const matchUserVirtualMachineRoute = (route: string) =>
146 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_USER });
148 export const matchAdminVirtualMachineRoute = (route: string) =>
149 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_ADMIN });
151 export const matchRepositoriesRoute = (route: string) =>
152 matchPath<ResourceRouteParams>(route, { path: Routes.REPOSITORIES });
154 export const matchSshKeysUserRoute = (route: string) =>
155 matchPath(route, { path: Routes.SSH_KEYS_USER });
157 export const matchSshKeysAdminRoute = (route: string) =>
158 matchPath(route, { path: Routes.SSH_KEYS_ADMIN });
160 export const matchSiteManagerRoute = (route: string) =>
161 matchPath(route, { path: Routes.SITE_MANAGER });
163 export const matchMyAccountRoute = (route: string) =>
164 matchPath(route, { path: Routes.MY_ACCOUNT });
166 export const matchLinkAccountRoute = (route: string) =>
167 matchPath(route, { path: Routes.LINK_ACCOUNT });
169 export const matchKeepServicesRoute = (route: string) =>
170 matchPath(route, { path: Routes.KEEP_SERVICES });
172 export const matchTokenRoute = (route: string) =>
173 matchPath(route, { path: Routes.TOKEN });
175 export const matchFedTokenRoute = (route: string) =>
176 matchPath(route, { path: Routes.FED_LOGIN });
178 export const matchUsersRoute = (route: string) =>
179 matchPath(route, { path: Routes.USERS });
181 export const matchUserProfileRoute = (route: string) =>
182 matchPath<ResourceRouteParams>(route, { path: Routes.USER_PROFILE });
184 export const matchApiClientAuthorizationsRoute = (route: string) =>
185 matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
187 export const matchGroupsRoute = (route: string) =>
188 matchPath(route, { path: Routes.GROUPS });
190 export const matchGroupDetailsRoute = (route: string) =>
191 matchPath<ResourceRouteParams>(route, { path: Routes.GROUP_DETAILS });
193 export const matchLinksRoute = (route: string) =>
194 matchPath(route, { path: Routes.LINKS });
196 export const matchPublicFavoritesRoute = (route: string) =>
197 matchPath(route, { path: Routes.PUBLIC_FAVORITES });
199 export const matchCollectionsContentAddressRoute = (route: string) =>
200 matchPath(route, { path: Routes.COLLECTIONS_CONTENT_ADDRESS });