Merge remote-tracking branch 'origin/main' into 19051-handle-quotes-in-search
[arvados-workbench2.git] / src / store / processes / processes-actions.ts
index 65a9a24c884cf4e6fd0fbf7996582c5cc3e05694..c4d421ac09d9b5719a9f8d1b8f9a00833b7cf662 100644 (file)
@@ -3,69 +3,85 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import { Dispatch } from "redux";
-import { RootState } from '~/store/store';
-import { ServiceRepository } from '~/services/services';
-import { updateResources } from '~/store/resources/resources-actions';
-import { FilterBuilder } from '~/services/api/filter-builder';
-import { ContainerRequestResource } from '~/models/container-request';
+import { RootState } from 'store/store';
+import { ServiceRepository } from 'services/services';
+import { updateResources } from 'store/resources/resources-actions';
 import { Process } from './process';
-import { dialogActions } from '~/store/dialog/dialog-actions';
-import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
-import { projectPanelActions } from '~/store/project-panel/project-panel-action';
-import { navigateToRunProcess } from '~/store/navigation/navigation-action';
-import { goToStep, runProcessPanelActions } from '~/store/run-process-panel/run-process-panel-actions';
-import { getResource } from '~/store/resources/resources';
-import { getInputValue } from "~/views-components/process-input-dialog/process-input-dialog";
+import { dialogActions } from 'store/dialog/dialog-actions';
+import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
+import { projectPanelActions } from 'store/project-panel/project-panel-action';
+import { navigateToRunProcess } from 'store/navigation/navigation-action';
+import { goToStep, runProcessPanelActions } from 'store/run-process-panel/run-process-panel-actions';
+import { getResource } from 'store/resources/resources';
 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 { 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 { getWorkflow, getWorkflowInputs } from "models/workflow";
+import { ProjectResource } from "models/project";
+import { UserResource } from "models/user";
 
 export const loadProcess = (containerRequestUuid: string) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<Process> => {
-        const response = await services.workflowService.list();
-        dispatch(runProcessPanelActions.SET_WORKFLOWS(response.items));
         const containerRequest = await services.containerRequestService.get(containerRequestUuid);
         dispatch<any>(updateResources([containerRequest]));
+
         if (containerRequest.containerUuid) {
             const container = await services.containerService.get(containerRequest.containerUuid);
             dispatch<any>(updateResources([container]));
-            await dispatch<any>(loadSubprocesses(containerRequest.containerUuid));
             return { containerRequest, container };
         }
         return { containerRequest };
     };
 
-export const loadSubprocesses = (containerUuid: string) =>
+export const loadContainers = (filters: string, loadMounts: boolean = true) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const containerRequests = await dispatch<any>(loadContainerRequests(
-            new FilterBuilder().addEqual('requestingContainerUuid', containerUuid).getFilters()
-        )) as ContainerRequestResource[];
-
-        const containerUuids: string[] = containerRequests.reduce((uuids, { containerUuid }) =>
-            containerUuid
-                ? [...uuids, containerUuid]
-                : uuids, []);
-
-        if (containerUuids.length > 0) {
-            await dispatch<any>(loadContainers(
-                new FilterBuilder().addIn('uuid', containerUuids).getFilters()
-            ));
+        let args: any = { filters };
+        if (!loadMounts) {
+            args.select = containerFieldsNoMounts;
         }
-    };
-
-export const loadContainerRequests = (filters: string) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const { items } = await services.containerRequestService.list({ filters });
+        const { items } = await services.containerService.list(args);
         dispatch<any>(updateResources(items));
         return items;
     };
 
-export const loadContainers = (filters: string) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const { items } = await services.containerService.list({ filters });
-        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",
+    "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) => {
@@ -83,21 +99,22 @@ export const reRunProcess = (processUuid: string, workflowUuid: string) =>
         const workflows = getState().runProcessPanel.searchWorkflows;
         const workflow = workflows.find(workflow => workflow.uuid === workflowUuid);
         if (workflow && process) {
-            const newValues = getInputs(process);
-            process.mounts.varLibCwlWorkflowJson.content.graph[1].inputs = newValues;
-            const stringifiedDefinition = JSON.stringify(process.mounts.varLibCwlWorkflowJson.content);
+            const mainWf = getWorkflow(process.mounts[MOUNT_PATH_CWL_WORKFLOW]);
+            if (mainWf) { mainWf.inputs = getInputs(process); }
+            const stringifiedDefinition = JSON.stringify(process.mounts[MOUNT_PATH_CWL_WORKFLOW].content);
             const newWorkflow = { ...workflow, definition: stringifiedDefinition };
 
-            const basicInitialData: RunProcessBasicFormData = { name: `Copy of: ${process.name}`, description: process.description };
+            const owner = getResource<ProjectResource | UserResource>(workflow.ownerUuid)(getState().resources);
+            const basicInitialData: RunProcessBasicFormData = { name: `Copy of: ${process.name}`, description: process.description, owner };
             dispatch<any>(initialize(RUN_PROCESS_BASIC_FORM, basicInitialData));
 
             const advancedInitialData: RunProcessAdvancedFormData = {
                 output: process.outputName,
-                runtime: process.schedulingParameters.maxRunTime,
+                runtime: process.schedulingParameters.max_run_time,
                 ram: process.runtimeConstraints.ram,
                 vcpus: process.runtimeConstraints.vcpus,
-                keepCacheRam: process.runtimeConstraints.keepCacheRam,
-                api: process.runtimeConstraints.API
+                keep_cache_ram: process.runtimeConstraints.keep_cache_ram,
+                acr_container_image: process.containerImage
             };
             dispatch<any>(initialize(RUN_PROCESS_ADVANCED_FORM, advancedInitialData));
 
@@ -110,10 +127,21 @@ export const reRunProcess = (processUuid: string, workflowUuid: string) =>
         }
     };
 
-const getInputs = (data: any) =>
-    data && data.mounts.varLibCwlWorkflowJson ? data.mounts.varLibCwlWorkflowJson.content.graph[1].inputs.map((it: any) => (
-        { type: it.type, id: it.id, label: it.label, default: getInputValue(it.id, data.mounts.varLibCwlCwlInputJson.content), doc: it.doc }
-    )) : [];
+const getInputs = (data: any) => {
+    if (!data || !data.mounts || !data.mounts[MOUNT_PATH_CWL_WORKFLOW]) { return []; }
+    const inputs = getWorkflowInputs(data.mounts[MOUNT_PATH_CWL_WORKFLOW].content);
+    return inputs ? inputs.map(
+        (it: any) => (
+            {
+                type: it.type,
+                id: it.id,
+                label: it.label,
+                default: data.mounts[MOUNT_PATH_CWL_INPUT].content[it.id],
+                doc: it.doc
+            }
+        )
+    ) : [];
+};
 
 export const openRemoveProcessDialog = (uuid: string) =>
     (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
@@ -137,5 +165,3 @@ export const removeProcessPermanently = (uuid: string) =>
         dispatch(projectPanelActions.REQUEST_ITEMS());
         dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removed.', hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
     };
-
-