1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { Dispatch } from 'redux';
6 import { unionize, ofType, UnionOf } from "~/common/unionize";
7 import { ServiceRepository } from "~/services/services";
8 import { RootState } from '~/store/store';
9 import { WorkflowResource } from '~/models/workflow';
10 import { getFormValues } from 'redux-form';
11 import { RUN_PROCESS_BASIC_FORM, RunProcessBasicFormData } from '~/views/run-process-panel/run-process-basic-form';
12 import { RUN_PROCESS_INPUTS_FORM } from '~/views/run-process-panel/run-process-inputs-form';
13 import { WorkflowInputsData } from '~/models/workflow';
14 import { createWorkflowMounts } from '~/models/process';
15 import { ContainerRequestState } from '~/models/container-request';
16 import { navigateToProcess } from '../navigation/navigation-action';
17 import { RunProcessAdvancedFormData, RUN_PROCESS_ADVANCED_FORM } from '~/views/run-process-panel/run-process-advanced-form';
18 import { isItemNotInProject, isProjectOrRunProcessRoute } from '~/store/projects/project-create-actions';
19 import { matchProjectRoute } from '~/routes/routes';
21 export const runProcessPanelActions = unionize({
22 SET_PROCESS_OWNER_UUID: ofType<string>(),
23 SET_CURRENT_STEP: ofType<number>(),
24 SET_WORKFLOWS: ofType<WorkflowResource[]>(),
25 SET_SELECTED_WORKFLOW: ofType<WorkflowResource>(),
26 SEARCH_WORKFLOWS: ofType<string>(),
27 RESET_RUN_PROCESS_PANEL: ofType<{}>(),
30 export interface RunProcessSecondStepDataFormProps {
35 export const RUN_PROCESS_SECOND_STEP_FORM_NAME = 'runProcessSecondStepFormName';
37 export type RunProcessPanelAction = UnionOf<typeof runProcessPanelActions>;
39 export const loadRunProcessPanel = () =>
40 async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
42 dispatch(runProcessPanelActions.RESET_RUN_PROCESS_PANEL());
43 const response = await services.workflowService.list();
44 dispatch(runProcessPanelActions.SET_WORKFLOWS(response.items));
50 export const setWorkflow = (workflow: WorkflowResource) =>
51 async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
52 dispatch(runProcessPanelActions.SET_SELECTED_WORKFLOW(workflow));
55 export const goToStep = (step: number) => runProcessPanelActions.SET_CURRENT_STEP(step);
57 const isRunProcessRoute = ({ router }: RootState) => {
58 const pathname = router.location ? router.location.pathname : '';
59 const match = matchProjectRoute(pathname);
63 export const runProcess = async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
64 const state = getState();
65 const basicForm = getFormValues(RUN_PROCESS_BASIC_FORM)(state) as RunProcessBasicFormData;
66 const inputsForm = getFormValues(RUN_PROCESS_INPUTS_FORM)(state) as WorkflowInputsData;
67 const advancedForm = getFormValues(RUN_PROCESS_ADVANCED_FORM)(state) as RunProcessAdvancedFormData;
68 const userUuid = getState().auth.user!.uuid;
69 const router = getState();
70 const properties = getState().properties;
71 const { processOwnerUuid, selectedWorkflow } = state.runProcessPanel;
72 if (selectedWorkflow) {
73 const newProcessData = {
74 ownerUuid: isItemNotInProject(properties) || !isProjectOrRunProcessRoute(router) ? userUuid : processOwnerUuid,
76 description: basicForm.description,
77 state: ContainerRequestState.COMMITTED,
78 mounts: createWorkflowMounts(selectedWorkflow, normalizeInputKeys(inputsForm)),
84 containerImage: 'arvados/jobs',
85 cwd: '/var/spool/cwl',
90 `--project-uuid=${processOwnerUuid}`,
91 '/var/lib/cwl/workflow.json#main',
92 '/var/lib/cwl/cwl.input.json'
94 outputPath: '/var/spool/cwl',
96 outputName: advancedForm && advancedForm.output ? advancedForm.output : undefined,
98 const newProcess = await services.containerRequestService.create(newProcessData);
99 dispatch(navigateToProcess(newProcess.uuid));
103 const normalizeInputKeys = (inputs: WorkflowInputsData): WorkflowInputsData =>
104 Object.keys(inputs).reduce((normalizedInputs, key) => ({
106 [key.split('/').slice(1).join('/')]: inputs[key],
108 export const searchWorkflows = (term: string) => runProcessPanelActions.SEARCH_WORKFLOWS(term);