19231: Add smaller page sizes (10 and 20 items) to load faster
[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     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`,
41     USERS: '/users',
42     USER_PROFILE: `/user/:id(${RESOURCE_UUID_PATTERN})`,
43     API_CLIENT_AUTHORIZATIONS: `/api_client_authorizations`,
44     GROUPS: '/groups',
45     GROUP_DETAILS: `/group/:id(${RESOURCE_UUID_PATTERN})`,
46     LINKS: '/links',
47     PUBLIC_FAVORITES: '/public-favorites',
48     COLLECTIONS_CONTENT_ADDRESS: `/collections/:id(${PORTABLE_DATA_HASH_PATTERN})`,
49     ALL_PROCESSES: '/all_processes',
50     NO_MATCH: '*',
51 };
52
53 export const getResourceUrl = (uuid: string) => {
54     const kind = extractUuidKind(uuid);
55     switch (kind) {
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);
64         default:
65             return undefined;
66     }
67 };
68
69 /**
70  * @returns A relative or federated url for the given uuid, with a token for federated WB1 urls
71  */
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)) {
76         return path;
77     } else if (config.remoteHostsConfig[cls]) {
78         let u: URL;
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);
87         } else {
88             u = new URL(config.remoteHostsConfig[cls].workbenchUrl);
89             if (includeToken) {
90                 u.search = "api_token=" + config.sessions.filter((s) => s.clusterId === cls)[0].token;
91             }
92         }
93         u.pathname = path;
94         return u.toString();
95     } else {
96         return "";
97     }
98 };
99
100
101 export const getProcessUrl = (uuid: string) => `/processes/${uuid}`;
102
103 export const getGroupUrl = (uuid: string) => `/group/${uuid}`;
104
105 export const getUserProfileUrl = (uuid: string) => `/user/${uuid}`;
106
107 export interface ResourceRouteParams {
108     id: string;
109 }
110
111 export const matchRootRoute = (route: string) =>
112     matchPath(route, { path: Routes.ROOT, exact: true });
113
114 export const matchFavoritesRoute = (route: string) =>
115     matchPath(route, { path: Routes.FAVORITES });
116
117 export const matchTrashRoute = (route: string) =>
118     matchPath(route, { path: Routes.TRASH });
119
120 export const matchAllProcessesRoute = (route: string) =>
121     matchPath(route, { path: Routes.ALL_PROCESSES });
122
123 export const matchProjectRoute = (route: string) =>
124     matchPath<ResourceRouteParams>(route, { path: Routes.PROJECTS });
125
126 export const matchCollectionRoute = (route: string) =>
127     matchPath<ResourceRouteParams>(route, { path: Routes.COLLECTIONS });
128
129 export const matchProcessRoute = (route: string) =>
130     matchPath<ResourceRouteParams>(route, { path: Routes.PROCESSES });
131
132 export const matchSharedWithMeRoute = (route: string) =>
133     matchPath(route, { path: Routes.SHARED_WITH_ME });
134
135 export const matchRunProcessRoute = (route: string) =>
136     matchPath(route, { path: Routes.RUN_PROCESS });
137
138 export const matchWorkflowRoute = (route: string) =>
139     matchPath<ResourceRouteParams>(route, { path: Routes.WORKFLOWS });
140
141 export const matchSearchResultsRoute = (route: string) =>
142     matchPath<ResourceRouteParams>(route, { path: Routes.SEARCH_RESULTS });
143
144 export const matchUserVirtualMachineRoute = (route: string) =>
145     matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_USER });
146
147 export const matchAdminVirtualMachineRoute = (route: string) =>
148     matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_ADMIN });
149
150 export const matchRepositoriesRoute = (route: string) =>
151     matchPath<ResourceRouteParams>(route, { path: Routes.REPOSITORIES });
152
153 export const matchSshKeysUserRoute = (route: string) =>
154     matchPath(route, { path: Routes.SSH_KEYS_USER });
155
156 export const matchSshKeysAdminRoute = (route: string) =>
157     matchPath(route, { path: Routes.SSH_KEYS_ADMIN });
158
159 export const matchSiteManagerRoute = (route: string) =>
160     matchPath(route, { path: Routes.SITE_MANAGER });
161
162 export const matchMyAccountRoute = (route: string) =>
163     matchPath(route, { path: Routes.MY_ACCOUNT });
164
165 export const matchLinkAccountRoute = (route: string) =>
166     matchPath(route, { path: Routes.LINK_ACCOUNT });
167
168 export const matchKeepServicesRoute = (route: string) =>
169     matchPath(route, { path: Routes.KEEP_SERVICES });
170
171 export const matchTokenRoute = (route: string) =>
172     matchPath(route, { path: Routes.TOKEN });
173
174 export const matchFedTokenRoute = (route: string) =>
175     matchPath(route, { path: Routes.FED_LOGIN });
176
177 export const matchUsersRoute = (route: string) =>
178     matchPath(route, { path: Routes.USERS });
179
180 export const matchUserProfileRoute = (route: string) =>
181     matchPath<ResourceRouteParams>(route, { path: Routes.USER_PROFILE });
182
183 export const matchApiClientAuthorizationsRoute = (route: string) =>
184     matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
185
186 export const matchGroupsRoute = (route: string) =>
187     matchPath(route, { path: Routes.GROUPS });
188
189 export const matchGroupDetailsRoute = (route: string) =>
190     matchPath<ResourceRouteParams>(route, { path: Routes.GROUP_DETAILS });
191
192 export const matchLinksRoute = (route: string) =>
193     matchPath(route, { path: Routes.LINKS });
194
195 export const matchPublicFavoritesRoute = (route: string) =>
196     matchPath(route, { path: Routes.PUBLIC_FAVORITES });
197
198 export const matchCollectionsContentAddressRoute = (route: string) =>
199     matchPath(route, { path: Routes.COLLECTIONS_CONTENT_ADDRESS });