Merge branch '21128-toolbar-context-menu'
[arvados-workbench2.git] / src / models / workflow.ts
index 59915137427d118167dd14d174574a3fcbdbf3f6..369db4c7c77a875dfea99ef5fe7e0a3a703d2526 100644 (file)
@@ -4,6 +4,7 @@
 
 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;
@@ -11,9 +12,9 @@ export interface WorkflowResource extends Resource {
     description: string;
     definition: string;
 }
-export interface WorkflowResoruceDefinition {
+export interface WorkflowResourceDefinition {
     cwlVersion: string;
-    $graph: Array<Workflow | CommandLineTool>;
+    $graph?: Array<Workflow | CommandLineTool>;
 }
 export interface Workflow {
     class: 'Workflow';
@@ -22,6 +23,7 @@ export interface Workflow {
     inputs: CommandInputParameter[];
     outputs: any[];
     steps: any[];
+    hints?: ProcessRequirement[];
 }
 
 export interface CommandLineTool {
@@ -29,6 +31,21 @@ export interface CommandLineTool {
     id: string;
     inputs: CommandInputParameter[];
     outputs: any[];
+    hints?: ProcessRequirement[];
+}
+
+export type ProcessRequirement = GenericProcessRequirement | WorkflowRunnerResources;
+
+export interface GenericProcessRequirement {
+    class: string;
+}
+
+export interface WorkflowRunnerResources {
+    class: 'http://arvados.org/cwl#WorkflowRunnerResources';
+    ramMin?: number;
+    coresMin?: number;
+    keep_cache?: number;
+    acrContainerImage?: string;
 }
 
 export type CommandInputParameter =
@@ -41,6 +58,8 @@ export type CommandInputParameter =
     FileCommandInputParameter |
     DirectoryCommandInputParameter |
     StringArrayCommandInputParameter |
+    IntArrayCommandInputParameter |
+    FloatArrayCommandInputParameter |
     FileArrayCommandInputParameter |
     DirectoryArrayCommandInputParameter |
     EnumCommandInputParameter;
@@ -90,6 +109,8 @@ export interface GenericCommandInputParameter<Type, Value> {
     doc?: string | string[];
     default?: Value;
     type?: Type | Array<Type | CWLType.NULL>;
+    value?: Value;
+    disabled?: boolean;
 }
 export type GenericArrayCommandInputParameter<Type, Value> = GenericCommandInputParameter<CommandInputArraySchema<Type>, Value[]>;
 
@@ -104,25 +125,47 @@ export type DirectoryCommandInputParameter = GenericCommandInputParameter<CWLTyp
 export type EnumCommandInputParameter = GenericCommandInputParameter<CommandInputEnumSchema, string>;
 
 export type StringArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.STRING, string>;
+export type IntArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.INT, string>;
+export type FloatArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.FLOAT, string>;
 export type FileArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.FILE, File>;
 export type DirectoryArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.DIRECTORY, Directory>;
 
 export type WorkflowInputsData = {
     [key: string]: boolean | number | string | File | Directory;
 };
-export const parseWorkflowDefinition = (workflow: WorkflowResource): WorkflowResoruceDefinition => {
+export const parseWorkflowDefinition = (workflow: WorkflowResource): WorkflowResourceDefinition => {
     const definition = safeLoad(workflow.definition);
     return definition;
 };
 
-export const getWorkflowInputs = (workflowDefinition: WorkflowResoruceDefinition) => {
-    const mainWorkflow = workflowDefinition.$graph.find(item => item.class === 'Workflow' && item.id === '#main');
+export const getWorkflow = (workflowDefinition: WorkflowResourceDefinition) => {
+    if (!workflowDefinition.$graph) { return undefined; }
+    const mainWorkflow = workflowDefinition.$graph.find(item => item.id === '#main');
     return mainWorkflow
-        ? mainWorkflow.inputs
+        ? mainWorkflow
+        : undefined;
+};
+
+export const getWorkflowInputs = (workflowDefinition: WorkflowResourceDefinition) => {
+    if (!workflowDefinition) { return undefined; }
+    return getWorkflow(workflowDefinition)
+        ? getWorkflow(workflowDefinition)!.inputs
+        : 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}`;
+    return `${input.label || input.id.split('/').pop()}`;
+};
+
+export const getIOParamId = (input: CommandInputParameter | CommandOutputParameter) => {
+    return `${input.id.split('/').pop()}`;
 };
 
 export const isRequiredInput = ({ type }: CommandInputParameter) => {
@@ -142,10 +185,31 @@ export const isPrimitiveOfType = (input: GenericCommandInputParameter<any, any>,
         : input.type === type;
 
 export const isArrayOfType = (input: GenericCommandInputParameter<any, any>, type: CWLType) =>
-    typeof input.type === 'object' &&
-        input.type.type === 'array'
-        ? input.type.items === type
-        : false;
+    input.type instanceof Array
+        ? (input.type.filter(t => typeof t === 'object' &&
+            t.type === 'array' &&
+            t.items === type).length > 0)
+        : (typeof input.type === 'object' &&
+            input.type.type === 'array' &&
+            input.type.items === type);
+
+export const getEnumType = (input: GenericCommandInputParameter<any, any>) => {
+    if (input.type instanceof Array) {
+        const f = input.type.filter(t => typeof t === 'object' &&
+            !(t instanceof Array) &&
+            t.type === 'enum');
+        if (f.length > 0) {
+            return f[0];
+        }
+    } else {
+        if ((typeof input.type === 'object' &&
+            !(input.type instanceof Array) &&
+            input.type.type === 'enum')) {
+            return input.type;
+        }
+    }
+    return null;
+};
 
 export const stringifyInputType = ({ type }: CommandInputParameter) => {
     if (typeof type === 'string') {