1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

Merge pull request #389 from oceanprotocol/feature/agorithm-details-view

View Algorithm details page
This commit is contained in:
Matthias Kretschmann 2021-03-02 12:10:48 +01:00 committed by GitHub
commit 93c115e75b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 133 additions and 59 deletions

View File

@ -0,0 +1,16 @@
.icon {
fill: var(--brand-grey-light);
width: 1.1em;
height: 1.1em;
vertical-align: baseline;
margin-bottom: -0.2em;
display: inline-block;
}
.typeLabel {
display: inline-block;
text-transform: uppercase;
border-right: 1px solid var(--border-color);
padding-right: calc(var(--spacer) / 3.5);
margin-right: calc(var(--spacer) / 4);
}

View File

@ -0,0 +1,33 @@
import React, { ReactElement } from 'react'
import styles from './AssetType.module.css'
import classNames from 'classnames/bind'
import { ReactComponent as Compute } from '../../images/compute.svg'
import { ReactComponent as Download } from '../../images/download.svg'
const cx = classNames.bind(styles)
export default function AssetType({
type,
accessType,
className
}: {
type: string
accessType: string
className?: string
}): ReactElement {
const styleClasses = cx({
[className]: className
})
return (
<div className={styleClasses}>
<div className={styles.typeLabel}>
{type === 'dataset' ? 'data set' : 'algorithm'}
</div>
{accessType === 'access' ? (
<Download role="img" aria-label="Download" className={styles.icon} />
) : (
<Compute role="img" aria-label="Compute" className={styles.icon} />
)}
</div>
)
}

View File

@ -69,20 +69,3 @@
width: auto; width: auto;
font-size: var(--font-size-mini); font-size: var(--font-size-mini);
} }
.icon {
fill: var(--brand-grey-light);
width: 1.1em;
height: 1.1em;
vertical-align: baseline;
margin-bottom: -0.2em;
display: inline-block;
}
.typeLabel {
display: inline-block;
text-transform: uppercase;
border-right: 1px solid var(--border-color);
padding-right: calc(var(--spacer) / 3.5);
margin-right: calc(var(--spacer) / 4);
}

View File

