@@ -0,0 +1,39 @@ | |||||
import { h, Component } from 'preact'; | |||||
import WBBreadcrumbs from 'wb-breadcrumbs'; | |||||
import fetchObjectParents from 'fetch-object-parents'; | |||||
class WBArvadosCrumbs extends Component { | |||||
constructor(...args) { | |||||
super(...args); | |||||
this.state.items = [ { 'name': 'All Projects' } ]; | |||||
} | |||||
fetchCrumbs() { | |||||
if (!this.props.uuid) { | |||||
this.setState({ 'items': [ { 'name': 'All Projects' } ] }); | |||||
return; | |||||
} | |||||
let { arvHost, arvToken } = this.props.app.state; | |||||
let prom = fetchObjectParents(arvHost, arvToken, this.props.uuid); | |||||
prom = prom.then(parents => this.setState({ 'items': parents })); | |||||
} | |||||
componentDidMount() { | |||||
this.fetchCrumbs(); | |||||
} | |||||
componentWillReceiveProps(nextProps) { | |||||
this.props = nextProps; | |||||
this.fetchCrumbs(); | |||||
} | |||||
render({ app }, { items }) { | |||||
return ( | |||||
<WBBreadcrumbs items={ items } | |||||
onItemClicked={ item => app.breadcrumbClicked(item) } /> | |||||
); | |||||
} | |||||
} | |||||
export default WBArvadosCrumbs; |
@@ -0,0 +1,24 @@ | |||||
import { h, Component } from 'preact'; | |||||
import WBNavbar from 'wb-navbar'; | |||||
import WBInlineSearch from 'wb-inline-search'; | |||||
class WBNavbarCommon extends Component { | |||||
render({ app, items, activeItem }) { | |||||
return ( | |||||
<WBNavbar items={ [ | |||||
{ 'name': 'Home', 'id': 'home' }, | |||||
{ 'name': 'All Projects', 'id': 'all-projects' }, | |||||
{ 'name': 'User', 'dropdown': [ { 'id': 'sign-out', 'name': 'Sign Out' } ]} | |||||
].concat(items) } rhs={ ( | |||||
<WBInlineSearch /> | |||||
) } onItemClicked={ item => app.navbarItemClicked(item) } | |||||
activeItem={ activeItem } /> | |||||
); | |||||
} | |||||
} | |||||
WBNavbarCommon.defaultProps = { | |||||
'items': [] | |||||
}; | |||||
export default WBNavbarCommon; |
@@ -0,0 +1,13 @@ | |||||
const typeIdToName = { | |||||
'tpzed': 'user', | |||||
'j7d0g': 'group', | |||||
'xvhdp': 'container_request', | |||||
'dz642': 'container', | |||||
'7fd4e': 'workflow' | |||||
}; | |||||
function arvadosTypeName(id) { | |||||
return typeIdToName[id]; | |||||
} | |||||
export default arvadosTypeName; |
@@ -0,0 +1,49 @@ | |||||
import makeArvadosRequest from 'make-arvados-request'; | |||||
import arvadosTypeName from 'arvados-type-name'; | |||||
function fetchObjectParents(arvHost, arvToken, uuid) { | |||||
let parents = []; | |||||
let cb = xhr => { | |||||
let objectType = arvadosTypeName(xhr.response['uuid'].split('-')[1]); | |||||
let item = { | |||||
'uuid': xhr.response['uuid'] | |||||
}; | |||||
if (objectType === 'user') { | |||||
item['name'] = xhr.response['first_name'] + ' ' + xhr.response['last_name']; | |||||
} else { | |||||
item['name'] = xhr.response['name']; | |||||
} | |||||
if (objectType === 'group') { | |||||
item['group_class'] = xhr.response['group_class']; | |||||
} | |||||
parents.push(item); | |||||
if (!xhr.response['owner_uuid'] || | |||||
xhr.response['owner_uuid'].endsWith('-tpzed-000000000000000')) { | |||||
return parents.reverse(); | |||||
} | |||||
objectType = arvadosTypeName(xhr.response['owner_uuid'].split('-')[1]); | |||||
return makeArvadosRequest(arvHost, arvToken, | |||||
'/arvados/v1/' + objectType + 's' + | |||||
'/' + xhr.response['owner_uuid']).then(cb); | |||||
}; | |||||
let objectType = arvadosTypeName(uuid.split('-')[1]); | |||||
let prom = makeArvadosRequest(arvHost, arvToken, | |||||
'/arvados/v1/' + objectType + 's' + | |||||
'/' + uuid); | |||||
prom = prom.then(cb); | |||||
return prom; | |||||
} | |||||
export default fetchObjectParents; |
@@ -3,6 +3,8 @@ import { Router, route } from 'preact-router'; | |||||
import WBBrowse from 'wb-browse'; | import WBBrowse from 'wb-browse'; | ||||
import WBSignIn from 'wb-sign-in'; | import WBSignIn from 'wb-sign-in'; | ||||
import WBLandingPage from 'wb-landing-page'; | import WBLandingPage from 'wb-landing-page'; | ||||
import WBProcessView from 'wb-process-view'; | |||||
import arvadosTypeName from 'arvados-type-name'; | |||||
class WBApp extends Component { | class WBApp extends Component { | ||||
constructor(...args) { | constructor(...args) { | ||||
@@ -37,6 +39,16 @@ class WBApp extends Component { | |||||
} | } | ||||
} | } | ||||
breadcrumbClicked(item) { | |||||
let objectType = arvadosTypeName(item.uuid.split('-')[1]); | |||||
if (objectType === 'user') | |||||
route('/browse/' + item.uuid) | |||||
else if (objectType === 'group' && item.group_class === 'project') | |||||
route('/browse/' + item.uuid); | |||||
else if (objectType === 'container_request') | |||||
route('/process/' + item.uuid) | |||||
} | |||||
render() { | render() { | ||||
return ( | return ( | ||||
<Router> | <Router> | ||||
@@ -47,6 +59,8 @@ class WBApp extends Component { | |||||
<WBBrowse path="/browse/:ownerUuid?/:activePage?/:objTypeTab?/:collectionPage?/:processPage?/:workflowPage?" | <WBBrowse path="/browse/:ownerUuid?/:activePage?/:objTypeTab?/:collectionPage?/:processPage?/:workflowPage?" | ||||
appCallbacks={ this.appCallbacks } | appCallbacks={ this.appCallbacks } | ||||
appState={ this.appState } /> | appState={ this.appState } /> | ||||
<WBProcessView path="/process/:uuid" app={ this } /> | |||||
</Router> | </Router> | ||||
); | ); | ||||
} | } | ||||
@@ -0,0 +1,19 @@ | |||||
import { h, Component } from 'preact'; | |||||
import WBNavbarCommon from 'wb-navbar-common'; | |||||
import WBArvadosCrumbs from 'wb-arvados-crumbs'; | |||||
class WBProcessView extends Component { | |||||
render({ app, uuid }) { | |||||
return ( | |||||
<div> | |||||
<WBNavbarCommon app={ app } /> | |||||
<WBArvadosCrumbs app={ app } uuid={ uuid } /> | |||||
<div class="my-2">This is the process view for { uuid }</div> | |||||
</div> | |||||
); | |||||
} | |||||
} | |||||
export default WBProcessView; |
@@ -1,7 +1,7 @@ | |||||
import { h, Component } from 'preact'; | import { h, Component } from 'preact'; | ||||
class WBNavbar extends Component { | class WBNavbar extends Component { | ||||
render({ title, items, rhs, onItemClicked, onTitleClicked }) { | |||||
render({ title, items, rhs, onItemClicked, onTitleClicked, activeItem }) { | |||||
return ( | return ( | ||||
<nav class="navbar navbar-expand-lg navbar-light bg-light"> | <nav class="navbar navbar-expand-lg navbar-light bg-light"> | ||||
<a class="navbar-brand" href="#" onclick={ e => { e.preventDefault(); onTitleClicked(); } }>{ title }</a> | <a class="navbar-brand" href="#" onclick={ e => { e.preventDefault(); onTitleClicked(); } }>{ title }</a> | ||||
@@ -23,7 +23,7 @@ class WBNavbar extends Component { | |||||
else if (typeof(i) === 'object') | else if (typeof(i) === 'object') | ||||
var li_cls = ['nav-item']; | var li_cls = ['nav-item']; | ||||
if (i['active']) | |||||
if (i['active'] || activeItem === i['id']) | |||||
li_cls.push('active'); | li_cls.push('active'); | ||||
var a_cls = ['nav-link']; | var a_cls = ['nav-link']; | ||||
if (i['disabled']) | if (i['disabled']) | ||||
@@ -87,7 +87,8 @@ WBNavbar.defaultProps = { | |||||
'items': [], | 'items': [], | ||||
'form': null, | 'form': null, | ||||
'onItemClicked': () => {}, | 'onItemClicked': () => {}, | ||||
'onTitleClicked': () => {} | |||||
'onTitleClicked': () => {}, | |||||
'activeItem': null | |||||
} | } | ||||
export default WBNavbar; | export default WBNavbar; |