1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from "react";
6 import { StyleRulesCallback, WithStyles, withStyles } from "@material-ui/core";
7 import { ProcessIcon } from "components/icon/icon";
8 import { Process } from "store/processes/process";
9 import { SubprocessPanel } from "views/subprocess-panel/subprocess-panel";
10 import { SubprocessFilterDataProps } from "components/subprocess-filter/subprocess-filter";
11 import { MPVContainer, MPVPanelContent, MPVPanelState } from "components/multi-panel-view/multi-panel-view";
12 import { ArvadosTheme } from "common/custom-theme";
13 import { ProcessDetailsCard } from "./process-details-card";
14 import { ProcessIOCard, ProcessIOCardType, ProcessIOParameter } from "./process-io-card";
15 import { ProcessResourceCard } from "./process-resource-card";
16 import { getProcessPanelLogs, ProcessLogsPanel } from "store/process-logs-panel/process-logs-panel";
17 import { ProcessLogsCard } from "./process-log-card";
18 import { FilterOption } from "views/process-panel/process-log-form";
19 import { getInputCollectionMounts } from "store/processes/processes-actions";
20 import { WorkflowInputsData } from "models/workflow";
21 import { CommandOutputParameter } from "cwlts/mappings/v1.0/CommandOutputParameter";
22 import { AuthState } from "store/auth/auth-reducer";
23 import { ProcessCmdCard } from "./process-cmd-card";
24 import { ContainerRequestResource } from "models/container-request";
25 import { OutputDetails, NodeInstanceType } from "store/process-panel/process-panel";
26 import { NotFoundView } from 'views/not-found-panel/not-found-panel';
28 export interface ProcessPanelRootDataProps {
30 subprocesses: Array<Process>;
31 filters: Array<SubprocessFilterDataProps>;
32 processLogsPanel: ProcessLogsPanel;
34 inputRaw: WorkflowInputsData | null;
35 inputParams: ProcessIOParameter[] | null;
36 outputData: OutputDetails | null;
37 outputDefinitions: CommandOutputParameter[];
38 outputParams: ProcessIOParameter[] | null;
39 nodeInfo: NodeInstanceType | null;
40 usageReport: string | null;
43 export interface ProcessPanelRootActionProps {
44 onContextMenu: (event: React.MouseEvent<HTMLElement>, process: Process) => void;
45 onToggle: (status: string) => void;
46 cancelProcess: (uuid: string) => void;
47 startProcess: (uuid: string) => void;
48 resumeOnHoldWorkflow: (uuid: string) => void;
49 onLogFilterChange: (filter: FilterOption) => void;
50 navigateToLog: (uuid: string) => void;
51 onCopyToClipboard: (uuid: string) => void;
52 loadInputs: (containerRequest: ContainerRequestResource) => void;
53 loadOutputs: (containerRequest: ContainerRequestResource) => void;
54 loadNodeJson: (containerRequest: ContainerRequestResource) => void;
55 loadOutputDefinitions: (containerRequest: ContainerRequestResource) => void;
56 updateOutputParams: () => void;
57 pollProcessLogs: (processUuid: string) => Promise<void>;
60 export type ProcessPanelRootProps = ProcessPanelRootDataProps & ProcessPanelRootActionProps;
62 const panelsData: MPVPanelState[] = [
64 { name: "Logs", visible: true },
65 { name: "Subprocesses" },
69 { name: "Resources" },
72 export const ProcessPanelRoot = ({
86 loadOutputDefinitions,
89 }: ProcessPanelRootProps) => {
90 const outputUuid = process?.containerRequest.outputUuid;
91 const containerRequest = process?.containerRequest;
92 const inputMounts = getInputCollectionMounts(process?.containerRequest);
94 React.useEffect(() => {
95 if (containerRequest) {
96 // Load inputs from mounts or props
97 loadInputs(containerRequest);
98 // Fetch raw output (loads from props or keep)
99 loadOutputs(containerRequest);
100 // Loads output definitions from mounts into store
101 loadOutputDefinitions(containerRequest);
102 // load the assigned instance type from node.json in
103 // the log collection
104 loadNodeJson(containerRequest);
106 }, [containerRequest, loadInputs, loadOutputs, loadOutputDefinitions, loadNodeJson]);
108 const maxHeight = "100%";
110 // Trigger processing output params when raw or definitions change
111 React.useEffect(() => {
112 updateOutputParams();
113 }, [outputData, outputDefinitions, updateOutputParams]);
118 panelStates={panelsData}
119 justify-content="flex-start"
125 data-cy="process-details">
128 onContextMenu={event => props.onContextMenu(event, process)}
129 cancelProcess={props.cancelProcess}
130 startProcess={props.startProcess}
131 resumeOnHoldWorkflow={props.resumeOnHoldWorkflow}
137 minHeight={maxHeight}
138 maxHeight={maxHeight}
139 data-cy="process-logs">
141 onCopy={props.onCopyToClipboard}
143 lines={getProcessPanelLogs(processLogsPanel)}
145 label: processLogsPanel.selectedFilter,
146 value: processLogsPanel.selectedFilter,
148 filters={processLogsPanel.filters.map(filter => ({ label: filter, value: filter }))}
149 onLogFilterChange={props.onLogFilterChange}
150 navigateToLog={props.navigateToLog}
151 pollProcessLogs={props.pollProcessLogs}
157 maxHeight={maxHeight}
158 data-cy="process-children">
159 <SubprocessPanel process={process} />
164 maxHeight={maxHeight}
165 data-cy="process-outputs">
167 label={ProcessIOCardType.OUTPUT}
169 params={outputParams}
170 raw={outputData?.raw}
171 outputUuid={outputUuid || ""}
177 maxHeight={maxHeight}
178 data-cy="process-inputs">
180 label={ProcessIOCardType.INPUT}
191 data-cy="process-cmd">
193 onCopy={props.onCopyToClipboard}
200 data-cy="process-resources">
204 usageReport={usageReport}
211 messages={["Process not found"]}