Merge branch 'v4' into feature/v4-c2d and fix conflicts
@ -1,9 +1,8 @@
|
||||
{
|
||||
"siteTitle": "Ocean Market",
|
||||
"siteTagline": "A marketplace to find, publish and trade data sets in the Ocean Network.",
|
||||
"siteUrl": "https://market.oceanprotocol.com",
|
||||
"siteIcon": "node_modules/@oceanprotocol/art/logo/favicon-white.png",
|
||||
"siteImage": "../src/@images/share.png",
|
||||
"siteUrl": "https://v4.market.oceanprotocol.com",
|
||||
"siteImage": "/share.png",
|
||||
"copyright": "All Rights Reserved. Powered by [Ocean Protocol](https://oceanprotocol.com)",
|
||||
"menu": [
|
||||
{
|
||||
|
2
package-lock.json
generated
@ -26715,6 +26715,7 @@
|
||||
"cross-fetch": "^3.1.5",
|
||||
"crypto-js": "^4.1.1",
|
||||
"decimal.js": "^10.3.1",
|
||||
"web3": "^1.7.1",
|
||||
"web3-core": "^1.7.1",
|
||||
"web3-eth-contract": "^1.7.1"
|
||||
}
|
||||
@ -26817,6 +26818,7 @@
|
||||
"integrity": "sha512-5vwpq6kbvwkQwKqAoOU3L72GZ3Ta8RRrewKj9OJRolx28KLJJ8Dg9Rf7obRwt5jQA9bkYd8gqzMTrI7H3xLfaw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@oclif/config": "^1.15.1",
|
||||
"@oclif/errors": "^1.3.3",
|
||||
"@oclif/parser": "^3.8.3",
|
||||
"@oclif/plugin-help": "^3",
|
||||
|
BIN
public/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
public/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
public/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
1
public/icon.svg
Normal file
After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
14
public/site.webmanifest
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
@ -2,7 +2,6 @@ export interface UseSiteMetadata {
|
||||
siteTitle: string
|
||||
siteTagline: string
|
||||
siteUrl: string
|
||||
siteIcon: string
|
||||
siteImage: string
|
||||
copyright: string
|
||||
menu: {
|
||||
|
@ -4,6 +4,7 @@ import { randomIntFromInterval } from './numbers'
|
||||
export interface WaveProperties {
|
||||
width?: number
|
||||
height?: number
|
||||
viewBox?: string
|
||||
color?: string
|
||||
fill?: boolean
|
||||
layerCount?: number
|
||||
@ -53,6 +54,7 @@ export class SvgWaves {
|
||||
return {
|
||||
width: 99,
|
||||
height: 99,
|
||||
viewBox: '0 0 99 99',
|
||||
color: WaveColors.Pink,
|
||||
fill: true,
|
||||
layerCount: 4,
|
||||
@ -107,8 +109,7 @@ export class SvgWaves {
|
||||
|
||||
generateSvg(): Element {
|
||||
const svg = document.createElementNS(SvgWaves.xmlns, 'svg')
|
||||
svg.setAttribute('width', this.properties.width.toString())
|
||||
svg.setAttribute('height', this.properties.height.toString())
|
||||
svg.setAttribute('viewBox', this.properties.viewBox.toString())
|
||||
svg.setAttribute('fill', this.properties.fill ? undefined : 'transparent')
|
||||
svg.setAttribute('xmlns', SvgWaves.xmlns)
|
||||
|
||||
|
@ -11,13 +11,6 @@ export function getOrderFeedback(
|
||||
}
|
||||
}
|
||||
|
||||
export function getCollectTokensFeedback(
|
||||
baseTokenSymbol: string,
|
||||
baseTokenBalance: string
|
||||
) {
|
||||
return `Collecting ${baseTokenBalance} ${baseTokenSymbol} from asset `
|
||||
}
|
||||
|
||||
export function getComputeFeedback(
|
||||
baseTokenSymbol?: string,
|
||||
datatokenSymbol?: string,
|
||||
|
@ -4,7 +4,7 @@ import styles from './index.module.css'
|
||||
import Loader from '../atoms/Loader'
|
||||
|
||||
interface ButtonBuyProps {
|
||||
action: 'download' | 'compute' | 'collect'
|
||||
action: 'download' | 'compute'
|
||||
disabled: boolean
|
||||
hasPreviousOrder: boolean
|
||||
hasDatatoken: boolean
|
||||
@ -148,8 +148,6 @@ export default function ButtonBuy({
|
||||
? 'Start Compute Job'
|
||||
: priceType === 'free' && algorithmPriceType === 'free'
|
||||
? 'Order Compute Job'
|
||||
: action === 'collect'
|
||||
? `Collect ${dtBalance} ${dtSymbol}`
|
||||
: `Buy Compute Job`
|
||||
|
||||
return (
|
||||
|
@ -17,24 +17,35 @@ export default function Seo({
|
||||
// Remove trailing slash from all URLs
|
||||
const canonical = `${siteUrl}${uri}`.replace(/\/$/, '')
|
||||
|
||||
const pageTitle = title
|
||||
? `${title} - ${siteTitle}`
|
||||
: `${siteTitle} — ${siteTagline}`
|
||||
|
||||
return (
|
||||
<Head>
|
||||
<html lang="en" />
|
||||
|
||||
<title>{`${siteTitle} — ${siteTagline}`}</title>
|
||||
<title>{pageTitle}</title>
|
||||
|
||||
{isBrowser &&
|
||||
window.location &&
|
||||
window.location.hostname !== 'oceanprotocol.com' && (
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
)}
|
||||
{isBrowser && window?.location?.hostname !== 'oceanprotocol.com' && (
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
)}
|
||||
|
||||
<link rel="canonical" href={canonical} />
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/apple-touch-icon.png"
|
||||
/>
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<meta name="theme-color" content="var(--background-content)" />
|
||||
|
||||
<meta name="description" content={description} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:url" content={uri} />
|
||||
<meta property="og:url" content={canonical} />
|
||||
|
||||
<meta name="image" content={`${siteUrl}${siteImage}`} />
|
||||
<meta property="og:image" content={`${siteUrl}${siteImage}`} />
|
||||
|
@ -16,10 +16,3 @@
|
||||
width: 100%;
|
||||
margin-top: calc(var(--spacer));
|
||||
}
|
||||
|
||||
.collect {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
margin-top: calc(var(--spacer) / 2);
|
||||
}
|
||||
|
@ -7,37 +7,16 @@ import ButtonBuy from '@shared/ButtonBuy'
|
||||
import { secondsToString } from '@utils/ddo'
|
||||
import AlgorithmDatasetsListForCompute from './Compute/AlgorithmDatasetsListForCompute'
|
||||
import styles from './Download.module.css'
|
||||
import {
|
||||
FileMetadata,
|
||||
LoggerInstance,
|
||||
ZERO_ADDRESS,
|
||||
FixedRateExchange
|
||||
} from '@oceanprotocol/lib'
|
||||
import { FileMetadata, LoggerInstance, ZERO_ADDRESS } from '@oceanprotocol/lib'
|
||||
import { order } from '@utils/order'
|
||||
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||
import { buyDtFromPool } from '@utils/pool'
|
||||
import { downloadFile } from '@utils/provider'
|
||||
import { getCollectTokensFeedback, getOrderFeedback } from '@utils/feedback'
|
||||
import { getOrderFeedback } from '@utils/feedback'
|
||||
import { getOrderPriceAndFees } from '@utils/accessDetailsAndPricing'
|
||||
import { OrderPriceAndFees } from 'src/@types/Price'
|
||||
import { toast } from 'react-toastify'
|
||||
import { gql, OperationResult } from 'urql'
|
||||
import { fetchData, getQueryContext } from '@utils/subgraph'
|
||||
import { getOceanConfig } from '@utils/ocean'
|
||||
import { FixedRateExchanges } from 'src/@types/subgraph/FixedRateExchanges'
|
||||
|
||||
const FixedRateExchangesQuery = gql`
|
||||
query FixedRateExchanges($user: String, $exchangeId: String) {
|
||||
fixedRateExchanges(where: { owner: $user, exchangeId: $exchangeId }) {
|
||||
id
|
||||
owner {
|
||||
id
|
||||
}
|
||||
exchangeId
|
||||
baseTokenBalance
|
||||
}
|
||||
}
|
||||
`
|
||||
export default function Download({
|
||||
asset,
|
||||
file,
|
||||
@ -61,9 +40,7 @@ export default function Download({
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [isOwned, setIsOwned] = useState(false)
|
||||
const [validOrderTx, setValidOrderTx] = useState('')
|
||||
const [isCollectLoading, setIsCollectLoading] = useState(false)
|
||||
const [baseTokenBalance, setBaseTokenBalance] = useState(0)
|
||||
const [collectStatusText, setCollectStatusText] = useState('')
|
||||
|
||||
const [orderPriceAndFees, setOrderPriceAndFees] =
|
||||
useState<OrderPriceAndFees>()
|
||||
useEffect(() => {
|
||||
@ -108,41 +85,19 @@ export default function Download({
|
||||
isOwned
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
if (!accountId || asset.nft.owner !== accountId) return
|
||||
const queryContext = getQueryContext(Number(asset.chainId))
|
||||
|
||||
async function getBaseTokenBalance() {
|
||||
const variables = {
|
||||
user: accountId.toLowerCase(),
|
||||
exchangeId: asset?.accessDetails?.addressOrId
|
||||
}
|
||||
const result: OperationResult<FixedRateExchanges> = await fetchData(
|
||||
FixedRateExchangesQuery,
|
||||
variables,
|
||||
queryContext
|
||||
)
|
||||
result?.data?.fixedRateExchanges[0]?.baseTokenBalance
|
||||
? setBaseTokenBalance(
|
||||
parseInt(result?.data?.fixedRateExchanges[0]?.baseTokenBalance)
|
||||
)
|
||||
: setBaseTokenBalance(0)
|
||||
}
|
||||
getBaseTokenBalance()
|
||||
}, [accountId, asset?.accessDetails?.addressOrId, asset.chainId, asset.nft])
|
||||
|
||||
async function handleOrderOrDownload() {
|
||||
setIsLoading(true)
|
||||
if (isOwned) {
|
||||
setStatusText(
|
||||
getOrderFeedback(
|
||||
asset.accessDetails?.baseToken?.symbol,
|
||||
asset.accessDetails?.datatoken?.symbol
|
||||
)[3]
|
||||
)
|
||||
await downloadFile(web3, asset, accountId, validOrderTx)
|
||||
} else {
|
||||
try {
|
||||
try {
|
||||
if (isOwned) {
|
||||
setStatusText(
|
||||
getOrderFeedback(
|
||||
asset.accessDetails?.baseToken?.symbol,
|
||||
asset.accessDetails?.datatoken?.symbol
|
||||
)[3]
|
||||
)
|
||||
|
||||
await downloadFile(web3, asset, accountId, validOrderTx)
|
||||
} else {
|
||||
if (!hasDatatoken && asset.accessDetails.type === 'dynamic') {
|
||||
setStatusText(
|
||||
getOrderFeedback(
|
||||
@ -152,9 +107,7 @@ export default function Download({
|
||||
)
|
||||
const tx = await buyDtFromPool(asset.accessDetails, accountId, web3)
|
||||
if (!tx) {
|
||||
toast.error('Failed to buy datatoken from pool!')
|
||||
setIsLoading(false)
|
||||
return
|
||||
throw new Error()
|
||||
}
|
||||
}
|
||||
setStatusText(
|
||||
@ -165,51 +118,19 @@ export default function Download({
|
||||
)
|
||||
const orderTx = await order(web3, asset, orderPriceAndFees, accountId)
|
||||
if (!orderTx) {
|
||||
toast.error('Failed to buy datatoken from pool!')
|
||||
setIsLoading(false)
|
||||
return
|
||||
throw new Error()
|
||||
}
|
||||
setIsOwned(true)
|
||||
setValidOrderTx(orderTx.transactionHash)
|
||||
} catch (ex) {
|
||||
LoggerInstance.log(ex.message)
|
||||
setIsLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
setIsLoading(false)
|
||||
}
|
||||
|
||||
async function handleCollectTokens() {
|
||||
setIsCollectLoading(true)
|
||||
const config = getOceanConfig(asset?.chainId)
|
||||
const fixed = new FixedRateExchange(web3, config.fixedRateExchangeAddress)
|
||||
try {
|
||||
setCollectStatusText(
|
||||
getCollectTokensFeedback(
|
||||
asset.accessDetails.baseToken?.symbol,
|
||||
baseTokenBalance.toString()
|
||||
)
|
||||
)
|
||||
|
||||
const tx = await fixed.collectBT(
|
||||
accountId,
|
||||
asset?.accessDetails?.addressOrId,
|
||||
baseTokenBalance.toString()
|
||||
)
|
||||
|
||||
if (!tx) {
|
||||
setIsCollectLoading(false)
|
||||
return
|
||||
}
|
||||
setBaseTokenBalance(0)
|
||||
return tx
|
||||
} catch (error) {
|
||||
LoggerInstance.log(error.message)
|
||||
setIsCollectLoading(false)
|
||||
} finally {
|
||||
setIsCollectLoading(false)
|
||||
LoggerInstance.error(error)
|
||||
const message = isOwned
|
||||
? 'Failed to download file!'
|
||||
: 'Failed to buy datatoken from pool!'
|
||||
toast.error(message)
|
||||
}
|
||||
setIsLoading(false)
|
||||
}
|
||||
|
||||
const PurchaseButton = () => (
|
||||
@ -234,26 +155,6 @@ export default function Download({
|
||||
/>
|
||||
)
|
||||
|
||||
const CollectTokensButton = () => (
|
||||
<ButtonBuy
|
||||
action="collect"
|
||||
onClick={handleCollectTokens}
|
||||
disabled={baseTokenBalance === 0 || !baseTokenBalance}
|
||||
hasPreviousOrder={false}
|
||||
hasDatatoken={false}
|
||||
dtSymbol={asset?.accessDetails?.baseToken.symbol}
|
||||
dtBalance={baseTokenBalance.toString()}
|
||||
datasetLowPoolLiquidity={false}
|
||||
assetType=""
|
||||
stepText={collectStatusText}
|
||||
assetTimeout=""
|
||||
isConsumable={false}
|
||||
consumableFeedback=""
|
||||
isBalanceSufficient={false}
|
||||
isLoading={isCollectLoading}
|
||||
/>
|
||||
)
|
||||
|
||||
return (
|
||||
<aside className={styles.consume}>
|
||||
<div className={styles.info}>
|
||||
@ -271,13 +172,6 @@ export default function Download({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{asset?.accessDetails?.datatoken?.name !== '' &&
|
||||
asset?.nft.owner === accountId && (
|
||||
<div className={styles.collect}>
|
||||
<CollectTokensButton />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{asset?.metadata?.type === 'algorithm' && (
|
||||
<AlgorithmDatasetsListForCompute
|
||||
algorithmDid={asset.id}
|
||||
|
@ -6,11 +6,13 @@ import ExplorerLink from '@shared/ExplorerLink'
|
||||
import SuccessConfetti from '@shared/SuccessConfetti'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import TokenApproval from '@shared/TokenApproval'
|
||||
import Decimal from 'decimal.js'
|
||||
|
||||
export default function Actions({
|
||||
isLoading,
|
||||
loaderMessage,
|
||||
successMessage,
|
||||
slippage,
|
||||
txId,
|
||||
actionName,
|
||||
amount,
|
||||
@ -23,6 +25,7 @@ export default function Actions({
|
||||
isLoading: boolean
|
||||
loaderMessage: string
|
||||
successMessage: string
|
||||
slippage?: string
|
||||
txId: string
|
||||
actionName: string
|
||||
amount?: string
|
||||
@ -45,6 +48,18 @@ export default function Actions({
|
||||
</Button>
|
||||
)
|
||||
|
||||
const applySlippage = (amount: string) => {
|
||||
if (!amount) return '0'
|
||||
const newAmount = new Decimal(amount)
|
||||
.mul(
|
||||
new Decimal(1)
|
||||
.plus(new Decimal(slippage).div(new Decimal(100)))
|
||||
.toString()
|
||||
)
|
||||
.toString()
|
||||
return newAmount
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.actions}>
|
||||
@ -53,7 +68,7 @@ export default function Actions({
|
||||
) : actionName === 'Supply' || actionName === 'Swap' ? (
|
||||
<TokenApproval
|
||||
actionButton={actionButton}
|
||||
amount={amount}
|
||||
amount={slippage ? applySlippage(amount) : amount}
|
||||
tokenAddress={tokenAddress}
|
||||
tokenSymbol={tokenSymbol}
|
||||
disabled={isDisabled}
|
||||
|
@ -193,6 +193,7 @@ export default function FormTrade({
|
||||
loaderMessage="Swapping tokens..."
|
||||
successMessage="Successfully swapped tokens."
|
||||
actionName={content.trade.action}
|
||||
slippage={values.slippage}
|
||||
amount={
|
||||
values.type === 'sell'
|
||||
? values.datatoken
|
||||
|
@ -4,10 +4,13 @@ import {
|
||||
Field,
|
||||
FieldInputProps,
|
||||
FormikContextType,
|
||||
useFormikContext
|
||||
useFormikContext,
|
||||
useField
|
||||
} from 'formik'
|
||||
import Input from '@shared/FormInput'
|
||||
import debounce from 'lodash.debounce'
|
||||
import Button from '@shared/atoms/Button'
|
||||
import Input from '@shared/FormInput'
|
||||
import Error from '@shared/FormInput/Error'
|
||||
import { FormTradeData, TradeItem } from './_types'
|
||||
import UserLiquidity from '../UserLiquidity'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
@ -28,11 +31,10 @@ export default function TradeInput({
|
||||
// Connect with form
|
||||
const {
|
||||
handleChange,
|
||||
setFieldValue,
|
||||
validateForm,
|
||||
values
|
||||
}: FormikContextType<FormTradeData> = useFormikContext()
|
||||
|
||||
const [field, meta] = useField(name)
|
||||
const isTopField =
|
||||
(name === 'baseToken' && values.type === 'buy') ||
|
||||
(name === 'datatoken' && values.type === 'sell')
|
||||
@ -61,11 +63,13 @@ export default function TradeInput({
|
||||
form={form}
|
||||
value={`${field.value}`}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) => {
|
||||
handleValueChange(name, Number(e.target.value))
|
||||
validateForm()
|
||||
handleChange(e)
|
||||
handleValueChange(name, Number(e.target.value))
|
||||
// debounce needed to avoid validating the wrong (pass) value
|
||||
debounce(() => validateForm(), 100)
|
||||
}}
|
||||
disabled={!accountId || disabled}
|
||||
additionalComponent={<Error meta={meta} />}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
|
@ -149,25 +149,12 @@ export default function AssetActions({
|
||||
/>
|
||||
)
|
||||
|
||||
const tabs: TabsItem[] = [
|
||||
{
|
||||
title: 'Use',
|
||||
content: UseContent
|
||||
}
|
||||
]
|
||||
const tabs: TabsItem[] = [{ title: 'Use', content: UseContent }]
|
||||
|
||||
asset?.accessDetails?.type === 'dynamic' &&
|
||||
tabs.push(
|
||||
{
|
||||
title: 'Pool',
|
||||
content: <Pool />,
|
||||
disabled: asset?.accessDetails.datatoken.name === ''
|
||||
},
|
||||
{
|
||||
title: 'Trade',
|
||||
content: <Trade />,
|
||||
disabled: asset?.accessDetails.datatoken.name === ''
|
||||
}
|
||||
{ title: 'Pool', content: <Pool /> },
|
||||
{ title: 'Trade', content: <Trade /> }
|
||||
)
|
||||
|
||||
return (
|
||||
|
@ -14,14 +14,14 @@ export default function DebugEditMetadata({
|
||||
const linksTransformed = values.links?.length &&
|
||||
values.links[0].valid && [values.links[0].url.replace('javascript:', '')]
|
||||
const newMetadata: Metadata = {
|
||||
...asset.metadata,
|
||||
...asset?.metadata,
|
||||
name: values.name,
|
||||
description: values.description,
|
||||
links: linksTransformed,
|
||||
author: values.author
|
||||
}
|
||||
const updatedService: Service = {
|
||||
...asset.services[0],
|
||||
...asset?.services[0],
|
||||
timeout: mapTimeoutStringToSeconds(values.timeout)
|
||||
}
|
||||
const updatedAsset: Asset = {
|
||||
|
@ -17,7 +17,6 @@ import { mapTimeoutStringToSeconds } from '@utils/ddo'
|
||||
import styles from './index.module.css'
|
||||
import content from '../../../../content/pages/edit.json'
|
||||
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||
import { setMinterToPublisher, setMinterToDispenser } from '@utils/dispenser'
|
||||
import { useAbortController } from '@hooks/useAbortController'
|
||||
import DebugEditMetadata from './DebugEditMetadata'
|
||||
import { getOceanConfig } from '@utils/ocean'
|
||||
@ -36,7 +35,6 @@ export default function Edit({
|
||||
const newAbortController = useAbortController()
|
||||
const [success, setSuccess] = useState<string>()
|
||||
const [error, setError] = useState<string>()
|
||||
const [timeoutStringValue, setTimeoutStringValue] = useState<string>()
|
||||
const isComputeType = asset?.services[0]?.type === 'compute'
|
||||
const hasFeedback = error || success
|
||||
|
||||
@ -130,7 +128,7 @@ export default function Edit({
|
||||
await handleSubmit(values, resetForm)
|
||||
}}
|
||||
>
|
||||
{({ isSubmitting, values, initialValues }) =>
|
||||
{({ isSubmitting, values }) =>
|
||||
isSubmitting || hasFeedback ? (
|
||||
<EditFeedback
|
||||
title="Updating Data Set"
|
||||
@ -151,8 +149,6 @@ export default function Edit({
|
||||
<article>
|
||||
<FormEditMetadata
|
||||
data={content.form.data}
|
||||
setTimeoutStringValue={setTimeoutStringValue}
|
||||
values={initialValues}
|
||||
showPrice={asset?.accessDetails?.type === 'fixed'}
|
||||
isComputeDataset={isComputeType}
|
||||
/>
|
||||
|
@ -18,3 +18,15 @@
|
||||
margin-left: calc(var(--spacer) / 2);
|
||||
margin-right: calc(var(--spacer) / 2);
|
||||
}
|
||||
|
||||
.actions a {
|
||||
padding: calc(var(--spacer) / 3);
|
||||
font-weight: var(--font-weight-bold);
|
||||
text-transform: uppercase;
|
||||
transition: 0.2s ease-out;
|
||||
}
|
||||
|
||||
.actions a:hover {
|
||||
transform: translate3d(0, -0.05rem, 0);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -3,15 +3,14 @@ import React, { ReactElement } from 'react'
|
||||
import { useAsset } from '@context/Asset'
|
||||
import Button from '@shared/atoms/Button'
|
||||
import styles from './FormActions.module.css'
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function FormActions({
|
||||
setShowEdit,
|
||||
handleClick
|
||||
}: {
|
||||
setShowEdit: (show: boolean) => void
|
||||
handleClick?: () => void
|
||||
}): ReactElement {
|
||||
const { isAssetNetwork } = useAsset()
|
||||
const { isAssetNetwork, asset } = useAsset()
|
||||
const { isValid }: FormikContextType<Partial<any>> = useFormikContext()
|
||||
|
||||
return (
|
||||
@ -23,9 +22,9 @@ export default function FormActions({
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
<Button style="text" onClick={() => setShowEdit(false)}>
|
||||
<Link href={`/asset/${asset?.id}`} key={asset?.id}>
|
||||
Cancel
|
||||
</Button>
|
||||
</Link>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ export default function FormEditComputeDataset({
|
||||
}): ReactElement {
|
||||
const { appConfig } = useSiteMetadata()
|
||||
const { asset } = useAsset()
|
||||
const [showEditCompute, setShowEditCompute] = useState<boolean>()
|
||||
const { values }: FormikContextType<ComputePrivacyForm> = useFormikContext()
|
||||
const [allAlgorithms, setAllAlgorithms] = useState<AssetSelectionAsset[]>()
|
||||
const newCancelToken = useCancelToken()
|
||||
@ -83,8 +82,7 @@ export default function FormEditComputeDataset({
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* <FormActions setShowEdit={setShowEdit} /> */}
|
||||
<FormActions setShowEdit={setShowEditCompute} />
|
||||
<FormActions />
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
@ -53,19 +53,14 @@ function handleTimeoutCustomOption(
|
||||
|
||||
export default function FormEditMetadata({
|
||||
data,
|
||||
setTimeoutStringValue,
|
||||
values,
|
||||
showPrice,
|
||||
isComputeDataset
|
||||
}: {
|
||||
data: InputProps[]
|
||||
setTimeoutStringValue: (value: string) => void
|
||||
values: Partial<MetadataEditForm>
|
||||
showPrice: boolean
|
||||
isComputeDataset: boolean
|
||||
}): ReactElement {
|
||||
const { oceanConfig } = useAsset()
|
||||
const [showEdit, setShowEdit] = useState<boolean>()
|
||||
const {
|
||||
validateField,
|
||||
setFieldValue
|
||||
@ -118,10 +113,7 @@ export default function FormEditMetadata({
|
||||
)
|
||||
)}
|
||||
|
||||
<FormActions
|
||||
setShowEdit={setShowEdit}
|
||||
// handleClick={() => setTimeoutStringValue(values?.services[0]?.timeout)}
|
||||
/>
|
||||
<FormActions />
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
@ -32,6 +32,8 @@
|
||||
|
||||
.description {
|
||||
font-size: var(--font-size-large);
|
||||
margin: calc(var(--spacer) * 0.3 / var(--line-height)) 0
|
||||
calc(var(--spacer) / var(--line-height)) 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
|
@ -11,24 +11,19 @@ import { useWeb3 } from '@context/Web3'
|
||||
import Alert from '@shared/atoms/Alert'
|
||||
|
||||
export default function Edit({ uri }: { uri: string }): ReactElement {
|
||||
const { asset, error, loading, owner } = useAsset()
|
||||
const { asset, error, isInPurgatory, owner, title } = useAsset()
|
||||
const [isCompute, setIsCompute] = useState(false)
|
||||
const [isOnwer, setIsOwner] = useState(false)
|
||||
const [pageTitle, setPageTitle] = useState<string>('')
|
||||
const { accountId } = useWeb3()
|
||||
|
||||
// Switch type value upon tab change
|
||||
function handleTabChange(tabName: string) {
|
||||
LoggerInstance.log('switched to tab', tabName)
|
||||
// add store restore from
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!asset || error) {
|
||||
if (!asset || error || accountId !== owner) {
|
||||
setPageTitle('Edit action not available')
|
||||
return
|
||||
}
|
||||
setPageTitle(isInPurgatory ? '' : `Edit ${title}`)
|
||||
setIsCompute(asset?.services[0]?.type === 'compute')
|
||||
setIsOwner(owner === accountId)
|
||||
}, [asset, error])
|
||||
}, [asset, error, isInPurgatory, title])
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
@ -42,23 +37,14 @@ export default function Edit({ uri }: { uri: string }): ReactElement {
|
||||
}
|
||||
].filter((tab) => tab !== undefined)
|
||||
|
||||
return asset && !loading && isOnwer ? (
|
||||
<Page uri={uri}>
|
||||
<div className={styles.contianer}>
|
||||
<Tabs
|
||||
items={tabs}
|
||||
handleTabChange={handleTabChange}
|
||||
defaultIndex={0}
|
||||
className={styles.edit}
|
||||
/>
|
||||
return asset && asset?.accessDetails && accountId === owner ? (
|
||||
<Page title={pageTitle} noPageHeader uri={uri}>
|
||||
<div className={styles.container}>
|
||||
<Tabs items={tabs} defaultIndex={0} className={styles.edit} />
|
||||
</div>
|
||||
</Page>
|
||||
) : !isOnwer ? (
|
||||
<Page
|
||||
title="Edit action available only to asset owner"
|
||||
noPageHeader
|
||||
uri={uri}
|
||||
>
|
||||
) : asset && asset?.accessDetails && accountId !== owner ? (
|
||||
<Page title={pageTitle} noPageHeader uri={uri}>
|
||||
<Alert
|
||||
title="Edit action available only to asset owner"
|
||||
text={error}
|
||||
@ -66,7 +52,7 @@ export default function Edit({ uri }: { uri: string }): ReactElement {
|
||||
/>
|
||||
</Page>
|
||||
) : (
|
||||
<Page title={undefined} uri={uri}>
|
||||
<Page title={pageTitle} noPageHeader uri={uri}>
|
||||
<Loader />
|
||||
</Page>
|
||||
)
|
||||
|
@ -4,6 +4,10 @@
|
||||
margin-bottom: var(--spacer);
|
||||
margin-left: calc(var(--spacer) / -4);
|
||||
margin-right: calc(var(--spacer) / -4);
|
||||
|
||||
/* Disable all user actions as to not run into unintended
|
||||
consequences of browsing away from publish. */
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (min-width: 60rem) {
|
||||
|
@ -4,7 +4,7 @@ import InputElement from '@shared/FormInput/InputElement'
|
||||
import Logo from '@images/logo.svg'
|
||||
import Conversion from '@shared/Price/Conversion'
|
||||
import { useField } from 'formik'
|
||||
import Error from './Error'
|
||||
import Error from '@shared/FormInput/Error'
|
||||
|
||||
export default function Coin({
|
||||
datatokenOptions,
|
||||
|
@ -3,7 +3,7 @@ import Tooltip from '@shared/atoms/Tooltip'
|
||||
import styles from './Fees.module.css'
|
||||
import { useField } from 'formik'
|
||||
import Input from '@shared/FormInput'
|
||||
import Error from './Error'
|
||||
import Error from '@shared/FormInput/Error'
|
||||
import { getOpcFees } from '../../../@utils/subgraph'
|
||||
import { OpcFeesQuery_opc as OpcFeesData } from '../../../@types/subgraph/OpcFeesQuery'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
|
@ -2,7 +2,7 @@ import Conversion from '@shared/Price/Conversion'
|
||||
import { Field, useField, useFormikContext } from 'formik'
|
||||
import React, { ReactElement } from 'react'
|
||||
import Input from '@shared/FormInput'
|
||||
import Error from './Error'
|
||||
import Error from '@shared/FormInput/Error'
|
||||
import PriceUnit from '@shared/Price/PriceUnit'
|
||||
import styles from './Price.module.css'
|
||||
import { FormPublishData } from '../_types'
|
||||
|
@ -8,7 +8,7 @@ export default function PageAssetDetails(): ReactElement {
|
||||
const { did } = router.query
|
||||
return (
|
||||
<AssetProvider did={did as string}>
|
||||
<PageTemplateAssetDetails uri={router.pathname} />
|
||||
<PageTemplateAssetDetails uri={router.asPath} />
|
||||
</AssetProvider>
|
||||
)
|
||||
}
|
||||
|