Improve run process form layout
[arvados-workbench2.git] / src / models / workflow.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { Resource, ResourceKind } from "./resource";
6 import { safeLoad } from 'js-yaml';
7
8 export interface WorkflowResource extends Resource {
9     kind: ResourceKind.WORKFLOW;
10     name: string;
11     description: string;
12     definition: string;
13 }
14 export interface WorkflowResoruceDefinition {
15     cwlVersion: string;
16     $graph: Array<Workflow | CommandLineTool>;
17 }
18 export interface Workflow {
19     class: 'Workflow';
20     doc?: string;
21     id?: string;
22     inputs: CommandInputParameter[];
23     outputs: any[];
24     steps: any[];
25 }
26
27 export interface CommandLineTool {
28     class: 'CommandLineTool';
29     id: string;
30     inputs: CommandInputParameter[];
31     outputs: any[];
32 }
33
34 export type CommandInputParameter =
35     BooleanCommandInputParameter |
36     IntCommandInputParameter |
37     LongCommandInputParameter |
38     FloatCommandInputParameter |
39     DoubleCommandInputParameter |
40     StringCommandInputParameter |
41     FileCommandInputParameter |
42     DirectoryCommandInputParameter |
43     StringArrayCommandInputParameter |
44     FileArrayCommandInputParameter |
45     DirectoryArrayCommandInputParameter |
46     EnumCommandInputParameter;
47
48 export enum CWLType {
49     NULL = 'null',
50     BOOLEAN = 'boolean',
51     INT = 'int',
52     LONG = 'long',
53     FLOAT = 'float',
54     DOUBLE = 'double',
55     STRING = 'string',
56     FILE = 'File',
57     DIRECTORY = 'Directory',
58 }
59
60 export interface CommandInputEnumSchema {
61     symbols: string[];
62     type: 'enum';
63     label?: string;
64     name?: string;
65 }
66
67 export interface CommandInputArraySchema<ItemType> {
68     items: ItemType;
69     type: 'array';
70     label?: string;
71 }
72
73 export interface File {
74     class: CWLType.FILE;
75     location?: string;
76     path?: string;
77     basename?: string;
78 }
79
80 export interface Directory {
81     class: CWLType.DIRECTORY;
82     location?: string;
83     path?: string;
84     basename?: string;
85 }
86
87 export interface GenericCommandInputParameter<Type, Value> {
88     id: string;
89     label?: string;
90     doc?: string | string[];
91     default?: Value;
92     type?: Type | Array<Type | CWLType.NULL>;
93 }
94 export type GenericArrayCommandInputParameter<Type, Value> = GenericCommandInputParameter<CommandInputArraySchema<Type>, Value[]>;
95
96 export type BooleanCommandInputParameter = GenericCommandInputParameter<CWLType.BOOLEAN, boolean>;
97 export type IntCommandInputParameter = GenericCommandInputParameter<CWLType.INT, number>;
98 export type LongCommandInputParameter = GenericCommandInputParameter<CWLType.LONG, number>;
99 export type FloatCommandInputParameter = GenericCommandInputParameter<CWLType.FLOAT, number>;
100 export type DoubleCommandInputParameter = GenericCommandInputParameter<CWLType.DOUBLE, number>;
101 export type StringCommandInputParameter = GenericCommandInputParameter<CWLType.STRING, string>;
102 export type FileCommandInputParameter = GenericCommandInputParameter<CWLType.FILE, File>;
103 export type DirectoryCommandInputParameter = GenericCommandInputParameter<CWLType.DIRECTORY, Directory>;
104 export type EnumCommandInputParameter = GenericCommandInputParameter<CommandInputEnumSchema, string>;
105
106 export type StringArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.STRING, string>;
107 export type FileArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.FILE, File>;
108 export type DirectoryArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.DIRECTORY, Directory>;
109
110 export const parseWorkflowDefinition = (workflow: WorkflowResource): WorkflowResoruceDefinition => {
111     const definition = safeLoad(workflow.definition);
112     return definition;
113 };
114
115 export const getWorkflowInputs = (workflowDefinition: WorkflowResoruceDefinition) => {
116     const mainWorkflow = workflowDefinition.$graph.find(item => item.class === 'Workflow' && item.id === '#main');
117     return mainWorkflow
118         ? mainWorkflow.inputs
119         : undefined;
120 };
121 export const getInputLabel = (input: CommandInputParameter) => {
122     return `${input.label || input.id}`;
123 };
124
125 export const isRequiredInput = ({ type }: CommandInputParameter) => {
126     if (type instanceof Array) {
127         for (const t of type) {
128             if (t === CWLType.NULL) {
129                 return false;
130             }
131         }
132     }
133     return true;
134 };
135
136 export const isPrimitiveOfType = (input: GenericCommandInputParameter<any, any>, type: CWLType) =>
137     input.type instanceof Array
138         ? input.type.indexOf(type) > -1
139         : input.type === type;
140
141 export const stringifyInputType = ({ type }: CommandInputParameter) => {
142     if (typeof type === 'string') {
143         return type;
144     } else if (type instanceof Array) {
145         return type.join(' | ');
146     } else if (typeof type === 'object') {
147         if (type.type === 'enum') {
148             return 'enum';
149         } else if (type.type === 'array') {
150             return `${type.items}[]`;
151         } else {
152             return 'unknown';
153         }
154     } else {
155         return 'unknown';
156     }
157 };