@@ -23,6 +23,7 @@ export default { | |||||
'src/css/index.css': 'dist/css/index.css', | 'src/css/index.css': 'dist/css/index.css', | ||||
'node_modules/bootstrap/dist/css/bootstrap.min.css': 'dist/css/bootstrap.min.css', | 'node_modules/bootstrap/dist/css/bootstrap.min.css': 'dist/css/bootstrap.min.css', | ||||
'node_modules/bootstrap/dist/js/bootstrap.min.js': 'dist/js/bootstrap.min.js', | 'node_modules/bootstrap/dist/js/bootstrap.min.js': 'dist/js/bootstrap.min.js', | ||||
'node_modules/jquery/dist/jquery.min.js': 'dist/js/jquery.min.js', | |||||
verbose: true | verbose: true | ||||
}), | }), | ||||
buble({jsx: 'h'}), | buble({jsx: 'h'}), | ||||
@@ -2,6 +2,7 @@ | |||||
<head> | <head> | ||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||||
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css" /> | <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css" /> | ||||
<script language="javascript" src="/js/jquery.min.js"></script> | |||||
<script language="javascript" src="/js/bootstrap.min.js"></script> | <script language="javascript" src="/js/bootstrap.min.js"></script> | ||||
</head> | </head> | ||||
<body> | <body> | ||||
@@ -1,37 +1,24 @@ | |||||
import { h, Component } from 'preact'; | import { h, Component } from 'preact'; | ||||
import WBTabs from 'wb-tabs'; | import WBTabs from 'wb-tabs'; | ||||
import WBTable from 'wb-table'; | |||||
import WBPagination from 'wb-pagination'; | |||||
class WBApp extends Component { | class WBApp extends Component { | ||||
render() { | render() { | ||||
return ( | return ( | ||||
<div> | <div> | ||||
<h1>WBApp</h1> | <h1>WBApp</h1> | ||||
<table class="table table-striped table-hover"> | |||||
<thead class="thead-light"> | |||||
<tr> | |||||
<th>Name</th> | |||||
<th>Description</th> | |||||
<th>Size</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td>Name</td> | |||||
<td>Description</td> | |||||
<td>0 bytes</td> | |||||
</tr> | |||||
<tr> | |||||
<td>Name</td> | |||||
<td>Description</td> | |||||
<td>0 bytes</td> | |||||
</tr> | |||||
<tr> | |||||
<td>Name</td> | |||||
<td>Description</td> | |||||
<td>0 bytes</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<WBPagination numPages={ 100 } activePage={ 0 } | |||||
onPageChanged={ idx => alert(idx) } /> | |||||
<WBTable | |||||
columns={ [ 'Name', 'Description', 'Size' ] } | |||||
rows={ [ | |||||
[ 'Name', 'Description', '0 bytes'], | |||||
[ 'Name', 'Description', '0 bytes'], | |||||
[ 'Name', 'Description', '0 bytes'], | |||||
[ 'Name', 'Description', '0 bytes'], | |||||
[ 'Name', 'Description', '0 bytes'] | |||||
] } /> | |||||
<WBTabs tabs={ [ | <WBTabs tabs={ [ | ||||
{ 'name': 'Ala', 'isActive': true }, | { 'name': 'Ala', 'isActive': true }, | ||||
"Ma", | "Ma", | ||||
@@ -0,0 +1,20 @@ | |||||
import { h, Component } from 'preact'; | |||||
import makeArvadosRequest from 'make-arvados-request'; | |||||
class WBProjectListing extends Component { | |||||
componentDidMount() { | |||||
let filters = [ | |||||
[ 'group_class', '=', 'project' ], | |||||
[ 'owner_uuid', '=', this.props.ownerUuid ] | |||||
]; | |||||
let req = makeArvadosRequest(his.props.arvHost, this.props.arvToken, | |||||
'/arvados/v1/groups?filters=' + encodeURIComponent(JSON.stringify(filters))) | |||||
} | |||||
render({ arvHost, arvToken, ownerUuid }) { | |||||
return ( | |||||
<div>Project Listing</div> | |||||
); | |||||
} | |||||
} |
@@ -0,0 +1,27 @@ | |||||
makeArvadosRequest(arvHost, arvToken, endpoint, method='GET', data=null, | |||||
contentType='application/json;charset=utf-8', responseType='json') { | |||||
let xhr = new XMLHttpRequest(); | |||||
xhr.open(method, 'https://' + arvHost + endpoint); | |||||
xhr.setRequestHeader('Authorization', 'OAuth2 ' + arvToken); | |||||
if (data !== null) | |||||
xhr.setRequestHeader('Content-Type', contentType); | |||||
xhr.responseType = responseType; | |||||
let res = new Promise((accept, reject) => { | |||||
xhr.onreadystatechange = () => { | |||||
if (xhr.readyState !== 4) | |||||
return; | |||||
if (xhr.status !== 200) | |||||
reject(xhr); | |||||
else | |||||
accept(xhr); | |||||
}; | |||||
xhr.send(data); | |||||
}); | |||||
return res; | |||||
} | |||||
export default makeArvadosRequest; |
@@ -0,0 +1,73 @@ | |||||
import { h, Component } from 'preact'; | |||||
class WBPagination extends Component { | |||||
renderVisiblePages(numPages, activePage, chunkSize, onPageChanged) { | |||||
let visible = {}; | |||||
let begActChnk = activePage - Math.floor(chunkSize / 2); | |||||
let endActChnk = activePage + Math.floor(chunkSize / 2) + 1; | |||||
for (let i = begActChnk; i < endActChnk; i++) | |||||
visible[i] = true; | |||||
for (let i = 0; i < chunkSize; i++) | |||||
visible[i] = true; | |||||
for (let i = Math.max(numPages - chunkSize, 0); i < numPages; i++) | |||||
visible[i] = true; | |||||
visible = Object.keys(visible).map(n => Number(n)); | |||||
let res = []; | |||||
let prev = 0; | |||||
res.push(( | |||||
<li class={ activePage === 0 ? "page-item disabled" : "page-item" }> | |||||
<a class="page-link" href="#" | |||||
onclick={ () => onPageChanged(activePage - 1) }>Previous</a> | |||||
</li> | |||||
)); | |||||
for (let i in visible) { | |||||
if (i > prev + 1) | |||||
res.push(( | |||||
<li class="page-item"> | |||||
<a class="page-link" href="#" | |||||
onclick={ () => onPageChanged(i - 1) }>...</a> | |||||
</li> | |||||
)); | |||||
prev = i; | |||||
res.push(( | |||||
<li class={ i === activePage ? "page-item active" : "page-item" }> | |||||
<a class="page-link" href="#" | |||||
onclick={ () => onPageChanged(i) }>{ i + 1 }</a> | |||||
</li> | |||||
)); | |||||
} | |||||
res.push(( | |||||
<li class={ activePage >= numPages - 1 ? "page-item disabled" : "page-item" }> | |||||
<a class="page-link" href="#" | |||||
onclick={ () => onPageChanged(activePage + 1) }>Next</a> | |||||
</li> | |||||
)); | |||||
return res; | |||||
} | |||||
render({ numPages, activePage, chunkSize, onPageChanged }) { | |||||
return ( | |||||
<nav aria-label="Pagination"> | |||||
<ul class="pagination"> | |||||
{ this.renderVisiblePages(numPages, activePage, chunkSize, onPageChanged) } | |||||
</ul> | |||||
</nav> | |||||
); | |||||
} | |||||
} | |||||
WBPagination.defaultProps = { | |||||
'chunkSize': 5 | |||||
}; | |||||
export default WBPagination; |
@@ -0,0 +1,26 @@ | |||||
import { h, Component } from 'preact'; | |||||
class WBTable extends Component { | |||||
render({ columns, rows }) { | |||||
return ( | |||||
<table class="table table-striped table-hover"> | |||||
<thead class="thead-light"> | |||||
<tr> | |||||
{ columns.map(c => <th>{ c }</th>) } | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
{ rows.map(r => ( | |||||
<tr> | |||||
{ columns.map((_, idx) => ( | |||||
<td>{ r[idx] }</td> | |||||
)) } | |||||
</tr> | |||||
)) } | |||||
</tbody> | |||||
</table> | |||||
); | |||||
} | |||||
} | |||||
export default WBTable; |