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