|
@@ -3,6 +3,7 @@ import WBNavbarCommon from 'wb-navbar-common'; |
|
|
import WBArvadosCrumbs from 'wb-arvados-crumbs';
|
|
|
import WBArvadosCrumbs from 'wb-arvados-crumbs';
|
|
|
import WBBrowseDialog from 'wb-browse-dialog';
|
|
|
import WBBrowseDialog from 'wb-browse-dialog';
|
|
|
import WBTable from 'wb-table';
|
|
|
import WBTable from 'wb-table';
|
|
|
|
|
|
import WBNameAndUuid from 'wb-name-and-uuid';
|
|
|
import makeArvadosRequest from 'make-arvados-request';
|
|
|
import makeArvadosRequest from 'make-arvados-request';
|
|
|
import linkState from 'linkstate';
|
|
|
import linkState from 'linkstate';
|
|
|
|
|
|
|
|
@@ -16,6 +17,51 @@ function parseDefinition(text) { |
|
|
return definition;
|
|
|
return definition;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function encodeURIComponentIncludingDots(s) {
|
|
|
|
|
|
return encodeURIComponent(s).replace('.', '%2E');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class WBPathDisplay extends Component {
|
|
|
|
|
|
fetchData() {
|
|
|
|
|
|
const { app, path } = this.props;
|
|
|
|
|
|
const { arvHost, arvToken } = app.state;
|
|
|
|
|
|
let m;
|
|
|
|
|
|
if (m = /^[0-9a-f]{32}\+[0-9]+/.exec(path));
|
|
|
|
|
|
else if (m = /^[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{15}/.exec(path));
|
|
|
|
|
|
else return;
|
|
|
|
|
|
let prom = makeArvadosRequest(arvHost, arvToken,
|
|
|
|
|
|
'/arvados/v1/collections/' + m[0]);
|
|
|
|
|
|
prom = prom.then(xhr => this.setState({
|
|
|
|
|
|
item: xhr.response,
|
|
|
|
|
|
tail: path.substr(m[0].length)
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
|
|
this.fetchData();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps) {
|
|
|
|
|
|
this.props = nextProps;
|
|
|
|
|
|
this.fetchData();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
render({}, { item, tail }) {
|
|
|
|
|
|
if (!item)
|
|
|
|
|
|
return 'Loading...';
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<span>
|
|
|
|
|
|
<a href={ '/collection-browse/' + item.uuid }>
|
|
|
|
|
|
{ item.name || item.uuid }
|
|
|
|
|
|
</a><a href={ '/collection-browse/' + item.uuid + '/' + encodeURIComponentIncludingDots(tail) }>
|
|
|
|
|
|
{ tail }
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
class WBLaunchWorkflowPage extends Component {
|
|
|
class WBLaunchWorkflowPage extends Component {
|
|
|
constructor(...args) {
|
|
|
constructor(...args) {
|
|
|
super(...args);
|
|
|
super(...args);
|
|
@@ -38,20 +84,25 @@ class WBLaunchWorkflowPage extends Component { |
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
renderInput(inputSpec) {
|
|
|
renderInput(inputSpec) {
|
|
|
|
|
|
const { app } = this.props;
|
|
|
|
|
|
|
|
|
const isFile = (inputSpec.type === 'File' || inputSpec.type === 'File[]' ||
|
|
|
const isFile = (inputSpec.type === 'File' || inputSpec.type === 'File[]' ||
|
|
|
(inputSpec.type.type === 'array' && inputSpec.type.items === 'File'));
|
|
|
(inputSpec.type.type === 'array' && inputSpec.type.items === 'File'));
|
|
|
|
|
|
|
|
|
const isDirectory = (inputSpec.type === 'Directory' || inputSpec.type === 'Directory[]' ||
|
|
|
const isDirectory = (inputSpec.type === 'Directory' || inputSpec.type === 'Directory[]' ||
|
|
|
(inputSpec.type.type === 'array' && inputSpec.type.items === 'Directory'));
|
|
|
(inputSpec.type.type === 'array' && inputSpec.type.items === 'Directory'));
|
|
|
|
|
|
|
|
|
const isArray = (inputSpec.type === 'File[]' || inputSpec.type === 'Directory[]' ||
|
|
|
|
|
|
inputSpec.type.type === 'array');
|
|
|
|
|
|
|
|
|
const isArray = true; // (inputSpec.type === 'File[]' || inputSpec.type === 'Directory[]' ||
|
|
|
|
|
|
// inputSpec.type.type === 'array');
|
|
|
|
|
|
|
|
|
if (!isFile && !isDirectory)
|
|
|
if (!isFile && !isDirectory)
|
|
|
return (
|
|
|
return (
|
|
|
<input class="form-control w-100" type="text" placeholder={ inputSpec.doc }
|
|
|
|
|
|
value={ this.state.inputs[inputSpec.id] }
|
|
|
|
|
|
onchange={ e => (this.state.inputs[inputSpec.id] = e.target.value) }></input>
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<input class="form-control w-100" type="text" placeholder={ inputSpec.label }
|
|
|
|
|
|
value={ this.state.inputs[inputSpec.id] }
|
|
|
|
|
|
onchange={ e => (this.state.inputs[inputSpec.id] = e.target.value) }></input>
|
|
|
|
|
|
<div class="mt-2 text-muted">{ inputSpec.doc }</div>
|
|
|
|
|
|
</div>
|
|
|
);
|
|
|
);
|
|
|
|
|
|
|
|
|
const button = (
|
|
|
const button = (
|
|
@@ -60,7 +111,7 @@ class WBLaunchWorkflowPage extends Component { |
|
|
e.preventDefault();
|
|
|
e.preventDefault();
|
|
|
this.browseDialogRef.current.show(isFile ? 'file' : 'directory', isArray,
|
|
|
this.browseDialogRef.current.show(isFile ? 'file' : 'directory', isArray,
|
|
|
v => {
|
|
|
v => {
|
|
|
this.state.inputs[inputSpec.id] = v.toString();
|
|
|
|
|
|
|
|
|
this.state.inputs[inputSpec.id] = JSON.stringify(v);
|
|
|
this.setState({});
|
|
|
this.setState({});
|
|
|
});
|
|
|
});
|
|
|
} }>
|
|
|
} }>
|
|
@@ -68,14 +119,36 @@ class WBLaunchWorkflowPage extends Component { |
|
|
</button>
|
|
|
</button>
|
|
|
);
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
let value = this.state.inputs[inputSpec.id];
|
|
|
|
|
|
if (value) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
value = jsyaml.load(value);
|
|
|
|
|
|
} catch (_) {}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
return (
|
|
|
return (
|
|
|
<div class="input-group">
|
|
|
|
|
|
<input class="form-control w-100" type="text" placeholder={ inputSpec.doc }
|
|
|
|
|
|
value={ this.state.inputs[inputSpec.id] }
|
|
|
|
|
|
onchange={ e => (this.state.inputs[inputSpec.id] = e.target.value) }></input>
|
|
|
|
|
|
<div class="input-group-append">
|
|
|
|
|
|
{ button }
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div class="input-group">
|
|
|
|
|
|
<input class="form-control w-100" type="text" placeholder={ inputSpec.label }
|
|
|
|
|
|
value={ this.state.inputs[inputSpec.id] }
|
|
|
|
|
|
onchange={ e => (this.state.inputs[inputSpec.id] = e.target.value) }></input>
|
|
|
|
|
|
<div class="input-group-append">
|
|
|
|
|
|
{ button }
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="mt-2 text-muted">{ inputSpec.doc }</div>
|
|
|
|
|
|
{ value ?
|
|
|
|
|
|
isArray ? (
|
|
|
|
|
|
<ul class="mb-0">
|
|
|
|
|
|
{ value.map(path => (
|
|
|
|
|
|
<li>
|
|
|
|
|
|
<WBPathDisplay app={ app } path={ path } />
|
|
|
|
|
|
</li>
|
|
|
|
|
|
)) }
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
) : (
|
|
|
|
|
|
<WBPathDisplay app={ app } path={ value } />
|
|
|
|
|
|
) : null }
|
|
|
</div>
|
|
|
</div>
|
|
|
);
|
|
|
);
|
|
|
}
|
|
|
}
|
|
@@ -102,24 +175,22 @@ class WBLaunchWorkflowPage extends Component { |
|
|
<div class="form-group">
|
|
|
<div class="form-group">
|
|
|
<label for="projectUuid">Project UUID</label>
|
|
|
<label for="projectUuid">Project UUID</label>
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
{ projectUuid ? (
|
|
|
|
|
|
<WBArvadosCrumbs app={ app } uuid={ projectUuid } />
|
|
|
|
|
|
) : null }
|
|
|
|
|
|
|
|
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
|
|
<input type="text" class="form-control" id="projectUuid"
|
|
|
|
|
|
placeholder="Enter Project UUID" aria-label="Project UUID"
|
|
|
|
|
|
aria-describedby="button-addon2" value={ projectUuid }
|
|
|
|
|
|
onChange={ linkState(this, 'projectUuid') } />
|
|
|
|
|
|
<div class="input-group-append">
|
|
|
|
|
|
<button class="btn btn-primary" type="button"
|
|
|
|
|
|
id="button-addon2" onclick={ e => { e.preventDefault();
|
|
|
|
|
|
this.browseDialogRef.current.show('owner', false,
|
|
|
|
|
|
projectUuid => this.setState({ projectUuid })); } }>Browse</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
|
|
<input type="text" class="form-control" id="projectUuid"
|
|
|
|
|
|
placeholder="Enter Project UUID" aria-label="Project UUID"
|
|
|
|
|
|
aria-describedby="button-addon2" value={ projectUuid }
|
|
|
|
|
|
onChange={ linkState(this, 'projectUuid') } />
|
|
|
|
|
|
<div class="input-group-append">
|
|
|
|
|
|
<button class="btn btn-primary" type="button"
|
|
|
|
|
|
id="button-addon2" onclick={ e => { e.preventDefault();
|
|
|
|
|
|
this.browseDialogRef.current.show('owner', false,
|
|
|
|
|
|
projectUuid => this.setState({ projectUuid })); } }>Browse</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{ projectUuid ? (
|
|
|
|
|
|
<WBArvadosCrumbs app={ app } uuid={ projectUuid } />
|
|
|
|
|
|
) : null }
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="form-group">
|
|
|
<div class="form-group">
|
|
@@ -144,6 +215,12 @@ class WBLaunchWorkflowPage extends Component { |
|
|
this.renderInput(it)
|
|
|
this.renderInput(it)
|
|
|
]) } />
|
|
|
]) } />
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<button class="btn btn-success" onclick={ e => { e.preventDefault(); this.submit(); } }>
|
|
|
|
|
|
Submit
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
</form>) : <div>Loading...</div> }
|
|
|
</form>) : <div>Loading...</div> }
|
|
|
</div>
|
|
|
</div>
|
|
|
);
|
|
|
);
|
|
|