f1ad7f02a9c2b521162d652cf7d69f9b14e907b7
[arvados-workbench2.git] / src / store / advanced-tab / advanced-tab.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { dialogActions } from '~/store/dialog/dialog-actions';
6 import { RootState } from '~/store/store';
7 import { Dispatch } from 'redux';
8 import { ResourceKind, extractUuidKind, Resource } from '~/models/resource';
9 import { getResource } from '~/store/resources/resources';
10 import { GroupContentsResourcePrefix } from '~/services/groups-service/groups-service';
11 import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
12 import { ContainerRequestResource } from '~/models/container-request';
13 import { CollectionResource } from '~/models/collection';
14 import { ProjectResource } from '~/models/project';
15
16 export const ADVANCED_TAB_DIALOG = 'advancedTabDialog';
17
18 export interface AdvancedTabDialogData {
19     apiResponse: any;
20     pythonHeader: string;
21     pythonExample: string;
22     cliGetHeader: string;
23     cliGetExample: string;
24     cliUpdateHeader: string;
25     cliUpdateExample: string;
26     curlHeader: string;
27     curlExample: string;
28 }
29
30 enum CollectionData {
31     COLLECTION = 'collection',
32     STORAGE_CLASSES_CONFIRMED = 'storage_classes_confirmed'
33 }
34
35 enum ProcessData {
36     CONTAINER_REQUEST = 'container_request',
37     OUTPUT_NAME = 'output_name'
38 }
39
40 enum ProjectData {
41     GROUP = 'group',
42     DELETE_AT = 'delete_at'
43 }
44
45 export const openAdvancedTabDialog = (uuid: string) =>
46     (dispatch: Dispatch<any>, getState: () => RootState) => {
47         const { resources } = getState();
48         const kind = extractUuidKind(uuid);
49         const data = getResource<any>(uuid)(resources);
50         if (data) {
51             console.log(data);
52             if (kind === ResourceKind.COLLECTION) {
53                 const dataCollection: AdvancedTabDialogData = {
54                     apiResponse: collectionApiResponse(data),
55                     pythonHeader: pythonHeader(CollectionData.COLLECTION),
56                     pythonExample: pythonExample(data.uuid, GroupContentsResourcePrefix.COLLECTION),
57                     cliGetHeader: cliGetHeader(CollectionData.COLLECTION),
58                     cliGetExample: cliGetExample(data.uuid, GroupContentsResourcePrefix.COLLECTION),
59                     cliUpdateHeader: cliUpdateHeader(CollectionData.COLLECTION, CollectionData.STORAGE_CLASSES_CONFIRMED),
60                     cliUpdateExample: cliUpdateExample(data.uuid, CollectionData.COLLECTION, data.storageClassesConfirmed, CollectionData.STORAGE_CLASSES_CONFIRMED),
61                     curlHeader: curlHeader(CollectionData.COLLECTION, CollectionData.STORAGE_CLASSES_CONFIRMED),
62                     curlExample: curlExample(data.uuid, GroupContentsResourcePrefix.COLLECTION, data.storageClassesConfirmed, CollectionData.COLLECTION, CollectionData.STORAGE_CLASSES_CONFIRMED)
63                 };
64                 dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataCollection }));
65             } else if (kind === ResourceKind.PROCESS) {
66                 const dataProcess: AdvancedTabDialogData = {
67                     apiResponse: containerRequestApiResponse(data),
68                     pythonHeader: pythonHeader(ProcessData.CONTAINER_REQUEST),
69                     pythonExample: pythonExample(data.uuid, GroupContentsResourcePrefix.PROCESS),
70                     cliGetHeader: cliGetHeader(ProcessData.CONTAINER_REQUEST),
71                     cliGetExample: cliGetExample(data.uuid, GroupContentsResourcePrefix.PROCESS),
72                     cliUpdateHeader: cliUpdateHeader(ProcessData.CONTAINER_REQUEST, ProcessData.OUTPUT_NAME),
73                     cliUpdateExample: cliUpdateExample(data.uuid, ProcessData.CONTAINER_REQUEST, data.outputName, ProcessData.OUTPUT_NAME),
74                     curlHeader: curlHeader(ProcessData.CONTAINER_REQUEST, ProcessData.OUTPUT_NAME),
75                     curlExample: curlExample(data.uuid, GroupContentsResourcePrefix.PROCESS, data.outputName, ProcessData.CONTAINER_REQUEST, ProcessData.OUTPUT_NAME)
76                 };
77                 dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataProcess }));
78             } else if (kind === ResourceKind.PROJECT) {
79                 const dataProject: AdvancedTabDialogData = {
80                     apiResponse: groupRequestApiResponse(data),
81                     pythonHeader: pythonHeader(ProjectData.GROUP),
82                     pythonExample: pythonExample(data.uuid, GroupContentsResourcePrefix.PROJECT),
83                     cliGetHeader: cliGetHeader(ProjectData.GROUP),
84                     cliGetExample: cliGetExample(data.uuid, GroupContentsResourcePrefix.PROJECT),
85                     cliUpdateHeader: cliUpdateHeader(ProjectData.GROUP, ProjectData.DELETE_AT),
86                     cliUpdateExample: cliUpdateExample(data.uuid, ProjectData.GROUP, data.deleteAt, ProjectData.DELETE_AT),
87                     curlHeader: curlHeader(ProjectData.GROUP, ProjectData.DELETE_AT),
88                     curlExample: curlExample(data.uuid, GroupContentsResourcePrefix.PROJECT, data.deleteAt, ProjectData.GROUP, ProjectData.DELETE_AT)
89                 };
90                 dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataProject }));
91             }
92         } else {
93             dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Could not open advanced tab for this resource.", hideDuration: 2000, kind: SnackbarKind.ERROR }));
94         }
95     };
96
97 const pythonHeader = (resourceKind: string) =>
98     `An example python command to get a ${resourceKind} using its uuid:`;
99
100 const pythonExample = (uuid: string, resourcePrefix: string) => {
101     const pythonExample = `import arvados
102
103  x = arvados.api().${resourcePrefix}().get(uuid='${uuid}').execute()`;
104
105     return pythonExample;
106 };
107
108 const cliGetHeader = (resourceKind: string) =>
109     `An example arv command to get a ${resourceKind} using its uuid:`;
110
111 const cliGetExample = (uuid: string, resourcePrefix: string) => {
112     const cliGetExample = `arv ${resourcePrefix} get \\
113  --uuid ${uuid}`;
114
115     return cliGetExample;
116 };
117
118 const cliUpdateHeader = (resourceKind: string, resourceName: string) =>
119     `An example arv command to update the "${resourceName}" attribute for the current ${resourceKind}:`;
120
121 const cliUpdateExample = (uuid: string, resourceKind: string, resource: string | string[], resourceName: string) => {
122     const CLIUpdateCollectionExample = `arv ${resourceKind} update \\ 
123  --uuid ${uuid} \\
124  --${resourceKind} '{"${resourceName}":${resource}}'`;
125
126     return CLIUpdateCollectionExample;
127 };
128
129 const curlHeader = (resourceKind: string, resource: string) =>
130     `An example curl command to update the "${resource}" attribute for the current ${resourceKind}:`;
131
132 const curlExample = (uuid: string, resourcePrefix: string, resource: string | string[], resourceKind: string, resourceName: string) => {
133     const curlExample = `curl -X PUT \\
134  -H "Authorization: OAuth2 $ARVADOS_API_TOKEN" \\
135  --data-urlencode ${resourceKind}@/dev/stdin \\
136  https://$ARVADOS_API_HOST/arvados/v1/${resourcePrefix}/${uuid} \\
137  <<EOF
138 {
139   "${resourceName}": ${resource}
140 }
141 EOF`;
142
143     return curlExample;
144 };
145
146 const containerRequestApiResponse = (apiResponse: ContainerRequestResource) => {
147     const { uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid, name, description, properties, state, requestingContainerUuid, containerUuid,
148         containerCountMax, mounts, runtimeConstraints, containerImage, environment, cwd, command, outputPath, priority, expiresAt, filters, updatedAt, containerCount,
149         useExisting, schedulingParameters, outputUuid, logUuid, outputName, outputTtl } = apiResponse;
150     const response = `{
151   "uuid": "${uuid}",
152   "owner_uuid": "${ownerUuid}",
153   "created_at": "${createdAt}",
154   "modified_at": "${modifiedAt}",
155   "modified_by_client_uuid": "${modifiedByClientUuid}",
156   "modified_by_user_uuid": "${modifiedByUserUuid}",
157   "name": "${name}",
158   "description": "${description}",
159   "properties": {
160     "?"
161   },
162   "state": "${state}",
163   "requesting_container_uuid": "${requestingContainerUuid}",
164   "container_uuid": "${containerUuid}",
165   "container_count_max": "${containerCountMax}",
166   "mounts": {
167     "?"
168   },
169   "runtime_constraints": { ${runtimeConstraints.API ? `\n    "API": "${runtimeConstraints.API}",` : ''} ${runtimeConstraints.vcpus ? `\n    "vcpus": "${runtimeConstraints.vcpus}",` : ''} ${runtimeConstraints.ram ? `\n    "ram": "${runtimeConstraints.ram}"` : ''} ${runtimeConstraints.keepCacheRam ? `\n    "keep_cache_ram": "${runtimeConstraints.keepCacheRam}"` : ''}
170   },
171   "container_image": "${containerImage}",
172   "environment": {
173     "?"
174   },
175   "cwd": "${cwd}",
176   "command": [
177     "${command.join(`", \n    "`)}"
178   ],
179   "output_path": "${outputPath}",
180   "priority": "${priority}",
181   "expires_at": "${expiresAt}",
182   "filters": "${filters}"
183   "updated_at": "${updatedAt || null}"
184   "container_count": "${containerCount}"
185   "use_existing": "${useExisting}",
186   "scheduling_parameters": { ${schedulingParameters.maxRunTime ? `\n    "max_runtime": "${schedulingParameters.maxRunTime}",` : ''} ${schedulingParameters.partitions ? `\n    "partitions": "${schedulingParameters.partitions}",` : ''} ${schedulingParameters.preemptible ? `\n    "preemptible": "${schedulingParameters.preemptible}"` : ''}
187   },
188   "output_uuid": "${outputUuid}",
189   "log_uuid": "${logUuid}",
190   "output_name": "${outputName}",
191   "output_ttl": "${outputTtl}"
192 }`;
193
194     return response;
195 };
196
197 const collectionApiResponse = (apiResponse: CollectionResource) => {
198     const { uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid, name, description, properties, portableDataHash, replicationDesired,
199         replicationConfirmedAt, replicationConfirmed, updatedAt, manifestText, deleteAt, fileNames, trashAt, isTrashed, storageClassesDesired,
200         storageClassesConfirmed, storageClassesConfirmedAt } = apiResponse;
201     const response = `{
202   "uuid": "${uuid}",
203   "owner_uuid": "${ownerUuid}",
204   "created_at": "${createdAt}",
205   "modified_by_client_uuid": "${modifiedByClientUuid}",
206   "modified_by_user_uuid": "${modifiedByUserUuid}",
207   "modified_at": "${modifiedAt}",
208   "portable_data_hash": "${portableDataHash}",
209   "replication_desired": "${replicationDesired}",
210   "replication_confirmed_at": "${replicationConfirmedAt}",
211   "replication_confirmed": "${replicationConfirmed}",
212   "updated_at": "${updatedAt || null}"
213   "manifest_text": "${manifestText || null}",
214   "name": "${name}",
215   "description": "${description}",
216   "properties": { 
217     "?"
218   },
219   "delete_at": "${deleteAt}",
220   "file_names": "${fileNames || null}",
221   "trash_at": "${trashAt}",
222   "is_trashed": "${isTrashed}",
223   "storage_classes_desired": [
224     ${storageClassesDesired.length > 0 ? `"${storageClassesDesired.join(`", \n    "`)}"` : ''}
225   ],
226   "storage_classes_confirmed": [
227     ${storageClassesConfirmed.length > 0 ? `"${storageClassesConfirmed.join(`", \n    "`)}"` : ''}
228   ],
229   "storage_classes_confirmed_at": "${storageClassesConfirmedAt}"  
230 }`;
231
232     return response;
233 };
234
235 const groupRequestApiResponse = (apiResponse: ProjectResource) => {
236     const { uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid, name, description, updatedAt, groupClass, trashAt, isTrashed, deleteAt } = apiResponse;
237     const response = `{
238   "uuid": "${uuid}",
239   "owner_uuid": "${ownerUuid}",
240   "created_at": "${createdAt}",
241   "modified_by_client_uuid": "${modifiedByClientUuid}",
242   "modified_by_user_uuid": "${modifiedByUserUuid}",
243   "modified_at": "${modifiedAt}",
244   "name": "${name}",
245   "description": "${description}",
246   "updated_at": "${updatedAt || null}"
247   "group_class": "${groupClass}",
248   "trash_at": "${trashAt}",
249   "is_trashed": "${isTrashed}",
250   "delete_at": "${deleteAt}",
251   "properties": {
252     "?"
253   }
254 }`;
255
256     return response;
257 };