mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Fetching prices from Aquarius in AssetList component (#1774)
* Fetching prices from Aquarius in AssetList component * Removing unused imports * Removing fetching logic from AssetList * Using Asset Price from Aquarius * removing unused code for loader * Updating ocean.js * Updating price format in tests * removing console logs * Fixing build issues * Updating condition for showing free price * Fixing tests * Removing logs * Showing No pricing schema available on asset teaser * Showing No pricing schema available on asset detail page * Adding additional tests * Removing console logs * Avoiding getInitialPaymentCollector failure (#1816) * early return is no web3 or ddo * Creating test for MetaFull * adding test: src/components/Asset/AssetContent/MetaSecondary.test.tsx * Adding test for bookmarks * Adding test for displaying payment collector * Removing comments * Renaming assetAquarius * Renaming assetWithAccessDetails * Ensuring that the payment collector is shown even without a wallet connected * Removing broken test * Using getDummyWeb3 for fetching the payment collector address * google validation (#1835) * Updating validation to exclude any google link * Updating Yup validation * Checking if domain includes google.com * Updating isGoogleUrl function * Moving isGoogleUrl into @utils/url/index file * isGoogleUrl function * Updating tests * Adding additional tests for other google domains * Updating tests * Updating isGoogleUrl file path * Updating pricing message (#1842) * Bump @storybook/addon-essentials from 6.5.13 to 6.5.15 (#1841) Bumps [@storybook/addon-essentials](https://github.com/storybookjs/storybook/tree/HEAD/addons/essentials) from 6.5.13 to 6.5.15. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/v6.5.15/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v6.5.15/addons/essentials) --- updated-dependencies: - dependency-name: "@storybook/addon-essentials" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @types/jest from 29.2.3 to 29.2.5 (#1840) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.2.3 to 29.2.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump prettier from 2.8.0 to 2.8.1 (#1837) Bumps [prettier](https://github.com/prettier/prettier) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.8.0...2.8.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-select from 5.6.1 to 5.7.0 (#1839) Bumps [react-select](https://github.com/JedWatson/react-select) from 5.6.1 to 5.7.0. - [Release notes](https://github.com/JedWatson/react-select/releases) - [Changelog](https://github.com/JedWatson/react-select/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/JedWatson/react-select/compare/react-select@5.6.1...react-select@5.7.0) --- updated-dependencies: - dependency-name: react-select dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-tabs from 5.1.0 to 6.0.0 (#1838) Bumps [react-tabs](https://github.com/reactjs/react-tabs) from 5.1.0 to 6.0.0. - [Release notes](https://github.com/reactjs/react-tabs/releases) - [Commits](https://github.com/reactjs/react-tabs/compare/v5.1.0...v6.0.0) --- updated-dependencies: - dependency-name: react-tabs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix asset route (#1836) * updating the buy button message for free assets * Updating pricing text for compute and algorithms * Updating tests * Adding a seperate sentence about paying gas fees for network charges with free assets * Fixing tests Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro> * Showing hosting type in File Info (#1846) * Bump @storybook/addon-essentials from 6.5.13 to 6.5.15 (#1841) Bumps [@storybook/addon-essentials](https://github.com/storybookjs/storybook/tree/HEAD/addons/essentials) from 6.5.13 to 6.5.15. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/v6.5.15/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v6.5.15/addons/essentials) --- updated-dependencies: - dependency-name: "@storybook/addon-essentials" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @types/jest from 29.2.3 to 29.2.5 (#1840) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.2.3 to 29.2.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump prettier from 2.8.0 to 2.8.1 (#1837) Bumps [prettier](https://github.com/prettier/prettier) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.8.0...2.8.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-select from 5.6.1 to 5.7.0 (#1839) Bumps [react-select](https://github.com/JedWatson/react-select) from 5.6.1 to 5.7.0. - [Release notes](https://github.com/JedWatson/react-select/releases) - [Changelog](https://github.com/JedWatson/react-select/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/JedWatson/react-select/compare/react-select@5.6.1...react-select@5.7.0) --- updated-dependencies: - dependency-name: react-select dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-tabs from 5.1.0 to 6.0.0 (#1838) Bumps [react-tabs](https://github.com/reactjs/react-tabs) from 5.1.0 to 6.0.0. - [Release notes](https://github.com/reactjs/react-tabs/releases) - [Commits](https://github.com/reactjs/react-tabs/compare/v5.1.0...v6.0.0) --- updated-dependencies: - dependency-name: react-tabs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix asset route (#1836) * Adding hosting type to the file info component * Writting smart contract hosting type across two lines Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro> * add initial price value for not supported price assets (#1851) * Updating test * Updating accessDetailsAndPricing * Adding orderPriceAndFees back in to show the price with fees on the asset detail page * Using price with fees for compute assets * Fixing conversions by ensuring that the symbol is always sent through * Removing unwanted changes in package-lock.json * Updating use of isUnsupportedPricing variable * Getting rid of getAccessDetailsForAssets completely * Removing unused imports and query * Fixing test * Removing unused import --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro> Co-authored-by: Bogdan Fazakas <bogdan.fazakas@gmail.com>
This commit is contained in:
parent
5a935fcd48
commit
ed4645e13c
@ -1,3 +0,0 @@
|
||||
import { assets } from '../../__fixtures__/datasetsWithAccessDetails'
|
||||
|
||||
export const getAccessDetailsForAssets = jest.fn().mockResolvedValue(assets)
|
@ -5,11 +5,6 @@ import {
|
||||
TokenPriceQuery_token as TokenPrice
|
||||
} from '../@types/subgraph/TokenPriceQuery'
|
||||
import {
|
||||
TokensPriceQuery,
|
||||
TokensPriceQuery_tokens as TokensPrice
|
||||
} from '../@types/subgraph/TokensPriceQuery'
|
||||
import {
|
||||
Asset,
|
||||
LoggerInstance,
|
||||
ProviderFees,
|
||||
ProviderInstance
|
||||
@ -21,64 +16,6 @@ import {
|
||||
publisherMarketOrderFee
|
||||
} from '../../app.config'
|
||||
|
||||
const tokensPriceQuery = gql`
|
||||
query TokensPriceQuery($datatokenIds: [ID!], $account: String) {
|
||||
tokens(first: 1000, where: { id_in: $datatokenIds }) {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
publishMarketFeeAddress
|
||||
publishMarketFeeToken
|
||||
publishMarketFeeAmount
|
||||
templateId
|
||||
orders(
|
||||
where: { payer: $account }
|
||||
orderBy: createdTimestamp
|
||||
orderDirection: desc
|
||||
) {
|
||||
tx
|
||||
serviceIndex
|
||||
createdTimestamp
|
||||
reuses(orderBy: createdTimestamp, orderDirection: desc) {
|
||||
id
|
||||
caller
|
||||
createdTimestamp
|
||||
tx
|
||||
block
|
||||
}
|
||||
}
|
||||
dispensers {
|
||||
id
|
||||
active
|
||||
isMinter
|
||||
maxBalance
|
||||
token {
|
||||
id
|
||||
name
|
||||
symbol
|
||||
}
|
||||
}
|
||||
fixedRateExchanges {
|
||||
id
|
||||
exchangeId
|
||||
price
|
||||
publishMarketSwapFee
|
||||
baseToken {
|
||||
symbol
|
||||
name
|
||||
address
|
||||
decimals
|
||||
}
|
||||
datatoken {
|
||||
symbol
|
||||
name
|
||||
address
|
||||
}
|
||||
active
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
const tokenPriceQuery = gql`
|
||||
query TokenPriceQuery($datatokenId: ID!, $account: String) {
|
||||
token(id: $datatokenId) {
|
||||
@ -139,7 +76,7 @@ const tokenPriceQuery = gql`
|
||||
`
|
||||
|
||||
function getAccessDetailsFromTokenPrice(
|
||||
tokenPrice: TokenPrice | TokensPrice,
|
||||
tokenPrice: TokenPrice,
|
||||
timeout?: number
|
||||
): AccessDetails {
|
||||
const accessDetails = {} as AccessDetails
|
||||
@ -216,7 +153,7 @@ export async function getOrderPriceAndFees(
|
||||
providerFees?: ProviderFees
|
||||
): Promise<OrderPriceAndFees> {
|
||||
const orderPriceAndFee = {
|
||||
price: '0',
|
||||
price: String(asset?.stats?.price?.value || '0'),
|
||||
publisherMarketOrderFee: publisherMarketOrderFee || '0',
|
||||
publisherMarketFixedSwapFee: '0',
|
||||
consumeMarketOrderFee: consumeMarketOrderFee || '0',
|
||||
@ -291,56 +228,3 @@ export async function getAccessDetails(
|
||||
LoggerInstance.error('Error getting access details: ', error.message)
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAccessDetailsForAssets(
|
||||
assets: Asset[],
|
||||
account = ''
|
||||
): Promise<AssetExtended[]> {
|
||||
const assetsExtended: AssetExtended[] = assets
|
||||
const chainAssetLists: { [key: number]: string[] } = {}
|
||||
|
||||
try {
|
||||
for (const asset of assets) {
|
||||
if (chainAssetLists[asset.chainId]) {
|
||||
chainAssetLists[asset.chainId].push(
|
||||
asset.services[0].datatokenAddress.toLowerCase()
|
||||
)
|
||||
} else {
|
||||
chainAssetLists[asset.chainId] = []
|
||||
chainAssetLists[asset.chainId].push(
|
||||
asset.services[0].datatokenAddress.toLowerCase()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
for (const chainKey in chainAssetLists) {
|
||||
const queryContext = getQueryContext(Number(chainKey))
|
||||
const tokenQueryResult: OperationResult<
|
||||
TokensPriceQuery,
|
||||
{ datatokenIds: [string]; account: string }
|
||||
> = await fetchData(
|
||||
tokensPriceQuery,
|
||||
{
|
||||
datatokenIds: chainAssetLists[chainKey],
|
||||
account: account?.toLowerCase()
|
||||
},
|
||||
queryContext
|
||||
)
|
||||
tokenQueryResult?.data?.tokens?.forEach((token) => {
|
||||
const currentAsset = assetsExtended.find(
|
||||
(asset) =>
|
||||
asset.services[0].datatokenAddress.toLowerCase() === token.id
|
||||
)
|
||||
const accessDetails = getAccessDetailsFromTokenPrice(
|
||||
token,
|
||||
currentAsset?.services[0]?.timeout
|
||||
)
|
||||
|
||||
currentAsset.accessDetails = accessDetails
|
||||
})
|
||||
}
|
||||
return assetsExtended
|
||||
} catch (error) {
|
||||
LoggerInstance.error('Error getting access details: ', error.message)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { getAccessDetailsForAssets } from './accessDetailsAndPricing'
|
||||
import { PublisherTrustedAlgorithm, Asset } from '@oceanprotocol/lib'
|
||||
import { AssetSelectionAsset } from '@shared/FormInput/InputElement/AssetSelection'
|
||||
import { getServiceByName } from './ddo'
|
||||
@ -8,17 +7,14 @@ export async function transformAssetToAssetSelection(
|
||||
assets: Asset[],
|
||||
selectedAlgorithms?: PublisherTrustedAlgorithm[]
|
||||
): Promise<AssetSelectionAsset[]> {
|
||||
const extendedAssets: AssetExtended[] = await getAccessDetailsForAssets(
|
||||
assets
|
||||
)
|
||||
const algorithmList: AssetSelectionAsset[] = []
|
||||
|
||||
for (const asset of extendedAssets) {
|
||||
for (const asset of assets) {
|
||||
const algoService =
|
||||
getServiceByName(asset, 'compute') || getServiceByName(asset, 'access')
|
||||
|
||||
if (
|
||||
asset?.accessDetails?.price &&
|
||||
asset?.stats?.price?.value &&
|
||||
algoService?.serviceEndpoint === datasetProviderEndpoint
|
||||
) {
|
||||
let selected = false
|
||||
@ -30,7 +26,7 @@ export async function transformAssetToAssetSelection(
|
||||
const algorithmAsset: AssetSelectionAsset = {
|
||||
did: asset.id,
|
||||
name: asset.metadata.name,
|
||||
price: asset.accessDetails.price,
|
||||
price: asset.stats.price.value,
|
||||
checked: selected,
|
||||
symbol: asset.datatokens[0].symbol
|
||||
}
|
||||
|
@ -1,19 +1,7 @@
|
||||
import AssetTeaser from '@shared/AssetTeaser'
|
||||
import React, { ReactElement, useEffect, useState } from 'react'
|
||||
import React, { ReactElement } from 'react'
|
||||
import Pagination from '@shared/Pagination'
|
||||
import styles from './index.module.css'
|
||||
import Loader from '@shared/atoms/Loader'
|
||||
import { useIsMounted } from '@hooks/useIsMounted'
|
||||
import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
|
||||
function LoaderArea() {
|
||||
return (
|
||||
<div className={styles.loaderWrap}>
|
||||
<Loader />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export declare type AssetListProps = {
|
||||
assets: AssetExtended[]
|
||||
@ -33,52 +21,27 @@ export default function AssetList({
|
||||
showPagination,
|
||||
page,
|
||||
totalPages,
|
||||
isLoading,
|
||||
onPageChange,
|
||||
className,
|
||||
noPublisher,
|
||||
noDescription,
|
||||
noPrice
|
||||
}: AssetListProps): ReactElement {
|
||||
const { accountId } = useWeb3()
|
||||
const [assetsWithPrices, setAssetsWithPrices] =
|
||||
useState<AssetExtended[]>(assets)
|
||||
const [loading, setLoading] = useState<boolean>(isLoading)
|
||||
const isMounted = useIsMounted()
|
||||
|
||||
useEffect(() => {
|
||||
if (!assets || !assets.length) return
|
||||
|
||||
setAssetsWithPrices(assets as AssetExtended[])
|
||||
setLoading(false)
|
||||
async function fetchPrices() {
|
||||
const assetsWithPrices = await getAccessDetailsForAssets(
|
||||
assets,
|
||||
accountId || ''
|
||||
)
|
||||
if (!isMounted() || !assetsWithPrices) return
|
||||
setAssetsWithPrices([...assetsWithPrices])
|
||||
}
|
||||
fetchPrices()
|
||||
}, [assets, isMounted, accountId])
|
||||
|
||||
// // This changes the page field inside the query
|
||||
// This changes the page field inside the query
|
||||
function handlePageChange(selected: number) {
|
||||
onPageChange(selected + 1)
|
||||
}
|
||||
|
||||
const styleClasses = `${styles.assetList} ${className || ''}`
|
||||
|
||||
return loading ? (
|
||||
<LoaderArea />
|
||||
) : (
|
||||
return (
|
||||
<>
|
||||
<div className={styleClasses}>
|
||||
{assetsWithPrices?.length > 0 ? (
|
||||
assetsWithPrices?.map((assetWithPrice) => (
|
||||
{assets?.length > 0 ? (
|
||||
assets?.map((asset) => (
|
||||
<AssetTeaser
|
||||
asset={assetWithPrice}
|
||||
key={assetWithPrice.id}
|
||||
asset={asset}
|
||||
key={asset.id}
|
||||
noPublisher={noPublisher}
|
||||
noDescription={noDescription}
|
||||
noPrice={noPrice}
|
||||
|
@ -1,8 +1,23 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import testRender from '../../../../.jest/testRender'
|
||||
import AssetTeaser from './index'
|
||||
import { asset } from '../../../../.jest/__fixtures__/datasetWithAccessDetails'
|
||||
|
||||
describe('@shared/AssetTeaser', () => {
|
||||
testRender(<AssetTeaser asset={asset} />)
|
||||
|
||||
it('renders no pricing schema available', () => {
|
||||
asset.stats.price = null
|
||||
render(<AssetTeaser asset={asset} />)
|
||||
expect(screen.getByText('No pricing schema available')).toBeInTheDocument()
|
||||
expect(screen.getByText('This is a test.')).toBeInTheDocument()
|
||||
})
|
||||
it('renders asset teaser with no description', () => {
|
||||
asset.metadata.description = null
|
||||
render(<AssetTeaser asset={asset} />)
|
||||
expect(
|
||||
screen.queryByText('This is a test description')
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
@ -21,16 +21,18 @@ export declare type AssetTeaserProps = {
|
||||
export default function AssetTeaser({
|
||||
asset,
|
||||
noPublisher,
|
||||
noDescription,
|
||||
noPrice
|
||||
noDescription
|
||||
}: AssetTeaserProps): ReactElement {
|
||||
const { name, type, description } = asset.metadata
|
||||
const { datatokens } = asset
|
||||
const isCompute = Boolean(getServiceByName(asset, 'compute'))
|
||||
const accessType = isCompute ? 'compute' : 'access'
|
||||
const { owner } = asset.nft
|
||||
const { orders, allocated } = asset.stats
|
||||
const isUnsupportedPricing = asset?.accessDetails?.type === 'NOT_SUPPORTED'
|
||||
const { orders, allocated, price } = asset.stats
|
||||
const isUnsupportedPricing =
|
||||
!asset.services.length ||
|
||||
asset?.stats?.price?.value === undefined ||
|
||||
asset?.accessDetails?.type === 'NOT_SUPPORTED'
|
||||
const { locale } = useUserPreferences()
|
||||
|
||||
return (
|
||||
@ -60,15 +62,13 @@ export default function AssetTeaser({
|
||||
</Dotdotdot>
|
||||
</div>
|
||||
)}
|
||||
{!noPrice && (
|
||||
<div className={styles.price}>
|
||||
{isUnsupportedPricing || !asset.services.length ? (
|
||||
{isUnsupportedPricing ? (
|
||||
<strong>No pricing schema available</strong>
|
||||
) : (
|
||||
<Price accessDetails={asset.accessDetails} size="small" />
|
||||
<Price price={price} assetId={asset.id} size="small" />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<footer className={styles.footer}>
|
||||
{allocated && allocated > 0 ? (
|
||||
<span className={styles.typeLabel}>
|
||||
|
@ -7,21 +7,21 @@ describe('@shared/FormInput/InputElement/AssetSelection', () => {
|
||||
{
|
||||
did: 'did:op:xxx',
|
||||
name: 'Asset',
|
||||
price: '10',
|
||||
price: 10,
|
||||
checked: false,
|
||||
symbol: 'OCEAN'
|
||||
},
|
||||
{
|
||||
did: 'did:op:yyy',
|
||||
name: 'Asset',
|
||||
price: '10',
|
||||
price: 10,
|
||||
checked: true,
|
||||
symbol: 'OCEAN'
|
||||
},
|
||||
{
|
||||
did: 'did:op:zzz',
|
||||
name: 'Asset',
|
||||
price: '0',
|
||||
price: 0,
|
||||
checked: false,
|
||||
symbol: 'OCEAN'
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import styles from './index.module.css'
|
||||
export interface AssetSelectionAsset {
|
||||
did: string
|
||||
name: string
|
||||
price: string
|
||||
price: number
|
||||
checked: boolean
|
||||
symbol: string
|
||||
}
|
||||
@ -106,8 +106,7 @@ export default function AssetSelection({
|
||||
</label>
|
||||
|
||||
<PriceUnit
|
||||
price={Number(asset.price)}
|
||||
type={asset.price === '0' ? 'free' : undefined}
|
||||
price={asset.price}
|
||||
size="small"
|
||||
className={styles.price}
|
||||
/>
|
||||
|
@ -59,14 +59,14 @@ describe('@shared/FormInput', () => {
|
||||
{
|
||||
did: 'did:op:xxx',
|
||||
name: 'Asset',
|
||||
price: '10',
|
||||
price: 10,
|
||||
checked: false,
|
||||
symbol: 'OCEAN'
|
||||
},
|
||||
{
|
||||
did: 'did:op:yyy',
|
||||
name: 'Asset',
|
||||
price: '10',
|
||||
price: 10,
|
||||
checked: true,
|
||||
symbol: 'OCEAN'
|
||||
}
|
||||
|
@ -10,11 +10,9 @@ export default function PriceUnit({
|
||||
size = 'small',
|
||||
conversion,
|
||||
symbol,
|
||||
type,
|
||||
decimals
|
||||
}: {
|
||||
price: number
|
||||
type?: string
|
||||
className?: string
|
||||
size?: 'small' | 'mini' | 'large'
|
||||
conversion?: boolean
|
||||
@ -25,12 +23,14 @@ export default function PriceUnit({
|
||||
|
||||
return (
|
||||
<div className={`${styles.price} ${styles[size]} ${className}`}>
|
||||
{type === 'free' ? (
|
||||
{price === 0 ? (
|
||||
<div>Free</div>
|
||||
) : !price || Number.isNaN(price) ? (
|
||||
<div>-</div>
|
||||
) : (
|
||||
<>
|
||||
<div>
|
||||
{Number.isNaN(price) ? '-' : formatNumber(price, locale, decimals)}{' '}
|
||||
{formatNumber(price, locale, decimals)}
|
||||
<span className={styles.symbol}>{symbol}</span>
|
||||
</div>
|
||||
{conversion && <Conversion price={price} symbol={symbol} />}
|
||||
|
@ -13,39 +13,25 @@ describe('@shared/Price', () => {
|
||||
it('renders fixed price', () => {
|
||||
render(
|
||||
<Price
|
||||
accessDetails={{ ...asset.accessDetails, type: 'fixed', price: '10' }}
|
||||
price={{ value: 10, tokenSymbol: 'OCEAN', tokenAddress: '0x123' }}
|
||||
/>
|
||||
)
|
||||
expect(screen.getByText('10')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders free price', () => {
|
||||
render(<Price accessDetails={{ ...asset.accessDetails, type: 'free' }} />)
|
||||
render(<Price price={{ value: 0 }} />)
|
||||
expect(screen.getByText('Free')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders null price', () => {
|
||||
render(<Price accessDetails={{ ...asset.accessDetails, price: null }} />)
|
||||
render(<Price price={{ value: null }} />)
|
||||
expect(screen.getByText('-')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders conversion', async () => {
|
||||
render(
|
||||
<Price
|
||||
accessDetails={{ ...asset.accessDetails, price: '10' }}
|
||||
conversion
|
||||
/>
|
||||
)
|
||||
render(<Price price={asset.stats.price} conversion />)
|
||||
expect(await screen.findByText('≈')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders no conversion when no price defined', async () => {
|
||||
render(
|
||||
<Price
|
||||
accessDetails={{ ...asset.accessDetails, price: null }}
|
||||
conversion
|
||||
/>
|
||||
)
|
||||
render(<Price price={{ value: null, tokenSymbol: 'TEST' }} conversion />)
|
||||
expect(screen.queryByText('≈')).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
@ -1,32 +1,30 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { AssetPrice } from '@oceanprotocol/lib'
|
||||
import PriceUnit from './PriceUnit'
|
||||
|
||||
export default function Price({
|
||||
accessDetails,
|
||||
price,
|
||||
orderPriceAndFees,
|
||||
className,
|
||||
size,
|
||||
conversion
|
||||
}: {
|
||||
accessDetails: AccessDetails
|
||||
price: AssetPrice
|
||||
orderPriceAndFees?: OrderPriceAndFees
|
||||
assetId?: string
|
||||
className?: string
|
||||
conversion?: boolean
|
||||
size?: 'small' | 'mini' | 'large'
|
||||
}): ReactElement {
|
||||
const isSupported =
|
||||
accessDetails?.type === 'free' ||
|
||||
(accessDetails?.type === 'fixed' && accessDetails?.baseToken?.symbol)
|
||||
const price = `${orderPriceAndFees?.price || accessDetails?.price}`
|
||||
if (!price && !orderPriceAndFees) return
|
||||
|
||||
return isSupported ? (
|
||||
return (
|
||||
<PriceUnit
|
||||
price={Number(price)}
|
||||
symbol={accessDetails?.baseToken?.symbol}
|
||||
price={Number(orderPriceAndFees?.price) || price?.value}
|
||||
symbol={price?.tokenSymbol}
|
||||
className={className}
|
||||
size={size}
|
||||
conversion={conversion}
|
||||
type={accessDetails?.type}
|
||||
/>
|
||||
) : null
|
||||
)
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ export default function Compute({
|
||||
/>
|
||||
) : (
|
||||
<Price
|
||||
accessDetails={asset?.accessDetails}
|
||||
price={asset.stats?.price}
|
||||
orderPriceAndFees={datasetOrderPriceAndFees}
|
||||
conversion
|
||||
size="large"
|
||||
|
@ -51,6 +51,9 @@ export default function Download({
|
||||
const [retry, setRetry] = useState<boolean>(false)
|
||||
|
||||
const isUnsupportedPricing =
|
||||
!asset?.accessDetails ||
|
||||
!asset.services.length ||
|
||||
asset?.stats?.price?.value === undefined ||
|
||||
asset?.accessDetails?.type === 'NOT_SUPPORTED' ||
|
||||
(asset?.accessDetails?.type === 'fixed' &&
|
||||
!asset?.accessDetails?.baseToken?.symbol)
|
||||
@ -60,7 +63,7 @@ export default function Download({
|
||||
}, [asset?.nft.state])
|
||||
|
||||
useEffect(() => {
|
||||
if (!asset?.accessDetails || isUnsupportedPricing) return
|
||||
if (isUnsupportedPricing) return
|
||||
|
||||
setIsOwned(asset?.accessDetails?.isOwned || false)
|
||||
setValidOrderTx(asset?.accessDetails?.validOrderTx || '')
|
||||
@ -100,7 +103,6 @@ export default function Download({
|
||||
(asset?.accessDetails?.type === 'fixed' && !orderPriceAndFees) ||
|
||||
!isMounted ||
|
||||
!accountId ||
|
||||
!asset?.accessDetails ||
|
||||
isUnsupportedPricing
|
||||
)
|
||||
return
|
||||
@ -202,7 +204,7 @@ export default function Download({
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
{isUnsupportedPricing || !asset.services.length ? (
|
||||
{isUnsupportedPricing ? (
|
||||
<Alert
|
||||
className={styles.fieldWarning}
|
||||
state="info"
|
||||
@ -214,7 +216,7 @@ export default function Download({
|
||||
<Loader message="Calculating full price (including fees)" />
|
||||
) : (
|
||||
<Price
|
||||
accessDetails={asset.accessDetails}
|
||||
price={asset.stats?.price}
|
||||
orderPriceAndFees={orderPriceAndFees}
|
||||
conversion
|
||||
size="large"
|
||||
|
@ -7,7 +7,6 @@ import Tooltip from '@shared/atoms/Tooltip'
|
||||
import AssetTitle from '@shared/AssetListTitle'
|
||||
import { getAssetsFromDids } from '@utils/aquarius'
|
||||
import { useCancelToken } from '@hooks/useCancelToken'
|
||||
import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import { useMarketMetadata } from '@context/MarketMetadata'
|
||||
|
||||
@ -32,7 +31,7 @@ const columns: TableOceanColumn<AssetExtended>[] = [
|
||||
},
|
||||
{
|
||||
name: 'Price',
|
||||
selector: (row) => <Price accessDetails={row.accessDetails} size="small" />,
|
||||
selector: (row) => <Price price={row.stats.price} size="small" />,
|
||||
right: true
|
||||
}
|
||||
]
|
||||
@ -66,11 +65,7 @@ export default function Bookmarks(): ReactElement {
|
||||
)
|
||||
if (!result?.length) return
|
||||
|
||||
const pinnedAssets: AssetExtended[] = await getAccessDetailsForAssets(
|
||||
result,
|
||||
accountId
|
||||
)
|
||||
setPinned(pinnedAssets)
|
||||
setPinned(result)
|
||||
} catch (error) {
|
||||
LoggerInstance.error(`Bookmarks error:`, error.message)
|
||||
} finally {
|
||||
|
@ -5,7 +5,6 @@ import Conversion from '@shared/Price/Conversion'
|
||||
import NumberUnit from './NumberUnit'
|
||||
import styles from './Stats.module.css'
|
||||
import { useProfile } from '@context/Profile'
|
||||
import { getAccessDetailsForAssets } from '@utils/accessDetailsAndPricing'
|
||||
import { getLocked } from '@utils/veAllocation'
|
||||
import PriceUnit from '@shared/Price/PriceUnit'
|
||||
import Button from '@shared/atoms/Button'
|
||||
@ -37,12 +36,10 @@ export default function Stats({
|
||||
|
||||
async function getPublisherTotalSales() {
|
||||
try {
|
||||
const assetsPrices = await getAccessDetailsForAssets(assets)
|
||||
let count = 0
|
||||
for (const priceInfo of assetsPrices) {
|
||||
if (priceInfo?.accessDetails?.price && priceInfo.stats.orders > 0) {
|
||||
count +=
|
||||
parseInt(priceInfo.accessDetails.price) * priceInfo.stats.orders
|
||||
for (const priceInfo of assets) {
|
||||
if (priceInfo?.stats?.price?.value && priceInfo.stats.orders > 0) {
|
||||
count += priceInfo.stats.price.value * priceInfo.stats.orders
|
||||
}
|
||||
}
|
||||
setTotalSales(count)
|
||||
|
Loading…
Reference in New Issue
Block a user