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

generate pages for all existing assets, make asset details view work for them

This commit is contained in:
Matthias Kretschmann 2020-07-01 17:11:45 +02:00
parent 6106b8f037
commit af62e9f5d4
Signed by: m
GPG Key ID: 606EEEF3C479A91F
14 changed files with 169 additions and 169 deletions

View File

@ -2,7 +2,7 @@
"site": {
"siteTitle": "Ocean Market",
"siteTagline": "A marketplace to find and publish open data sets in the Ocean Network.",
"siteUrl": "https://market.oceanprotocol.now.sh/",
"siteUrl": "https://market.oceanprotocol.now.sh",
"siteIcon": "node_modules/@oceanprotocol/art/logo/favicon-white.png",
"siteImage": "../src/images/share.png",
"copyright": "All Rights Reserved. Powered by [Ocean Protocol](https://oceanprotocol.com)",

View File

@ -1,3 +1,7 @@
const path = require('path')
const axios = require('axios')
// const { config } = require('./src/config/ocean')
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
node: {
@ -6,3 +10,32 @@ exports.onCreateWebpackConfig = ({ actions }) => {
}
})
}
exports.createPages = async ({ actions, reporter }) => {
const { createPage } = actions
// Query for markdown nodes to use in creating pages.
const result = await axios(
`https://aquarius.marketplace.oceanprotocol.com/api/v1/aquarius/assets`
)
const assets = result.data.ids
// Handle errors
if (result.errors) {
reporter.panicOnBuild(`Error while querying Aquarius for all assets.`)
return
}
// Create pages for each DID
const assetDetailsTemplate = path.resolve(
`src/components/templates/AssetDetails/index.tsx`
)
assets.forEach((did) => {
const path = `/asset/${did}`
createPage({
path,
component: assetDetailsTemplate,
context: { did }
})
})
}

View File

