16073: Fix not correctly setting empty inputs to turn off loading spinner
[arvados-workbench2.git] / src / store / process-panel / process-panel-actions.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { unionize, ofType, UnionOf } from "common/unionize";
6 import { getRawOutputs, loadProcess } from 'store/processes/processes-actions';
7 import { Dispatch } from 'redux';
8 import { ProcessStatus } from 'store/processes/process';
9 import { RootState } from 'store/store';
10 import { ServiceRepository } from "services/services";
11 import { navigateTo, navigateToWorkflows } from 'store/navigation/navigation-action';
12 import { snackbarActions } from 'store/snackbar/snackbar-actions';
13 import { SnackbarKind } from '../snackbar/snackbar-actions';
14 import { showWorkflowDetails } from 'store/workflow-panel/workflow-panel-actions';
15 import { loadSubprocessPanel } from "../subprocess-panel/subprocess-panel-actions";
16 import { initProcessLogsPanel, processLogsPanelActions } from "store/process-logs-panel/process-logs-panel-actions";
17 import { CollectionFile } from "models/collection-file";
18 import { ContainerRequestResource } from "models/container-request";
19
20 export const processPanelActions = unionize({
21     SET_PROCESS_PANEL_CONTAINER_REQUEST_UUID: ofType<string>(),
22     SET_PROCESS_PANEL_FILTERS: ofType<string[]>(),
23     TOGGLE_PROCESS_PANEL_FILTER: ofType<string>(),
24 });
25
26 export type ProcessPanelAction = UnionOf<typeof processPanelActions>;
27
28 export const toggleProcessPanelFilter = processPanelActions.TOGGLE_PROCESS_PANEL_FILTER;
29
30 export const loadProcessPanel = (uuid: string) =>
31     async (dispatch: Dispatch) => {
32         dispatch(processLogsPanelActions.RESET_PROCESS_LOGS_PANEL());
33         dispatch<ProcessPanelAction>(processPanelActions.SET_PROCESS_PANEL_CONTAINER_REQUEST_UUID(uuid));
34         await dispatch<any>(loadProcess(uuid));
35         dispatch(initProcessPanelFilters);
36         dispatch<any>(initProcessLogsPanel(uuid));
37         dispatch<any>(loadSubprocessPanel());
38     };
39
40 export const navigateToOutput = (uuid: string) =>
41     async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
42         try {
43             await services.collectionService.get(uuid);
44             dispatch<any>(navigateTo(uuid));
45         } catch {
46             dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'This collection does not exists!', hideDuration: 2000, kind: SnackbarKind.ERROR }));
47         }
48     };
49
50 export const loadOutputs = (containerRequest: ContainerRequestResource, setOutputs) =>
51     async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
52         const noOutputs = {rawOutputs: {}};
53         if (!containerRequest.outputUuid) {setOutputs(noOutputs); return;};
54         try {
55             const propsOutputs = getRawOutputs(containerRequest);
56             const filesPromise = services.collectionService.files(containerRequest.outputUuid);
57             const collectionPromise = services.collectionService.get(containerRequest.outputUuid);
58             const [files, collection] = await Promise.all([filesPromise, collectionPromise]);
59
60             // If has propsOutput, skip fetching cwl.output.json
61             if (propsOutputs !== undefined) {
62                 setOutputs({rawOutputs: propsOutputs, pdh: collection.portableDataHash});
63             } else {
64                 // Fetch outputs from keep
65                 const outputFile = files.find((file) => file.name === 'cwl.output.json') as CollectionFile | undefined;
66                 let outputData = outputFile ? await services.collectionService.getFileContents(outputFile) : undefined;
67                 if (outputData && (outputData = JSON.parse(outputData)) && collection.portableDataHash) {
68                     setOutputs({
69                         rawOutputs: outputData,
70                         pdh: collection.portableDataHash,
71                     });
72                 } else {
73                     setOutputs(noOutputs);
74                 }
75             }
76         } catch {
77             setOutputs(noOutputs);
78         }
79     };
80
81 export const openWorkflow = (uuid: string) =>
82     (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
83         dispatch<any>(navigateToWorkflows);
84         dispatch<any>(showWorkflowDetails(uuid));
85     };
86
87 export const initProcessPanelFilters = processPanelActions.SET_PROCESS_PANEL_FILTERS([
88     ProcessStatus.QUEUED,
89     ProcessStatus.COMPLETED,
90     ProcessStatus.FAILED,
91     ProcessStatus.RUNNING,
92     ProcessStatus.ONHOLD,
93     ProcessStatus.FAILING,
94     ProcessStatus.WARNING,
95     ProcessStatus.CANCELLED
96 ]);