// // Copyright (C) Stanislaw Adaszewski, 2020 // Contact: s.adaszewski@gmail.com // Website: https://adared.ch/wba // License: GNU Affero General Public License, Version 3 // import { h, Component } from 'preact'; import WBManifestWorkerWrapper from 'wb-manifest-worker-wrapper'; import makeArvadosRequest from 'make-arvados-request'; import WBTable from 'wb-table'; import WBPagination from 'wb-pagination'; function unescapeName(name) { return name.replace(/(\\\\|\\[0-9]{3})/g, (_, $1) => ($1 === '\\\\' ? '\\' : String.fromCharCode(parseInt($1.substr(1), 8)))); } class WBBrowseDialogCollectionContent extends Component { constructor(...args) { super(...args); this.state.manifestWorker = new WBManifestWorkerWrapper(); this.state.mode = 'manifestDownload'; this.state.rows = []; } componentDidMount() { const { app, collectionUuid } = this.props; const { arvHost, arvToken } = app.state; const { manifestWorker } = this.state; let prom = makeArvadosRequest(arvHost, arvToken, '/arvados/v1/collections/' + collectionUuid); let streams; prom = prom.then(xhr => { streams = xhr.response.manifest_text.split('\n'); const paths = streams.filter(s => s).map(s => { const n = s.indexOf(' '); return unescapeName(s.substr(0, n)); }); return manifestWorker.postMessage([ 'precreatePaths', paths ]); }); prom = prom.then(() => { this.setState({ 'mode': 'manifestParse' }); let prom_1 = new Promise(accept => accept()); for (let i = 0; i < streams.length; i++) { prom_1 = prom_1.then(() => manifestWorker.postMessage([ 'parseStream', streams[i] ])); prom_1 = prom_1.then(() => manifestWorker.postMessage([ 'listDirectory', '.' + this.props.collectionPath, true ])); prom_1 = prom_1.then(e => this.prepareRows(e.data[1])); } return prom_1; }); prom = prom.then(() => manifestWorker.postMessage([ 'listDirectory', '.' + this.props.collectionPath, true ])); prom = prom.then(e => { this.state.mode = 'browsingReady'; this.prepareRows(e.data[1]) }); } componentWillReceiveProps(nextProps) { this.props = nextProps; if (this.state.mode !== 'browsingReady') return; let prom = this.state.manifestWorker.postMessage([ 'listDirectory', '.' + this.props.collectionPath, true ]); prom = prom.then(e => this.prepareRows(e.data[1])); } prepareRows(listing) { const { makeSelectionCell, collectionPath, navigate, page, itemsPerPage, collectionUuid, textSearch, selectWhat } = this.props; const textLower = textSearch.toLowerCase(); listing = listing.filter(it => (it[1].toLowerCase().indexOf(textLower) !== -1)); const numPages = Math.ceil(listing.length / itemsPerPage); const rows = listing.slice(page * itemsPerPage, (page + 1) * itemsPerPage).map(it => [ ((it[0] === 'd' && [].concat(selectWhat).indexOf('directory') !== -1) || (it[0] === 'f' && [].concat(selectWhat).indexOf('file') !== -1)) ? makeSelectionCell(collectionUuid + collectionPath + '/' + it[1] + (it[0] === 'd' ? '/' : '')) : null, it[0] === 'd' ? ( { e.preventDefault(); navigate({ 'collectionPath': collectionPath + '/' + it[1], 'bottomPage': 0 }); } }>{ it[1] } ) : it[1], it[0] === 'f' ? filesize(it[2]) : '' ]); this.setState({ rows, numPages }); } render({ page, navigate }, { rows, mode, numPages }) { return (
{ mode === 'browsingReady' ? ( null ) : [
{ mode === 'manifestParse' ? 'Parsing manifest...' : 'Downloading manifest...' }
,
] } navigate({ 'bottomPage': i }) } />
); } } WBBrowseDialogCollectionContent.defaultProps = { 'itemsPerPage': 20 }; export default WBBrowseDialogCollectionContent;