1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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';
15 export const ADVANCED_TAB_DIALOG = 'advancedTabDialog';
17 export interface AdvancedTabDialogData {
20 pythonExample: string;
22 cliGetExample: string;
23 cliUpdateHeader: string;
24 cliUpdateExample: string;
30 COLLECTION = 'collection',
31 STORAGE_CLASSES_CONFIRMED = 'storage_classes_confirmed'
35 CONTAINER_REQUEST = 'container_request',
36 OUTPUT_NAME = 'output_name'
41 DELETE_AT = 'delete_at'
44 interface AdvancedData extends Resource {
45 storageClassesConfirmed: string[];
50 export const openAdvancedTabDialog = (uuid: string) =>
51 (dispatch: Dispatch<any>, getState: () => RootState) => {
52 const { resources } = getState();
53 const kind = extractUuidKind(uuid);
54 const data = getResource<any>(uuid)(resources);
57 if (kind === ResourceKind.COLLECTION) {
58 const dataCollection: AdvancedTabDialogData = {
59 apiResponse: collectionApiResponse(data),
60 pythonHeader: pythonHeader(CollectionData.COLLECTION),
61 pythonExample: pythonExample(data.uuid, GroupContentsResourcePrefix.COLLECTION),
62 cliGetHeader: cliGetHeader(CollectionData.COLLECTION),
63 cliGetExample: cliGetExample(data.uuid, GroupContentsResourcePrefix.COLLECTION),
64 cliUpdateHeader: cliUpdateHeader(CollectionData.COLLECTION, CollectionData.STORAGE_CLASSES_CONFIRMED),
65 cliUpdateExample: cliUpdateExample(data.uuid, CollectionData.COLLECTION, data.storageClassesConfirmed, CollectionData.STORAGE_CLASSES_CONFIRMED),
66 curlHeader: curlHeader(CollectionData.COLLECTION, CollectionData.STORAGE_CLASSES_CONFIRMED),
67 curlExample: curlExample(data.uuid, GroupContentsResourcePrefix.COLLECTION, data.storageClassesConfirmed, CollectionData.COLLECTION, CollectionData.STORAGE_CLASSES_CONFIRMED)
69 dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataCollection }));
70 } else if (kind === ResourceKind.PROCESS) {
71 const dataProcess: AdvancedTabDialogData = {
72 apiResponse: containerRequestApiResponse(data),
73 pythonHeader: pythonHeader(ProcessData.CONTAINER_REQUEST),
74 pythonExample: pythonExample(data.uuid, GroupContentsResourcePrefix.PROCESS),
75 cliGetHeader: cliGetHeader(ProcessData.CONTAINER_REQUEST),
76 cliGetExample: cliGetExample(data.uuid, GroupContentsResourcePrefix.PROCESS),
77 cliUpdateHeader: cliUpdateHeader(ProcessData.CONTAINER_REQUEST, ProcessData.OUTPUT_NAME),
78 cliUpdateExample: cliUpdateExample(data.uuid, ProcessData.CONTAINER_REQUEST, data.outputName, ProcessData.OUTPUT_NAME),
79 curlHeader: curlHeader(ProcessData.CONTAINER_REQUEST, ProcessData.OUTPUT_NAME),
80 curlExample: curlExample(data.uuid, GroupContentsResourcePrefix.PROCESS, data.outputName, ProcessData.CONTAINER_REQUEST, ProcessData.OUTPUT_NAME)
82 dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataProcess }));
83 } else if (kind === ResourceKind.PROJECT) {
84 const dataProject: AdvancedTabDialogData = {
85 apiResponse: `'${data}'`,
86 pythonHeader: pythonHeader(ProjectData.GROUP),
87 pythonExample: pythonExample(data.uuid, GroupContentsResourcePrefix.PROJECT),
88 cliGetHeader: cliGetHeader(ProjectData.GROUP),
89 cliGetExample: cliGetExample(data.uuid, GroupContentsResourcePrefix.PROJECT),
90 cliUpdateHeader: cliUpdateHeader(ProjectData.GROUP, ProjectData.DELETE_AT),
91 cliUpdateExample: cliUpdateExample(data.uuid, ProjectData.GROUP, data.deleteAt, ProjectData.DELETE_AT),
92 curlHeader: curlHeader(ProjectData.GROUP, ProjectData.DELETE_AT),
93 curlExample: curlExample(data.uuid, GroupContentsResourcePrefix.PROJECT, data.deleteAt, ProjectData.GROUP, ProjectData.DELETE_AT)
95 dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataProject }));
98 dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Could not open advanced tab for this resource.", hideDuration: 2000, kind: SnackbarKind.ERROR }));
102 const pythonHeader = (resourceKind: string) =>
103 `An example python command to get a ${resourceKind} using its uuid:`;
105 const pythonExample = (uuid: string, resourcePrefix: string) => {
106 const pythonExample = `import arvados
108 x = arvados.api().${resourcePrefix}().get(uuid='${uuid}').execute()`;
110 return pythonExample;
113 const cliGetHeader = (resourceKind: string) =>
114 `An example arv command to get a ${resourceKind} using its uuid:`;
116 const cliGetExample = (uuid: string, resourcePrefix: string) => {
117 const cliGetExample = `arv ${resourcePrefix} get \\
120 return cliGetExample;
123 const cliUpdateHeader = (resourceKind: string, resourceName: string) =>
124 `An example arv command to update the "${resourceName}" attribute for the current ${resourceKind}:`;
126 const cliUpdateExample = (uuid: string, resourceKind: string, resource: string | string[], resourceName: string) => {
127 const CLIUpdateCollectionExample = `arv ${resourceKind} update \\
129 --${resourceKind} '{"${resourceName}":${resource}}'`;
131 return CLIUpdateCollectionExample;
134 const curlHeader = (resourceKind: string, resource: string) =>
135 `An example curl command to update the "${resource}" attribute for the current ${resourceKind}:`;
137 const curlExample = (uuid: string, resourcePrefix: string, resource: string | string[], resourceKind: string, resourceName: string) => {
138 const curlExample = `curl -X PUT \\
139 -H "Authorization: OAuth2 $ARVADOS_API_TOKEN" \\
140 --data-urlencode ${resourceKind}@/dev/stdin \\
141 https://$ARVADOS_API_HOST/arvados/v1/${resourcePrefix}/${uuid} \\
144 "${resourceName}": ${resource}
151 const containerRequestApiResponse = (apiResponse: ContainerRequestResource) => {
153 "uuid": "${apiResponse.uuid}",
154 "owner_uuid": "${apiResponse.ownerUuid}",
155 "created_at": "${apiResponse.createdAt}",
156 "modified_at": "${apiResponse.modifiedAt}",
157 "modified_by_client_uuid": "${apiResponse.modifiedByClientUuid}",
158 "modified_by_user_uuid": "${apiResponse.modifiedByUserUuid}",
159 "name": "${apiResponse.name}",
160 "description": "${apiResponse.description}",
161 "properties": "${apiResponse.properties}",
162 "state": "${apiResponse.state}",
163 "requesting_container_uuid": "${apiResponse.requestingContainerUuid}",
164 "container_uuid": "${apiResponse.containerUuid}",
165 "container_count_max": "${apiResponse.containerCountMax}",
166 "mounts": "${apiResponse.mounts}",
167 "runtime_constraints": "${apiResponse.runtimeConstraints}",
168 "container_image": "${apiResponse.containerImage}",
169 "environment": "${apiResponse.environment}",
170 "cwd": "${apiResponse.cwd}",
171 "command": "${apiResponse.command}",
172 "output_path": "${apiResponse.outputPath}",
173 "priority": "${apiResponse.priority}",
174 "expires_at": "${apiResponse.expiresAt}",
175 "filters": "${apiResponse.filters}"
176 "use_existing": "${apiResponse.useExisting}",
177 "output_uuid": "${apiResponse.outputUuid}",
178 "scheduling_parameters": "${apiResponse.schedulingParameters}",
179 "kind": "${apiResponse.kind}",
180 "log_uuid": "${apiResponse.logUuid}",
181 "output_name": "${apiResponse.outputName}",
182 "output_ttl": "${apiResponse.outputTtl}",
188 const collectionApiResponse = (apiResponse: CollectionResource) => {
190 "uuid": "${apiResponse.uuid}",
191 "owner_uuid": "${apiResponse.ownerUuid}",
192 "created_at": "${apiResponse.createdAt}",
193 "modified_at": "${apiResponse.modifiedAt}",
194 "modified_by_client_uuid": "${apiResponse.modifiedByClientUuid}",
195 "modified_by_user_uuid": "${apiResponse.modifiedByUserUuid}",
196 "portable_data_hash": "${apiResponse.portableDataHash}",
197 "replication_desired": "${apiResponse.replicationDesired}",
198 "replication_confirmed_at": "${apiResponse.replicationConfirmedAt}",
199 "replication_confirmed": "${apiResponse.replicationConfirmed}",
201 "manifest_text": "${apiResponse.manifestText}",
202 "name": "${apiResponse.name}",
203 "description": "${apiResponse.description}",
204 "properties": "${apiResponse.properties}",
205 "delete_at": "${apiResponse.deleteAt}",
207 "trash_at": "${apiResponse.trashAt}",
208 "is_trashed": "${apiResponse.isTrashed}",
217 const groupRequestApiResponse = (apiResponse: ContainerRequestResource) => {
219 "uuid": "${apiResponse.uuid}",
220 "owner_uuid": "${apiResponse.ownerUuid}",
221 "created_at": "${apiResponse.createdAt}",
222 "modified_at": "${apiResponse.modifiedAt}",
223 "modified_by_client_uuid": "${apiResponse.modifiedByClientUuid}",
224 "modified_by_user_uuid": "${apiResponse.modifiedByUserUuid}",
225 "name": "${apiResponse.name}",
226 "description": "${apiResponse.description}",
227 "properties": "${apiResponse.properties}",
228 "state": "${apiResponse.state}",
229 "requesting_container_uuid": "${apiResponse.requestingContainerUuid}",
230 "container_uuid": "${apiResponse.containerUuid}",
231 "container_count_max": "${apiResponse.containerCountMax}",
232 "mounts": "${apiResponse.mounts}",
233 "runtime_constraints": "${apiResponse.runtimeConstraints}",
234 "container_image": "${apiResponse.containerImage}",
235 "environment": "${apiResponse.environment}",
236 "cwd": "${apiResponse.cwd}",
237 "command": "${apiResponse.command}",
238 "output_path": "${apiResponse.outputPath}",
239 "priority": "${apiResponse.priority}",
240 "expires_at": "${apiResponse.expiresAt}",
241 "filters": "${apiResponse.filters}"
242 "use_existing": "${apiResponse.useExisting}",
243 "output_uuid": "${apiResponse.outputUuid}",
244 "scheduling_parameters": "${apiResponse.schedulingParameters}",
245 "kind": "${apiResponse.kind}",
246 "log_uuid": "${apiResponse.logUuid}",
247 "output_name": "${apiResponse.outputName}",
248 "output_ttl": "${apiResponse.outputTtl}",