diff --git a/frontend/src/js/arvados/process/wb-submit-container-request.js b/frontend/src/js/arvados/process/wb-submit-container-request.js
new file mode 100644
index 0000000..060b2c1
--- /dev/null
+++ b/frontend/src/js/arvados/process/wb-submit-container-request.js
@@ -0,0 +1,87 @@
+import makeArvadosRequest from 'make-arvados-request';
+import wbUuidsToCwl from 'wb-uuids-to-cwl';
+
+function wbParseWorkflowInputs(workflowDefinition, userInputs, errors) {
+ // first see if all inputs are parseable
+ const inputs = {};
+
+ const main = workflowDefinition['$graph'].find(a => (a.id === '#main'));
+
+ for (let k in userInputs) {
+ try {
+ let val = jsyaml.safeLoad(userInputs[k]);
+ val = wbUuidsToCwl(val);
+ k = k.split('/').slice(1).join('/');
+ inputs[k] = (val === undefined ? null : val);
+ } catch (exc) {
+ errors.push('Error parsing ' + k + ': ' + exc.message);
+ }
+ }
+
+ return inputs;
+}
+
+// params:
+// arvHost, arvToken, inputs,
+// projectUuid, workflowDefinition, workflowUuid
+// processName, processDescription
+function wbSubmitContainerRequest(params) {
+
+ const { workflowDefinition, workflowUuid,
+ processName, processDescription, inputs,
+ arvHost, arvToken, projectUuid } = params;
+
+ // prepare a request
+ const req = {
+ name: processName,
+ description: processDescription,
+ owner_uuid: projectUuid,
+ container_image: 'arvados/jobs',
+ properties: {
+ template_uuid: workflowUuid
+ },
+ runtime_constraints: {
+ API: true,
+ vcpus: 1,
+ ram: 1073741824
+ },
+ cwd: '/var/spool/cwl',
+ command: [
+ 'arvados-cwl-runner',
+ '--local',
+ '--api=containers',
+ '--project-uuid=' + projectUuid,
+ '--collection-cache-size=256',
+ '/var/lib/cwl/workflow.json#main',
+ '/var/lib/cwl/cwl.input.json'],
+ output_path: '/var/spool/cwl',
+ priority: 1,
+ state: 'Committed',
+ mounts: {
+ 'stdout': {
+ kind: 'file',
+ path: '/var/spool/cwl/cwl.output.json'
+ },
+ '/var/spool/cwl': {
+ kind: 'collection',
+ writable: true
+ },
+ '/var/lib/cwl/workflow.json': {
+ kind: 'json',
+ content: workflowDefinition
+ },
+ '/var/lib/cwl/cwl.input.json': {
+ kind: 'json',
+ content: inputs
+ }
+ }
+ };
+
+ const prom = makeArvadosRequest(arvHost, arvToken,
+ '/arvados/v1/container_requests',
+ { method: 'POST', data: JSON.stringify(req) });
+
+ return prom;
+}
+
+export { wbParseWorkflowInputs, wbSubmitContainerRequest };
diff --git a/frontend/src/js/arvados/process/wb-uuids-to-cwl.js b/frontend/src/js/arvados/process/wb-uuids-to-cwl.js
index 6c0a3ff..cb1df7c 100644
--- a/frontend/src/js/arvados/process/wb-uuids-to-cwl.js
+++ b/frontend/src/js/arvados/process/wb-uuids-to-cwl.js
@@ -2,7 +2,7 @@ function wbUuidsToCwl(obj) {
if (obj instanceof Array) {
const res = [];
for (let k in obj) {
- res[k] = uuidsToCwl(obj[k]);
+ res[k] = wbUuidsToCwl(obj[k]);
}
return res;
}
diff --git a/frontend/src/js/component/wb-workflow-input.js b/frontend/src/js/component/wb-workflow-input.js
new file mode 100644
index 0000000..473a611
--- /dev/null
+++ b/frontend/src/js/component/wb-workflow-input.js
@@ -0,0 +1,71 @@
+import { h, Component } from 'preact';
+import wbInputSpecInfo from 'wb-input-spec-info';
+import WBPathDisplay from 'wb-path-display';
+import { parseKeepRef } from 'wb-process-misc';
+
+class WBWorkflowInput extends Component {
+ render({ app, inputSpec, inputsDict, browseDialogRef }) {
+ const { isFile, isDirectory, isArray } = wbInputSpecInfo(inputSpec);
+
+ if (!isFile && !isDirectory)
+ return (
+
+
(inputsDict[inputSpec.id] = e.target.value) }>
+
{ inputSpec.doc }
+
+ );
+
+ const button = (
+
+ );
+
+ let value = inputsDict[inputSpec.id];
+ if (value) {
+ try {
+ value = jsyaml.load(value);
+ } catch (_) {}
+ }
+
+ return (
+
+
+
{ inputSpec.doc }
+ { value ?
+ isArray ? (
+
+ { value.map(path => (
+ -
+
+
+ )) }
+
+ ) : (
+
+ ) : null }
+
+ );
+ }
+}
+
+export default WBWorkflowInput;
diff --git a/frontend/src/js/page/wb-launch-workflow-page.js b/frontend/src/js/page/wb-launch-workflow-page.js
index cda3671..603ad5b 100644
--- a/frontend/src/js/page/wb-launch-workflow-page.js
+++ b/frontend/src/js/page/wb-launch-workflow-page.js
@@ -4,15 +4,12 @@ import WBNavbarCommon from 'wb-navbar-common';
import WBArvadosCrumbs from 'wb-arvados-crumbs';
import WBBrowseDialog from 'wb-browse-dialog';
import WBTable from 'wb-table';
-import WBNameAndUuid from 'wb-name-and-uuid';
import makeArvadosRequest from 'make-arvados-request';
import { wbDisableControls, wbEnableControls } from 'wb-disable-controls';
import linkState from 'linkstate';
import wbParseWorkflowDef from 'wb-parse-workflow-def';
-import wbInputSpecInfo from 'wb-input-spec-info';
-import wbUuidsToCwl from 'wb-uuids-to-cwl';
-import { encodeURIComponentIncludingDots, parseKeepRef } from 'wb-process-misc';
-import WBPathDisplay from 'wb-path-display';
+import { wbParseWorkflowInputs, wbSubmitContainerRequest } from 'wb-submit-container-request';
+import WBWorkflowInput from 'wb-workflow-input';
class WBLaunchWorkflowPage extends Component {
constructor(...args) {
@@ -43,156 +40,40 @@ class WBLaunchWorkflowPage extends Component {
});
}
- renderInput(inputSpec) {
- const { app } = this.props;
-
- const { isFile, isDirectory, isArray } = wbInputSpecInfo(inputSpec);
-
- if (!isFile && !isDirectory)
- return (
-
-
(this.state.inputs[inputSpec.id] = e.target.value) }>
-
{ inputSpec.doc }
-
- );
-
- const button = (
-
- );
-
- let value = this.state.inputs[inputSpec.id];
- if (value) {
- try {
- value = jsyaml.load(value);
- } catch (_) {}
- }
-
- return (
-
-
-
{ inputSpec.doc }
- { value ?
- isArray ? (
-
- { value.map(path => (
- -
-
-
- )) }
-
- ) : (
-
- ) : null }
-
- );
- }
-
submit() {
// first see if all inputs are parseable
- const inputs = {};
- const errors = [];
-
- const { workflowDefinition } = this.state;
- const main = workflowDefinition['$graph'].find(a => (a.id === '#main'));
-
- for (let k in this.state.inputs) {
- try {
- let val = jsyaml.safeLoad(this.state.inputs[k]);
- val = wbUuidsToCwl(val);
- k = k.split('/').slice(1).join('/');
- inputs[k] = (val === undefined ? null : val);
- } catch (exc) {
- errors.push('Error parsing ' + k + ': ' + exc.message);
- }
- }
+ const { app, workflowUuid } = this.props;
+ const { arvHost, arvToken, currentUser } = app.state;
+ const { workflowDefinition, projectUuid,
+ processName, processDescription,
+ defaultProcessName, defaultProcessDescription } = this.state;
+ const errors = [];
+ const inputs = wbParseWorkflowInputs(workflowDefinition,
+ this.state.inputs, errors);
if (errors.length > 0) {
this.setState({ errors });
return;
}
- // prepare a request
- const { app, workflowUuid } = this.props;
- const { processName, processDescription,
- defaultProcessName, defaultProcessDescription,
- projectUuid } = this.state;
- const { arvHost, arvToken, currentUser } = app.state;
- const req = {
- name: processName || defaultProcessName,
- description: processDescription || defaultProcessDescription,
- owner_uuid: projectUuid || currentUser.uuid,
- container_image: 'arvados/jobs',
- properties: {
- template_uuid: workflowUuid
- },
- runtime_constraints: {
- API: true,
- vcpus: 1,
- ram: 1073741824
- },
- cwd: '/var/spool/cwl',
- command: [
- 'arvados-cwl-runner',
- '--local',
- '--api=containers',
- '--project-uuid=' + (projectUuid || currentUser.uuid),
- '--collection-cache-size=256',
- '/var/lib/cwl/workflow.json#main',
- '/var/lib/cwl/cwl.input.json'],
- output_path: '/var/spool/cwl',
- priority: 1,
- state: 'Committed',
- mounts: {
- 'stdout': {
- kind: 'file',
- path: '/var/spool/cwl/cwl.output.json'
- },
- '/var/spool/cwl': {
- kind: 'collection',
- writable: true
- },
- '/var/lib/cwl/workflow.json': {
- kind: 'json',
- content: workflowDefinition
- },
- '/var/lib/cwl/cwl.input.json': {
- kind: 'json',
- content: inputs
- }
- }
- };
+ const params = {
+ arvHost, arvToken, inputs,
+ processName: processName || defaultProcessName,
+ processDescription: processDescription || defaultProcessDescription,
+ projectUuid: projectUuid || currentUser.uuid,
+ workflowUuid, workflowDefinition
+ }
wbDisableControls();
- let prom = makeArvadosRequest(arvHost, arvToken,
- '/arvados/v1/container_requests',
- { method: 'POST', data: JSON.stringify(req) });
+ let prom = wbSubmitContainerRequest(params);
prom = prom.then(xhr => {
wbEnableControls();
route('/process/' + xhr.response.uuid);
});
-
- // throw Error('Not implemented');
+ prom = prom.catch(exc => {
+ wbEnableControls();
+ this.setState({ errors: [ exc.message ] });
+ });
}
render({ app, workflowUuid },
@@ -254,16 +135,12 @@ class WBLaunchWorkflowPage extends Component {
(a.id === '#main')).inputs.map(it => [
it.label || it.id,
- this.renderInput(it)
+ ( )
]) } />
-
-
-
-
{ errors.length > 0 ? (
{ errors.map(err => (
@@ -273,6 +150,12 @@ class WBLaunchWorkflowPage extends Component {
))}
) : null }
+
+
+
+
) : Loading...
}
);