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 REPOSITORIES: '/repositories',
29 SHARED_WITH_ME: '/shared-with-me',
30 RUN_PROCESS: '/run-process',
31 VIRTUAL_MACHINES_ADMIN: '/virtual-machines-admin',
32 VIRTUAL_MACHINES_USER: '/virtual-machines-user',
33 WORKFLOWS: '/workflows',
34 REGISTEREDWORKFLOW: `/workflows/:id(${RESOURCE_UUID_PATTERN})`,
35 SEARCH_RESULTS: '/search-results',
36 SSH_KEYS_ADMIN: `/ssh-keys-admin`,
37 SSH_KEYS_USER: `/ssh-keys-user`,
38 INSTANCE_TYPES: `/instance-types`,
39 SITE_MANAGER: `/site-manager`,
40 MY_ACCOUNT: '/my-account',
41 LINK_ACCOUNT: '/link_account',
42 KEEP_SERVICES: `/keep-services`,
44 USER_PROFILE: `/user/:id(${RESOURCE_UUID_PATTERN})`,
45 API_CLIENT_AUTHORIZATIONS: `/api_client_authorizations`,
47 GROUP_DETAILS: `/group/:id(${RESOURCE_UUID_PATTERN})`,
49 PUBLIC_FAVORITES: '/public-favorites',
50 COLLECTIONS_CONTENT_ADDRESS: `/collections/:id(${PORTABLE_DATA_HASH_PATTERN})`,
51 ALL_PROCESSES: '/all_processes',
55 export const getResourceUrl = (uuid: string) => {
56 const kind = extractUuidKind(uuid);
58 case ResourceKind.PROJECT:
59 return getProjectUrl(uuid);
60 case ResourceKind.USER:
61 return getProjectUrl(uuid);
62 case ResourceKind.COLLECTION:
63 return getCollectionUrl(uuid);
64 case ResourceKind.PROCESS:
65 return getProcessUrl(uuid);
66 case ResourceKind.WORKFLOW:
67 return getWorkflowUrl(uuid);
74 * @returns A relative or federated url for the given uuid, with a token for federated WB1 urls
76 export const getNavUrl = (uuid: string, config: FederationConfig, includeToken: boolean = true): string => {
77 const path = getResourceUrl(uuid) || "";
78 const cls = uuid.substring(0, 5);
79 if (cls === config.localCluster || extractUuidKind(uuid) === ResourceKind.USER || COLLECTION_PDH_REGEX.exec(uuid)) {
81 } else if (config.remoteHostsConfig[cls]) {
83 if (config.remoteHostsConfig[cls].workbench2Url) {
84 /* NOTE: wb2 presently doesn't support passing api_token
85 to arbitrary page to set credentials, only through
86 api-token route. So for navigation to work, user needs
87 to already be logged in. In the future we want to just
88 request the records and display in the current
89 workbench instance making this redirect unnecessary. */
90 u = new URL(config.remoteHostsConfig[cls].workbench2Url);
92 u = new URL(config.remoteHostsConfig[cls].workbenchUrl);
94 u.search = "api_token=" + config.sessions.filter((s) => s.clusterId === cls)[0].token;
105 export const getProcessUrl = (uuid: string) => `/processes/${uuid}`;
107 export const getWorkflowUrl = (uuid: string) => `/workflows/${uuid}`;
109 export const getGroupUrl = (uuid: string) => `/group/${uuid}`;
111 export const getUserProfileUrl = (uuid: string) => `/user/${uuid}`;
113 export interface ResourceRouteParams {
117 export const matchRootRoute = (route: string) =>
118 matchPath(route, { path: Routes.ROOT, exact: true });
120 export const matchFavoritesRoute = (route: string) =>
121 matchPath(route, { path: Routes.FAVORITES });
123 export const matchTrashRoute = (route: string) =>
124 matchPath(route, { path: Routes.TRASH });
126 export const matchAllProcessesRoute = (route: string) =>
127 matchPath(route, { path: Routes.ALL_PROCESSES });
129 export const matchRegisteredWorkflowRoute = (route: string) =>
130 matchPath<ResourceRouteParams>(route, { path: Routes.REGISTEREDWORKFLOW });
132 export const matchProjectRoute = (route: string) =>
133 matchPath<ResourceRouteParams>(route, { path: Routes.PROJECTS });
135 export const matchCollectionRoute = (route: string) =>
136 matchPath<ResourceRouteParams>(route, { path: Routes.COLLECTIONS });
138 export const matchProcessRoute = (route: string) =>
139 matchPath<ResourceRouteParams>(route, { path: Routes.PROCESSES });
141 export const matchSharedWithMeRoute = (route: string) =>
142 matchPath(route, { path: Routes.SHARED_WITH_ME });
144 export const matchRunProcessRoute = (route: string) =>
145 matchPath(route, { path: Routes.RUN_PROCESS });
147 export const matchWorkflowRoute = (route: string) =>
148 matchPath<ResourceRouteParams>(route, { path: Routes.WORKFLOWS });
150 export const matchSearchResultsRoute = (route: string) =>
151 matchPath<ResourceRouteParams>(route, { path: Routes.SEARCH_RESULTS });
153 export const matchUserVirtualMachineRoute = (route: string) =>
154 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_USER });
156 export const matchAdminVirtualMachineRoute = (route: string) =>
157 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_ADMIN });
159 export const matchRepositoriesRoute = (route: string) =>
160 matchPath<ResourceRouteParams>(route, { path: Routes.REPOSITORIES });
162 export const matchSshKeysUserRoute = (route: string) =>
163 matchPath(route, { path: Routes.SSH_KEYS_USER });
165 export const matchSshKeysAdminRoute = (route: string) =>
166 matchPath(route, { path: Routes.SSH_KEYS_ADMIN });
168 export const matchInstanceTypesRoute = (route: string) =>
169 matchPath(route, { path: Routes.INSTANCE_TYPES });
171 export const matchSiteManagerRoute = (route: string) =>
172 matchPath(route, { path: Routes.SITE_MANAGER });
174 export const matchMyAccountRoute = (route: string) =>
175 matchPath(route, { path: Routes.MY_ACCOUNT });
177 export const matchLinkAccountRoute = (route: string) =>
178 matchPath(route, { path: Routes.LINK_ACCOUNT });
180 export const matchKeepServicesRoute = (route: string) =>
181 matchPath(route, { path: Routes.KEEP_SERVICES });
183 export const matchTokenRoute = (route: string) =>
184 matchPath(route, { path: Routes.TOKEN });
186 export const matchFedTokenRoute = (route: string) =>
187 matchPath(route, { path: Routes.FED_LOGIN });
189 export const matchUsersRoute = (route: string) =>
190 matchPath(route, { path: Routes.USERS });
192 export const matchUserProfileRoute = (route: string) =>
193 matchPath<ResourceRouteParams>(route, { path: Routes.USER_PROFILE });
195 export const matchApiClientAuthorizationsRoute = (route: string) =>
196 matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
198 export const matchGroupsRoute = (route: string) =>
199 matchPath(route, { path: Routes.GROUPS });
201 export const matchGroupDetailsRoute = (route: string) =>
202 matchPath<ResourceRouteParams>(route, { path: Routes.GROUP_DETAILS });
204 export const matchLinksRoute = (route: string) =>
205 matchPath(route, { path: Routes.LINKS });
207 export const matchPublicFavoritesRoute = (route: string) =>
208 matchPath(route, { path: Routes.PUBLIC_FAVORITES });
210 export const matchCollectionsContentAddressRoute = (route: string) =>
211 matchPath(route, { path: Routes.COLLECTIONS_CONTENT_ADDRESS });