19900: Don't dispay errors when fetching process output collection, container, or...
[arvados.git] / src / store / processes / processes-actions.ts
index 6203382c5f23a1f09ee16164705403ef8f29b0b9..6ea1e6a99ca54065bd752518afa2ceff98bcd923 100644 (file)
@@ -17,7 +17,7 @@ import { initialize } from "redux-form";
 import { RUN_PROCESS_BASIC_FORM, RunProcessBasicFormData } from "views/run-process-panel/run-process-basic-form";
 import { RunProcessAdvancedFormData, RUN_PROCESS_ADVANCED_FORM } from "views/run-process-panel/run-process-advanced-form";
 import { MOUNT_PATH_CWL_WORKFLOW, MOUNT_PATH_CWL_INPUT } from 'models/process';
-import { CommandInputParameter, getWorkflow, getWorkflowInputs, getWorkflowOutputs } from "models/workflow";
+import { CommandInputParameter, getWorkflow, getWorkflowInputs, getWorkflowOutputs, WorkflowInputsData } from "models/workflow";
 import { ProjectResource } from "models/project";
 import { UserResource } from "models/user";
 import { CommandOutputParameter } from "cwlts/mappings/v1.0/CommandOutputParameter";
@@ -27,21 +27,73 @@ export const loadProcess = (containerRequestUuid: string) =>
         const containerRequest = await services.containerRequestService.get(containerRequestUuid);
         dispatch<any>(updateResources([containerRequest]));
 
+        if (containerRequest.outputUuid) {
+            const collection = await services.collectionService.get(containerRequest.outputUuid, false);
+            dispatch<any>(updateResources([collection]));
+        }
+
         if (containerRequest.containerUuid) {
-            const container = await services.containerService.get(containerRequest.containerUuid);
+            const container = await services.containerService.get(containerRequest.containerUuid, false);
             dispatch<any>(updateResources([container]));
+            if (container.runtimeUserUuid) {
+                const runtimeUser = await services.userService.get(container.runtimeUserUuid, false);
+                dispatch<any>(updateResources([runtimeUser]));
+            }
             return { containerRequest, container };
         }
         return { containerRequest };
     };
 
-export const loadContainers = (filters: string) =>
+export const loadContainers = (filters: string, loadMounts: boolean = true) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const { items } = await services.containerService.list({ filters });
+        let args: any = { filters };
+        if (!loadMounts) {
+            args.select = containerFieldsNoMounts;
+        }
+        const { items } = await services.containerService.list(args);
         dispatch<any>(updateResources(items));
         return items;
     };
 
+// Until the api supports unselecting fields, we need a list of all other fields to omit mounts
+const containerFieldsNoMounts = [
+    "auth_uuid",
+    "command",
+    "container_image",
+    "cost",
+    "created_at",
+    "cwd",
+    "environment",
+    "etag",
+    "exit_code",
+    "finished_at",
+    "gateway_address",
+    "href",
+    "interactive_session_started",
+    "kind",
+    "lock_count",
+    "locked_by_uuid",
+    "log",
+    "modified_at",
+    "modified_by_client_uuid",
+    "modified_by_user_uuid",
+    "output_path",
+    "output_properties",
+    "output_storage_classes",
+    "output",
+    "owner_uuid",
+    "priority",
+    "progress",
+    "runtime_auth_scopes",
+    "runtime_constraints",
+    "runtime_status",
+    "runtime_user_uuid",
+    "scheduling_parameters",
+    "started_at",
+    "state",
+    "uuid",
+]
+
 export const cancelRunningWorkflow = (uuid: string) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         try {
@@ -86,8 +138,27 @@ export const reRunProcess = (processUuid: string, workflowUuid: string) =>
         }
     };
 
+/*
+ * Fetches raw inputs from containerRequest mounts with fallback to properties
+ * Returns undefined if containerRequest not loaded
+ * Returns {} if inputs not found in mounts or props
+ */
+export const getRawInputs = (data: any): WorkflowInputsData | undefined => {
+    if (!data) { return undefined; }
+    const mountInput = data.mounts?.[MOUNT_PATH_CWL_INPUT]?.content;
+    const propsInput = data.properties?.cwl_input;
+    if (!mountInput && !propsInput) { return {}; }
+    return (mountInput || propsInput);
+}
+
 export const getInputs = (data: any): CommandInputParameter[] => {
+    // Definitions from mounts are needed so we return early if missing
     if (!data || !data.mounts || !data.mounts[MOUNT_PATH_CWL_WORKFLOW]) { return []; }
+    const content  = getRawInputs(data) as any;
+    // Only escape if content is falsy to allow displaying definitions if no inputs are present
+    // (Don't check raw content length)
+    if (!content) { return []; }
+
     const inputs = getWorkflowInputs(data.mounts[MOUNT_PATH_CWL_WORKFLOW].content);
     return inputs ? inputs.map(
         (it: any) => (
@@ -95,14 +166,23 @@ export const getInputs = (data: any): CommandInputParameter[] => {
                 type: it.type,
                 id: it.id,
                 label: it.label,
-                default: data.mounts[MOUNT_PATH_CWL_INPUT].content[it.id],
-                value: data.mounts[MOUNT_PATH_CWL_INPUT].content[it.id.split('/').pop()] || [],
+                default: content[it.id],
+                value: content[it.id.split('/').pop()] || [],
                 doc: it.doc
             }
         )
     ) : [];
 };
 
+/*
+ * Fetches raw outputs from containerRequest properties
+ * Assumes containerRequest is loaded
+ */
+export const getRawOutputs = (data: any): CommandInputParameter[] | undefined => {
+    if (!data || !data.properties || !data.properties.cwl_output) { return undefined; }
+    return (data.properties.cwl_output);
+}
+
 export type InputCollectionMount = {
     path: string;
     pdh: string;