From 7b653c46bacb1766d59dee523bd87e15a5e3687f Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Tue, 20 Apr 2021 09:44:18 +0300 Subject: [PATCH 01/22] fetch asset price withoud relying on ddo.price --- src/providers/Asset.tsx | 88 +++-------------------------------------- src/utils/subgraph.ts | 79 +++++++++++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 91 deletions(-) diff --git a/src/providers/Asset.tsx b/src/providers/Asset.tsx index 0f336cc6a..d6e947e57 100644 --- a/src/providers/Asset.tsx +++ b/src/providers/Asset.tsx @@ -12,11 +12,9 @@ import { PurgatoryData } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Purga import getAssetPurgatoryData from '../utils/purgatory' import axios, { CancelToken } from 'axios' import { retrieveDDO } from '../utils/aquarius' +import { getPrice } from '../utils/subgraph' import { MetadataMarket } from '../@types/MetaData' import { useOcean } from './Ocean' -import { gql, useQuery } from '@apollo/client' -import { PoolPrice } from '../@types/apollo/PoolPrice' -import { FrePrice } from '../@types/apollo/FrePrice' interface AssetProviderValue { isInPurgatory: boolean @@ -33,25 +31,6 @@ interface AssetProviderValue { refreshDdo: (token?: CancelToken) => Promise } -const poolQuery = gql` - query PoolPrice($datatoken: String) { - pools(where: { datatokenAddress: $datatoken }) { - spotPrice - datatokenReserve - oceanReserve - } - } -` - -const freQuery = gql` - query FrePrice($datatoken: String) { - fixedRateExchanges(orderBy: id, where: { datatoken: $datatoken }) { - rate - id - } - } -` - const AssetContext = createContext({} as AssetProviderValue) const refreshInterval = 10000 // 10 sec. @@ -74,64 +53,6 @@ function AssetProvider({ const [owner, setOwner] = useState() const [error, setError] = useState() const [type, setType] = useState() - const [variables, setVariables] = useState({}) - - /* eslint-disable @typescript-eslint/no-unused-vars */ - const { - refetch: refetchFre, - startPolling: startPollingFre, - data: frePrice - } = useQuery(freQuery, { - variables, - skip: false - }) - const { - refetch: refetchPool, - startPolling: startPollingPool, - data: poolPrice - } = useQuery(poolQuery, { - variables, - skip: false - }) - /* eslint-enable @typescript-eslint/no-unused-vars */ - - // this is not working as expected, thus we need to fetch both pool and fre - // useEffect(() => { - // if (!ddo || !variables || variables === '') return - - // if (ddo.price.type === 'exchange') { - // refetchFre(variables) - // startPollingFre(refreshInterval) - // } else { - // refetchPool(variables) - // startPollingPool(refreshInterval) - // } - // }, [ddo, variables]) - - useEffect(() => { - if ( - !frePrice || - frePrice.fixedRateExchanges.length === 0 || - price.type !== 'exchange' - ) - return - setPrice((prevState) => ({ - ...prevState, - value: frePrice.fixedRateExchanges[0].rate, - address: frePrice.fixedRateExchanges[0].id - })) - }, [frePrice]) - - useEffect(() => { - if (!poolPrice || poolPrice.pools.length === 0 || price.type !== 'pool') - return - setPrice((prevState) => ({ - ...prevState, - value: poolPrice.pools[0].spotPrice, - ocean: poolPrice.pools[0].oceanReserve, - datatoken: poolPrice.pools[0].datatokenReserve - })) - }, [poolPrice]) const fetchDdo = async (token?: CancelToken) => { Logger.log('[asset] Init asset, get DDO') @@ -198,8 +119,11 @@ function AssetProvider({ // Set price & metadata from DDO first // TODO Hacky hack, temporary™: set isConsumable to true by default since Aquarius can't be trusted. - setPrice({ ...ddo.price, isConsumable: 'true' }) - setVariables({ datatoken: ddo?.dataToken.toLowerCase() }) + // setPrice({ ...ddo.price, isConsumable: 'true' }) + + const returnedPrice = await getPrice(ddo) + console.log('returnedPrice', returnedPrice) + setPrice({ ...returnedPrice, isConsumable: 'true' }) // Get metadata from DDO const { attributes } = ddo.findServiceByType('metadata') diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index 3ae3304cf..f07cfefb0 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -1,5 +1,5 @@ import { gql, DocumentNode, ApolloQueryResult } from '@apollo/client' -import { DDO } from '@oceanprotocol/lib' +import { DDO, BestPrice } from '@oceanprotocol/lib' import { getApolloClientInstance } from '../providers/ApolloClientProvider' import BigNumber from 'bignumber.js' @@ -7,8 +7,8 @@ export interface PriceList { [key: string]: string } -const freQuery = gql` - query AssetFrePrice($datatoken_in: [String!]) { +const FreQuery = gql` + query AssetsFrePrice($datatoken_in: [String!]) { fixedRateExchanges(orderBy: id, where: { datatoken_in: $datatoken_in }) { rate id @@ -20,8 +20,17 @@ const freQuery = gql` } ` -const poolQuery = gql` - query AssetPoolPrice($datatokenAddress_in: [String!]) { +const AssetFreQuery = gql` + query AssetFrePrice($datatoken: String) { + fixedRateExchanges(orderBy: id, where: { datatoken: $datatoken }) { + rate + id + } + } +` + +const PoolQuery = gql` + query AssetsPoolPrice($datatokenAddress_in: [String!]) { pools(where: { datatokenAddress_in: $datatokenAddress_in }) { spotPrice id @@ -30,7 +39,19 @@ const poolQuery = gql` } ` -const previousOrderQuery = gql` +const AssetPoolPriceQuerry = gql` + query AssetPoolPrice($datatokenAddress: String) { + pools(where: { datatokenAddress: $datatokenAddress }) { + id + spotPrice + datatokenReserve + oceanReserve + datatokenAddress + } + } +` + +const PreviousOrderQuery = gql` query AssetPreviousOrder($id: String!, $account: String!) { tokenOrders( first: 1 @@ -70,7 +91,7 @@ export async function getPreviousOrders( account: account } const fetchedPreviousOrders: any = await fetchData( - previousOrderQuery, + PreviousOrderQuery, variables ) if (fetchedPreviousOrders.data?.tokenOrders?.length === 0) return null @@ -104,13 +125,53 @@ export async function getAssetPrices(assets: DDO[]): Promise { const poolVariables = { datatokenAddress_in: dataTokenList } - const poolPriceResponse: any = await fetchData(poolQuery, poolVariables) + const poolPriceResponse: any = await fetchData(PoolQuery, poolVariables) for (const poolPrice of poolPriceResponse.data?.pools) { priceList[didDTMap[poolPrice.datatokenAddress]] = poolPrice.spotPrice } - const frePriceResponse: any = await fetchData(freQuery, freVariables) + const frePriceResponse: any = await fetchData(FreQuery, freVariables) for (const frePrice of frePriceResponse.data?.fixedRateExchanges) { priceList[didDTMap[frePrice.datatoken?.address]] = frePrice.rate } return priceList } + +export async function getPrice(asset: DDO): Promise { + const freVariables = { + datatoken: asset?.dataToken.toLowerCase() + } + + const poolVariables = { + datatokenAddress: asset?.dataToken.toLowerCase() + } + + const poolPriceResponse: any = await fetchData( + AssetPoolPriceQuerry, + poolVariables + ) + const frePriceResponse: any = await fetchData(AssetFreQuery, freVariables) + if (poolPriceResponse.data?.pools.length > 0) { + const price: BestPrice = { + type: 'pool', + address: poolPriceResponse.data?.pools[0]?.id, + value: poolPriceResponse.data?.pools[0]?.spotPrice, + ocean: poolPriceResponse.data?.pools[0]?.oceanReserve, + datatoken: poolPriceResponse.data?.pools[0]?.datatokenReserve, + pools: [poolPriceResponse.data?.pools[0]?.id] + } + return price + } else if (frePriceResponse.data?.fixedRateExchanges.length > 0) { + const price: BestPrice = { + type: 'exchange', + value: frePriceResponse.data?.fixedRateExchanges[0]?.rate, + address: frePriceResponse.data?.fixedRateExchanges[0]?.id, + exchange_id: frePriceResponse.data?.fixedRateExchanges[0]?.id, + ocean: 0, + datatoken: 0, + pools: [] + } + return price + } else { + return null + } +} From 4aae5fe6c184e484ba03d44d4163be6140a43fc2 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Wed, 21 Apr 2021 13:00:30 +0300 Subject: [PATCH 02/22] removed price querry from compute --- .../organisms/AssetActions/Compute/index.tsx | 73 +------------------ 1 file changed, 3 insertions(+), 70 deletions(-) diff --git a/src/components/organisms/AssetActions/Compute/index.tsx b/src/components/organisms/AssetActions/Compute/index.tsx index 3286acb75..c716ab58b 100644 --- a/src/components/organisms/AssetActions/Compute/index.tsx +++ b/src/components/organisms/AssetActions/Compute/index.tsx @@ -3,7 +3,6 @@ import { DDO, File as FileMetadata, Logger, - ServiceType, publisherTrustedAlgorithm, BestPrice } from '@oceanprotocol/lib' @@ -34,11 +33,8 @@ import FormStartComputeDataset from './FormComputeDataset' import styles from './index.module.css' import SuccessConfetti from '../../../atoms/SuccessConfetti' import Button from '../../../atoms/Button' -import { gql, useQuery } from '@apollo/client' -import { FrePrice } from '../../../../@types/apollo/FrePrice' -import { PoolPrice } from '../../../../@types/apollo/PoolPrice' import { secondsToString } from '../../../../utils/metadata' -import { getPreviousOrders } from '../../../../utils/subgraph' +import { getPreviousOrders, getPrice } from '../../../../utils/subgraph' const SuccessAction = () => ( ) -const freQuery = gql` - query AlgorithmFrePrice($datatoken: String) { - fixedRateExchanges(orderBy: id, where: { datatoken: $datatoken }) { - rate - id - } - } -` -const poolQuery = gql` - query AlgorithmPoolPrice($datatoken: String) { - pools(where: { datatokenAddress: $datatoken }) { - spotPrice - } - } -` - export default function Compute({ isBalanceSufficient, dtBalance, @@ -91,7 +71,6 @@ export default function Compute({ ) const [algorithmDTBalance, setalgorithmDTBalance] = useState() const [algorithmPrice, setAlgorithmPrice] = useState() - const [variables, setVariables] = useState({}) const [ previousAlgorithmOrderId, setPreviousAlgorithmOrderId @@ -99,25 +78,6 @@ export default function Compute({ const [datasetTimeout, setDatasetTimeout] = useState() const [algorithmTimeout, setAlgorithmTimeout] = useState() - /* eslint-disable @typescript-eslint/no-unused-vars */ - const { - refetch: refetchFre, - startPolling: startPollingFre, - data: frePrice - } = useQuery(freQuery, { - variables, - skip: false - }) - const { - refetch: refetchPool, - startPolling: startPollingPool, - data: poolPrice - } = useQuery(poolQuery, { - variables, - skip: false - }) - /* eslint-enable @typescript-eslint/no-unused-vars */ - const isComputeButtonDisabled = isJobStarting === true || file === null || !ocean || !isBalanceSufficient const hasDatatoken = Number(dtBalance) >= 1 @@ -211,37 +171,10 @@ export default function Compute({ setDatasetTimeout(secondsToString(timeout)) }, [ddo]) - useEffect(() => { - if ( - !frePrice || - frePrice.fixedRateExchanges.length === 0 || - algorithmPrice.type !== 'exchange' - ) - return - setAlgorithmPrice((prevState) => ({ - ...prevState, - value: frePrice.fixedRateExchanges[0].rate, - address: frePrice.fixedRateExchanges[0].id - })) - }, [frePrice]) - - useEffect(() => { - if ( - !poolPrice || - poolPrice.pools.length === 0 || - algorithmPrice.type !== 'pool' - ) - return - setAlgorithmPrice((prevState) => ({ - ...prevState, - value: poolPrice.pools[0].spotPrice - })) - }, [poolPrice]) - const initMetadata = useCallback(async (ddo: DDO): Promise => { if (!ddo) return - setAlgorithmPrice(ddo.price) - setVariables({ datatoken: ddo?.dataToken.toLowerCase() }) + const price = await getPrice(ddo) + setAlgorithmPrice(price) }, []) useEffect(() => { From 0cef2cccd59c5ebe023a8fd301dc072fe24695b9 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Thu, 22 Apr 2021 14:03:58 +0300 Subject: [PATCH 03/22] update price value for pool assets using consumePrice and added isConsumable logic --- package-lock.json | 2 +- src/providers/Asset.tsx | 7 +------ src/utils/subgraph.ts | 27 +++++++++++++++++++++------ 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 81941ee59..cc1026ce2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18101,7 +18101,7 @@ } }, "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1a27c59c15ab1e95ee8e5c4ed6ad814c49cc439e", + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f", "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.11.8", diff --git a/src/providers/Asset.tsx b/src/providers/Asset.tsx index d6e947e57..548128f38 100644 --- a/src/providers/Asset.tsx +++ b/src/providers/Asset.tsx @@ -117,13 +117,8 @@ function AssetProvider({ const initMetadata = useCallback(async (ddo: DDO): Promise => { if (!ddo) return - // Set price & metadata from DDO first - // TODO Hacky hack, temporary™: set isConsumable to true by default since Aquarius can't be trusted. - // setPrice({ ...ddo.price, isConsumable: 'true' }) - const returnedPrice = await getPrice(ddo) - console.log('returnedPrice', returnedPrice) - setPrice({ ...returnedPrice, isConsumable: 'true' }) + setPrice({ ...returnedPrice }) // Get metadata from DDO const { attributes } = ddo.findServiceByType('metadata') diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index f07cfefb0..69c995eec 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -32,8 +32,9 @@ const AssetFreQuery = gql` const PoolQuery = gql` query AssetsPoolPrice($datatokenAddress_in: [String!]) { pools(where: { datatokenAddress_in: $datatokenAddress_in }) { - spotPrice id + spotPrice + consumePrice datatokenAddress } } @@ -44,9 +45,10 @@ const AssetPoolPriceQuerry = gql` pools(where: { datatokenAddress: $datatokenAddress }) { id spotPrice + consumePrice + datatokenAddress datatokenReserve oceanReserve - datatokenAddress } } ` @@ -127,7 +129,10 @@ export async function getAssetPrices(assets: DDO[]): Promise { } const poolPriceResponse: any = await fetchData(PoolQuery, poolVariables) for (const poolPrice of poolPriceResponse.data?.pools) { - priceList[didDTMap[poolPrice.datatokenAddress]] = poolPrice.spotPrice + priceList[didDTMap[poolPrice.datatokenAddress]] = + poolPrice.consumePrice === '-1' + ? poolPrice.spotPrice + : poolPrice.consumePrice } const frePriceResponse: any = await fetchData(FreQuery, freVariables) for (const frePrice of frePriceResponse.data?.fixedRateExchanges) { @@ -154,13 +159,22 @@ export async function getPrice(asset: DDO): Promise { const price: BestPrice = { type: 'pool', address: poolPriceResponse.data?.pools[0]?.id, - value: poolPriceResponse.data?.pools[0]?.spotPrice, + value: + poolPriceResponse.data?.pools[0]?.consumePrice === '-1' + ? poolPriceResponse.data?.pools[0]?.spotPrice + : poolPriceResponse.data?.pools[0]?.consumePrice, ocean: poolPriceResponse.data?.pools[0]?.oceanReserve, datatoken: poolPriceResponse.data?.pools[0]?.datatokenReserve, - pools: [poolPriceResponse.data?.pools[0]?.id] + pools: [poolPriceResponse.data?.pools[0]?.id], + isConsumable: + poolPriceResponse.data?.pools[0]?.consumePrice === '-1' + ? 'false' + : 'true' } return price } else if (frePriceResponse.data?.fixedRateExchanges.length > 0) { + // TODO Hacky hack, temporary™: set isConsumable to true for fre assets. + // isConsumable: 'true' const price: BestPrice = { type: 'exchange', value: frePriceResponse.data?.fixedRateExchanges[0]?.rate, @@ -168,7 +182,8 @@ export async function getPrice(asset: DDO): Promise { exchange_id: frePriceResponse.data?.fixedRateExchanges[0]?.id, ocean: 0, datatoken: 0, - pools: [] + pools: [], + isConsumable: 'true' } return price } else { From 1d02f53a06791b2d8442a9b277f3251d36e88715 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Fri, 23 Apr 2021 12:07:59 +0300 Subject: [PATCH 04/22] fixed no price set usecase --- src/utils/subgraph.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index 69c995eec..2c8998930 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -187,6 +187,16 @@ export async function getPrice(asset: DDO): Promise { } return price } else { - return null + const price: BestPrice = { + type: '', + value: 0, + address: '', + exchange_id: '', + ocean: 0, + datatoken: 0, + pools: [], + isConsumable: 'false' + } + return price } } From e73d14001294661341a195608bada441321a7130 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Fri, 7 May 2021 16:00:40 +0300 Subject: [PATCH 05/22] trigger check previous order after starting a compute job --- .../organisms/AssetActions/Compute/index.tsx | 6 +++++- src/utils/subgraph.ts | 12 ++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/organisms/AssetActions/Compute/index.tsx b/src/components/organisms/AssetActions/Compute/index.tsx index 06089e9de..9ced34559 100644 --- a/src/components/organisms/AssetActions/Compute/index.tsx +++ b/src/components/organisms/AssetActions/Compute/index.tsx @@ -136,6 +136,7 @@ export default function Compute({ timeout.toString() ) const assetType = ddo.findServiceByType('metadata').attributes.main.type + console.log('checkPreviousOrders asset ' + assetType + ' id= ', orderId) if (assetType === 'algorithm') { setPreviousAlgorithmOrderId(orderId) setHasPreviousAlgorithmOrder(!!orderId) @@ -430,7 +431,10 @@ export default function Compute({ Logger.log('[compute] Starting compute job response: ', response) - setHasPreviousDatasetOrder(true) + // setHasPreviousDatasetOrder(true) + // setHasPreviousAlgorithmOrder(true) + checkPreviousOrders(selectedAlgorithmAsset) + checkPreviousOrders(ddo) setIsPublished(true) } catch (error) { setError('Failed to start job!') diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index c424251ef..3edd20c82 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -75,14 +75,18 @@ export async function getPreviousOrders( variables ) if (fetchedPreviousOrders.data?.tokenOrders?.length === 0) return null + console.log('order fetchedPreviousOrders', fetchedPreviousOrders?.data) if (assetTimeout === '0') { return fetchedPreviousOrders?.data?.tokenOrders[0]?.tx } else { - const expiry = new BigNumber( + console.log( + 'order timestamp', fetchedPreviousOrders?.data?.tokenOrders[0]?.timestamp - ).plus(assetTimeout) - const unixTime = new BigNumber(Math.floor(Date.now() / 1000)) - if (unixTime.isLessThan(expiry)) { + ) + const expiry = + fetchedPreviousOrders?.data?.tokenOrders[0]?.timestamp * 1000 + + Number(assetTimeout) * 1000 + if (Date.now() <= expiry) { return fetchedPreviousOrders?.data?.tokenOrders[0]?.tx } else { return null From fadffb5d870ec6b258dcb3d4cd3594f222372b22 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Mon, 10 May 2021 15:35:49 +0300 Subject: [PATCH 06/22] added no cache fetch policy on appolo request and removed debug logs --- src/components/organisms/AssetActions/Compute/index.tsx | 7 ++----- src/utils/subgraph.ts | 8 ++------ 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/components/organisms/AssetActions/Compute/index.tsx b/src/components/organisms/AssetActions/Compute/index.tsx index 9ced34559..62c12d62b 100644 --- a/src/components/organisms/AssetActions/Compute/index.tsx +++ b/src/components/organisms/AssetActions/Compute/index.tsx @@ -136,7 +136,6 @@ export default function Compute({ timeout.toString() ) const assetType = ddo.findServiceByType('metadata').attributes.main.type - console.log('checkPreviousOrders asset ' + assetType + ' id= ', orderId) if (assetType === 'algorithm') { setPreviousAlgorithmOrderId(orderId) setHasPreviousAlgorithmOrder(!!orderId) @@ -431,10 +430,8 @@ export default function Compute({ Logger.log('[compute] Starting compute job response: ', response) - // setHasPreviousDatasetOrder(true) - // setHasPreviousAlgorithmOrder(true) - checkPreviousOrders(selectedAlgorithmAsset) - checkPreviousOrders(ddo) + await checkPreviousOrders(selectedAlgorithmAsset) + await checkPreviousOrders(ddo) setIsPublished(true) } catch (error) { setError('Failed to start job!') diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index 3edd20c82..05e16ef8b 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -53,7 +53,8 @@ async function fetchData( const client = getApolloClientInstance() const response = await client.query({ query: query, - variables: variables + variables: variables, + fetchPolicy: 'no-cache' }) return response } catch (error) { @@ -75,14 +76,9 @@ export async function getPreviousOrders( variables ) if (fetchedPreviousOrders.data?.tokenOrders?.length === 0) return null - console.log('order fetchedPreviousOrders', fetchedPreviousOrders?.data) if (assetTimeout === '0') { return fetchedPreviousOrders?.data?.tokenOrders[0]?.tx } else { - console.log( - 'order timestamp', - fetchedPreviousOrders?.data?.tokenOrders[0]?.timestamp - ) const expiry = fetchedPreviousOrders?.data?.tokenOrders[0]?.timestamp * 1000 + Number(assetTimeout) * 1000 From 574e4a02f15d64ef82253f5ba70bda72d7793932 Mon Sep 17 00:00:00 2001 From: Norbi <37236152+KatunaNorbert@users.noreply.github.com> Date: Tue, 11 May 2021 11:33:05 +0300 Subject: [PATCH 07/22] used price from useAsset instead of ddo (#590) Co-authored-by: Norbi --- src/components/organisms/AssetActions/index.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/organisms/AssetActions/index.tsx b/src/components/organisms/AssetActions/index.tsx index 41ac03ed5..967760a57 100644 --- a/src/components/organisms/AssetActions/index.tsx +++ b/src/components/organisms/AssetActions/index.tsx @@ -18,7 +18,6 @@ export default function AssetActions(): ReactElement { const [isBalanceSufficient, setIsBalanceSufficient] = useState() const [dtBalance, setDtBalance] = useState() - const isCompute = Boolean(ddo?.findServiceByType('compute')) // Get and set user DT balance @@ -74,10 +73,7 @@ export default function AssetActions(): ReactElement { } ] - // Check from metadata, cause that is available earlier - const hasPool = ddo?.price?.type === 'pool' - - hasPool && + price?.type === 'pool' && tabs.push( { title: 'Pool', From 5adf03c5f16849f383436c37e6721f3093fd283e Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Tue, 11 May 2021 16:09:16 +0300 Subject: [PATCH 08/22] added fetchPolicy no-cache on graph requests from subgraph.ts util --- src/utils/subgraph.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index 2c8998930..2cf0df0c2 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -75,7 +75,8 @@ async function fetchData( const client = getApolloClientInstance() const response = await client.query({ query: query, - variables: variables + variables: variables, + fetchPolicy: 'no-cache' }) return response } catch (error) { @@ -142,6 +143,7 @@ export async function getAssetPrices(assets: DDO[]): Promise { } export async function getPrice(asset: DDO): Promise { + console.log('get price', asset) const freVariables = { datatoken: asset?.dataToken.toLowerCase() } From 3dba118546643c9889f698946f7074026b3158f4 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Tue, 11 May 2021 16:15:35 +0300 Subject: [PATCH 09/22] remove unnecessary console log --- src/utils/subgraph.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index 2cf0df0c2..9f5ede40c 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -143,7 +143,6 @@ export async function getAssetPrices(assets: DDO[]): Promise { } export async function getPrice(asset: DDO): Promise { - console.log('get price', asset) const freVariables = { datatoken: asset?.dataToken.toLowerCase() } From 82acbba5ce364f5904b2f57b8cbd4cddd22b5956 Mon Sep 17 00:00:00 2001 From: claudiaHash <49017601+claudiaHash@users.noreply.github.com> Date: Mon, 17 May 2021 16:14:40 +0300 Subject: [PATCH 10/22] Remove price from queries (#600) * subgraph query added * return ddo list * price queries removed from sorting and filtering * subgraph query added return ddo list price queries removed from sorting and filtering * subgraph query removed * removed unused subgraph query * undo subgraph fetchData change * linting errors fixed * files renamed, priceType removed * removed unused imports and vars * removed all price filter variables Co-authored-by: claudia.holhos --- .../templates/Search/filterPrice.tsx | 188 ------------------ ...ce.module.css => filterService.module.css} | 0 .../templates/Search/filterService.tsx | 108 ++++++++++ src/components/templates/Search/index.tsx | 21 +- src/components/templates/Search/sort.tsx | 21 +- src/components/templates/Search/utils.ts | 45 +---- 6 files changed, 119 insertions(+), 264 deletions(-) delete mode 100644 src/components/templates/Search/filterPrice.tsx rename src/components/templates/Search/{filterPrice.module.css => filterService.module.css} (100%) create mode 100644 src/components/templates/Search/filterService.tsx diff --git a/src/components/templates/Search/filterPrice.tsx b/src/components/templates/Search/filterPrice.tsx deleted file mode 100644 index d722bdc01..000000000 --- a/src/components/templates/Search/filterPrice.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import React, { ReactElement, useEffect, useState } from 'react' -import { useNavigate } from '@reach/router' -import styles from './filterPrice.module.css' -import classNames from 'classnames/bind' -import { - addExistingParamsToUrl, - FilterByPriceOptions, - FilterByTypeOptions -} from './utils' -import Button from '../../atoms/Button' - -const cx = classNames.bind(styles) - -const clearFilters = [{ display: 'Clear', value: '' }] - -const priceFilterItems = [ - { display: 'fixed price', value: FilterByPriceOptions.Fixed }, - { display: 'dynamic price', value: FilterByPriceOptions.Dynamic } -] - -const serviceFilterItems = [ - { display: 'data sets', value: FilterByTypeOptions.Data }, - { display: 'algorithms', value: FilterByTypeOptions.Algorithm } -] - -export default function FilterPrice({ - priceType, - serviceType, - setPriceType, - setServiceType -}: { - priceType: string - setPriceType: React.Dispatch> - serviceType: string - setServiceType: React.Dispatch> -}): ReactElement { - const navigate = useNavigate() - - const [priceSelections, setPriceSelections] = useState([]) - const [serviceSelections, setServiceSelections] = useState([]) - - async function applyPriceFilter(filterBy: string) { - let urlLocation = await addExistingParamsToUrl(location, 'priceType') - if (filterBy) { - urlLocation = `${urlLocation}&priceType=${filterBy}` - } - setPriceType(filterBy) - navigate(urlLocation) - } - - async function applyServiceFilter(filterBy: string) { - let urlLocation = await addExistingParamsToUrl(location, 'serviceType') - if (filterBy && location.search.indexOf('&serviceType') === -1) { - urlLocation = `${urlLocation}&serviceType=${filterBy}` - } - setServiceType(filterBy) - navigate(urlLocation) - } - - async function handleSelectedFilter(isSelected: boolean, value: string) { - if ( - value === FilterByPriceOptions.Fixed || - value === FilterByPriceOptions.Dynamic - ) { - if (isSelected) { - if (priceSelections.length > 1) { - // both selected -> select the other one - const otherValue = priceFilterItems.find((p) => p.value !== value) - .value - await applyPriceFilter(otherValue) - } else { - // only the current one selected -> deselect it - await applyPriceFilter(undefined) - } - } else { - if (priceSelections.length > 0) { - // one already selected -> both selected - await applyPriceFilter(FilterByPriceOptions.All) - setPriceSelections(priceFilterItems.map((p) => p.value)) - } else { - // none selected -> select - await applyPriceFilter(value) - setPriceSelections([value]) - } - } - } else { - if (isSelected) { - if (serviceSelections.length > 1) { - const otherValue = serviceFilterItems.find((p) => p.value !== value) - .value - await applyServiceFilter(otherValue) - setServiceSelections([otherValue]) - } else { - await applyServiceFilter(undefined) - } - } else { - if (serviceSelections.length) { - await applyServiceFilter(undefined) - setServiceSelections(serviceFilterItems.map((p) => p.value)) - } else { - await applyServiceFilter(value) - setServiceSelections([value]) - } - } - } - } - - async function applyClearFilter() { - let urlLocation = await addExistingParamsToUrl( - location, - 'priceType', - 'serviceType' - ) - - urlLocation = `${urlLocation}` - - setServiceSelections([]) - setPriceSelections([]) - - setPriceType(undefined) - setServiceType(undefined) - navigate(urlLocation) - } - - return ( -
- {priceFilterItems.map((e, index) => { - const isPriceSelected = - e.value === priceType || priceSelections.includes(e.value) - const selectFilter = cx({ - [styles.selected]: isPriceSelected, - [styles.filter]: true - }) - return ( - - ) - })} - {serviceFilterItems.map((e, index) => { - const isServiceSelected = - e.value === serviceType || serviceSelections.includes(e.value) - const selectFilter = cx({ - [styles.selected]: isServiceSelected, - [styles.filter]: true - }) - return ( - - ) - })} - {clearFilters.map((e, index) => { - const showClear = - priceSelections.length > 0 || serviceSelections.length > 0 - return ( - - ) - })} -
- ) -} diff --git a/src/components/templates/Search/filterPrice.module.css b/src/components/templates/Search/filterService.module.css similarity index 100% rename from src/components/templates/Search/filterPrice.module.css rename to src/components/templates/Search/filterService.module.css diff --git a/src/components/templates/Search/filterService.tsx b/src/components/templates/Search/filterService.tsx new file mode 100644 index 000000000..11718b57e --- /dev/null +++ b/src/components/templates/Search/filterService.tsx @@ -0,0 +1,108 @@ +import React, { ReactElement, useState } from 'react' +import { useNavigate } from '@reach/router' +import styles from './filterService.module.css' +import classNames from 'classnames/bind' +import { addExistingParamsToUrl, FilterByTypeOptions } from './utils' +import Button from '../../atoms/Button' + +const cx = classNames.bind(styles) + +const clearFilters = [{ display: 'Clear', value: '' }] + +const serviceFilterItems = [ + { display: 'data sets', value: FilterByTypeOptions.Data }, + { display: 'algorithms', value: FilterByTypeOptions.Algorithm } +] + +export default function FilterPrice({ + serviceType, + setServiceType +}: { + serviceType: string + setServiceType: React.Dispatch> +}): ReactElement { + const navigate = useNavigate() + const [serviceSelections, setServiceSelections] = useState([]) + + async function applyServiceFilter(filterBy: string) { + let urlLocation = await addExistingParamsToUrl(location, 'serviceType') + if (filterBy && location.search.indexOf('&serviceType') === -1) { + urlLocation = `${urlLocation}&serviceType=${filterBy}` + } + setServiceType(filterBy) + navigate(urlLocation) + } + + async function handleSelectedFilter(isSelected: boolean, value: string) { + if (isSelected) { + if (serviceSelections.length > 1) { + const otherValue = serviceFilterItems.find((p) => p.value !== value) + .value + await applyServiceFilter(otherValue) + setServiceSelections([otherValue]) + } else { + await applyServiceFilter(undefined) + } + } else { + if (serviceSelections.length) { + await applyServiceFilter(undefined) + setServiceSelections(serviceFilterItems.map((p) => p.value)) + } else { + await applyServiceFilter(value) + setServiceSelections([value]) + } + } + } + + async function applyClearFilter() { + let urlLocation = await addExistingParamsToUrl(location, 'serviceType') + + urlLocation = `${urlLocation}` + + setServiceSelections([]) + setServiceType(undefined) + navigate(urlLocation) + } + + return ( +
+ {serviceFilterItems.map((e, index) => { + const isServiceSelected = + e.value === serviceType || serviceSelections.includes(e.value) + const selectFilter = cx({ + [styles.selected]: isServiceSelected, + [styles.filter]: true + }) + return ( + + ) + })} + {clearFilters.map((e, index) => { + const showClear = serviceSelections.length > 0 + return ( + + ) + })} +
+ ) +} diff --git a/src/components/templates/Search/index.tsx b/src/components/templates/Search/index.tsx index 16938a70a..0e4697d9a 100644 --- a/src/components/templates/Search/index.tsx +++ b/src/components/templates/Search/index.tsx @@ -4,7 +4,7 @@ import SearchBar from '../../molecules/SearchBar' import AssetList from '../../organisms/AssetList' import styles from './index.module.css' import queryString from 'query-string' -import PriceFilter from './filterPrice' +import ServiceFilter from './filterService' import Sort from './sort' import { getResults } from './utils' import { navigate } from 'gatsby' @@ -21,19 +21,9 @@ export default function SearchPage({ }): ReactElement { const { config } = useOcean() const parsed = queryString.parse(location.search) - const { - text, - owner, - tags, - page, - sort, - sortOrder, - priceType, - serviceType - } = parsed + const { text, owner, tags, page, sort, sortOrder, serviceType } = parsed const [queryResult, setQueryResult] = useState() const [loading, setLoading] = useState() - const [price, setPriceType] = useState(priceType as string) const [service, setServiceType] = useState(serviceType as string) const [sortType, setSortType] = useState(sort as string) const [sortDirection, setSortDirection] = useState( @@ -58,7 +48,6 @@ export default function SearchPage({ tags, sort, page, - priceType, serviceType, sortOrder, config.metadataCacheUri @@ -80,10 +69,8 @@ export default function SearchPage({ )}
-
diff --git a/src/components/templates/Search/sort.tsx b/src/components/templates/Search/sort.tsx index 908937dbf..41f2c67d1 100644 --- a/src/components/templates/Search/sort.tsx +++ b/src/components/templates/Search/sort.tsx @@ -3,9 +3,7 @@ import { useNavigate } from '@reach/router' import { addExistingParamsToUrl, SortTermOptions, - SortValueOptions, - FilterByPriceOptions, - FilterByTypeOptions + SortValueOptions } from './utils' import Button from '../../atoms/Button' import styles from './sort.module.css' @@ -13,26 +11,18 @@ import classNames from 'classnames/bind' const cx = classNames.bind(styles) -const sortItems = [ - { display: 'Published', value: SortTermOptions.Created }, - { display: 'Liquidity', value: SortTermOptions.Liquidity }, - { display: 'Price', value: SortTermOptions.Price } -] +const sortItems = [{ display: 'Published', value: SortTermOptions.Created }] export default function Sort({ sortType, setSortType, sortDirection, - setSortDirection, - setPriceType, - setServiceType + setSortDirection }: { sortType: string setSortType: React.Dispatch> sortDirection: string setSortDirection: React.Dispatch> - setPriceType: React.Dispatch> - setServiceType: React.Dispatch> }): ReactElement { const navigate = useNavigate() const directionArrow = String.fromCharCode( @@ -41,12 +31,7 @@ export default function Sort({ async function sortResults(sortBy?: string, direction?: string) { let urlLocation: string if (sortBy) { - urlLocation = await addExistingParamsToUrl(location, 'sort', 'priceType') urlLocation = `${urlLocation}&sort=${sortBy}` - if (sortBy === SortTermOptions.Liquidity) { - urlLocation = `${urlLocation}&priceType=${FilterByPriceOptions.Dynamic}` - setPriceType(FilterByPriceOptions.Dynamic) - } setSortType(sortBy) } else if (direction) { urlLocation = await addExistingParamsToUrl(location, 'sortOrder') diff --git a/src/components/templates/Search/utils.ts b/src/components/templates/Search/utils.ts index dbc1f9b7f..c7fdda6bf 100644 --- a/src/components/templates/Search/utils.ts +++ b/src/components/templates/Search/utils.ts @@ -6,8 +6,6 @@ import { MetadataCache, Logger } from '@oceanprotocol/lib' import queryString from 'query-string' export const SortTermOptions = { - Liquidity: 'liquidity', - Price: 'price', Created: 'created' } as const type SortTermOptions = typeof SortTermOptions[keyof typeof SortTermOptions] @@ -25,36 +23,12 @@ export const SortValueOptions = { } as const type SortValueOptions = typeof SortValueOptions[keyof typeof SortValueOptions] -export const FilterByPriceOptions = { - Fixed: 'exchange', - Dynamic: 'pool', - All: 'all' -} as const -type FilterByPriceOptions = typeof FilterByPriceOptions[keyof typeof FilterByPriceOptions] - export const FilterByTypeOptions = { Data: 'dataset', Algorithm: 'algorithm' } as const type FilterByTypeOptions = typeof FilterByTypeOptions[keyof typeof FilterByTypeOptions] -function addPriceFilterToQuery(sortTerm: string, priceFilter: string): string { - if (priceFilter === FilterByPriceOptions.All) { - sortTerm = priceFilter - ? sortTerm === '' - ? `(price.type:${FilterByPriceOptions.Fixed} OR price.type:${FilterByPriceOptions.Dynamic})` - : `${sortTerm} AND (price.type:${FilterByPriceOptions.Dynamic} OR price.type:${FilterByPriceOptions.Fixed})` - : sortTerm - } else { - sortTerm = priceFilter - ? sortTerm === '' - ? `price.type:${priceFilter}` - : `${sortTerm} AND price.type:${priceFilter}` - : sortTerm - } - return sortTerm -} - function addTypeFilterToQuery(sortTerm: string, typeFilter: string): string { sortTerm = typeFilter ? sortTerm === '' @@ -64,13 +38,8 @@ function addTypeFilterToQuery(sortTerm: string, typeFilter: string): string { return sortTerm } -function getSortType(sortParam: string): string { - const sortTerm = - sortParam === SortTermOptions.Liquidity - ? SortElasticTerm.Liquidity - : sortParam === SortTermOptions.Price - ? SortElasticTerm.Price - : SortTermOptions.Created +function getSortType(): string { + const sortTerm = SortTermOptions.Created return sortTerm } @@ -83,10 +52,9 @@ export function getSearchQuery( offset?: string, sort?: string, sortOrder?: string, - priceType?: string, serviceType?: string ): SearchQuery { - const sortTerm = getSortType(sort) + const sortTerm = getSortType() const sortValue = sortOrder === SortValueOptions.Ascending ? 1 : -1 let searchTerm = owner ? `(publicKey.owner:${owner})` @@ -98,7 +66,6 @@ export function getSearchQuery( `(service.attributes.additionalInformation.categories:\"${categories}\")` : text || '' searchTerm = addTypeFilterToQuery(searchTerm, serviceType) - searchTerm = addPriceFilterToQuery(searchTerm, priceType) return { page: Number(page) || 1, @@ -136,7 +103,6 @@ export async function getResults( offset?: string sort?: string sortOrder?: string - priceType?: string serviceType?: string }, metadataCacheUri: string @@ -150,10 +116,10 @@ export async function getResults( categories, sort, sortOrder, - priceType, serviceType } = params const metadataCache = new MetadataCache(metadataCacheUri, Logger) + const searchQuery = getSearchQuery( text, owner, @@ -163,11 +129,10 @@ export async function getResults( offset, sort, sortOrder, - priceType, serviceType ) - const queryResult = await metadataCache.queryMetadata(searchQuery) + const queryResult = await metadataCache.queryMetadata(searchQuery) return queryResult } From f0ed9f68cb5954be17296373ecdb22e268f1c287 Mon Sep 17 00:00:00 2001 From: Norbi <37236152+KatunaNorbert@users.noreply.github.com> Date: Mon, 17 May 2021 16:32:01 +0300 Subject: [PATCH 11/22] Add new custom form field for single value selection (#504) * created BoxSelection component * wip * design changes * integrate with form * refactoring * used inside appearance component * WIP, added space between options * adde new fields to BoxSelection used for chain selection * fixed errors * removed access type option from publish.json * updated component for chain selection * updated for compute type on publish dataset * added component to dockerImageOpions * removed Dotdotdot component from options * remove space * styling updates, fix React warning for terms checkbox Co-authored-by: Norbi Co-authored-by: Matthias Kretschmann --- content/pages/publish/form-algorithm.json | 4 +- content/pages/publish/form-dataset.json | 2 +- src/components/atoms/Input/InputElement.tsx | 14 +++- .../FormFields/BoxSelection.module.css | 57 +++++++++++++++ .../molecules/FormFields/BoxSelection.tsx | 70 +++++++++++++++++++ .../UserPreferences/Appearance.module.css | 4 ++ .../molecules/UserPreferences/Appearance.tsx | 56 ++++++++------- .../UserPreferences/Chain.module.css | 11 +++ .../molecules/UserPreferences/Chain.tsx | 61 ++++++++-------- .../pages/Publish/FormAlgoPublish.tsx | 24 ++++++- src/components/pages/Publish/FormPublish.tsx | 18 +++++ 11 files changed, 261 insertions(+), 60 deletions(-) create mode 100644 src/components/molecules/FormFields/BoxSelection.module.css create mode 100644 src/components/molecules/FormFields/BoxSelection.tsx diff --git a/content/pages/publish/form-algorithm.json b/content/pages/publish/form-algorithm.json index 0a91c3b04..d5839527f 100644 --- a/content/pages/publish/form-algorithm.json +++ b/content/pages/publish/form-algorithm.json @@ -28,8 +28,8 @@ "label": "Docker Image", "placeholder": "e.g. python3.7", "help": "Please select an image to run your algorithm.", - "type": "select", - "options": ["node:latest", "python:latest", "custom image"], + "type": "boxSelection", + "options": [], "required": true }, { diff --git a/content/pages/publish/form-dataset.json b/content/pages/publish/form-dataset.json index 3b3a67b58..847ee53ef 100644 --- a/content/pages/publish/form-dataset.json +++ b/content/pages/publish/form-dataset.json @@ -34,7 +34,7 @@ "name": "access", "label": "Access Type", "help": "Choose how you want your files to be accessible for the specified price.", - "type": "select", + "type": "boxSelection", "options": ["Download", "Compute"], "required": true }, diff --git a/src/components/atoms/Input/InputElement.tsx b/src/components/atoms/Input/InputElement.tsx index 89a67a658..8e0e83c8a 100644 --- a/src/components/atoms/Input/InputElement.tsx +++ b/src/components/atoms/Input/InputElement.tsx @@ -4,6 +4,9 @@ import styles from './InputElement.module.css' import { InputProps } from '.' import FilesInput from '../../molecules/FormFields/FilesInput' import Terms from '../../molecules/FormFields/Terms' +import BoxSelection, { + BoxSelectionOption +} from '../../molecules/FormFields/BoxSelection' import Datatoken from '../../molecules/FormFields/Datatoken' import classNames from 'classnames/bind' import AssetSelection, { @@ -91,7 +94,7 @@ export default function InputElement({ id={slugify(option)} type={type} name={name} - checked={props.defaultChecked} + defaultChecked={props.defaultChecked} {...props} />