18559: Link from users panel to user profile page.
[arvados-workbench2.git] / src / routes / routes.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
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";
11
12 export interface FederationConfig {
13     localCluster: string;
14     remoteHostsConfig: { [key: string]: Config };
15     sessions: Session[];
16 }
17
18 export const Routes = {
19     ROOT: '/',
20     TOKEN: '/token',
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',
27     TRASH: '/trash',
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     USERS: '/users',
43     USER_PROFILE: `/user/:id(${RESOURCE_UUID_PATTERN})`,
44     API_CLIENT_AUTHORIZATIONS: `/api_client_authorizations`,
45     GROUPS: '/groups',
46     GROUP_DETAILS: `/group/:id(${RESOURCE_UUID_PATTERN})`,
47     LINKS: '/links',
48     PUBLIC_FAVORITES: '/public-favorites',
49     COLLECTIONS_CONTENT_ADDRESS: `/collections/:id(${PORTABLE_DATA_HASH_PATTERN})`,
50     ALL_PROCESSES: '/all_processes',
51     NO_MATCH: '*',
52 };
53
54 export const getResourceUrl = (uuid: string) => {
55     const kind = extractUuidKind(uuid);
56     switch (kind) {
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);
65         default:
66             return undefined;
67     }
68 };
69
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)) {
74         return path;
75     } else if (config.remoteHostsConfig[cls]) {
76         let u: URL;
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);
85         } else {
86             u = new URL(config.remoteHostsConfig[cls].workbenchUrl);
87             u.search = "api_token=" + config.sessions.filter((s) => s.clusterId === cls)[0].token;
88         }
89         u.pathname = path;
90         return u.toString();
91     } else {
92         return "";
93     }
94 };
95
96
97 export const getProcessUrl = (uuid: string) => `/processes/${uuid}`;
98
99 export const getProcessLogUrl = (uuid: string) => `/process-logs/${uuid}`;
100
101 export const getGroupUrl = (uuid: string) => `/group/${uuid}`;
102
103 export const getUserProfileUrl = (uuid: string) => `/user/${uuid}`;
104
105 export interface ResourceRouteParams {
106     id: string;
107 }
108
109 export const matchRootRoute = (route: string) =>
110     matchPath(route, { path: Routes.ROOT, exact: true });
111
112 export const matchFavoritesRoute = (route: string) =>
113     matchPath(route, { path: Routes.FAVORITES });
114
115 export const matchTrashRoute = (route: string) =>
116     matchPath(route, { path: Routes.TRASH });
117
118 export const matchAllProcessesRoute = (route: string) =>
119     matchPath(route, { path: Routes.ALL_PROCESSES });
120
121 export const matchProjectRoute = (route: string) =>
122     matchPath<ResourceRouteParams>(route, { path: Routes.PROJECTS });
123
124 export const matchCollectionRoute = (route: string) =>
125     matchPath<ResourceRouteParams>(route, { path: Routes.COLLECTIONS });
126
127 export const matchProcessRoute = (route: string) =>
128     matchPath<ResourceRouteParams>(route, { path: Routes.PROCESSES });
129
130 export const matchProcessLogRoute = (route: string) =>
131     matchPath<ResourceRouteParams>(route, { path: Routes.PROCESS_LOGS });
132
133 export const matchSharedWithMeRoute = (route: string) =>
134     matchPath(route, { path: Routes.SHARED_WITH_ME });
135
136 export const matchRunProcessRoute = (route: string) =>
137     matchPath(route, { path: Routes.RUN_PROCESS });
138
139 export const matchWorkflowRoute = (route: string) =>
140     matchPath<ResourceRouteParams>(route, { path: Routes.WORKFLOWS });
141
142 export const matchSearchResultsRoute = (route: string) =>
143     matchPath<ResourceRouteParams>(route, { path: Routes.SEARCH_RESULTS });
144
145 export const matchUserVirtualMachineRoute = (route: string) =>
146     matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_USER });
147
148 export const matchAdminVirtualMachineRoute = (route: string) =>
149     matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_ADMIN });
150
151 export const matchRepositoriesRoute = (route: string) =>
152     matchPath<ResourceRouteParams>(route, { path: Routes.REPOSITORIES });
153
154 export const matchSshKeysUserRoute = (route: string) =>
155     matchPath(route, { path: Routes.SSH_KEYS_USER });
156
157 export const matchSshKeysAdminRoute = (route: string) =>
158     matchPath(route, { path: Routes.SSH_KEYS_ADMIN });
159
160 export const matchSiteManagerRoute = (route: string) =>
161     matchPath(route, { path: Routes.SITE_MANAGER });
162
163 export const matchMyAccountRoute = (route: string) =>
164     matchPath(route, { path: Routes.MY_ACCOUNT });
165
166 export const matchLinkAccountRoute = (route: string) =>
167     matchPath(route, { path: Routes.LINK_ACCOUNT });
168
169 export const matchKeepServicesRoute = (route: string) =>
170     matchPath(route, { path: Routes.KEEP_SERVICES });
171
172 export const matchTokenRoute = (route: string) =>
173     matchPath(route, { path: Routes.TOKEN });
174
175 export const matchFedTokenRoute = (route: string) =>
176     matchPath(route, { path: Routes.FED_LOGIN });
177
178 export const matchUsersRoute = (route: string) =>
179     matchPath(route, { path: Routes.USERS });
180
181 export const matchUserProfileRoute = (route: string) =>
182     matchPath<ResourceRouteParams>(route, { path: Routes.USER_PROFILE });
183
184 export const matchApiClientAuthorizationsRoute = (route: string) =>
185     matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
186
187 export const matchGroupsRoute = (route: string) =>
188     matchPath(route, { path: Routes.GROUPS });
189
190 export const matchGroupDetailsRoute = (route: string) =>
191     matchPath<ResourceRouteParams>(route, { path: Routes.GROUP_DETAILS });
192
193 export const matchLinksRoute = (route: string) =>
194     matchPath(route, { path: Routes.LINKS });
195
196 export const matchPublicFavoritesRoute = (route: string) =>
197     matchPath(route, { path: Routes.PUBLIC_FAVORITES });
198
199 export const matchCollectionsContentAddressRoute = (route: string) =>
200     matchPath(route, { path: Routes.COLLECTIONS_CONTENT_ADDRESS });