diff --git a/frontend/src/js/dialog/wb-browse-dialog.js b/frontend/src/js/dialog/wb-browse-dialog.js index fa9954d..e96d6ff 100644 --- a/frontend/src/js/dialog/wb-browse-dialog.js +++ b/frontend/src/js/dialog/wb-browse-dialog.js @@ -20,7 +20,7 @@ import { createHashHistory } from 'history'; // // props: // selectMany: Boolean -// selectWhat: [ 'file', 'directory' ] +// selectWhat: [ 'file', 'directory', 'owner' ] // // state: // selected: Array of UUID @@ -43,6 +43,7 @@ class WBBrowseDialog extends Component { this.state.collectionPath = ''; this.state.textSearch = ''; this.state.id = ('id' in this.props) ? this.props.id : uuid.v4(); + this.state.accept = () => {}; } navigateBack() { @@ -52,7 +53,7 @@ class WBBrowseDialog extends Component { this.navigate(url, false); } - navigate(url, useHistory=true) { + navigate(url, useHistory=true, stateUpdate={}) { if (typeof(url) === 'object') { url = ['', 'browse-dialog', 'mode' in url ? url.mode : this.state.mode, @@ -71,11 +72,11 @@ class WBBrowseDialog extends Component { let [ _1, _2, mode, uuid, topPage, bottomPage, textSearch, collectionPath ] = url.split('/'); topPage = parseInt(topPage, 10) || 0; bottomPage = parseInt(bottomPage, 10) || 0; - collectionPath = decodeURIComponent(collectionPath); - this.setState({ + collectionPath = decodeURIComponent(collectionPath || ''); + this.setState(Object.assign({ 'currentUrl': url, mode, uuid, topPage, bottomPage, textSearch, collectionPath - }); + }, stateUpdate)); } select(uuid) { @@ -111,14 +112,13 @@ class WBBrowseDialog extends Component { } makeSelectionCell(uuid) { - const { selectMany, id, accept } = this.props; - const { selected } = this.state; + const { selected, accept, selectMany, id } = this.state; return selectMany ? (
{ - if (e.target.value === 'on') + if (e.target.checked) this.select(uuid); else this.deselect(uuid); @@ -135,14 +135,19 @@ class WBBrowseDialog extends Component { ); } - show(callback) { + show(selectWhat, selectMany, accept=(() => {})) { + const { app } = this.props; + const { currentUser } = app.state; + this.navigate('/browse-dialog/browse/' + currentUser.uuid, false, + { selectWhat, selectMany, accept, history: [] }); $('#' + this.state.id).modal(); } - render({ app, selectMany, selectWhat }, + render({ app }, { history, currentUrl, mode, uuid, topPage, bottomPage, textSearch, - collectionPath, id }) { + collectionPath, id, accept, selectedOrder, + selectMany, selectWhat }) { return (
diff --git a/frontend/src/js/page/wb-launch-workflow-page.js b/frontend/src/js/page/wb-launch-workflow-page.js index a7802ea..29e14f8 100644 --- a/frontend/src/js/page/wb-launch-workflow-page.js +++ b/frontend/src/js/page/wb-launch-workflow-page.js @@ -1,66 +1,26 @@ import { h, Component, createRef } from 'preact'; import WBNavbarCommon from 'wb-navbar-common'; import WBArvadosCrumbs from 'wb-arvados-crumbs'; -import WBToolboxDialog from 'wb-toolbox-dialog'; import WBBrowseDialog from 'wb-browse-dialog'; +import WBTable from 'wb-table'; import makeArvadosRequest from 'make-arvados-request'; import linkState from 'linkstate'; -function createInputsTemplate(workflow) { - const g = JSON.parse(workflow.definition)['$graph']; - const main = g.find(it => (it.id === '#main')); - let res = ''; - main.inputs.map(it => { - let id = it.id.split('/'); - id = id[id.length - 1]; - if (it.label) res += ' // ' + it.label + '\n'; - if (it.doc) res += ' // ' + it.doc + '\n'; - res += ' // Type: ' + ((typeof(it.type) === 'string') ? - it.type : JSON.stringify(it.type)) + '\n\n'; - res += ' \'' + id + '\': \'\',\n\n'; - //res += ' // ' + ' '.repeat(id.length) + '^^^^\n\n'; - }); - /* let res = main.inputs.map(it => { it.value = null; return it; }); - res = JSON.stringify(res, null, 2); - res = res.split('\n'); - res = res.map((ln, i) => (i == 0 ? ln : ' ' + ln)); - res = res.join('\n'); */ - return res; -} - -function uuidsToCwlObjects(spec) { - if (typeof(spec) === 'string') { - if (/^[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{15}/.exec(spec)) { - return { - 'class': 'Directory', - 'location': 'keep:' + spec - }; - } else if (/^[a-f0-9]{32}\+[0-9]+/.exec(spec)) { - return { - 'class': 'Directory', - 'location': 'keep:' + spec - }; - } else { - return spec; - } - } else if (typeof(spec) === 'object') { - const res = (spec instanceof Array) ? [] : {}; - Object.keys(spec).map(k => (res[k] = uuidsToCwlObjects(spec[k]))); - return res; - - } else { - return spec; +function parseDefinition(text) { + let definition; + try { + definition = JSON.parse(text); + } catch (_) { + definition = jsyaml.load(text); } + return definition; } class WBLaunchWorkflowPage extends Component { constructor(...args) { super(...args); - this.state.browseDialogId = uuid.v4(); - this.state.insertDialogId = uuid.v4(); - this.state.insertManyDialogId = uuid.v4(); - this.state.realBrowseDialogId = uuid.v4(); - this.inputsTextArea = createRef(); + this.browseDialogRef = createRef(); + this.state.inputs = {}; } componentDidMount() { @@ -71,47 +31,64 @@ class WBLaunchWorkflowPage extends Component { '/arvados/v1/workflows/' + workflowUuid); prom = prom.then(xhr => this.setState({ 'workflow': xhr.response, + 'workflowDefinition': parseDefinition(xhr.response.definition), 'defaultProcessName': xhr.response.name + ' ' + (new Date().toISOString()), - 'defaultProcessDescription': xhr.response.description, - 'inputsFunctionText': '(() => {\n return {\n' + - createInputsTemplate(xhr.response) + - ' };\n})()' + 'defaultProcessDescription': xhr.response.description })); } + renderInput(inputSpec) { + const isFile = (inputSpec.type === 'File' || inputSpec.type === 'File[]' || + (inputSpec.type.type === 'array' && inputSpec.type.items === 'File')); + + const isDirectory = (inputSpec.type === 'Directory' || inputSpec.type === 'Directory[]' || + (inputSpec.type.type === 'array' && inputSpec.type.items === 'Directory')); + + const isArray = (inputSpec.type === 'File[]' || inputSpec.type === 'Directory[]' || + inputSpec.type.type === 'array'); + + if (!isFile && !isDirectory) + return ( + (this.state.inputs[inputSpec.id] = e.target.value) }> + ); + + const button = ( + + ); + + return ( +
+ (this.state.inputs[inputSpec.id] = e.target.value) }> +
+ { button } +
+
+ ); + } + render({ app, workflowUuid }, - { workflow, projectUuid, processName, processDescription, - defaultProcessName, defaultProcessDescription, - inputsFunctionText, browseDialogId, - insertDialogId, insertManyDialogId, - realBrowseDialogId, inputsPreview }) { + { workflow, workflowDefinition, projectUuid, processName, processDescription, + defaultProcessName, defaultProcessDescription }) { return (
- - this.setState({ 'projectUuid': value }) } /> - - { - const t = this.inputsTextArea.current; - const start = t.selectionStart; - const end = t.selectionEnd; - this.setState({ - 'inputsFunctionText': t.value.substr(0, start) + value + - t.value.substr(end) - }); - } } /> - - alert(values) } /> - - + { workflow ? (
@@ -138,17 +115,13 @@ class WBLaunchWorkflowPage extends Component {
+ this.browseDialogRef.current.show('owner', false, + projectUuid => this.setState({ projectUuid })); } }>Browse
-
- - -
-
-
-
- - - - - -
- - - -
- -
- - -
- + (a.id === '#main')).inputs.map(it => [ + it.label || it.id, + this.renderInput(it) + ]) } />
) :
Loading...
}