| @@ -68,13 +68,16 @@ class WBCollectionListing extends Component { | |||
| fetchItems() { | |||
| let { arvHost, arvToken } = this.props.app.state; | |||
| let { activePage, itemsPerPage, ownerUuid } = this.props; | |||
| let { activePage, itemsPerPage, ownerUuid, textSearch } = this.props; | |||
| let filters = []; | |||
| if (ownerUuid) | |||
| filters.push([ 'owner_uuid', '=', ownerUuid ]); | |||
| if (textSearch) | |||
| filters.push([ 'any', 'ilike', '%' + textSearch + '%' ]); | |||
| let prom = makeArvadosRequest(arvHost, arvToken, | |||
| '/arvados/v1/collections?filters=' + encodeURIComponent(JSON.stringify(filters)) + | |||
| '&limit=' + encodeURIComponent(itemsPerPage) + | |||
| @@ -1,12 +1,13 @@ | |||
| import { h, Component } from 'preact'; | |||
| class WBInlineSearch extends Component { | |||
| render() { | |||
| render({ textSearch, navigate }) { | |||
| return ( | |||
| <form class="form-inline my-2 my-lg-0"> | |||
| <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" /> | |||
| <div class="form-inline my-2 my-lg-0"> | |||
| <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" | |||
| value={ textSearch } onchange={ navigate ? (e => navigate(e.target.value)) : null } /> | |||
| <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> | |||
| </form> | |||
| </div> | |||
| ); | |||
| } | |||
| } | |||
| @@ -3,7 +3,7 @@ import WBNavbar from 'wb-navbar'; | |||
| import WBInlineSearch from 'wb-inline-search'; | |||
| class WBNavbarCommon extends Component { | |||
| render({ app, items, activeItem }) { | |||
| render({ app, items, activeItem, textSearch, textSearchNavigate }) { | |||
| return ( | |||
| <WBNavbar | |||
| items={ [ | |||
| @@ -13,9 +13,9 @@ class WBNavbarCommon extends Component { | |||
| { 'name': 'Shared with Me', 'id': 'shared-with-me' }, | |||
| { 'name': 'Current User', 'dropdown': [ { 'id': 'sign-out', 'name': 'Sign Out' } ]} | |||
| ].concat(items) } | |||
| rhs={ ( | |||
| <WBInlineSearch /> | |||
| ) } | |||
| rhs={ textSearchNavigate ? ( | |||
| <WBInlineSearch textSearch={ textSearch } navigate={ textSearchNavigate } /> | |||
| ) : null } | |||
| titleUrl = { '/browse/' + app.state.currentUser.uuid } | |||
| getItemUrl={ item => app.navbarItemUrl(item) } | |||
| activeItem={ activeItem } /> | |||
| @@ -57,7 +57,8 @@ class WBProcessListing extends Component { | |||
| const { arvHost, arvToken } = this.props.appState; | |||
| const { requestStates, reqStateMask } = this.state; | |||
| const { activePage, itemsPerPage, ownerUuid, | |||
| requestingContainerUuid, waitForNextProps } = this.props; | |||
| requestingContainerUuid, waitForNextProps, | |||
| textSearch } = this.props; | |||
| if (waitForNextProps) | |||
| return; | |||
| @@ -69,6 +70,8 @@ class WBProcessListing extends Component { | |||
| filters.push([ 'state', 'in', requestStates.filter((_, idx) => reqStateMask[idx]) ]); | |||
| if (ownerUuid) | |||
| filters.push([ 'owner_uuid', '=', ownerUuid ]); | |||
| if (textSearch) | |||
| filters.push([ 'any', 'ilike', '%' + textSearch + '%' ]) | |||
| let prom = makeArvadosRequest(arvHost, arvToken, | |||
| '/arvados/v1/container_requests?filters=' + encodeURIComponent(JSON.stringify(filters)) + | |||
| @@ -24,8 +24,7 @@ class WBProjectListing extends Component { | |||
| renderSelectionCell(item), | |||
| (<div> | |||
| <div> | |||
| <a href="#" | |||
| onclick={ e => { e.preventDefault(); route('/browse/' + item['uuid']) }}> | |||
| <a href={ '/browse/' + item.uuid }> | |||
| { item['name'] } | |||
| </a> { renderRenameLink(item, () => this.fetchItems()) } | |||
| </div> | |||
| @@ -45,13 +44,15 @@ class WBProjectListing extends Component { | |||
| } | |||
| fetchItems() { | |||
| let { activePage, mode, itemsPerPage, ownerUuid, app } = this.props; | |||
| let { activePage, mode, itemsPerPage, ownerUuid, app, textSearch } = this.props; | |||
| let { arvHost, arvToken } = app.state; | |||
| let filters = [ | |||
| [ 'group_class', '=', 'project' ] | |||
| ]; | |||
| if (ownerUuid) | |||
| filters.push([ 'owner_uuid', '=', ownerUuid ]); | |||
| if (textSearch) | |||
| filters.push([ 'any', 'ilike', '%' + textSearch + '%' ]); | |||
| let prom = makeArvadosRequest(arvHost, arvToken, | |||
| '/arvados/v1/groups' + (mode === 'shared-with-me' ? '/shared' : '') + | |||
| '?filters=' + encodeURIComponent(JSON.stringify(filters)) + | |||
| @@ -15,12 +15,17 @@ class WBUserListing extends Component { | |||
| preparePage() { | |||
| const { arvHost, arvToken } = this.props.app.state; | |||
| const { itemsPerPage, page } = this.props; | |||
| const { itemsPerPage, page, textSearch } = this.props; | |||
| const order = ['last_name asc']; | |||
| const filters = []; | |||
| if (textSearch) | |||
| filters.push([ 'any', 'ilike', '%' + textSearch + '%' ]); | |||
| let prom = makeArvadosRequest(arvHost, arvToken, | |||
| '/arvados/v1/users?order=' + encodeURIComponent(JSON.stringify(order)) + | |||
| '&filters=' + encodeURIComponent(JSON.stringify(filters)) + | |||
| '&limit=' + itemsPerPage + '&offset=' + (itemsPerPage * page)); | |||
| prom = prom.then(xhr => { | |||
| this.setState({ | |||
| @@ -50,10 +50,12 @@ class WBWorkflowListing extends Component { | |||
| fetchItems() { | |||
| const { arvHost, arvToken } = this.props.app.state; | |||
| const { page, itemsPerPage, ownerUuid } = this.props; | |||
| const { page, itemsPerPage, ownerUuid, textSearch } = this.props; | |||
| const filters = []; | |||
| if (ownerUuid) | |||
| filters.push([ 'owner_uuid', '=', ownerUuid ]); | |||
| if (textSearch) | |||
| filters.push([ 'any', 'ilike', '%' + textSearch + '%' ]); | |||
| const select = ['uuid', 'name', 'description', 'owner_uuid', 'created_at']; | |||
| let prom = makeArvadosRequest(arvHost, arvToken, | |||
| '/arvados/v1/workflows?filters=' + encodeURIComponent(JSON.stringify(filters)) + | |||
| @@ -75,10 +75,10 @@ class WBApp extends Component { | |||
| <WBSignOut path='/sign-out' app={ this } /> | |||
| <WBBrowse path="/browse/:ownerUuid?/:activePage?/:objTypeTab?/:collectionPage?/:processPage?/:workflowPage?" | |||
| <WBBrowse path="/browse/:ownerUuid?/:activePage?/:objTypeTab?/:collectionPage?/:processPage?/:workflowPage?/:textSearch?" | |||
| app={ this } mode="browse" /> | |||
| <WBBrowse path="/shared-with-me/:activePage?" | |||
| <WBBrowse path="/shared-with-me/:activePage?/:textSearch?" | |||
| app={ this } mode="shared-with-me" /> | |||
| <WBProcessView path="/process/:uuid/:page?" app={ this } /> | |||
| @@ -89,7 +89,7 @@ class WBApp extends Component { | |||
| <WBCollectionBrowse path='/collection-browse/:uuid/:collectionPath?/:page?' app={ this } /> | |||
| <WBUsersPage path='/users/:page?' app={ this } /> | |||
| <WBUsersPage path='/users/:page?/:textSearch?' app={ this } /> | |||
| <WBWorkflowView path="/workflow/:uuid" app={ this } /> | |||
| @@ -52,8 +52,9 @@ class WBBrowse extends Component { | |||
| const mode = ('mode' in params ? params.mode : this.props.mode); | |||
| if (mode === 'shared-with-me') | |||
| return '/shared-with-me/' + ('activePage' in params ? params.activePage : | |||
| (this.props.activePage || '')); | |||
| return '/shared-with-me/' + | |||
| ('activePage' in params ? params.activePage : (this.props.activePage || '')) + '/' + | |||
| ('textSearch' in params ? params.textSearch : (this.props.textSearch || '')); | |||
| let res = '/browse/' + | |||
| ('ownerUuid' in params ? params.ownerUuid : (this.props.ownerUuid || '')) + '/' + | |||
| @@ -61,7 +62,8 @@ class WBBrowse extends Component { | |||
| ('objTypeTab' in params ? params.objTypeTab : (this.props.objTypeTab || '')) + '/' + | |||
| ('collectionPage' in params ? params.collectionPage : (this.props.collectionPage || '')) + '/' + | |||
| ('processPage' in params ? params.processPage : (this.props.processPage || '')) + '/' + | |||
| ('workflowPage' in params ? params.workflowPage : (this.props.workflowPage || '')); | |||
| ('workflowPage' in params ? params.workflowPage : (this.props.workflowPage || '')) + '/' + | |||
| encodeURIComponent('textSearch' in params ? params.textSearch : (this.props.textSearch || '')); | |||
| return res; | |||
| } | |||
| @@ -141,7 +143,8 @@ class WBBrowse extends Component { | |||
| } | |||
| render({ mode, ownerUuid, activePage, app, | |||
| objTypeTab, collectionPage, processPage, workflowPage }, { selected }) { | |||
| objTypeTab, collectionPage, processPage, workflowPage, | |||
| textSearch }, { selected }) { | |||
| return ( | |||
| <div> | |||
| @@ -151,9 +154,13 @@ class WBBrowse extends Component { | |||
| <WBNewProjectDialog app={ app } ref={ this.newProjectDialogRef } /> | |||
| <WBNavbarCommon app={ app } activeItem={ mode === 'shared-with-me' ? 'shared-with-me' : | |||
| (!ownerUuid) ? 'all-projects' : | |||
| (ownerUuid === app.state.currentUser.uuid) ? 'home' : null } /> | |||
| <WBNavbarCommon app={ app } | |||
| activeItem={ mode === 'shared-with-me' ? 'shared-with-me' : | |||
| (!ownerUuid) ? 'all-projects' : | |||
| (ownerUuid === app.state.currentUser.uuid) ? 'home' : null } | |||
| textSearch={ textSearch } | |||
| textSearchNavigate={ textSearch => route(this.getUrl({ textSearch, | |||
| activePage: 0, collectionPage: 0, processPage: 0, workflowPage: 0 })) } /> | |||
| <WBArvadosCrumbs mode={ mode } uuid={ ownerUuid } app={ app } /> | |||
| @@ -174,7 +181,8 @@ class WBBrowse extends Component { | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } | |||
| renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } | |||
| renderSelectionCell={ it => this.renderSelectionCell(it) } | |||
| renderSharingButton={ it => this.renderSharingButton(it) } /> | |||
| renderSharingButton={ it => this.renderSharingButton(it) } | |||
| textSearch={ textSearch } /> | |||
| { (mode !== 'browse') ? null : ( | |||
| <WBTabs tabs={ [ | |||
| @@ -195,7 +203,8 @@ class WBBrowse extends Component { | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } | |||
| renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } | |||
| renderSelectionCell={ it => this.renderSelectionCell(it) } | |||
| renderSharingButton={ it => this.renderSharingButton(it) } /> | |||
| renderSharingButton={ it => this.renderSharingButton(it) } | |||
| textSearch={ textSearch } /> | |||
| ) : (objTypeTab === 'process') ? ( | |||
| <WBProcessListing app={ app } | |||
| @@ -207,7 +216,8 @@ class WBBrowse extends Component { | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } | |||
| renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } | |||
| renderSelectionCell={ it => this.renderSelectionCell(it) } | |||
| renderSharingButton={ it => this.renderSharingButton(it) } /> | |||
| renderSharingButton={ it => this.renderSharingButton(it) } | |||
| textSearch={ textSearch } /> | |||
| ) : (objTypeTab === 'workflow') ? ( | |||
| <WBWorkflowListing app={ app } | |||
| @@ -218,7 +228,8 @@ class WBBrowse extends Component { | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } | |||
| renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } | |||
| renderSelectionCell={ it => this.renderSelectionCell(it) } | |||
| renderSharingButton={ it => this.renderSharingButton(it) } /> | |||
| renderSharingButton={ it => this.renderSharingButton(it) } | |||
| textSearch={ textSearch } /> | |||
| ) : null | |||
| } | |||
| @@ -1,19 +1,27 @@ | |||
| import { h, Component } from 'preact'; | |||
| import { route } from 'preact-router'; | |||
| import WBNavbarCommon from 'wb-navbar-common'; | |||
| import WBUserListing from 'wb-user-listing'; | |||
| class WBUsersPage extends Component { | |||
| getUrl(page) { | |||
| return ('/users/' + page); | |||
| getUrl(params) { | |||
| const url = '/users/' + | |||
| Number('page' in params ? params.page : (this.props.page || 0)) + '/' + | |||
| encodeURIComponent('textSearch' in params ? params.textSearch : (this.props.textSearch || '')); | |||
| return url; | |||
| // return ('/users/' + page); | |||
| } | |||
| render({ app, page }) { | |||
| render({ app, page, textSearch }) { | |||
| return ( | |||
| <div> | |||
| <WBNavbarCommon app={ app } activeItem="all-users" /> | |||
| <WBNavbarCommon app={ app } activeItem="all-users" | |||
| textSearch={ textSearch } | |||
| textSearchNavigate={ textSearch => route(this.getUrl({ textSearch, page: 0 })) } /> | |||
| <WBUserListing app={ app } page={ Number(page || 0) } | |||
| getPageUrl={ page => this.getUrl(page) } /> | |||
| textSearch={ textSearch } | |||
| getPageUrl={ page => this.getUrl({ page }) } /> | |||
| </div> | |||
| ); | |||
| } | |||