IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
瀏覽代碼

Further progress in workflow launcher.

master
父節點
當前提交
d9c7f4b0b9
共有 4 個文件被更改,包括 123 次插入43 次删除
  1. +6
    -3
      frontend/src/js/dialog/wb-browse-dialog-collection-content.js
  2. +5
    -6
      frontend/src/js/dialog/wb-browse-dialog-collection-list.js
  3. +7
    -6
      frontend/src/js/dialog/wb-browse-dialog.js
  4. +105
    -28
      frontend/src/js/page/wb-launch-workflow-page.js

+ 6
- 3
frontend/src/js/dialog/wb-browse-dialog-collection-content.js 查看文件

@@ -67,13 +67,16 @@ class WBBrowseDialogCollectionContent extends Component {
prepareRows(listing) {
const { makeSelectionCell, collectionPath, navigate,
page, itemsPerPage, collectionUuid, textSearch } = this.props;
page, itemsPerPage, collectionUuid, textSearch, selectWhat } = this.props;
const textLower = textSearch.toLowerCase();
listing = listing.filter(it => (it[1].toLowerCase().indexOf(textLower) !== -1));
const numPages = Math.ceil(listing.length / itemsPerPage);
const rows = listing.slice(page * itemsPerPage,
(page + 1) * itemsPerPage).map(it => [
makeSelectionCell(collectionUuid + '/' + collectionPath + '/' + it[1]),
((it[0] === 'd' && selectWhat === 'directory') ||
(it[0] === 'f' && selectWhat === 'file')) ?
makeSelectionCell(collectionUuid + collectionPath + '/' + it[1]) :
null,
it[0] === 'd' ? (
<a href="#" onclick={ e => {
e.preventDefault();
@@ -99,7 +102,7 @@ class WBBrowseDialogCollectionContent extends Component {
aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
</div>
] }
<WBTable headerClasses={ ['col-sm-1', 'col-sm-4', 'col-sm-4'] }
<WBTable headerClasses={ [ 'w-1' ] }
columns={ [ '', 'Name', 'Size' ] } rows={ rows } />
<WBPagination numPages={ numPages } activePage={ page }
onPageChanged={ i => navigate({ 'bottomPage': i }) } />


+ 5
- 6
frontend/src/js/dialog/wb-browse-dialog-collection-list.js 查看文件

@@ -20,15 +20,14 @@ class WBBrowseDialogCollectionList extends Component {
prepareRows(items) {
const { navigate, selectWhat, makeSelectionCell } = this.props;
return items.map(it => (selectWhat === 'directory' ? [
makeSelectionCell(it.uuid)
] : []).concat([
return items.map(it => [
(selectWhat === 'directory' ? makeSelectionCell(it.uuid) : null),
(
<a href="#" onclick={ e => { e.preventDefault();
navigate('/browse-dialog/content/' + it.uuid + '////'); } }>{ it.name }</a>
),
it.uuid
]));
]);
}
fetchRows() {
@@ -54,8 +53,8 @@ class WBBrowseDialogCollectionList extends Component {
render({ selectWhat, page, navigate }, { rows, numPages }) {
return (
<div>
<WBTable columns={ (selectWhat === 'directory' ? [''] : []).concat(['Name', 'UUID']) }
headerClasses={ selectWhat === 'directory' ? ['col-sm-1', 'col-sm-4', 'col-sm-4'] : [] }
<WBTable columns={ ['', 'Name', 'UUID'] }
headerClasses={ ['w-1'] }
rows={ rows } />
<WBPagination activePage={ page } numPages={ numPages }


+ 7
- 6
frontend/src/js/dialog/wb-browse-dialog.js 查看文件

@@ -87,9 +87,9 @@ class WBBrowseDialog extends Component {
}
selected[uuid] = true;
selectedOrder.push(uuid);
this.setState({
/* this.setState({
selected, selectedOrder
});
}); */
}
deselect(uuid) {
@@ -99,9 +99,9 @@ class WBBrowseDialog extends Component {
const n = selectedOrder.indexOf(uuid);
selectedOrder = selected.splice(n, n + 1);
delete selected[uuid];
this.setState({
/* this.setState({
selected, selectedOrder
});
}); */
}
resetSelection() {
@@ -139,7 +139,8 @@ class WBBrowseDialog extends Component {
const { app } = this.props;
const { currentUser } = app.state;
this.navigate('/browse-dialog/browse/' + currentUser.uuid, false,
{ selectWhat, selectMany, accept, history: [] });
{ selectWhat, selectMany, accept, history: [],
selected: {}, selectedOrder: [] });
$('#' + this.state.id).modal();
}
@@ -238,7 +239,7 @@ class WBBrowseDialog extends Component {
<div class="modal-footer">
{ selectMany ? (
<button type="button" class="btn btn-primary"
onclick={ e => { e.preventDefault(); accept(selectedOrder); } }>Accept</button>
onclick={ e => { e.preventDefault(); accept(selectedOrder); $('#' + id).modal('hide'); } }>Accept</button>
) : null }
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div>


+ 105
- 28
frontend/src/js/page/wb-launch-workflow-page.js 查看文件

@@ -3,6 +3,7 @@ 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 linkState from 'linkstate';
@@ -16,6 +17,51 @@ function parseDefinition(text) {
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 {
constructor(...args) {
super(...args);
@@ -38,20 +84,25 @@ class WBLaunchWorkflowPage extends Component {
}
renderInput(inputSpec) {
const { app } = this.props;
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');
const isArray = true; // (inputSpec.type === 'File[]' || inputSpec.type === 'Directory[]' ||
// inputSpec.type.type === 'array');
if (!isFile && !isDirectory)
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 = (
@@ -60,7 +111,7 @@ class WBLaunchWorkflowPage extends Component {
e.preventDefault();
this.browseDialogRef.current.show(isFile ? 'file' : 'directory', isArray,
v => {
this.state.inputs[inputSpec.id] = v.toString();
this.state.inputs[inputSpec.id] = JSON.stringify(v);
this.setState({});
});
} }>
@@ -68,14 +119,36 @@ class WBLaunchWorkflowPage extends Component {
</button>
);
let value = this.state.inputs[inputSpec.id];
if (value) {
try {
value = jsyaml.load(value);
} catch (_) {}
}
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 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>
);
}
@@ -102,24 +175,22 @@ class WBLaunchWorkflowPage extends Component {
<div class="form-group">
<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>
{ projectUuid ? (
<WBArvadosCrumbs app={ app } uuid={ projectUuid } />
) : null }
</div>
<div class="form-group">
@@ -144,6 +215,12 @@ class WBLaunchWorkflowPage extends Component {
this.renderInput(it)
]) } />
</div>
<div class="form-group">
<button class="btn btn-success" onclick={ e => { e.preventDefault(); this.submit(); } }>
Submit
</button>
</div>
</form>) : <div>Loading...</div> }
</div>
);


Loading…
取消
儲存