import { Resource, ResourceKind } from "./resource";
import { safeLoad } from 'js-yaml';
+import { CommandOutputParameter } from "cwlts/mappings/v1.0/CommandOutputParameter";
export interface WorkflowResource extends Resource {
kind: ResourceKind.WORKFLOW;
: undefined;
};
+export const getWorkflowOutputs = (workflowDefinition: WorkflowResourceDefinition) => {
+ if (!workflowDefinition) { return undefined; }
+ return getWorkflow(workflowDefinition)
+ ? getWorkflow(workflowDefinition)!.outputs
+ : undefined;
+};
+
export const getInputLabel = (input: CommandInputParameter) => {
return `${input.label || input.id.split('/').pop()}`;
};
-export const getInputId = (input: CommandInputParameter) => {
+export const getIOParamId = (input: CommandInputParameter | CommandOutputParameter) => {
return `${input.id.split('/').pop()}`;
};
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 { CommandInputParameter, getWorkflow, getWorkflowInputs } from "models/workflow";
+import { CommandInputParameter, getWorkflow, getWorkflowInputs, getWorkflowOutputs } from "models/workflow";
import { ProjectResource } from "models/project";
import { UserResource } from "models/user";
+import { CommandOutputParameter } from "cwlts/mappings/v1.0/CommandOutputParameter";
export const loadProcess = (containerRequestUuid: string) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<Process> => {
) : [];
};
+export const getOutputParameters = (data: any): CommandOutputParameter[] => {
+ if (!data || !data.mounts || !data.mounts[MOUNT_PATH_CWL_WORKFLOW]) { return []; }
+ const outputs = getWorkflowOutputs(data.mounts[MOUNT_PATH_CWL_WORKFLOW].content);
+ return outputs ? outputs.map(
+ (it: any) => (
+ {
+ type: it.type,
+ id: it.id,
+ label: it.label,
+ doc: it.doc
+ }
+ )
+ ) : [];
+};
+
export const openRemoveProcessDialog = (uuid: string) =>
(dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
dispatch(dialogActions.OPEN_DIALOG({
setTabState(value);
}
- return <Card className={classes.card}>
+ return <Card className={classes.card} data-cy="process-io-card">
<CardHeader
className={classes.header}
classes={{
</Paper>
);
-// secondaryFiles File[] is not part of CommandOutputParameter so we pass in an extra param
-export const getInputDisplayValue = (auth: AuthState, input: CommandInputParameter | CommandOutputParameter, pdh?: string, secondaryFiles: File[] = []): ProcessIOValue[] => {
+type FileWithSecondaryFiles = {
+ secondaryFiles: File[];
+}
+
+export const getInputDisplayValue = (auth: AuthState, input: CommandInputParameter | CommandOutputParameter, pdh?: string): ProcessIOValue[] => {
switch (true) {
case isPrimitiveOfType(input, CWLType.BOOLEAN):
return [{display: String((input as BooleanCommandInputParameter).value)}];
case isPrimitiveOfType(input, CWLType.FILE):
const mainFile = (input as FileCommandInputParameter).value;
+ // secondaryFiles: File[] is not part of CommandOutputParameter so we cast to access secondaryFiles
+ const secondaryFiles = ((mainFile as unknown) as FileWithSecondaryFiles)?.secondaryFiles || [];
const files = [
...(mainFile ? [mainFile] : []),
...secondaryFiles
return [{ display: ((input as FloatArrayCommandInputParameter).value || []).join(', ') }];
case isArrayOfType(input, CWLType.FILE):
- return ((input as FileArrayCommandInputParameter).value || [])
+ const fileArrayMainFile = ((input as FileArrayCommandInputParameter).value || []);
+ const fileArraySecondaryFiles = fileArrayMainFile.map((file) => (
+ ((file as unknown) as FileWithSecondaryFiles)?.secondaryFiles || []
+ )).reduce((acc: File[], params: File[]) => (acc.concat(params)), []);
+
+ const fileArrayFiles = [
+ ...fileArrayMainFile,
+ ...fileArraySecondaryFiles
+ ];
+
+ return fileArrayFiles
.map(file => fileToProcessIOValue(file, auth, pdh));
case isArrayOfType(input, CWLType.DIRECTORY):
import { getProcessPanelLogs, ProcessLogsPanel } from 'store/process-logs-panel/process-logs-panel';
import { ProcessLogsCard } from './process-log-card';
import { FilterOption } from 'views/process-panel/process-log-form';
-import { getInputs } from 'store/processes/processes-actions';
-import { CommandInputParameter, getInputId } from 'models/workflow';
+import { getInputs, getOutputParameters } from 'store/processes/processes-actions';
+import { CommandInputParameter, getIOParamId } from 'models/workflow';
import { CommandOutputParameter } from 'cwlts/mappings/v1.0/CommandOutputParameter';
import { AuthState } from 'store/auth/auth-reducer';
}, [outputUuid, fetchOutputs]);
React.useEffect(() => {
- if (outputDetails.rawOutputs) {
- setProcessedOutputs(formatOutputData(outputDetails.rawOutputs, outputDetails.pdh, auth));
+ if (outputDetails.rawOutputs && process) {
+ const outputDefinitions = getOutputParameters(process.containerRequest);
+ setProcessedOutputs(formatOutputData(outputDefinitions, outputDetails.rawOutputs, outputDetails.pdh, auth));
} else {
setProcessedOutputs([]);
}
- }, [outputDetails, auth]);
+ }, [outputDetails, auth, process]);
React.useEffect(() => {
if (process) {
const formatInputData = (inputs: CommandInputParameter[], auth: AuthState): ProcessIOParameter[] => {
return inputs.map(input => {
+ const doc = Array.isArray(input.doc) ? input.doc.join(', ') : input.doc;
return {
- id: getInputId(input),
- doc: input.label || "",
+ id: getIOParamId(input),
+ doc: input.label || doc || "",
value: getInputDisplayValue(auth, input)
};
});
};
-const formatOutputData = (rawData: any, pdh: string | undefined, auth: AuthState): ProcessIOParameter[] => {
- if (!rawData) { return []; }
- return Object.keys(rawData).map((id): ProcessIOParameter => {
- const multiple = rawData[id].length > 0;
- const outputArray = multiple ? rawData[id] : [rawData[id]];
+const formatOutputData = (definitions: CommandOutputParameter[], values: any, pdh: string | undefined, auth: AuthState): ProcessIOParameter[] => {
+ return definitions.map(output => {
+ const doc = Array.isArray(output.doc) ? output.doc.join(', ') : output.doc;
return {
- id,
- doc: outputArray.map((outputParam: CommandOutputParameter) => (outputParam.doc))
- // Doc can be string or string[], concat conveniently works with both
- .reduce((acc: string[], input: string | string[]) => (acc.concat(input)), [])
- // Remove undefined and empty doc strings
- .filter(str => str)
- .join(", "),
- value: outputArray.map(outputParam => getInputDisplayValue(auth, {
- type: outputParam.class,
- value: outputParam,
- ...outputParam
- }, pdh, outputParam.secondaryFiles))
- .reduce((acc: ProcessIOParameter[], params: ProcessIOParameter[]) => (acc.concat(params)), [])
+ id: getIOParamId(output),
+ doc: output.label || doc || "",
+ value: getInputDisplayValue(auth, Object.assign(output, { value: values[getIOParamId(output)] }), pdh)
};
});
};