| @@ -0,0 +1,82 @@ | |||||
| import { h, Component } from 'preact'; | |||||
| import makeArvadosRequest from 'make-arvados-request'; | |||||
| import WBPagination from 'wb-pagination'; | |||||
| import WBTable from 'wb-table'; | |||||
| class WBBrowseDialogProjectList extends Component { | |||||
| constructor(...args) { | |||||
| super(...args); | |||||
| this.state.rows = []; | |||||
| } | |||||
| componentDidMount() { | |||||
| this.fetchRows(); | |||||
| } | |||||
| componentWillReceiveProps(nextProps) { | |||||
| this.props = nextProps; | |||||
| this.setState({ | |||||
| 'page': 0 | |||||
| }); | |||||
| this.fetchRows(); | |||||
| } | |||||
| changePage(page) { | |||||
| this.setState({ | |||||
| 'page': page | |||||
| }); | |||||
| this.fetchRows(); | |||||
| } | |||||
| prepareRows(items) { | |||||
| return items.map(it => [ | |||||
| it.name, | |||||
| it.file_count, | |||||
| it.file_size_total | |||||
| ]); | |||||
| } | |||||
| fetchRows() { | |||||
| const { arvHost, arvToken } = this.props.app.state; | |||||
| const { textSearch, itemsPerPage } = this.props; | |||||
| const ownerUuid = ('ownerUuid' in this.state ? | |||||
| this.state.ownerUuid : this.props.ownerUuid); | |||||
| const { page } = this.state; | |||||
| const filters = [ | |||||
| ['group_class', '=', 'project'] | |||||
| ]; | |||||
| if (ownerUuid) | |||||
| filters.push(['owner_uuid', '=', ownerUuid]); | |||||
| if (textSearch) | |||||
| filters.push(['name', 'ilike', '%' + textSearch + '%']); | |||||
| let prom = makeArvadosRequest(arvHost, arvToken, | |||||
| '/arvados/v1/groups?filters=' + | |||||
| encodeURIComponent(JSON.stringify(filters)) + | |||||
| '&limit=' + itemsPerPage + | |||||
| '&offset=' + (page * itemsPerPage)); | |||||
| prom = prom.then(xhr => { | |||||
| this.setState({ | |||||
| 'rows': this.prepareRows(xhr.response.items), | |||||
| 'numPages': xhr.response.items_available / itemsPerPage | |||||
| }); | |||||
| }); | |||||
| } | |||||
| render({ app }, { ownerUuid, textSearch, page, numPages, rows }) { | |||||
| return ( | |||||
| <div> | |||||
| <WBTable columns={ ['Name', 'File Count', 'Size'] } | |||||
| rows={ rows } /> | |||||
| <WBPagination numPages={ numPages } activePage={ page } | |||||
| onPageChanged={ i => this.changePage(i) } /> | |||||
| </div> | |||||
| ); | |||||
| } | |||||
| } | |||||
| WBBrowseDialogProjectList.defaultProps = { | |||||
| 'itemsPerPage': 5 | |||||
| }; | |||||
| export default WBBrowseDialogProjectList; | |||||
| @@ -0,0 +1,60 @@ | |||||
| import { h, Component } from 'preact'; | |||||
| import WBBrowseDialogProjectList from 'wb-browse-dialog-project-list'; | |||||
| import WBBrowseDialogCollectionList from 'wb-browse-dialog-project-list'; | |||||
| class WBBrowseDialog extends Component { | |||||
| render({ app, id }, { mode }) { | |||||
| return ( | |||||
| <div class="modal" id={ id } tabindex="-1" role="dialog"> | |||||
| <div class="modal-dialog modal-lg" role="document"> | |||||
| <div class="modal-content"> | |||||
| <div class="modal-header"> | |||||
| <h5 class="modal-title">Browse</h5> | |||||
| <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | |||||
| <span aria-hidden="true">×</span> | |||||
| </button> | |||||
| </div> | |||||
| <div class="modal-body"> | |||||
| <button class="btn btn-sm btn-outline-primary">Back</button> | |||||
| <input class="form-control" type="search" placeholder="Search" /> | |||||
| <div class="input-group mb-3"> | |||||
| <div class="input-group-prepend"> | |||||
| <button class="btn btn-outline-secondary" type="button">Back</button> | |||||
| </div> | |||||
| <input type="text" class="form-control" placeholder="Search" | |||||
| aria-label="Search" /> | |||||
| <div class="input-group-append"> | |||||
| <button class="btn btn-outline-primary" type="button">Search</button> | |||||
| </div> | |||||
| </div> | |||||
| <h5>Projects</h5> | |||||
| <WBBrowseDialogProjectList app={ app } /> | |||||
| { mode === 'collection-content' ? ( | |||||
| <h5>Content</h5> | |||||
| ) : ( | |||||
| <div> | |||||
| <h5>Collections</h5> | |||||
| <WBBrowseDialogCollectionList app={ app } /> | |||||
| </div> | |||||
| ) } | |||||
| </div> | |||||
| <div class="modal-footer"> | |||||
| <button type="button" class="btn btn-primary">Accept</button> | |||||
| <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| } | |||||
| } | |||||
| export default WBBrowseDialog; | |||||
| @@ -2,6 +2,7 @@ import { h, Component, createRef } from 'preact'; | |||||
| import WBNavbarCommon from 'wb-navbar-common'; | import WBNavbarCommon from 'wb-navbar-common'; | ||||
| import WBArvadosCrumbs from 'wb-arvados-crumbs'; | import WBArvadosCrumbs from 'wb-arvados-crumbs'; | ||||
| import WBToolboxDialog from 'wb-toolbox-dialog'; | import WBToolboxDialog from 'wb-toolbox-dialog'; | ||||
| import WBBrowseDialog from 'wb-browse-dialog'; | |||||
| import makeArvadosRequest from 'make-arvados-request'; | import makeArvadosRequest from 'make-arvados-request'; | ||||
| import linkState from 'linkstate'; | import linkState from 'linkstate'; | ||||
| @@ -58,6 +59,7 @@ class WBLaunchWorkflowPage extends Component { | |||||
| this.state.browseDialogId = uuid.v4(); | this.state.browseDialogId = uuid.v4(); | ||||
| this.state.insertDialogId = uuid.v4(); | this.state.insertDialogId = uuid.v4(); | ||||
| this.state.insertManyDialogId = uuid.v4(); | this.state.insertManyDialogId = uuid.v4(); | ||||
| this.state.realBrowseDialogId = uuid.v4(); | |||||
| this.inputsTextArea = createRef(); | this.inputsTextArea = createRef(); | ||||
| } | } | ||||
| @@ -82,7 +84,7 @@ class WBLaunchWorkflowPage extends Component { | |||||
| defaultProcessName, defaultProcessDescription, | defaultProcessName, defaultProcessDescription, | ||||
| inputsFunctionText, browseDialogId, | inputsFunctionText, browseDialogId, | ||||
| insertDialogId, insertManyDialogId, | insertDialogId, insertManyDialogId, | ||||
| inputsPreview }) { | |||||
| realBrowseDialogId, inputsPreview }) { | |||||
| return ( | return ( | ||||
| <div> | <div> | ||||
| @@ -108,6 +110,8 @@ class WBLaunchWorkflowPage extends Component { | |||||
| items={ app.state.toolboxItems } selectMany={ true } | items={ app.state.toolboxItems } selectMany={ true } | ||||
| onAccepted={ values => alert(values) } /> | onAccepted={ values => alert(values) } /> | ||||
| <WBBrowseDialog app={ app } id={ realBrowseDialogId } /> | |||||
| { workflow ? | { workflow ? | ||||
| (<form class="container-fluid"> | (<form class="container-fluid"> | ||||
| <h1>Launch Workflow</h1> | <h1>Launch Workflow</h1> | ||||
| @@ -171,6 +175,11 @@ class WBLaunchWorkflowPage extends Component { | |||||
| e.preventDefault(); | e.preventDefault(); | ||||
| $('#' + insertManyDialogId).modal(); | $('#' + insertManyDialogId).modal(); | ||||
| } }>Insert Many</button> | } }>Insert Many</button> | ||||
| <button class="btn btn-primary mr-2" onclick={ e => { | |||||
| e.preventDefault(); | |||||
| $('#' + realBrowseDialogId).modal(); | |||||
| } }>Insert Browse</button> | |||||
| </div> | </div> | ||||
| <textarea class="form-control" ref={ this.inputsTextArea } id="inputs" | <textarea class="form-control" ref={ this.inputsTextArea } id="inputs" | ||||