mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Merge pull request #1217 from oceanprotocol/fix/compute-jobs
Fix compute jobs
This commit is contained in:
commit
c86a9f8429
1773
package-lock.json
generated
1773
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,7 @@
|
||||
"@coingecko/cryptoformat": "^0.4.4",
|
||||
"@loadable/component": "^5.15.2",
|
||||
"@oceanprotocol/art": "^3.2.0",
|
||||
"@oceanprotocol/lib": "^1.0.0-next.33",
|
||||
"@oceanprotocol/lib": "^1.0.0-next.36",
|
||||
"@oceanprotocol/typographies": "^0.1.0",
|
||||
"@portis/web3": "^4.0.7",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
|
@ -74,15 +74,14 @@ async function getAssetMetadata(
|
||||
const baseQueryparams = {
|
||||
chainIds,
|
||||
filters: [
|
||||
getFilterTerm('datatokens', queryDtList),
|
||||
getFilterTerm('service.type', 'compute'),
|
||||
getFilterTerm('services.datatokenAddress', queryDtList),
|
||||
getFilterTerm('services.type', 'compute'),
|
||||
getFilterTerm('metadata.type', 'dataset')
|
||||
],
|
||||
ignorePurgatory: true
|
||||
} as BaseQueryParams
|
||||
const query = generateBaseQuery(baseQueryparams)
|
||||
const result = await queryMetadata(query, cancelToken)
|
||||
|
||||
return result?.results
|
||||
}
|
||||
|
||||
@ -215,42 +214,43 @@ async function getJobs(
|
||||
assets: Asset[]
|
||||
): Promise<ComputeJobMetaData[]> {
|
||||
const computeJobs: ComputeJobMetaData[] = []
|
||||
providerUrls.forEach(async (providerUrl) => {
|
||||
try {
|
||||
const providerComputeJobs = (await ProviderInstance.computeStatus(
|
||||
providerUrl,
|
||||
accountId
|
||||
)) as ComputeJob[]
|
||||
// commented loop since we decide how to filter jobs
|
||||
// for await (const providerUrl of providerUrls) {
|
||||
try {
|
||||
const providerComputeJobs = (await ProviderInstance.computeStatus(
|
||||
providerUrls[0],
|
||||
accountId
|
||||
)) as ComputeJob[]
|
||||
|
||||
if (!providerComputeJobs) {
|
||||
providerComputeJobs.sort((a, b) => {
|
||||
if (a.dateCreated > b.dateCreated) {
|
||||
return -1
|
||||
}
|
||||
if (a.dateCreated < b.dateCreated) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
providerComputeJobs.forEach((job) => {
|
||||
const did = job.inputDID[0]
|
||||
const asset = assets.filter((x) => x.id === did)[0]
|
||||
if (providerComputeJobs) {
|
||||
providerComputeJobs.sort((a, b) => {
|
||||
if (a.dateCreated > b.dateCreated) {
|
||||
return -1
|
||||
}
|
||||
if (a.dateCreated < b.dateCreated) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
|
||||
if (!asset) {
|
||||
const compJob: ComputeJobMetaData = {
|
||||
...job,
|
||||
assetName: asset.metadata.name,
|
||||
assetDtSymbol: asset.datatokens[0].symbol,
|
||||
networkId: asset.chainId
|
||||
}
|
||||
computeJobs.push(compJob)
|
||||
providerComputeJobs.forEach((job) => {
|
||||
const did = job.inputDID[0]
|
||||
const asset = assets.filter((x) => x.id === did)[0]
|
||||
if (asset) {
|
||||
const compJob: ComputeJobMetaData = {
|
||||
...job,
|
||||
assetName: asset.metadata.name,
|
||||
assetDtSymbol: asset.datatokens[0].symbol,
|
||||
networkId: asset.chainId
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
LoggerInstance.error(err.message)
|
||||
computeJobs.push(compJob)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
LoggerInstance.error(err.message)
|
||||
}
|
||||
// }
|
||||
return computeJobs
|
||||
}
|
||||
export async function getComputeJobs(
|
||||
@ -274,21 +274,18 @@ export async function getComputeJobs(
|
||||
user: accountId.toLowerCase()
|
||||
}
|
||||
|
||||
console.log(' getComputeJobs variables ', variables)
|
||||
const results = await fetchDataForMultipleChains(
|
||||
assetDTAddress ? getComputeOrdersByDatatokenAddress : getComputeOrders,
|
||||
variables,
|
||||
assetDTAddress ? [asset?.chainId] : chainIds
|
||||
)
|
||||
|
||||
console.log(' getComputeJobs results getComputeOrders', results)
|
||||
let tokenOrders: TokenOrder[] = []
|
||||
results.map((result) => {
|
||||
result.orders.forEach((tokenOrder: TokenOrder) =>
|
||||
tokenOrders.push(tokenOrder)
|
||||
)
|
||||
})
|
||||
console.log(' getComputeJobs tokenOrders ', tokenOrders)
|
||||
if (tokenOrders.length === 0) {
|
||||
return computeResult
|
||||
}
|
||||
@ -296,6 +293,7 @@ export async function getComputeJobs(
|
||||
tokenOrders = tokenOrders.sort(
|
||||
(a, b) => b.createdTimestamp - a.createdTimestamp
|
||||
)
|
||||
|
||||
const datatokenAddressList = tokenOrders.map(
|
||||
(tokenOrder: TokenOrder) => tokenOrder.datatoken.address
|
||||
)
|
||||
@ -311,6 +309,7 @@ export async function getComputeJobs(
|
||||
assets.forEach((asset: Asset) =>
|
||||
providerUrls.push(asset.services[0].serviceEndpoint)
|
||||
)
|
||||
|
||||
computeResult.computeJobs = await getJobs(providerUrls, accountId, assets)
|
||||
computeResult.isLoaded = true
|
||||
|
||||
|
@ -243,13 +243,10 @@ export async function fetchDataForMultipleChains(
|
||||
let datas: any[] = []
|
||||
try {
|
||||
for (const chainId of chainIds) {
|
||||
// console.log('fetch chainID', chainId)
|
||||
const context: OperationContext = getQueryContext(chainId)
|
||||
const response = await fetchData(query, variables, context)
|
||||
// console.log('fetch response', response)
|
||||
if (!response || response.error) continue
|
||||
datas = datas.concat(response?.data)
|
||||
// console.log('fetch datas', datas)
|
||||
}
|
||||
return datas
|
||||
} catch (error) {
|
||||
@ -358,10 +355,8 @@ export async function getAccountTVLInOwnAssets(
|
||||
chainIds
|
||||
)
|
||||
let tvl = new Decimal(0)
|
||||
// console.log('resss', results)
|
||||
|
||||
for (const result of results) {
|
||||
// console.log('result.poolShares', result.poolShares)
|
||||
for (const poolShare of result.poolShares) {
|
||||
const poolUserTvl = calculateUserTVL(
|
||||
poolShare.shares,
|
||||
@ -369,7 +364,6 @@ export async function getAccountTVLInOwnAssets(
|
||||
poolShare.pool.baseTokenLiquidity
|
||||
)
|
||||
tvl = tvl.add(new Decimal(poolUserTvl))
|
||||
// console.log('result.poolShares', tvl.toString())
|
||||
}
|
||||
}
|
||||
return tvl.toDecimalPlaces(MAX_DECIMALS).toString()
|
||||
|
@ -9,7 +9,8 @@ import {
|
||||
Datatoken,
|
||||
ProviderInstance,
|
||||
ComputeAsset,
|
||||
ZERO_ADDRESS
|
||||
ZERO_ADDRESS,
|
||||
ComputeEnvironment
|
||||
} from '@oceanprotocol/lib'
|
||||
import { toast } from 'react-toastify'
|
||||
import Price from '@shared/Price'
|
||||
@ -83,6 +84,8 @@ export default function Compute({
|
||||
const [isConsumablePrice, setIsConsumablePrice] = useState(true)
|
||||
const [isAlgoConsumablePrice, setIsAlgoConsumablePrice] = useState(true)
|
||||
const [computeStatusText, setComputeStatusText] = useState('')
|
||||
const [computeEnv, setComputeEnv] = useState<ComputeEnvironment>()
|
||||
const [computeValidUntil, setComputeValidUntil] = useState<number>()
|
||||
const [datasetOrderPriceAndFees, setDatasetOrderPriceAndFees] =
|
||||
useState<OrderPriceAndFees>()
|
||||
const [isRequestingDataseOrderPrice, setIsRequestingDataseOrderPrice] =
|
||||
@ -110,28 +113,76 @@ export default function Compute({
|
||||
return hasAlgoDt
|
||||
}
|
||||
|
||||
async function initPriceAndFees() {
|
||||
const computeEnv = await getComputeEnviroment(asset)
|
||||
setComputeEnv(computeEnv)
|
||||
const validUntil = getValidUntilTime(
|
||||
computeEnv?.maxJobDuration,
|
||||
asset.services[0].timeout,
|
||||
selectedAlgorithmAsset.services[0].timeout
|
||||
)
|
||||
setComputeValidUntil(validUntil)
|
||||
if (
|
||||
asset?.accessDetails?.addressOrId !== ZERO_ADDRESS ||
|
||||
asset?.accessDetails?.type !== 'free'
|
||||
) {
|
||||
setIsRequestingDataseOrderPrice(true)
|
||||
setComputeStatusText(
|
||||
getComputeFeedback(
|
||||
asset.accessDetails.baseToken?.symbol,
|
||||
asset.accessDetails.datatoken?.symbol,
|
||||
asset.metadata.type
|
||||
)[0]
|
||||
)
|
||||
const datasetPriceAndFees = await getOrderPriceAndFees(
|
||||
asset,
|
||||
accountId,
|
||||
computeEnv?.id,
|
||||
validUntil
|
||||
)
|
||||
if (!datasetPriceAndFees) {
|
||||
setError('Error setting dataset price and fees!')
|
||||
toast.error('Error setting dataset price and fees!')
|
||||
return
|
||||
}
|
||||
setDatasetOrderPriceAndFees(datasetPriceAndFees)
|
||||
setIsRequestingDataseOrderPrice(false)
|
||||
}
|
||||
|
||||
if (
|
||||
selectedAlgorithmAsset?.accessDetails?.addressOrId !== ZERO_ADDRESS ||
|
||||
selectedAlgorithmAsset?.accessDetails?.type !== 'free'
|
||||
) {
|
||||
setIsRequestingAlgoOrderPrice(true)
|
||||
setComputeStatusText(
|
||||
getComputeFeedback(
|
||||
selectedAlgorithmAsset?.accessDetails?.baseToken?.symbol,
|
||||
selectedAlgorithmAsset?.accessDetails?.datatoken?.symbol,
|
||||
selectedAlgorithmAsset?.metadata?.type
|
||||
)[0]
|
||||
)
|
||||
const algorithmOrderPriceAndFees = await getOrderPriceAndFees(
|
||||
selectedAlgorithmAsset,
|
||||
ZERO_ADDRESS,
|
||||
computeEnv?.id,
|
||||
validUntil
|
||||
)
|
||||
if (!algorithmOrderPriceAndFees) {
|
||||
setError('Error setting algorithm price and fees!')
|
||||
toast.error('Error setting algorithm price and fees!')
|
||||
return
|
||||
}
|
||||
setAlgoOrderPriceAndFees(algorithmOrderPriceAndFees)
|
||||
setIsRequestingAlgoOrderPrice(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!asset?.accessDetails || !accountId) return
|
||||
|
||||
setIsConsumablePrice(asset?.accessDetails?.isPurchasable)
|
||||
setIsOwned(asset?.accessDetails?.isOwned)
|
||||
setValidOrderTx(asset?.accessDetails?.validOrderTx)
|
||||
|
||||
async function initDatasetPriceAndFees() {
|
||||
if (
|
||||
asset?.accessDetails?.addressOrId === ZERO_ADDRESS ||
|
||||
asset?.accessDetails?.type === 'free'
|
||||
)
|
||||
return
|
||||
|
||||
setIsRequestingDataseOrderPrice(true)
|
||||
setComputeStatusText('Calculating price including fees.')
|
||||
const orderPriceAndFees = await getOrderPriceAndFees(asset, accountId)
|
||||
setDatasetOrderPriceAndFees(orderPriceAndFees)
|
||||
setIsRequestingDataseOrderPrice(false)
|
||||
}
|
||||
|
||||
initDatasetPriceAndFees()
|
||||
}, [asset?.accessDetails])
|
||||
|
||||
useEffect(() => {
|
||||
@ -143,26 +194,9 @@ export default function Compute({
|
||||
selectedAlgorithmAsset?.accessDetails?.validOrderTx
|
||||
)
|
||||
|
||||
async function initAlgoPriceAndFees() {
|
||||
if (
|
||||
selectedAlgorithmAsset?.accessDetails?.addressOrId === ZERO_ADDRESS ||
|
||||
selectedAlgorithmAsset?.accessDetails?.type === 'free'
|
||||
)
|
||||
return
|
||||
|
||||
setIsRequestingAlgoOrderPrice(true)
|
||||
setComputeStatusText('Calculating price including fees.')
|
||||
const orderPriceAndFees = await getOrderPriceAndFees(
|
||||
selectedAlgorithmAsset,
|
||||
accountId
|
||||
)
|
||||
setAlgoOrderPriceAndFees(orderPriceAndFees)
|
||||
setIsRequestingAlgoOrderPrice(false)
|
||||
}
|
||||
|
||||
async function initSelectedAlgo() {
|
||||
const hasAlgoDt = await checkAssetDTBalance(selectedAlgorithmAsset)
|
||||
!hasAlgoDt && (await initAlgoPriceAndFees())
|
||||
await checkAssetDTBalance(selectedAlgorithmAsset)
|
||||
await initPriceAndFees()
|
||||
}
|
||||
|
||||
initSelectedAlgo()
|
||||
@ -215,32 +249,6 @@ export default function Compute({
|
||||
return
|
||||
}
|
||||
|
||||
const computeEnv = await getComputeEnviroment(asset)
|
||||
const validUntil = getValidUntilTime(
|
||||
computeEnv?.maxJobDuration,
|
||||
asset.services[0].timeout,
|
||||
selectedAlgorithmAsset.services[0].timeout
|
||||
)
|
||||
|
||||
setComputeStatusText(
|
||||
getComputeFeedback(
|
||||
asset.accessDetails.baseToken?.symbol,
|
||||
asset.accessDetails.datatoken?.symbol,
|
||||
asset.metadata.type
|
||||
)[0]
|
||||
)
|
||||
const datasetPriceAndFees = await getOrderPriceAndFees(
|
||||
asset,
|
||||
accountId,
|
||||
computeEnv?.id,
|
||||
validUntil
|
||||
)
|
||||
if (!datasetPriceAndFees) {
|
||||
setError('Error setting dataset price and fees!')
|
||||
toast.error('Error setting dataset price and fees!')
|
||||
return
|
||||
}
|
||||
|
||||
let datasetOrderTx
|
||||
if (isOwned) {
|
||||
datasetOrderTx = validOrderTx
|
||||
@ -266,7 +274,10 @@ export default function Compute({
|
||||
return
|
||||
}
|
||||
}
|
||||
LoggerInstance.log('dataset orderPriceAndFees: ', datasetPriceAndFees)
|
||||
LoggerInstance.log(
|
||||
'dataset orderPriceAndFees: ',
|
||||
datasetOrderPriceAndFees
|
||||
)
|
||||
setComputeStatusText(
|
||||
getComputeFeedback(
|
||||
asset.accessDetails.baseToken?.symbol,
|
||||
@ -277,10 +288,10 @@ export default function Compute({
|
||||
const orderTx = await order(
|
||||
web3,
|
||||
asset,
|
||||
datasetPriceAndFees,
|
||||
datasetOrderPriceAndFees,
|
||||
accountId,
|
||||
computeEnv?.id,
|
||||
validUntil,
|
||||
computeValidUntil,
|
||||
computeEnv?.consumerAddress
|
||||
)
|
||||
if (!orderTx) {
|
||||
@ -301,26 +312,6 @@ export default function Compute({
|
||||
}
|
||||
}
|
||||
|
||||
setComputeStatusText(
|
||||
getComputeFeedback(
|
||||
selectedAlgorithmAsset.accessDetails.baseToken?.symbol,
|
||||
selectedAlgorithmAsset.accessDetails.datatoken?.symbol,
|
||||
selectedAlgorithmAsset.metadata.type
|
||||
)[0]
|
||||
)
|
||||
const algorithmOrderPriceAndFees = await getOrderPriceAndFees(
|
||||
selectedAlgorithmAsset,
|
||||
ZERO_ADDRESS,
|
||||
computeEnv?.id,
|
||||
validUntil
|
||||
)
|
||||
|
||||
if (!algorithmOrderPriceAndFees) {
|
||||
setError('Error setting algorithm price and fees!')
|
||||
toast.error('Error setting algorithm price and fees!')
|
||||
return
|
||||
}
|
||||
|
||||
let algorithmOrderTx
|
||||
if (isAlgorithmOwned) {
|
||||
algorithmOrderTx = validAlgorithmOrderTx
|
||||
@ -362,10 +353,10 @@ export default function Compute({
|
||||
const orderTx = await order(
|
||||
web3,
|
||||
selectedAlgorithmAsset,
|
||||
algorithmOrderPriceAndFees,
|
||||
algoOrderPriceAndFees,
|
||||
accountId,
|
||||
computeEnv?.id,
|
||||
validUntil,
|
||||
computeValidUntil,
|
||||
computeEnv?.consumerAddress
|
||||
)
|
||||
if (!orderTx) {
|
||||
|
@ -62,6 +62,20 @@
|
||||
.assetMeta code {
|
||||
color: var(--color-secondary);
|
||||
font-size: var(--font-size-small);
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
flex: 6;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.assetMeta span {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.assetMeta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.meta {
|
||||
|
@ -33,7 +33,8 @@ function Asset({
|
||||
</a>
|
||||
</h3>
|
||||
<p className={styles.assetMeta}>
|
||||
{symbol} | <code>{did}</code>
|
||||
<span className={styles.assetMeta}> {`${symbol} | `}</span>
|
||||
<code className={styles.assetMeta}>{did}</code>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
@ -97,7 +98,7 @@ export default function Details({
|
||||
/>
|
||||
)}
|
||||
<MetaItem title="Job ID" content={<code>{job.jobId}</code>} />
|
||||
{/* {job.resultsDid && (
|
||||
{/* {job.results[0]. && (
|
||||
<MetaItem
|
||||
title="Published Results DID"
|
||||
content={<code>{job.resultsDid}</code>}
|
||||
|
@ -3,6 +3,10 @@
|
||||
border-bottom-left-radius: var(--border-radius) !important;
|
||||
}
|
||||
|
||||
.results li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.help {
|
||||
margin-top: calc(var(--spacer) / 3);
|
||||
}
|
||||
|
@ -1,90 +1,106 @@
|
||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||
import React, { ReactElement, useState } from 'react'
|
||||
import Loader from '@shared/atoms/Loader'
|
||||
import {
|
||||
ComputeResultType,
|
||||
downloadFileBrowser,
|
||||
LoggerInstance,
|
||||
Provider
|
||||
} from '@oceanprotocol/lib'
|
||||
import React, { ReactElement, useEffect, useState } from 'react'
|
||||
import { ListItem } from '@shared/atoms/Lists'
|
||||
import Button from '@shared/atoms/Button'
|
||||
import styles from './Results.module.css'
|
||||
import FormHelp from '@shared/FormInput/Help'
|
||||
import content from '../../../../../content/pages/history.json'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import { useCancelToken } from '@hooks/useCancelToken'
|
||||
import { retrieveAsset } from '@utils/aquarius'
|
||||
|
||||
export default function Results({
|
||||
job
|
||||
}: {
|
||||
job: ComputeJobMetaData
|
||||
}): ReactElement {
|
||||
const { accountId } = useWeb3()
|
||||
const providerInstance = new Provider()
|
||||
const { accountId, web3 } = useWeb3()
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [hasFetched, setHasFetched] = useState(false)
|
||||
const isFinished = job.dateFinished !== null
|
||||
|
||||
async function getResults() {
|
||||
const [datasetProvider, setDatasetProvider] = useState<string>()
|
||||
const newCancelToken = useCancelToken()
|
||||
useEffect(() => {
|
||||
async function getAssetMetadata() {
|
||||
const ddo = await retrieveAsset(job.inputDID[0], newCancelToken())
|
||||
setDatasetProvider(ddo.services[0].serviceEndpoint)
|
||||
}
|
||||
getAssetMetadata()
|
||||
}, [job.inputDID[0]])
|
||||
|
||||
function getDownloadButtonValue(type: ComputeResultType): string {
|
||||
let buttonName
|
||||
switch (type) {
|
||||
case 'output':
|
||||
buttonName = 'Download results'
|
||||
break
|
||||
case 'algorithmLog':
|
||||
buttonName = 'Download algorithm logs'
|
||||
break
|
||||
case 'configrationLog':
|
||||
buttonName = 'Download configuration logs'
|
||||
break
|
||||
case 'publishLog':
|
||||
buttonName = 'Download publish logs'
|
||||
break
|
||||
default:
|
||||
buttonName = 'Download results'
|
||||
break
|
||||
}
|
||||
return buttonName
|
||||
}
|
||||
|
||||
async function downloadResults(resultIndex: number) {
|
||||
if (!accountId || !job) return
|
||||
|
||||
try {
|
||||
setIsLoading(true)
|
||||
// const jobStatus = await ocean.compute.status(
|
||||
// account,
|
||||
// job.did,
|
||||
// undefined,
|
||||
// undefined,
|
||||
// job.jobId
|
||||
// )
|
||||
// if (jobStatus?.length > 0) {
|
||||
// job.algorithmLogUrl = jobStatus[0].algorithmLogUrl
|
||||
// job.resultsUrl = jobStatus[0].resultsUrl
|
||||
// }
|
||||
const jobResult = await providerInstance.getComputeResultUrl(
|
||||
datasetProvider,
|
||||
web3,
|
||||
accountId,
|
||||
job.jobId,
|
||||
resultIndex
|
||||
)
|
||||
await downloadFileBrowser(jobResult)
|
||||
} catch (error) {
|
||||
LoggerInstance.error(error.message)
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
setHasFetched(true)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.results}>
|
||||
{hasFetched ? (
|
||||
{isFinished ? (
|
||||
<ul>
|
||||
<ListItem>
|
||||
{/* {job.algorithmLogUrl ? (
|
||||
<a href={job.algorithmLogUrl} target="_blank" rel="noreferrer">
|
||||
View Log
|
||||
</a>
|
||||
) : (
|
||||
'No logs found.'
|
||||
)} */}
|
||||
</ListItem>
|
||||
|
||||
{/* {job.resultsUrl &&
|
||||
Array.isArray(job.resultsUrl) &&
|
||||
job.resultsUrl.map((url, i) =>
|
||||
url ? (
|
||||
<ListItem key={job.jobId}>
|
||||
<a href={url} target="_blank" rel="noreferrer">
|
||||
View Result {i + 1}
|
||||
</a>
|
||||
{job.results &&
|
||||
Array.isArray(job.results) &&
|
||||
job.results.map((jobResult, i) =>
|
||||
jobResult.filename ? (
|
||||
<ListItem key={i}>
|
||||
<Button
|
||||
style="primary"
|
||||
size="small"
|
||||
onClick={() => downloadResults(i)}
|
||||
disabled={isLoading || !isFinished}
|
||||
>
|
||||
{getDownloadButtonValue(jobResult.type)}
|
||||
</Button>
|
||||
</ListItem>
|
||||
) : (
|
||||
<ListItem>No results found.</ListItem>
|
||||
)
|
||||
)} */}
|
||||
)}
|
||||
</ul>
|
||||
) : (
|
||||
<Button
|
||||
style="primary"
|
||||
size="small"
|
||||
onClick={() => getResults()}
|
||||
disabled={isLoading || !isFinished}
|
||||
>
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
) : !isFinished ? (
|
||||
'Waiting for results...'
|
||||
) : (
|
||||
'Get Results'
|
||||
)}
|
||||
</Button>
|
||||
<p> Waiting for results...</p>
|
||||
)}
|
||||
<FormHelp className={styles.help}>{content.compute.storage}</FormHelp>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user