@@ -2,6 +2,9 @@ | |||
function makeArvadosRequest(arvHost, arvToken, endpoint, method='GET', data=null, | |||
contentType='application/json;charset=utf-8', responseType='json') { | |||
if (!arvHost || !arvToken) | |||
return new Promise((accept, reject) => reject()); | |||
let xhr = new XMLHttpRequest(); | |||
xhr.open(method, 'https://' + arvHost + endpoint); | |||
xhr.setRequestHeader('Authorization', 'OAuth2 ' + arvToken); | |||
@@ -1,24 +1,36 @@ | |||
import { h, Component } from 'preact'; | |||
import { Router, route } from 'preact-router'; | |||
import WBTabs from 'wb-tabs'; | |||
import WBTable from 'wb-table'; | |||
import WBPagination from 'wb-pagination'; | |||
import WBProjectListing from 'wb-project-listing'; | |||
import WBNavbar from 'wb-navbar'; | |||
import WBBrowse from 'wb-browse'; | |||
import WBSignIn from 'wb-sign-in'; | |||
import WBLandingPage from 'wb-landing-page'; | |||
class WBApp extends Component { | |||
render({}, { activePage }) { | |||
constructor(...args) { | |||
super(...args); | |||
this.state.arvHost = window.localStorage['arvHost']; | |||
this.state.arvToken = window.localStorage['arvToken']; | |||
this.appCallbacks = { | |||
'navbarItemClicked': this.navbarItemClicked | |||
}; | |||
} | |||
navbarItemClicked(item) { | |||
if (item['id'] === 'sign-out') { | |||
delete window.localStorage['arvHost']; | |||
delete window.localStorage['arvToken']; | |||
delete window.localStorage['currentUser']; | |||
route('/sign-in'); | |||
} | |||
} | |||
render({}, { activePage, arvHost, arvToken }) { | |||
return ( | |||
<Router> | |||
<div path="/"> | |||
Hello, world! | |||
</div> | |||
<WBLandingPage path="/" /> | |||
<WBSignIn path="/sign-in" /> | |||
<WBBrowse path="/browse/:ownerUuid?" /> | |||
<WBBrowse path="/browse/:ownerUuid?" appCallbacks={ this.appCallbacks } /> | |||
</Router> | |||
); | |||
} | |||
@@ -4,15 +4,16 @@ import WBProjectListing from 'wb-project-listing'; | |||
import WBInlineSearch from 'wb-inline-search'; | |||
class WBBrowse extends Component { | |||
render({ ownerUuid }) { | |||
render({ ownerUuid, appCallbacks }) { | |||
return ( | |||
<div> | |||
<WBNavbar items={ [ | |||
{ 'name': 'Browse', 'active': true }, | |||
{ 'name': 'User', 'dropdown': [ 'Sign Off' ]} | |||
{ 'name': 'User', 'dropdown': [ { 'id': 'sign-out', 'name': 'Sign Out' } ]} | |||
] } rhs={ ( | |||
<WBInlineSearch /> | |||
) } /> | |||
) } onItemClicked={ appCallbacks.navbarItemClicked } /> | |||
<WBProjectListing arvHost="api.arkau.roche.com" | |||
arvToken="v2/arkau-gj3su-uf4hnu2o2qkvm8j/15kla38mafzq6b31d5t74ynhk6iuy32v1ticslodr0obvvhde9" | |||
ownerUuid={ ownerUuid } | |||
@@ -0,0 +1,20 @@ | |||
import { h, Component } from 'preact'; | |||
import makeArvadosRequest from 'make-arvados-request'; | |||
import { route } from 'preact-router'; | |||
class WBLandingPage extends Component { | |||
componentDidMount() { | |||
let { arvHost, arvToken } = window.localStorage; | |||
let prom = makeArvadosRequest(arvHost, arvToken, '/arvados/v1/users/current'); | |||
prom = prom.then(xhr => route('/browse/' + xhr.response['uuid'])); | |||
prom = prom.catch(() => route('/sign-in')); | |||
} | |||
render() { | |||
return ( | |||
<div>Please wait...</div> | |||
); | |||
} | |||
} | |||
export default WBLandingPage; |
@@ -1,24 +1,49 @@ | |||
import { h, Component } from 'preact'; | |||
import { route } from 'preact-router'; | |||
import WBNavbar from 'wb-navbar'; | |||
import linkState from 'linkstate'; | |||
import makeArvadosRequest from 'make-arvados-request'; | |||
class WBLogin extends Component { | |||
render() { | |||
class WBSignIn extends Component { | |||
onSubmit() { | |||
let { arvHost, arvToken } = this.state; | |||
window.localStorage['arvHost'] = arvHost; | |||
window.localStorage['arvToken'] = arvToken; | |||
let prom = makeArvadosRequest(arvHost, arvToken, '/arvados/v1/users/current'); | |||
prom = prom.then(xhr => { | |||
window.localStorage['currentUser'] = JSON.stringify(xhr.response); | |||
route('/browse/' + xhr.response['uuid']); | |||
}); | |||
prom = prom.catch(() => { | |||
alert('Sign in unsuccessful. Verify your input and try again.') | |||
}); | |||
} | |||
render({}, { arvHost, arvToken }) { | |||
return ( | |||
<div> | |||
<div class="container"> | |||
<WBNavbar /> | |||
<div class="container my-3"> | |||
<div class="row justify-content-center"> | |||
<div class="col-6"> | |||
<h1>Sign In</h1> | |||
<form> | |||
<div class="form-group"> | |||
<label for="arvHost">Arvados API Host</label> | |||
<input type="text" class="form-control" id="arvHost" placeholder="Enter Arvados API Host" /> | |||
<input type="text" class="form-control" id="arvHost" | |||
placeholder="Enter Arvados API Host" | |||
value={ arvHost } | |||
onInput={ linkState(this, 'arvHost') } /> | |||
</div> | |||
<div class="form-group"> | |||
<label for="arvToken">Token</label> | |||
<input type="text" class="form-control" id="arvToken" placeholder="Enter Arvados API Token" /> | |||
<input type="text" class="form-control" id="arvToken" | |||
placeholder="Enter Arvados API Token" | |||
value={ arvToken } | |||
onInput={ linkState(this, 'arvToken') } /> | |||
</div> | |||
<button type="submit" class="btn btn-primary">Submit</button> | |||
<button type="submit" class="btn btn-primary" | |||
onclick={ e => { e.preventDefault(); this.onSubmit(); } }>Submit</button> | |||
</form> | |||
</div> | |||
</div> | |||
@@ -28,4 +53,4 @@ class WBLogin extends Component { | |||
} | |||
} | |||
export default WBLogin; | |||
export default WBSignIn; |
@@ -1,10 +1,10 @@ | |||
import { h, Component } from 'preact'; | |||
class WBNavbar extends Component { | |||
render({ title, items, rhs, onItemClicked }) { | |||
render({ title, items, rhs, onItemClicked, onTitleClicked }) { | |||
return ( | |||
<nav class="navbar navbar-expand-lg navbar-light bg-light"> | |||
<a class="navbar-brand" href="#">{ title }</a> | |||
<a class="navbar-brand" href="#" onclick={ e => { e.preventDefault(); onTitleClicked(); } }>{ title }</a> | |||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> | |||
<span class="navbar-toggler-icon"></span> | |||
@@ -52,6 +52,11 @@ class WBNavbar extends Component { | |||
return ( | |||
<div class="dropdown-divider" /> | |||
); | |||
else if (typeof(d) === 'object' && d['name']) | |||
return ( | |||
<a class="dropdown-item" href="#" onclick={ e => { e.preventDefault(); onItemClicked(d); } }>{ d['name'] }</a> | |||
); | |||
}) } | |||
</div> | |||
</li> | |||
@@ -81,7 +86,8 @@ WBNavbar.defaultProps = { | |||
'title': 'Workbench Advanced', | |||
'items': [], | |||
'form': null, | |||
'onItemClicked': () => {} | |||
'onItemClicked': () => {}, | |||
'onTitleClicked': () => {} | |||
} | |||
export default WBNavbar; |