@ -8,8 +8,7 @@ import removeMarkdown from 'remove-markdown'
import Publisher from '../atoms/Publisher' import Publisher from '../atoms/Publisher'
import { useMetadata } from '@oceanprotocol/react' import { useMetadata } from '@oceanprotocol/react'
import Time from '../atoms/Time' import Time from '../atoms/Time'
import { ReactComponent as Compute } from '../../images/compute.svg' import AssetType from '../atoms/AssetType'
import { ReactComponent as Download } from '../../images/download.svg'
declare type AssetTeaserProps = { declare type AssetTeaserProps = {
ddo: DDO ddo: DDO
@ -20,7 +19,8 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({ ddo }: AssetTeaserProps) => {
const { attributes } = ddo.findServiceByType('metadata') const { attributes } = ddo.findServiceByType('metadata')
const { name, type } = attributes.main const { name, type } = attributes.main
const { dataTokenInfo } = ddo const { dataTokenInfo } = ddo
const accessType = ddo.service[1].type const isCompute = Boolean(ddo?.findServiceByType('compute'))
const accessType = isCompute ? 'compute' : 'access'
return ( return (
<article className={`${styles.teaser} ${styles[type]}`}> <article className={`${styles.teaser} ${styles[type]}`}>
@ -33,20 +33,11 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({ ddo }: AssetTeaserProps) => {
<Publisher account={owner} minimal className={styles.publisher} /> <Publisher account={owner} minimal className={styles.publisher} />
</header> </header>
<aside className={styles.typeDetails}> <AssetType
<div className={styles.typeLabel}> type={type}
{type === 'dataset' ? 'data set' : 'algorithm'} accessType={accessType}
</div> className={styles.typeDetails}
{accessType === 'access' ? ( />
<Download
role="img"
aria-label="Download"
className={styles.icon}
/>
) : (
<Compute role="img" aria-label="Compute" className={styles.icon} />
)}
</aside>
<div className={styles.content}> <div className={styles.content}>
<Dotdotdot tagName="p" clamp={3}> <Dotdotdot tagName="p" clamp={3}>

View File

@ -17,6 +17,7 @@ import Input from '../../atoms/Input'
import Alert from '../../atoms/Alert' import Alert from '../../atoms/Alert'
import { useSiteMetadata } from '../../../hooks/useSiteMetadata' import { useSiteMetadata } from '../../../hooks/useSiteMetadata'
import checkPreviousOrder from '../../../utils/checkPreviousOrder' import checkPreviousOrder from '../../../utils/checkPreviousOrder'
import { useAsset } from '../../../providers/Asset'
export default function Compute({ export default function Compute({
ddo, ddo,
@ -29,6 +30,7 @@ export default function Compute({
}): ReactElement { }): ReactElement {
const { marketFeeAddress } = useSiteMetadata() const { marketFeeAddress } = useSiteMetadata()
const { type } = useAsset()
const { ocean, accountId } = useOcean() const { ocean, accountId } = useOcean()
const { compute, isLoading, computeStepText, computeError } = useCompute() const { compute, isLoading, computeStepText, computeError } = useCompute()
const { buyDT, dtSymbol } = usePricing(ddo) const { buyDT, dtSymbol } = usePricing(ddo)
@ -129,16 +131,29 @@ export default function Compute({
</div> </div>
</div> </div>
<Input {type === 'algorithm' ? (
type="select" <Input
name="algorithm" type="select"
label="Select image to run the algorithm" name="data"
placeholder="" label="Select dataset for the algorithm"
size="small" placeholder=""
value={computeType} size="small"
options={computeOptions.map((x) => x.name)} value="dataset-1"
onChange={handleSelectChange} options={['dataset-1', 'dataset-2', 'dataset-3'].map((x) => x)}
/> onChange={handleSelectChange}
/>
) : (
<Input
type="select"
name="algorithm"
label="Select image to run the algorithm"
placeholder=""
size="small"
value={computeType}
options={computeOptions.map((x) => x.name)}
onChange={handleSelectChange}
/>
)}
<Dropzone multiple={false} handleOnDrop={onDrop} /> <Dropzone multiple={false} handleOnDrop={onDrop} />
<div className={styles.actions}> <div className={styles.actions}>

View File

@ -48,7 +48,7 @@ export default function Consume({
const { marketFeeAddress } = useSiteMetadata() const { marketFeeAddress } = useSiteMetadata()
const [hasPreviousOrder, setHasPreviousOrder] = useState(false) const [hasPreviousOrder, setHasPreviousOrder] = useState(false)
const [previousOrderId, setPreviousOrderId] = useState<string>() const [previousOrderId, setPreviousOrderId] = useState<string>()
const { isInPurgatory, price } = useAsset() const { isInPurgatory, price, type } = useAsset()
const { buyDT, pricingStepText, pricingError, pricingIsLoading } = usePricing( const { buyDT, pricingStepText, pricingError, pricingIsLoading } = usePricing(
ddo ddo
) )
@ -168,7 +168,6 @@ export default function Consume({
{!isInPurgatory && <PurchaseButton />} {!isInPurgatory && <PurchaseButton />}
</div> </div>
</div> </div>
<footer className={styles.feedback}> <footer className={styles.feedback}>
<Web3Feedback isBalanceSufficient={isBalanceSufficient} /> <Web3Feedback isBalanceSufficient={isBalanceSufficient} />
</footer> </footer>

View File

@ -6,7 +6,15 @@ import Publisher from '../../atoms/Publisher'
import { useAsset } from '../../../providers/Asset' import { useAsset } from '../../../providers/Asset'
export default function MetaFull(): ReactElement { export default function MetaFull(): ReactElement {
const { ddo, metadata, isInPurgatory } = useAsset() const { ddo, metadata, isInPurgatory, type } = useAsset()
function DockerImage() {
const algorithmContainer = ddo.findServiceByType('metadata').attributes.main
.algorithm.container
const { image } = algorithmContainer
const { tag } = algorithmContainer
return <span>{`${image}:${tag}`}</span>
}
return ( return (
<div className={styles.metaFull}> <div className={styles.metaFull}>
@ -17,6 +25,9 @@ export default function MetaFull(): ReactElement {
title="Owner" title="Owner"
content={<Publisher account={ddo?.publicKey[0].owner} />} content={<Publisher account={ddo?.publicKey[0].owner} />}
/> />
{type === 'algorithm' && (
<MetaItem title="Docker Image" content={<DockerImage />} />
)}
{/* <MetaItem {/* <MetaItem
title="Data Created" title="Data Created"
content={<Time date={metadata?.main.dateCreated} />} content={<Time date={metadata?.main.dateCreated} />}

View File

@ -9,5 +9,17 @@
.date { .date {
font-size: var(--font-size-mini); font-size: var(--font-size-mini);
margin-top: calc(var(--spacer) / 2); }
.typeAndDate {
margin-top: calc(var(--spacer) / 2);
display: flex;
}
.typeDetails {
border-right: 1px solid var(--border-color);
padding-right: calc(var(--spacer) / 3.5);
margin-right: calc(var(--spacer) / 4);
width: auto;
font-size: var(--font-size-mini);
} }

View File

@ -5,10 +5,13 @@ import EtherscanLink from '../../atoms/EtherscanLink'
import Publisher from '../../atoms/Publisher' import Publisher from '../../atoms/Publisher'
import Time from '../../atoms/Time' import Time from '../../atoms/Time'
import styles from './MetaMain.module.css' import styles from './MetaMain.module.css'
import AssetType from '../../atoms/AssetType'
export default function MetaMain(): ReactElement { export default function MetaMain(): ReactElement {
const { ddo, owner } = useAsset() const { ddo, owner, type } = useAsset()
const { networkId } = useOcean() const { networkId } = useOcean()
const isCompute = Boolean(ddo?.findServiceByType('compute'))
const accessType = isCompute ? 'compute' : 'access'
return ( return (
<aside className={styles.meta}> <aside className={styles.meta}>
@ -20,15 +23,22 @@ export default function MetaMain(): ReactElement {
<div> <div>
Published By <Publisher account={owner} /> Published By <Publisher account={owner} />
</div> </div>
<p className={styles.date}> <div className={styles.typeAndDate}>
<Time date={ddo?.created} relative /> <AssetType
{ddo?.created !== ddo?.updated && ( type={type}
<> accessType={accessType}
{' — '} className={styles.typeDetails}
updated <Time date={ddo?.updated} relative /> />
</> <p className={styles.date}>
)} <Time date={ddo?.created} relative />
</p> {ddo?.created !== ddo?.updated && (
<>
{' — '}
updated <Time date={ddo?.updated} relative />
</>
)}
</p>
</div>
</aside> </aside>
) )
} }

View File

@ -7,7 +7,7 @@ import React, {
useCallback, useCallback,
ReactNode ReactNode
} from 'react' } from 'react'
import { Logger, DDO, BestPrice } from '@oceanprotocol/lib' import { Logger, DDO, BestPrice, MetadataMain } from '@oceanprotocol/lib'
import { PurgatoryData } from '@oceanprotocol/lib/dist/node/ddo/interfaces/PurgatoryData' import { PurgatoryData } from '@oceanprotocol/lib/dist/node/ddo/interfaces/PurgatoryData'
import { getDataTokenPrice, useOcean } from '@oceanprotocol/react' import { getDataTokenPrice, useOcean } from '@oceanprotocol/react'
import getAssetPurgatoryData from '../utils/purgatory' import getAssetPurgatoryData from '../utils/purgatory'
@ -25,6 +25,7 @@ interface AssetProviderValue {
title: string | undefined title: string | undefined
owner: string | undefined owner: string | undefined
price: BestPrice | undefined price: BestPrice | undefined
type: MetadataMain['type'] | undefined
error?: string error?: string
refreshInterval: number refreshInterval: number
refreshDdo: (token?: CancelToken) => Promise<void> refreshDdo: (token?: CancelToken) => Promise<void>
@ -52,6 +53,7 @@ function AssetProvider({
const [price, setPrice] = useState<BestPrice>() const [price, setPrice] = useState<BestPrice>()
const [owner, setOwner] = useState<string>() const [owner, setOwner] = useState<string>()
const [error, setError] = useState<string>() const [error, setError] = useState<string>()
const [type, setType] = useState<MetadataMain['type']>()
const refreshPrice = useCallback(async () => { const refreshPrice = useCallback(async () => {
if ( if (
@ -160,6 +162,7 @@ function AssetProvider({
const { attributes } = ddo.findServiceByType('metadata') const { attributes } = ddo.findServiceByType('metadata')
setMetadata((attributes as unknown) as MetadataMarket) setMetadata((attributes as unknown) as MetadataMarket)
setTitle(attributes?.main.name) setTitle(attributes?.main.name)
setType(attributes.main.type)
setOwner(ddo.publicKey[0].owner) setOwner(ddo.publicKey[0].owner)
setIsInPurgatory(ddo.isInPurgatory === 'true') setIsInPurgatory(ddo.isInPurgatory === 'true')
@ -184,6 +187,7 @@ function AssetProvider({
title, title,
owner, owner,
price, price,
type,
error, error,
isInPurgatory, isInPurgatory,
purgatoryData, purgatoryData,