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);
69 export const getNavUrl = (uuid: string, config: FederationConfig) => {
70 const path = getResourceUrl(uuid) || "";
71 const cls = uuid.substring(0, 5);
72 if (cls === config.localCluster || extractUuidKind(uuid) === ResourceKind.USER || COLLECTION_PDH_REGEX.exec(uuid)) {
74 } else if (config.remoteHostsConfig[cls]) {
76 if (config.remoteHostsConfig[cls].workbench2Url) {
77 /* NOTE: wb2 presently doesn't support passing api_token
78 to arbitrary page to set credentials, only through
79 api-token route. So for navigation to work, user needs
80 to already be logged in. In the future we want to just
81 request the records and display in the current
82 workbench instance making this redirect unnecessary. */
83 u = new URL(config.remoteHostsConfig[cls].workbench2Url);
85 u = new URL(config.remoteHostsConfig[cls].workbenchUrl);
86 u.search = "api_token=" + config.sessions.filter((s) => s.clusterId === cls)[0].token;
96 export const getProcessUrl = (uuid: string) => `/processes/${uuid}`;
98 export const getGroupUrl = (uuid: string) => `/group/${uuid}`;
100 export const getUserProfileUrl = (uuid: string) => `/user/${uuid}`;
102 export interface ResourceRouteParams {
106 export const matchRootRoute = (route: string) =>
107 matchPath(route, { path: Routes.ROOT, exact: true });
109 export const matchFavoritesRoute = (route: string) =>
110 matchPath(route, { path: Routes.FAVORITES });
112 export const matchTrashRoute = (route: string) =>
113 matchPath(route, { path: Routes.TRASH });
115 export const matchAllProcessesRoute = (route: string) =>
116 matchPath(route, { path: Routes.ALL_PROCESSES });
118 export const matchProjectRoute = (route: string) =>
119 matchPath<ResourceRouteParams>(route, { path: Routes.PROJECTS });
121 export const matchCollectionRoute = (route: string) =>
122 matchPath<ResourceRouteParams>(route, { path: Routes.COLLECTIONS });
124 export const matchProcessRoute = (route: string) =>
125 matchPath<ResourceRouteParams>(route, { path: Routes.PROCESSES });
127 export const matchSharedWithMeRoute = (route: string) =>
128 matchPath(route, { path: Routes.SHARED_WITH_ME });
130 export const matchRunProcessRoute = (route: string) =>
131 matchPath(route, { path: Routes.RUN_PROCESS });
133 export const matchWorkflowRoute = (route: string) =>
134 matchPath<ResourceRouteParams>(route, { path: Routes.WORKFLOWS });
136 export const matchSearchResultsRoute = (route: string) =>
137 matchPath<ResourceRouteParams>(route, { path: Routes.SEARCH_RESULTS });
139 export const matchUserVirtualMachineRoute = (route: string) =>
140 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_USER });
142 export const matchAdminVirtualMachineRoute = (route: string) =>
143 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_ADMIN });
145 export const matchRepositoriesRoute = (route: string) =>
146 matchPath<ResourceRouteParams>(route, { path: Routes.REPOSITORIES });
148 export const matchSshKeysUserRoute = (route: string) =>
149 matchPath(route, { path: Routes.SSH_KEYS_USER });
151 export const matchSshKeysAdminRoute = (route: string) =>
152 matchPath(route, { path: Routes.SSH_KEYS_ADMIN });
154 export const matchSiteManagerRoute = (route: string) =>
155 matchPath(route, { path: Routes.SITE_MANAGER });
157 export const matchMyAccountRoute = (route: string) =>
158 matchPath(route, { path: Routes.MY_ACCOUNT });
160 export const matchLinkAccountRoute = (route: string) =>
161 matchPath(route, { path: Routes.LINK_ACCOUNT });
163 export const matchKeepServicesRoute = (route: string) =>
164 matchPath(route, { path: Routes.KEEP_SERVICES });
166 export const matchTokenRoute = (route: string) =>
167 matchPath(route, { path: Routes.TOKEN });
169 export const matchFedTokenRoute = (route: string) =>
170 matchPath(route, { path: Routes.FED_LOGIN });
172 export const matchUsersRoute = (route: string) =>
173 matchPath(route, { path: Routes.USERS });
175 export const matchUserProfileRoute = (route: string) =>
176 matchPath<ResourceRouteParams>(route, { path: Routes.USER_PROFILE });
178 export const matchApiClientAuthorizationsRoute = (route: string) =>
179 matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
181 export const matchGroupsRoute = (route: string) =>
182 matchPath(route, { path: Routes.GROUPS });
184 export const matchGroupDetailsRoute = (route: string) =>
185 matchPath<ResourceRouteParams>(route, { path: Routes.GROUP_DETAILS });
187 export const matchLinksRoute = (route: string) =>
188 matchPath(route, { path: Routes.LINKS });
190 export const matchPublicFavoritesRoute = (route: string) =>
191 matchPath(route, { path: Routes.PUBLIC_FAVORITES });
193 export const matchCollectionsContentAddressRoute = (route: string) =>
194 matchPath(route, { path: Routes.COLLECTIONS_CONTENT_ADDRESS });