@@ -7,6 +7,11 @@ import WBCheckboxes from 'wb-checkboxes'; | |||
import wbFormatDate from 'wb-format-date'; | |||
import wbFetchObjects from 'wb-fetch-objects'; | |||
import WBNameAndUuid from 'wb-name-and-uuid'; | |||
import WBProcessState from 'wb-process-state'; | |||
function maskRows(rows) { | |||
return rows.map(r => r.map(c => '-')); | |||
} | |||
class WBProcessListing extends Component { | |||
@@ -15,9 +20,7 @@ class WBProcessListing extends Component { | |||
this.state.rows = []; | |||
this.state.numPages = 0; | |||
this.state.requestStates = [ 'Uncommitted', 'Committed', 'Final' ]; | |||
// this.state.containerStates = [ 'Queued', 'Locked', 'Running', 'Cancelled', 'Complete' ]; | |||
this.state.reqStateMask = [ true, true, true ]; | |||
// this.state.contStateMask = [ true, true, true, true, true ]; | |||
} | |||
componentDidMount() { | |||
@@ -25,14 +28,8 @@ class WBProcessListing extends Component { | |||
} | |||
prepareRows(requests, containerLookup, ownerLookup, outputLookup) { | |||
const { renderRenameLink, renderDeleteButton } = this.props; | |||
const { app, renderRenameLink, renderDeleteButton } = this.props; | |||
return requests.map(item => { | |||
const container = item.container_uuid in containerLookup ? | |||
containerLookup[item.container_uuid] : null; | |||
const runtimeStatus = container ? container.runtime_status : null; | |||
const error = runtimeStatus ? runtimeStatus.error : null; | |||
const warning = runtimeStatus ? runtimeStatus.warning : null; | |||
return ( [ | |||
(<div> | |||
<div> | |||
@@ -42,22 +39,10 @@ class WBProcessListing extends Component { | |||
</div> | |||
<div>{ item['uuid'] }</div> | |||
</div>), | |||
( <div> | |||
{ item['state'] } | |||
{ item.container_uuid ? | |||
container ? | |||
[ " / ", container.state ] : | |||
[ " / ", <i>Container Not Found</i> ] : | |||
null } | |||
{ !(error || warning) && container && container.state === 'Complete' ? " / Success" : null } | |||
{ error ? [" / ", <a href={ '/container/' + container.uuid } | |||
title={ error }>E</a> ] : null } | |||
{ warning ? [ " / ", <a href={ '/container/' + container.uuid } | |||
title={ warning }>W</a> ] : null } | |||
</div> ), | |||
( <WBNameAndUuid uuid={ item['owner_uuid'] } lookup={ ownerLookup } /> ), | |||
( <WBProcessState app={ app } process={ item } /> ), | |||
( <WBNameAndUuid app={ app } uuid={ item['owner_uuid'] } /> ), | |||
wbFormatDate(item['created_at']), | |||
( <WBNameAndUuid uuid={ item['output_uuid'] } lookup={ outputLookup } /> ), | |||
( <WBNameAndUuid app={ app } uuid={ item['output_uuid'] } /> ), | |||
(<div> | |||
{ renderDeleteButton(item, () => this.fetchItems()) } | |||
</div>) | |||
@@ -78,64 +63,22 @@ class WBProcessListing extends Component { | |||
filters.push([ 'state', 'in', requestStates.filter((_, idx) => reqStateMask[idx]) ]); | |||
if (ownerUuid) | |||
filters.push([ 'owner_uuid', '=', ownerUuid ]); | |||
//if (requestingContainerUuid) | |||
//filters.push(); | |||
let prom = makeArvadosRequest(arvHost, arvToken, | |||
'/arvados/v1/container_requests?filters=' + encodeURIComponent(JSON.stringify(filters)) + | |||
'&limit=' + itemsPerPage + | |||
'&offset=' + (itemsPerPage * activePage)); | |||
let requests; | |||
let numPages; | |||
prom = prom.then(xhr => { | |||
requests = xhr.response.items; | |||
numPages = Math.ceil(xhr.response['items_available'] / xhr.response['limit']); | |||
/* container_uuids = requests.map(r => r.container_uuid); | |||
container_uuids = container_uuids.filter(uuid => uuid); | |||
const filters_1 = [ | |||
[ 'uuid', 'in', container_uuids ] | |||
]; | |||
return makeArvadosRequest(arvHost, arvToken, | |||
'/arvados/v1/containers?filters=' + | |||
encodeURIComponent(JSON.stringify(filters_1)));*/ | |||
return wbFetchObjects(arvHost, arvToken, | |||
requests.map(r => r.container_uuid).filter(uuid => uuid)); | |||
}); | |||
let containerLookup; | |||
prom = prom.then(lookup => { | |||
containerLookup = lookup; | |||
// const containers = xhr.response.items; | |||
// containers.map(c => (containerLookup[c.uuid] = c)); | |||
return wbFetchObjects(arvHost, arvToken, | |||
requests.map(r => r.owner_uuid).filter(uuid => uuid)); | |||
}); | |||
let ownerLookup; | |||
prom = prom.then(lookup => { | |||
ownerLookup = lookup; | |||
return wbFetchObjects(arvHost, arvToken, | |||
requests.map(r => r.output_uuid).filter(uuid => uuid)); | |||
}); | |||
let outputLookup; | |||
prom = prom.then(lookup => (outputLookup = lookup)); | |||
// prom = prom.then(() => makeArvadosRequest(arvHost, arvToken, | |||
// '/arvados/v1/')) | |||
prom = prom.then(() => | |||
prom = prom.then(xhr => | |||
this.setState({ | |||
'numPages': numPages, | |||
'rows': this.prepareRows(requests, containerLookup, | |||
ownerLookup, outputLookup) | |||
'numPages': Math.ceil(xhr.response['items_available'] / xhr.response['limit']), | |||
'rows': this.prepareRows(xhr.response.items) | |||
})); | |||
} | |||
componentWillReceiveProps(nextProps, nextState) { | |||
// this.setState({ 'rows': [] }); // .rows = []; | |||
this.props = nextProps; | |||
this.setState({ 'rows': maskRows(this.state.rows) }); | |||
this.fetchItems(); | |||
} | |||
@@ -0,0 +1,47 @@ | |||
import { h, Component } from 'preact'; | |||
import makeArvadosRequest from 'make-arvados-request'; | |||
class WBProcessState extends Component { | |||
componentDidMount() { | |||
this.fetchData(); | |||
} | |||
componentWillReceiveProps(nextProps) { | |||
this.props = nextProps; | |||
this.fetchData(); | |||
} | |||
fetchData() { | |||
const { app, process } = this.props; | |||
const { arvHost, arvToken } = app.state; | |||
if (!process.container_uuid) | |||
return; | |||
let prom = makeArvadosRequest(arvHost, arvToken, | |||
'/arvados/v1/containers/' + process.container_uuid); | |||
prom = prom.then(xhr => this.setState({ 'container': xhr.response })); | |||
prom = prom.catch(() => this.setState({ 'apiError': 'Failed to fetch container' })); | |||
} | |||
render({ process }, { container, apiError }) { | |||
const runtimeStatus = container ? container.runtime_status : null; | |||
const error = runtimeStatus ? runtimeStatus.error : null; | |||
const warning = runtimeStatus ? runtimeStatus.warning : null; | |||
return ( | |||
<div> | |||
{ process.state } | |||
{ apiError ? <i>{ [ ' / ', apiError ] }</i> : null } | |||
{ container ? [ " / ", container.state ] : null } | |||
{ !(error || warning) && container && container.state === 'Complete' ? " / Success" : null } | |||
{ error ? [" / ", <a href={ '/container/' + container.uuid } | |||
title={ error }>E</a> ] : null } | |||
{ warning ? [ " / ", <a href={ '/container/' + container.uuid } | |||
title={ warning }>W</a> ] : null } | |||
</div> | |||
); | |||
} | |||
} | |||
export default WBProcessState; |
@@ -7,6 +7,10 @@ function wbFetchObjects(arvHost, arvToken, uuids) { | |||
uuids = {}; | |||
Object.keys(unique).map(u => { | |||
let typeName = arvadosTypeName(u); | |||
if (!typeName) { | |||
console.log('Unknown type name for UUID: ' + u); | |||
return; | |||
} | |||
if (!(typeName in uuids)) | |||
uuids[typeName] = []; | |||
uuids[typeName].push(u); | |||
@@ -23,6 +27,7 @@ function wbFetchObjects(arvHost, arvToken, uuids) { | |||
encodeURIComponent(JSON.stringify(filters)))); | |||
prom = prom.then(xhr => xhr.response.items.map(it => ( | |||
lookup[it.uuid] = it))); | |||
prom = prom.catch(xhr => console.log(xhr.responseURL + ': ' + xhr.statusText)); | |||
} | |||
prom = prom.then(() => lookup); | |||
@@ -121,7 +121,8 @@ class WBBrowse extends Component { | |||
renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } /> | |||
) : (objTypeTab === 'process') ? ( | |||
<WBProcessListing appState={ app.state } | |||
<WBProcessListing app={ app } | |||
appState={ app.state } | |||
ownerUuid={ ownerUuid } | |||
itemsPerPage="20" | |||
activePage={ Number(processPage || 0) } | |||
@@ -9,6 +9,7 @@ import detectHashes from 'detect-hashes'; | |||
import WBCommonFields from 'wb-common-fields'; | |||
import WBContainerRequestFields from 'wb-container-request-fields'; | |||
import WBProcessListing from 'wb-process-listing'; | |||
import wbFetchObjects from 'wb-fetch-objects'; | |||
class WBProcessView extends Component { | |||
constructor(...args) { | |||
@@ -55,9 +56,12 @@ class WBProcessView extends Component { | |||
uuids.map(u => (dict[u] = true)); | |||
return Object.keys(dict); | |||
}); | |||
prom = prom.then(uuids => { | |||
prom = prom.then(uuids => wbFetchObjects(arvHost, arvToken, uuids)); | |||
/* prom = prom.then(() => { | |||
// let uuids = detectUuids([ req, cont ]); | |||
let objectTypes = uuids.map(u => arvadosTypeName(u.split('-')[1]) + 's'); | |||
let objectTypes = uuids.map(u => arvadosTypeName(u) + 's'); | |||
//objectTypes = objectTypes.filter(ot => ot); | |||
//objectTypes = objectTypes.map(ot => ot + 's'); | |||
let objQueries = {}; | |||
objectTypes.map(t => (objQueries[t] = [])); | |||
uuids.map((u, idx) => (objQueries[objectTypes[idx]].push(u))); | |||
@@ -76,11 +80,11 @@ class WBProcessView extends Component { | |||
} | |||
prom_1 = prom_1.then(() => objects); | |||
return prom_1; | |||
}); | |||
}); */ | |||
prom = prom.then(objects => { | |||
let objDict = {}; | |||
objects.map(o => (objDict[o['uuid']] = o)); | |||
let urls = objects.map(o => urlForObject(o)); | |||
// let objDict = {}; | |||
// objects.map(o => (objDict[o['uuid']] = o)); | |||
let urls = Object.values(objects).map(o => urlForObject(o)); | |||
this.setState({ | |||
'objectUrls': urls, | |||
'request': req, | |||
@@ -95,7 +99,7 @@ class WBProcessView extends Component { | |||
componentWillReceiveProps(nextProps) { | |||
this.props = nextProps; | |||
this.setState({ 'objectUrls': [], 'request': null, 'container': null }); | |||
// this.setState({ 'objectUrls': [], 'request': null, 'container': null }); | |||
this.fetchData(); | |||
} | |||
@@ -118,7 +122,8 @@ class WBProcessView extends Component { | |||
{ container ? ([ | |||
<h2>Children</h2>, | |||
<WBProcessListing appState={ app.state } | |||
<WBProcessListing app={ app } | |||
appState={ app.state } | |||
requestingContainerUuid={ container.uuid } | |||
itemsPerPage="20" | |||
activePage={ Number(page || 0) } | |||