From c66df4da40549da5f3e251cc0ecfdc59ebd08d65 Mon Sep 17 00:00:00 2001 From: Stanislaw Adaszewski Date: Fri, 7 Feb 2020 16:58:46 +0100 Subject: [PATCH] Pagination for collection content. --- .../src/js/component/wb-collection-content.js | 45 ++++++++++++++----- frontend/src/js/misc/make-arvados-request.js | 8 +++- frontend/src/js/page/wb-collection-browse.js | 4 +- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/frontend/src/js/component/wb-collection-content.js b/frontend/src/js/component/wb-collection-content.js index 0da5890..8bd1b10 100644 --- a/frontend/src/js/component/wb-collection-content.js +++ b/frontend/src/js/component/wb-collection-content.js @@ -2,6 +2,7 @@ import { h, Component } from 'preact'; import WBTable from 'wb-table'; import WBBreadcrumbs from 'wb-breadcrumbs'; import { WBManifestReader } from 'wb-collection-manifest'; +import WBPagination from 'wb-pagination'; import makeArvadosRequest from 'make-arvados-request'; import wbDownloadFile from 'wb-download-file'; @@ -10,13 +11,15 @@ class WBCollectionContent extends Component { super(...args); this.state.rows = []; this.state.manifestReader = null; + this.state.loaded = 0; + this.state.total = 0; } getUrl(params) { let res = '/collection-browse/' + - (params.uuid || this.props.uuid) + '/' + - encodeURIComponent(params.collectionPath || this.props.collectionPath) + '/' + - (params.page || this.props.page); + ('uuid' in params ? params.uuid : this.props.uuid) + '/' + + encodeURIComponent('collectionPath' in params ? params.collectionPath : this.props.collectionPath) + '/' + + ('page' in params ? params.page : this.props.page); return res; } @@ -27,7 +30,10 @@ class WBCollectionContent extends Component { let select = [ 'manifest_text' ]; let prom = makeArvadosRequest(arvHost, arvToken, '/arvados/v1/collections/' + uuid + - '?select=' + encodeURIComponent(JSON.stringify(select))); + '?select=' + encodeURIComponent(JSON.stringify(select)), + { 'onProgress': e => { + this.setState({ 'loaded': e.loaded, 'total': e.total }); + } }); prom = prom.then(xhr => { this.state.manifestReader = new WBManifestReader(xhr.response.manifest_text); this.prepareRows(); @@ -41,23 +47,27 @@ class WBCollectionContent extends Component { prepareRows() { let { manifestReader } = this.state; - let { collectionPath } = this.props; + let { collectionPath, page, itemsPerPage } = this.props; let { arvHost, arvToken } = this.props.app.state; //path = path.split('/'); //path = [ '.' ].concat(path); - let listing = manifestReader.listDirectory('.' + collectionPath); + let listing = manifestReader.listDirectory('.' + collectionPath) + const numPages = Math.ceil(listing.length / itemsPerPage); + listing = listing.slice(page * itemsPerPage, + page * itemsPerPage + itemsPerPage); this.setState({ + 'numPages': numPages, 'rows': listing.map(item => ( (item[0] === 'd') ? [ - ({ item[1] }/), + ({ item[1] }/), 'Directory', null, (
) ] : [ - ({ item[1] }), + ({ item[1] }), 'File', filesize(item[2]), (
@@ -73,13 +83,23 @@ class WBCollectionContent extends Component { }); } - render({ collectionPath }, { rows }) { + render({ collectionPath, page }, { manifestReader, rows, numPages, loaded, total }) { return (
- + { manifestReader ? ( +
+ + + this.getUrl({ 'page': page }) } /> +
+ ) : ( +
Downloading manifest: { filesize(loaded) }
+ ) } +
); } @@ -87,7 +107,8 @@ class WBCollectionContent extends Component { WBCollectionContent.defaultProps = { 'collectionPath': '', - 'page': 0 + 'page': 0, + 'itemsPerPage': 20 }; export default WBCollectionContent; diff --git a/frontend/src/js/misc/make-arvados-request.js b/frontend/src/js/misc/make-arvados-request.js index 7ed69a5..8799ed5 100644 --- a/frontend/src/js/misc/make-arvados-request.js +++ b/frontend/src/js/misc/make-arvados-request.js @@ -9,12 +9,14 @@ function makeArvadosRequest(arvHost, arvToken, endpoint, params={}) { 'contentType': 'application/json;charset=utf-8', 'responseType': 'json', 'useSsl': true, - 'requireToken': true + 'requireToken': true, + 'onProgress': () => {} }; Object.keys(defaultParams).map(k => (params[k] = (k in params ? params[k] : defaultParams[k]))); - let { method, data, contentType, responseType, useSsl, requireToken } = params; + let { method, data, contentType, responseType, + useSsl, requireToken, onProgress } = params; if (!(arvHost && (arvToken || !requireToken))) return new Promise((accept, reject) => reject()); @@ -27,6 +29,8 @@ function makeArvadosRequest(arvHost, arvToken, endpoint, params={}) { xhr.setRequestHeader('Content-Type', contentType); xhr.responseType = responseType; + xhr.onprogress = onProgress; + let prom = new Promise((accept, reject) => { xhr.onreadystatechange = () => { if (xhr.readyState !== 4) diff --git a/frontend/src/js/page/wb-collection-browse.js b/frontend/src/js/page/wb-collection-browse.js index d92cd86..0d1f386 100644 --- a/frontend/src/js/page/wb-collection-browse.js +++ b/frontend/src/js/page/wb-collection-browse.js @@ -4,7 +4,7 @@ import WBArvadosCrumbs from 'wb-arvados-crumbs'; import WBCollectionContent from 'wb-collection-content'; class WBCollectionBrowse extends Component { - render({ app, uuid, collectionPath }, {}) { + render({ app, uuid, collectionPath, page }, {}) { return (
@@ -16,7 +16,7 @@ class WBCollectionBrowse extends Component {
+ collectionPath={ collectionPath } page={ Number(page || 0) } />
); }