@ -1,15 +1,5 @@
import { MetaData, AdditionalInformation, Curation } from '@oceanprotocol/squid'
declare type DeliveryType = 'files' | 'api' | 'subscription'
declare type Granularity =
| 'hourly'
| 'daily'
| 'weekly'
| 'monthly'
| 'annually'
| 'Not updated periodically'
| ''
import { MetaData, AdditionalInformation } from '@oceanprotocol/squid'
import { ServiceMetadata } from '@oceanprotocol/squid/dist/node/ddo/Service'
export interface Sample {
name: string
@ -21,14 +11,15 @@ export declare type AccessType = 'Download' | 'Compute'
export interface AdditionalInformationMarket extends AdditionalInformation {
description: string
links?: Sample[] // redefine existing key, cause not specific enough in Squid
deliveryType: DeliveryType
termsAndConditions: boolean
dateRange?: [string, string]
supportName?: string
supportEmail?: string
access: AccessType
}
export interface MetaDataMarket extends MetaData {
additionalInformation: AdditionalInformationMarket
}
export interface ServiceMetaDataMarket extends ServiceMetadata {
attributes: MetaDataMarket
}

View File

@ -10,18 +10,18 @@ import { config } from '../config/ocean'
export interface LayoutProps {
children: ReactNode
title?: string
title: string
uri: string
description?: string
noPageHeader?: boolean
location?: Location
}
export default function Layout({
children,
title,
uri,
description,
noPageHeader,
location
noPageHeader
}: LayoutProps): ReactElement {
return (
<Web3Provider>
@ -33,12 +33,7 @@ export default function Layout({
<meta name="theme-color" content="#ca2935" />
</Helmet>
<Seo
title={title}
description={description}
uri={location.href}
location={location}
/>
<Seo title={title} description={description} uri={uri} />
<Header />
<main className={styles.main}>

View File

@ -1,18 +1,16 @@
import React from 'react'
import React, { ReactElement } from 'react'
import { Helmet } from 'react-helmet'
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
export default function Seo({
title,
description,
uri,
location
uri
}: {
title?: string
description?: string
uri: string
location: Location
}) {
}): ReactElement {
const { siteTitle, siteTagline, siteUrl, siteImage } = useSiteMetadata()
// Remove trailing slash from all URLs
@ -37,7 +35,7 @@ export default function Seo({
<meta name="description" content={description} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:url" content={location.href} />
<meta property="og:url" content={uri} />
<meta
name="image"

View File

@ -1,6 +1,5 @@
import React, { useState, useEffect } from 'react'
import { DDO, Ocean } from '@oceanprotocol/squid'
import { ServiceMetadata } from '@oceanprotocol/squid/dist/node/ddo/Service'
import React, { useState, useEffect, ReactElement } from 'react'
import { Ocean } from '@oceanprotocol/squid'
import { fromWei } from 'web3-utils'
import compareAsBN, { Comparisson } from '../../utils/compareAsBN'
import Loader from '../atoms/Loader'
@ -15,18 +14,19 @@ import {
import styles from './Compute.module.css'
import Button from '../atoms/Button'
import Input from '../atoms/Input'
import { MetaDataMarket } from '../../@types/MetaData'
export default function Compute({
ddo,
did,
metadata,
balance,
ocean
}: {
ddo: DDO | null
did: string
metadata: MetaDataMarket
balance: string | null
ocean: Ocean | null
}) {
if (!ddo) return null
}): ReactElement {
const { compute, isLoading, computeStepText, computeError } = useCompute()
const [isJobStarting, setIsJobStarting] = useState(false)
const [, setError] = useState('')
@ -41,9 +41,7 @@ export default function Compute({
const [isPublished, setIsPublished] = useState(false)
const [file, setFile] = useState(null)
const metadata = ddo.findServiceByType('metadata') as ServiceMetadata
const { price } = metadata.attributes.main
const { price } = metadata.main
const isFree = price === '0'
const [isTermsAgreed, setIsTermsAgreed] = useState(true)
@ -85,7 +83,7 @@ export default function Compute({
setIsPublished(false)
setError('')
await compute(ddo.id, algorithmRawCode, computeContainer)
await compute(did, algorithmRawCode, computeContainer)
setIsPublished(true)
setFile(null)

View File

@ -1,25 +1,26 @@
import React from 'react'
import { DDO } from '@oceanprotocol/squid'
import React, { ReactElement } from 'react'
import Web3 from 'web3'
import compareAsBN, { Comparisson } from '../../utils/compareAsBN'
import Button from '../atoms/Button'
import File from '../atoms/File'
import Price from '../atoms/Price'
import { MetaDataMarket } from '../../@types/MetaData'
import Web3Feedback from '../molecules/Web3Feedback'
import styles from './Consume.module.css'
import Loader from '../atoms/Loader'
import { useWeb3, useOcean, useConsume } from '@oceanprotocol/react'
import { useOcean, useConsume } from '@oceanprotocol/react'
import { MetaDataMarket } from '../../@types/MetaData'
export default function Consume({ ddo }: { ddo: DDO | undefined }) {
if (!ddo) return null
const { web3 } = useWeb3()
export default function Consume({
did,
metadata
}: {
did: string
metadata: MetaDataMarket
}): ReactElement {
const { ocean, balanceInOcean } = useOcean()
const { consume, consumeStepText, isLoading } = useConsume()
const { attributes } = ddo.findServiceByType('metadata')
const { price } = attributes.main
const file = (attributes as any).main.files[0]
const { price } = metadata.main
const file = metadata.main.files[0]
const isFree = price === '0'
const isBalanceSufficient =
isFree ||
@ -34,7 +35,11 @@ export default function Consume({ ddo }: { ddo: DDO | undefined }) {
return isLoading ? (
<Loader message={consumeStepText} isHorizontal />
) : (
<Button primary onClick={() => consume(ddo.id)} disabled={isDisabled}>
<Button
style="primary"
onClick={() => consume(did)}
disabled={isDisabled}
>
{isFree ? 'Download' : 'Buy'}
</Button>
)

View File

@ -1,21 +1,20 @@
import React from 'react'
import { DDO } from '@oceanprotocol/squid'
import { MetaDataMarket } from '../../../@types/MetaData'
import React, { ReactElement } from 'react'
import Time from '../../atoms/Time'
import MetaItem from './MetaItem'
import styles from './MetaFull.module.css'
import { MetaDataMarket } from '../../../@types/MetaData'
export default function MetaFull({
ddo,
attributes
did,
metadata
}: {
ddo: DDO | undefined
attributes: MetaDataMarket
}) {
const { dateCreated, author, license } = attributes.main
did: string
metadata: MetaDataMarket
}): ReactElement {
const { dateCreated, author, license } = metadata.main
let dateRange
if (attributes && attributes.additionalInformation) {
;({ dateRange } = attributes.additionalInformation)
if (metadata && metadata.additionalInformation) {
;({ dateRange } = metadata.additionalInformation)
}
// In practice dateRange will always be defined, but in the rare case it isn't
@ -43,7 +42,7 @@ export default function MetaFull({
}
/>
<MetaItem title="DID" content={<code>{ddo?.id}</code>} />
<MetaItem title="DID" content={<code>{did}</code>} />
</div>
)
}

View File

@ -1,20 +1,18 @@
import React from 'react'
import React, { ReactElement } from 'react'
import shortid from 'shortid'
import { MetaDataMarket } from '../../../@types/MetaData'
import { ListItem } from '../../atoms/Lists'
import { refundPolicy, assetTerms } from '../../../../site.config'
import MetaItem from './MetaItem'
import styles from './MetaSecondary.module.css'
import { MetaDataMarket } from '../../../@types/MetaData'
export default function MetaSecondary({
attributes
metadata
}: {
attributes: MetaDataMarket
}) {
const { price } = attributes.main
let links, supportName, supportEmail
if (attributes && attributes.additionalInformation) {
;({ links, supportName, supportEmail } = attributes.additionalInformation)
metadata: MetaDataMarket
}): ReactElement {
let links
if (metadata && metadata.additionalInformation) {
;({ links } = metadata.additionalInformation)
}
return (
@ -35,37 +33,6 @@ export default function MetaSecondary({
/>
</div>
)}
{(supportName || supportEmail) && (
<MetaItem
title="Support Contact"
content={
<>
{supportName && <p>{supportName}</p>}
{supportEmail && <p>{supportEmail}</p>}
</>
}
/>
)}
{price !== '0' && (
<MetaItem
title="Refund Policy"
content={
<ul>
{refundPolicy.map((item) => (
<ListItem key={shortid.generate()}>{item}</ListItem>
))}
</ul>
}
/>
)}
{assetTerms.map((item) => (
<MetaItem
key={shortid.generate()}
title={item.name}
content={item.value}
/>
))}
</aside>
)
}

View File

@ -1,8 +1,9 @@
import React, { useState } from 'react'
import { DDO } from '@oceanprotocol/squid'
import { Link } from 'gatsby'
import React, { useState, ReactElement, useEffect } from 'react'
import { Aquarius, Logger } from '@oceanprotocol/squid'
import { Link, PageProps } from 'gatsby'
import { config } from '../../../config/ocean'
import Layout from '../../../components/Layout'
import { MetaDataMarket } from '../../../@types/MetaData'
import { MetaDataMarket, ServiceMetaDataMarket } from '../../../@types/MetaData'
import Time from '../../atoms/Time'
import Markdown from '../../atoms/Markdown'
import Consume from '../../organisms/Consume'
@ -10,39 +11,30 @@ import Tags from '../../atoms/Tags'
import { Alert } from '../../atoms/Alert'
import MetaFull from './MetaFull'
import MetaSecondary from './MetaSecondary'
import Rating from '../../atoms/Rating'
import RatingAction from './RatingAction'
// import Rating from '../../atoms/Rating'
// import RatingAction from './RatingAction'
import styles from './index.module.css'
import { useMetadata, useOcean } from '@oceanprotocol/react'
import Compute from '../../organisms/Compute'
import DeleteAction from '../../molecules/DeleteAsset'
export declare type AssetDetailsPageProps = {
title: string
ddo?: DDO
attributes?: MetaDataMarket
error?: string
}
// import DeleteAction from '../../molecules/DeleteAsset'
const AssetDetailsPageMeta = ({
attributes,
ddo
metadata,
did
}: {
attributes: MetaDataMarket
ddo: DDO
metadata: MetaDataMarket
did: string
}) => {
if (!attributes) return null
const { ocean, balanceInOcean } = useOcean()
const { datePublished } = attributes.main
const { datePublished } = metadata.main
const {
description,
copyrightHolder,
categories,
tags,
access
} = attributes.additionalInformation
const { curation } = attributes
} = metadata.additionalInformation
const { curation } = metadata
const { getCuration } = useMetadata()
const [rating, setRating] = useState<number>(curation ? curation.rating : 0)
@ -50,8 +42,9 @@ const AssetDetailsPageMeta = ({
curation ? curation.numVotes : 0
)
const isCompute = access && access === 'Compute'
const onVoteUpdate = async () => {
const { rating, numVotes } = await getCuration(ddo.id)
const { rating, numVotes } = await getCuration(did)
setRating(rating)
setNumVotes(numVotes)
@ -72,7 +65,7 @@ const AssetDetailsPageMeta = ({
</Link>
</p>
)}
<Rating curation={{ rating, numVotes }} readonly />
{/* <Rating curation={{ rating, numVotes }} readonly /> */}
</aside>
<h2 className={styles.sectionTitle}>Summary</h2>
@ -80,7 +73,7 @@ const AssetDetailsPageMeta = ({
{tags && tags.length > 0 && <Tags items={tags} />}
<MetaFull ddo={ddo} attributes={attributes} />
<MetaFull did={did} metadata={metadata} />
<div className={styles.buttonGroup}>
{/* <EditAction
ddo={ddo}
@ -88,48 +81,73 @@ const AssetDetailsPageMeta = ({
account={account}
refetchMetadata={refetchMetadata}
/> */}
<DeleteAction ddo={ddo} />
{/* <DeleteAction ddo={ddo} /> */}
</div>
</div>
<div>
<div className={styles.sticky}>
{isCompute ? (
<Compute ddo={ddo} ocean={ocean} balance={balanceInOcean} />
<Compute
did={did}
metadata={metadata}
ocean={ocean}
balance={balanceInOcean}
/>
) : (
<Consume ddo={ddo} />
<Consume did={did} metadata={metadata} />
)}
<RatingAction did={ddo.id} onVote={onVoteUpdate} />
<MetaSecondary attributes={attributes} />
{/* <RatingAction did={did} onVote={onVoteUpdate} /> */}
<MetaSecondary metadata={metadata} />
</div>
</div>
</>
)
}
const AssetDetailsPage = ({
ddo,
attributes,
title,
error
}: AssetDetailsPageProps) => {
if (error) {
return (
<Layout title={title} noPageHeader>
<Alert title={title} text={error} state="error" />
</Layout>
)
export default function AssetDetailsPage(props: PageProps): ReactElement {
const [metadata, setMetadata] = useState<MetaDataMarket>()
const [title, setTitle] = useState<string>()
const [error, setError] = useState<string>()
const { did } = props.pageContext as { did: string }
useEffect(() => {
async function init() {
try {
const aquarius = new Aquarius(config.aquariusUri, Logger)
const ddo = await aquarius.retrieveDDO(did)
if (!ddo) {
setTitle('Could not retrieve asset')
setError('The DDO was not found in Aquarius.')
return
}
return (
<Layout title={title}>
const { attributes }: ServiceMetaDataMarket = ddo.findServiceByType(
'metadata'
)
setTitle(attributes.main.name)
console.log(attributes)
setMetadata(attributes)
} catch (error) {
setTitle('Error retrieving asset')
setError(error.message)
}
}
init()
}, [])
return error ? (
<Layout title={title} noPageHeader uri={props.path}>
<Alert title={title} text={error} state="error" />
</Layout>
) : did && metadata ? (
<Layout title={title} uri={props.path}>
<article className={styles.grid}>
{attributes && (
<AssetDetailsPageMeta ddo={ddo as DDO} attributes={attributes} />
)}
<AssetDetailsPageMeta did={did} metadata={metadata} />
</article>
</Layout>
)
) : null
}
export default AssetDetailsPage

View File

@ -8,7 +8,7 @@ export default function PageGatsbyHistory(props: PageProps): ReactElement {
const { title, description } = content
return (
<Layout title={title} description={description} location={props.location}>
<Layout title={title} description={description} uri={props.uri}>
<PageHistory />
</Layout>
)

View File

@ -8,11 +8,7 @@ export default function PageGatsbyHome(props: PageProps): ReactElement {
const { siteTitle, siteTagline } = useSiteMetadata()
return (
<Layout
title={siteTitle}
description={siteTagline}
location={props.location}
>
<Layout title={siteTitle} description={siteTagline} uri={props.uri}>
<PageHome />
</Layout>
)

View File

@ -8,7 +8,7 @@ export default function PageGatsbyPublish(props: PageProps): ReactElement {
const { title, description } = content
return (
<Layout title={title} description={description} location={props.location}>
<Layout title={title} description={description} uri={props.uri}>
<PagePublish />
</Layout>
)

View File

@ -9,7 +9,7 @@ export default function PageGatsbySearch(props: PageProps): ReactElement {
const { text, tag } = parsed
return (
<Layout title={`Search for ${text || tag}`} location={props.location}>
<Layout title={`Search for ${text || tag}`} uri={props.uri}>
<PageSearch location={props.location} />
</Layout>
)