1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from "react";
6 import { ProcessIcon } from "components/icon/icon";
7 import { Process } from "store/processes/process";
8 import { SubprocessPanel } from "views/subprocess-panel/subprocess-panel";
9 import { SubprocessFilterDataProps } from "components/subprocess-filter/subprocess-filter";
10 import { MPVContainer, MPVPanelContent, MPVPanelState } from "components/multi-panel-view/multi-panel-view";
11 import { ProcessDetailsCard } from "./process-details-card";
12 import { ProcessIOCard, ProcessIOCardType, ProcessIOParameter } from "./process-io-card";
13 import { ProcessResourceCard } from "./process-resource-card";
14 import { getProcessPanelLogs, ProcessLogsPanel } from "store/process-logs-panel/process-logs-panel";
15 import { ProcessLogsCard } from "./process-log-card";
16 import { FilterOption } from "views/process-panel/process-log-form";
17 import { getInputCollectionMounts } from "store/processes/processes-actions";
18 import { WorkflowInputsData } from "models/workflow";
19 import { CommandOutputParameter } from "cwlts/mappings/v1.0/CommandOutputParameter";
20 import { AuthState } from "store/auth/auth-reducer";
21 import { ProcessCmdCard } from "./process-cmd-card";
22 import { ContainerRequestResource } from "models/container-request";
23 import { OutputDetails, NodeInstanceType } from "store/process-panel/process-panel";
24 import { NotFoundView } from 'views/not-found-panel/not-found-panel';
26 export interface ProcessPanelRootDataProps {
28 subprocesses: Array<Process>;
29 filters: Array<SubprocessFilterDataProps>;
30 processLogsPanel: ProcessLogsPanel;
32 inputRaw: WorkflowInputsData | null;
33 inputParams: ProcessIOParameter[] | null;
34 outputData: OutputDetails | null;
35 outputDefinitions: CommandOutputParameter[];
36 outputParams: ProcessIOParameter[] | null;
37 nodeInfo: NodeInstanceType | null;
38 usageReport: string | null;
41 export interface ProcessPanelRootActionProps {
42 onContextMenu: (event: React.MouseEvent<HTMLElement>, process: Process) => void;
43 onToggle: (status: string) => void;
44 cancelProcess: (uuid: string) => void;
45 startProcess: (uuid: string) => void;
46 resumeOnHoldWorkflow: (uuid: string) => void;
47 onLogFilterChange: (filter: FilterOption) => void;
48 navigateToLog: (uuid: string) => void;
49 onCopyToClipboard: (uuid: string) => void;
50 loadInputs: (containerRequest: ContainerRequestResource) => void;
51 loadOutputs: (containerRequest: ContainerRequestResource) => void;
52 loadNodeJson: (containerRequest: ContainerRequestResource) => void;
53 loadOutputDefinitions: (containerRequest: ContainerRequestResource) => void;
54 updateOutputParams: () => void;
55 pollProcessLogs: (processUuid: string) => Promise<void>;
58 export type ProcessPanelRootProps = ProcessPanelRootDataProps & ProcessPanelRootActionProps;
60 const panelsData: MPVPanelState[] = [
62 { name: "Logs", visible: true },
63 { name: "Subprocesses" },
67 { name: "Resources" },
70 export const ProcessPanelRoot = ({
84 loadOutputDefinitions,
87 }: ProcessPanelRootProps) => {
88 const outputUuid = process?.containerRequest.outputUuid;
89 const containerRequest = process?.containerRequest;
90 const inputMounts = getInputCollectionMounts(process?.containerRequest);
92 React.useEffect(() => {
93 if (containerRequest) {
94 // Load inputs from mounts or props
95 loadInputs(containerRequest);
96 // Fetch raw output (loads from props or keep)
97 loadOutputs(containerRequest);
98 // Loads output definitions from mounts into store
99 loadOutputDefinitions(containerRequest);
100 // load the assigned instance type from node.json in
101 // the log collection
102 loadNodeJson(containerRequest);
104 }, [containerRequest, loadInputs, loadOutputs, loadOutputDefinitions, loadNodeJson]);
106 const maxHeight = "100%";
108 // Trigger processing output params when raw or definitions change
109 React.useEffect(() => {
110 updateOutputParams();
111 }, [outputData, outputDefinitions, updateOutputParams]);
116 panelStates={panelsData}
117 justify-content="flex-start"
123 data-cy="process-details">
126 onContextMenu={event => props.onContextMenu(event, process)}
127 cancelProcess={props.cancelProcess}
128 startProcess={props.startProcess}
129 resumeOnHoldWorkflow={props.resumeOnHoldWorkflow}
135 minHeight={maxHeight}
136 maxHeight={maxHeight}
137 data-cy="process-logs">
139 onCopy={props.onCopyToClipboard}
141 lines={getProcessPanelLogs(processLogsPanel)}
143 label: processLogsPanel.selectedFilter,
144 value: processLogsPanel.selectedFilter,
146 filters={processLogsPanel.filters.map(filter => ({ label: filter, value: filter }))}
147 onLogFilterChange={props.onLogFilterChange}
148 navigateToLog={props.navigateToLog}
149 pollProcessLogs={props.pollProcessLogs}
155 maxHeight={maxHeight}
156 data-cy="process-children">
157 <SubprocessPanel process={process} />
162 maxHeight={maxHeight}
163 data-cy="process-outputs">
165 label={ProcessIOCardType.OUTPUT}
167 params={outputParams}
168 raw={outputData?.raw}
169 outputUuid={outputUuid || ""}
175 maxHeight={maxHeight}
176 data-cy="process-inputs">
178 label={ProcessIOCardType.INPUT}
189 data-cy="process-cmd">
191 onCopy={props.onCopyToClipboard}
198 data-cy="process-resources">
202 usageReport={usageReport}
209 messages={["Process not found"]}