mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Edit Advance Settings form for Edit Credentials & edit isOrderDisabled Flag (#655)
* #638 Initial design * #638 fix import and get value from env file * #638 Fix UI * #638 Improved UI * #638 Add deny credential and isOrderDisabled * UI update * Fix lint * Attempt fix issue * Revert "Attempt fix issue" This reverts commite3d916fe61
. * Extract default credential type * Fix complexity issue * Fix complexity issue * Fix typo error * Enhance UI * Enhance Credentials Component UI * Reduce duplication * Revert "Reduce duplication" This reverts commite3bf6b4a2a
. Co-authored-by: KY Lau <kian_yee.lau@daimler.com>
This commit is contained in:
parent
e26ed0e81a
commit
4fc5862654
@ -11,3 +11,5 @@ GATSBY_NETWORK="rinkeby"
|
|||||||
#GATSBY_PORTIS_ID="xxx"
|
#GATSBY_PORTIS_ID="xxx"
|
||||||
#GATSBY_ALLOW_FIXED_PRICING="true"
|
#GATSBY_ALLOW_FIXED_PRICING="true"
|
||||||
#GATSBY_ALLOW_DYNAMIC_PRICING="true"
|
#GATSBY_ALLOW_DYNAMIC_PRICING="true"
|
||||||
|
#GATSBY_ALLOW_ADVANCED_SETTINGS="true"
|
||||||
|
#GATSBY_CREDENTIAL_TYPE="address"
|
||||||
|
@ -44,5 +44,9 @@ module.exports = {
|
|||||||
// Used to show or hide the fixed and dynamic price options
|
// Used to show or hide the fixed and dynamic price options
|
||||||
// tab to publishers during the price creation.
|
// tab to publishers during the price creation.
|
||||||
allowFixedPricing: process.env.GATSBY_ALLOW_FIXED_PRICING || 'true',
|
allowFixedPricing: process.env.GATSBY_ALLOW_FIXED_PRICING || 'true',
|
||||||
allowDynamicPricing: process.env.GATSBY_ALLOW_DYNAMIC_PRICING || 'true'
|
allowDynamicPricing: process.env.GATSBY_ALLOW_DYNAMIC_PRICING || 'true',
|
||||||
|
|
||||||
|
// Used to show or hide advanced settings button in asset details page
|
||||||
|
allowAdvancedSettings: process.env.GATSBY_ALLOW_ADVANCED_SETTINGS || 'false',
|
||||||
|
credentialType: process.env.GATSBY_CREDENTIAL_TYPE || 'address'
|
||||||
}
|
}
|
||||||
|
31
content/pages/editAdvancedSettings.json
Normal file
31
content/pages/editAdvancedSettings.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"description": "Update advanced settings of this data set. Updating these settings will create an on-chain transaction you have to approve in your wallet.",
|
||||||
|
"form": {
|
||||||
|
"success": "🎉 Successfully updated. 🎉",
|
||||||
|
"successAction": "Close",
|
||||||
|
"error": "Updating DDO failed.",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"name": "allow",
|
||||||
|
"label": "Allow ETH Address",
|
||||||
|
"placeholder": "e.g. 0x12345678901234567890abcd",
|
||||||
|
"help": "Enter ETH address and click ADD button to append the list. Only ETH address in allow list can consume this asset. If the list is empty means anyone can download or compute this asset",
|
||||||
|
"type": "credentials"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deny",
|
||||||
|
"label": "Deny ETH Address",
|
||||||
|
"placeholder": "e.g. 0x12345678901234567890abcd",
|
||||||
|
"help": "Enter ETH address and click ADD button to append the list. If ETH address is fall under deny list, download or compute of this asset is denied",
|
||||||
|
"type": "credentials"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "isOrderDisabled",
|
||||||
|
"label": "Disable Consumption",
|
||||||
|
"help": "Disable dataset being download or compute when dataset undergoing maintenance.",
|
||||||
|
"type": "checkbox",
|
||||||
|
"options": ["Disable"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ import classNames from 'classnames/bind'
|
|||||||
import AssetSelection, {
|
import AssetSelection, {
|
||||||
AssetSelectionAsset
|
AssetSelectionAsset
|
||||||
} from '../../molecules/FormFields/AssetSelection'
|
} from '../../molecules/FormFields/AssetSelection'
|
||||||
|
import Credentials from '../../molecules/FormFields/Credential'
|
||||||
|
|
||||||
const cx = classNames.bind(styles)
|
const cx = classNames.bind(styles)
|
||||||
|
|
||||||
@ -137,6 +138,8 @@ export default function InputElement({
|
|||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
case 'credentials':
|
||||||
|
return <Credentials name={name} {...field} {...props} />
|
||||||
default:
|
default:
|
||||||
return prefix || postfix ? (
|
return prefix || postfix ? (
|
||||||
<div className={`${prefix ? styles.prefixGroup : styles.postfixGroup}`}>
|
<div className={`${prefix ? styles.prefixGroup : styles.postfixGroup}`}>
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
.chip {
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
display: flex;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonWrapper {
|
||||||
|
width: 100%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crossButton {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crossButton svg {
|
||||||
|
display: inline-block;
|
||||||
|
width: var(--font-size-large);
|
||||||
|
height: var(--font-size-large);
|
||||||
|
fill: var(--brand-pink);
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll {
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
min-height: fit-content;
|
||||||
|
max-height: 200px;
|
||||||
|
position: relative;
|
||||||
|
overflow: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credential {
|
||||||
|
padding: 0;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
background-color: var(--background-highlight);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
81
src/components/molecules/FormFields/Credential/index.tsx
Normal file
81
src/components/molecules/FormFields/Credential/index.tsx
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import { useField } from 'formik'
|
||||||
|
import { InputProps } from '../../../atoms/Input'
|
||||||
|
import React, { useState, ChangeEvent, FormEvent, useEffect } from 'react'
|
||||||
|
import InputGroup from '../../../atoms/Input/InputGroup'
|
||||||
|
import Button from '../../../atoms/Button'
|
||||||
|
import styles from './Credential.module.css'
|
||||||
|
import { isAddress } from 'web3-utils'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
import { ReactComponent as Cross } from '../../../../images/cross.svg'
|
||||||
|
import InputElement from '../../../atoms/Input/InputElement'
|
||||||
|
|
||||||
|
export default function Credentials(props: InputProps) {
|
||||||
|
const [field, meta, helpers] = useField(props.name)
|
||||||
|
const [arrayInput, setArrayInput] = useState<string[]>(field.value || [])
|
||||||
|
const [value, setValue] = useState('')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
helpers.setValue(arrayInput)
|
||||||
|
}, [arrayInput])
|
||||||
|
|
||||||
|
function handleDeleteChip(value: string) {
|
||||||
|
const newInput = arrayInput.filter((input) => input !== value)
|
||||||
|
setArrayInput(newInput)
|
||||||
|
helpers.setValue(newInput)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAddValue(e: FormEvent<HTMLButtonElement>) {
|
||||||
|
e.preventDefault()
|
||||||
|
if (!isAddress(value)) {
|
||||||
|
toast.error('Wallet address is invalid')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (arrayInput.includes(value)) {
|
||||||
|
toast.error('Wallet address already added into list')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setArrayInput((arrayInput) => [...arrayInput, value])
|
||||||
|
setValue('')
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.credential}>
|
||||||
|
<InputGroup>
|
||||||
|
<InputElement
|
||||||
|
type="text"
|
||||||
|
name="address"
|
||||||
|
size="default"
|
||||||
|
placeholder={props.placeholder}
|
||||||
|
value={value}
|
||||||
|
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||||
|
setValue(e.target.value)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
onClick={(e: FormEvent<HTMLButtonElement>) => handleAddValue(e)}
|
||||||
|
>
|
||||||
|
Add
|
||||||
|
</Button>
|
||||||
|
</InputGroup>
|
||||||
|
<div className={styles.scroll}>
|
||||||
|
{arrayInput &&
|
||||||
|
arrayInput.map((value) => {
|
||||||
|
return (
|
||||||
|
<div className={styles.chip} key={value}>
|
||||||
|
<code>{value}</code>
|
||||||
|
<span className={styles.buttonWrapper}>
|
||||||
|
<Button
|
||||||
|
className={styles.crossButton}
|
||||||
|
style="text"
|
||||||
|
onClick={(even) => handleDeleteChip(value)}
|
||||||
|
>
|
||||||
|
<Cross />
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
import { DDO, Credentials, CredentialType } from '@oceanprotocol/lib'
|
||||||
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
|
import { AdvancedSettingsForm } from '../../../../models/FormEditCredential'
|
||||||
|
import { useOcean } from '../../../../providers/Ocean'
|
||||||
|
import DebugOutput from '../../../atoms/DebugOutput'
|
||||||
|
|
||||||
|
export interface AdvancedSettings {
|
||||||
|
credentail: Credentials
|
||||||
|
isOrderDisabled: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DebugEditCredential({
|
||||||
|
values,
|
||||||
|
ddo,
|
||||||
|
credentialType
|
||||||
|
}: {
|
||||||
|
values: AdvancedSettingsForm
|
||||||
|
ddo: DDO
|
||||||
|
credentialType: CredentialType
|
||||||
|
}): ReactElement {
|
||||||
|
const { ocean } = useOcean()
|
||||||
|
const [advancedSettings, setAdvancedSettings] = useState<AdvancedSettings>()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ocean) return
|
||||||
|
|
||||||
|
async function transformValues() {
|
||||||
|
const newDdo = await ocean.assets.updateCredentials(
|
||||||
|
ddo,
|
||||||
|
credentialType,
|
||||||
|
values.allow,
|
||||||
|
values.deny
|
||||||
|
)
|
||||||
|
setAdvancedSettings({
|
||||||
|
credentail: newDdo.credentials,
|
||||||
|
isOrderDisabled: values.isOrderDisabled
|
||||||
|
})
|
||||||
|
}
|
||||||
|
transformValues()
|
||||||
|
}, [values, ddo, ocean])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DebugOutput title="Collected Form Values" output={values} />
|
||||||
|
<DebugOutput title="Transformed Form Values" output={advancedSettings} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,163 @@
|
|||||||
|
import { Formik } from 'formik'
|
||||||
|
import React, { ReactElement, useState } from 'react'
|
||||||
|
import { useAsset } from '../../../../providers/Asset'
|
||||||
|
import { useUserPreferences } from '../../../../providers/UserPreferences'
|
||||||
|
import styles from './index.module.css'
|
||||||
|
import { Logger, CredentialType, DDO } from '@oceanprotocol/lib'
|
||||||
|
import MetadataFeedback from '../../../molecules/MetadataFeedback'
|
||||||
|
import { graphql, useStaticQuery } from 'gatsby'
|
||||||
|
import { useWeb3 } from '../../../../providers/Web3'
|
||||||
|
import { useOcean } from '../../../../providers/Ocean'
|
||||||
|
import FormAdvancedSettings from './FormAdvancedSettings'
|
||||||
|
import {
|
||||||
|
AdvancedSettingsForm,
|
||||||
|
getInitialValues,
|
||||||
|
validationSchema
|
||||||
|
} from '../../../../models/FormEditCredential'
|
||||||
|
import DebugEditCredential from './DebugEditAdvancedSettings'
|
||||||
|
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
|
||||||
|
|
||||||
|
const contentQuery = graphql`
|
||||||
|
query EditAvanceSettingsQuery {
|
||||||
|
content: allFile(
|
||||||
|
filter: { relativePath: { eq: "pages/editAdvancedSettings.json" } }
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
childPagesJson {
|
||||||
|
description
|
||||||
|
form {
|
||||||
|
success
|
||||||
|
successAction
|
||||||
|
error
|
||||||
|
data {
|
||||||
|
name
|
||||||
|
placeholder
|
||||||
|
label
|
||||||
|
help
|
||||||
|
type
|
||||||
|
options
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
function getDefaultCredentialType(credentialType: string): CredentialType {
|
||||||
|
switch (credentialType) {
|
||||||
|
case 'address':
|
||||||
|
return CredentialType.address
|
||||||
|
case 'credential3Box':
|
||||||
|
return CredentialType.credential3Box
|
||||||
|
default:
|
||||||
|
return CredentialType.address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function EditAdvancedSettings({
|
||||||
|
setShowEdit
|
||||||
|
}: {
|
||||||
|
setShowEdit: (show: boolean) => void
|
||||||
|
}): ReactElement {
|
||||||
|
const data = useStaticQuery(contentQuery)
|
||||||
|
const content = data.content.edges[0].node.childPagesJson
|
||||||
|
|
||||||
|
const { debug } = useUserPreferences()
|
||||||
|
const { accountId } = useWeb3()
|
||||||
|
const { ocean } = useOcean()
|
||||||
|
const { metadata, ddo, refreshDdo } = useAsset()
|
||||||
|
const [success, setSuccess] = useState<string>()
|
||||||
|
const [error, setError] = useState<string>()
|
||||||
|
const { appConfig } = useSiteMetadata()
|
||||||
|
|
||||||
|
const hasFeedback = error || success
|
||||||
|
|
||||||
|
const credentialType = getDefaultCredentialType(appConfig.credentialType)
|
||||||
|
|
||||||
|
async function handleSubmit(
|
||||||
|
values: Partial<AdvancedSettingsForm>,
|
||||||
|
resetForm: () => void
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
let newDdo: DDO
|
||||||
|
newDdo = await ocean.assets.updateCredentials(
|
||||||
|
ddo,
|
||||||
|
credentialType,
|
||||||
|
values.allow,
|
||||||
|
values.deny
|
||||||
|
)
|
||||||
|
|
||||||
|
newDdo = await ocean.assets.editMetadata(newDdo, {
|
||||||
|
status: {
|
||||||
|
isOrderDisabled: values.isOrderDisabled
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const storedddo = await ocean.assets.updateMetadata(newDdo, accountId)
|
||||||
|
|
||||||
|
if (!storedddo) {
|
||||||
|
setError(content.form.error)
|
||||||
|
Logger.error(content.form.error)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
setSuccess(content.form.success)
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(error.message)
|
||||||
|
setError(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Formik
|
||||||
|
initialValues={getInitialValues(ddo, credentialType)}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={async (values, { resetForm }) => {
|
||||||
|
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
||||||
|
await handleSubmit(values, resetForm)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ isSubmitting, values }) =>
|
||||||
|
isSubmitting || hasFeedback ? (
|
||||||
|
<MetadataFeedback
|
||||||
|
title="Updating Data Set"
|
||||||
|
error={error}
|
||||||
|
success={success}
|
||||||
|
setError={setError}
|
||||||
|
successAction={{
|
||||||
|
name: content.form.successAction,
|
||||||
|
onClick: async () => {
|
||||||
|
await refreshDdo()
|
||||||
|
setShowEdit(false)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<p className={styles.description}>{content.description}</p>
|
||||||
|
<article className={styles.grid}>
|
||||||
|
<FormAdvancedSettings
|
||||||
|
data={content.form.data}
|
||||||
|
setShowEdit={setShowEdit}
|
||||||
|
/>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
{debug === true && (
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<DebugEditCredential
|
||||||
|
values={values}
|
||||||
|
ddo={ddo}
|
||||||
|
credentialType={credentialType}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Formik>
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
import React, { ChangeEvent, ReactElement } from 'react'
|
||||||
|
import styles from './FormEditMetadata.module.css'
|
||||||
|
import { Field, Form, FormikContextType, useFormikContext } from 'formik'
|
||||||
|
import Button from '../../../atoms/Button'
|
||||||
|
import Input from '../../../atoms/Input'
|
||||||
|
import { FormFieldProps } from '../../../../@types/Form'
|
||||||
|
import { useOcean } from '../../../../providers/Ocean'
|
||||||
|
import { useWeb3 } from '../../../../providers/Web3'
|
||||||
|
import { AdvancedSettingsForm } from '../../../../models/FormEditCredential'
|
||||||
|
|
||||||
|
export default function FormAdvancedSettings({
|
||||||
|
data,
|
||||||
|
setShowEdit
|
||||||
|
}: {
|
||||||
|
data: FormFieldProps[]
|
||||||
|
setShowEdit: (show: boolean) => void
|
||||||
|
}): ReactElement {
|
||||||
|
const { accountId } = useWeb3()
|
||||||
|
const { ocean, config } = useOcean()
|
||||||
|
const {
|
||||||
|
isValid,
|
||||||
|
validateField,
|
||||||
|
setFieldValue
|
||||||
|
}: FormikContextType<Partial<AdvancedSettingsForm>> = useFormikContext()
|
||||||
|
|
||||||
|
function handleFieldChange(
|
||||||
|
e: ChangeEvent<HTMLInputElement>,
|
||||||
|
field: FormFieldProps
|
||||||
|
) {
|
||||||
|
validateField(field.name)
|
||||||
|
if (e.target.type === 'checkbox')
|
||||||
|
setFieldValue(field.name, e.target.checked)
|
||||||
|
else setFieldValue(field.name, e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form className={styles.form}>
|
||||||
|
{data.map((field: FormFieldProps) => (
|
||||||
|
<Field
|
||||||
|
key={field.name}
|
||||||
|
{...field}
|
||||||
|
component={Input}
|
||||||
|
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||||
|
handleFieldChange(e, field)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<footer className={styles.actions}>
|
||||||
|
<Button style="primary" disabled={!ocean || !accountId || !isValid}>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
<Button style="text" onClick={() => setShowEdit(false)}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</footer>
|
||||||
|
</Form>
|
||||||
|
)
|
||||||
|
}
|
@ -17,6 +17,8 @@ import MetaMain from './MetaMain'
|
|||||||
import EditHistory from './EditHistory'
|
import EditHistory from './EditHistory'
|
||||||
import { useWeb3 } from '../../../providers/Web3'
|
import { useWeb3 } from '../../../providers/Web3'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
|
import EditAdvancedSettings from '../AssetActions/Edit/EditAdvancedSettings'
|
||||||
|
import { useSiteMetadata } from '../../../hooks/useSiteMetadata'
|
||||||
|
|
||||||
export interface AssetContentProps {
|
export interface AssetContentProps {
|
||||||
path?: string
|
path?: string
|
||||||
@ -48,8 +50,11 @@ export default function AssetContent(props: AssetContentProps): ReactElement {
|
|||||||
const [showPricing, setShowPricing] = useState(false)
|
const [showPricing, setShowPricing] = useState(false)
|
||||||
const [showEdit, setShowEdit] = useState<boolean>()
|
const [showEdit, setShowEdit] = useState<boolean>()
|
||||||
const [showEditCompute, setShowEditCompute] = useState<boolean>()
|
const [showEditCompute, setShowEditCompute] = useState<boolean>()
|
||||||
|
const [showEditAdvancedSettings, setShowEditAdvancedSettings] =
|
||||||
|
useState<boolean>()
|
||||||
const [isOwner, setIsOwner] = useState(false)
|
const [isOwner, setIsOwner] = useState(false)
|
||||||
const { ddo, price, metadata, type } = useAsset()
|
const { ddo, price, metadata, type } = useAsset()
|
||||||
|
const { appConfig } = useSiteMetadata()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!accountId || !owner) return
|
if (!accountId || !owner) return
|
||||||
@ -70,10 +75,17 @@ export default function AssetContent(props: AssetContentProps): ReactElement {
|
|||||||
setShowEditCompute(true)
|
setShowEditCompute(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleEditAdvancedSettingsButton() {
|
||||||
|
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
||||||
|
setShowEditAdvancedSettings(true)
|
||||||
|
}
|
||||||
|
|
||||||
return showEdit ? (
|
return showEdit ? (
|
||||||
<Edit setShowEdit={setShowEdit} />
|
<Edit setShowEdit={setShowEdit} />
|
||||||
) : showEditCompute ? (
|
) : showEditCompute ? (
|
||||||
<EditComputeDataset setShowEdit={setShowEditCompute} />
|
<EditComputeDataset setShowEdit={setShowEditCompute} />
|
||||||
|
) : showEditAdvancedSettings ? (
|
||||||
|
<EditAdvancedSettings setShowEdit={setShowEditAdvancedSettings} />
|
||||||
) : (
|
) : (
|
||||||
<article className={styles.grid}>
|
<article className={styles.grid}>
|
||||||
<div>
|
<div>
|
||||||
@ -103,6 +115,18 @@ export default function AssetContent(props: AssetContentProps): ReactElement {
|
|||||||
<Button style="text" size="small" onClick={handleEditButton}>
|
<Button style="text" size="small" onClick={handleEditButton}>
|
||||||
Edit Metadata
|
Edit Metadata
|
||||||
</Button>
|
</Button>
|
||||||
|
{appConfig.allowAdvancedSettings === 'true' && (
|
||||||
|
<>
|
||||||
|
<span className={styles.separator}>|</span>
|
||||||
|
<Button
|
||||||
|
style="text"
|
||||||
|
size="small"
|
||||||
|
onClick={handleEditAdvancedSettingsButton}
|
||||||
|
>
|
||||||
|
Edit Advanced Settings
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
{ddo.findServiceByType('compute') && type === 'dataset' && (
|
{ddo.findServiceByType('compute') && type === 'dataset' && (
|
||||||
<>
|
<>
|
||||||
<span className={styles.separator}>|</span>
|
<span className={styles.separator}>|</span>
|
||||||
|
@ -27,6 +27,8 @@ interface UseSiteMetadata {
|
|||||||
portisId: string
|
portisId: string
|
||||||
allowFixedPricing: string
|
allowFixedPricing: string
|
||||||
allowDynamicPricing: string
|
allowDynamicPricing: string
|
||||||
|
allowAdvancedSettings: string
|
||||||
|
credentialType: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +61,8 @@ const query = graphql`
|
|||||||
portisId
|
portisId
|
||||||
allowFixedPricing
|
allowFixedPricing
|
||||||
allowDynamicPricing
|
allowDynamicPricing
|
||||||
|
allowAdvancedSettings
|
||||||
|
credentialType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
src/images/cross.svg
Normal file
3
src/images/cross.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x-circle-fill" viewBox="0 0 16 16">
|
||||||
|
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 364 B |
72
src/models/FormEditCredential.ts
Normal file
72
src/models/FormEditCredential.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import {
|
||||||
|
CredentialAction,
|
||||||
|
Credential,
|
||||||
|
Credentials,
|
||||||
|
CredentialType,
|
||||||
|
DDO
|
||||||
|
} from '@oceanprotocol/lib'
|
||||||
|
import * as Yup from 'yup'
|
||||||
|
|
||||||
|
export interface AdvancedSettingsForm {
|
||||||
|
allow: string[]
|
||||||
|
deny: string[]
|
||||||
|
isOrderDisabled: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export const validationSchema: Yup.SchemaOf<AdvancedSettingsForm> =
|
||||||
|
Yup.object().shape({
|
||||||
|
allow: Yup.array().nullable(),
|
||||||
|
deny: Yup.array().nullable(),
|
||||||
|
isOrderDisabled: Yup.boolean().nullable()
|
||||||
|
})
|
||||||
|
|
||||||
|
function getCredentialList(
|
||||||
|
credential: Credential[],
|
||||||
|
credentialType: CredentialType
|
||||||
|
): string[] {
|
||||||
|
const credentialByType = credential.find(
|
||||||
|
(credential) => credential.type === credentialType
|
||||||
|
)
|
||||||
|
return credentialByType.value && credentialByType.value.length > 0
|
||||||
|
? credentialByType.value
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAssetCredentials(
|
||||||
|
credentials: Credentials,
|
||||||
|
credentialType: CredentialType,
|
||||||
|
credentialAction: CredentialAction
|
||||||
|
): string[] {
|
||||||
|
if (!credentials) return []
|
||||||
|
|
||||||
|
if (credentialAction === 'allow') {
|
||||||
|
return credentials.allow
|
||||||
|
? getCredentialList(credentials.allow, credentialType)
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
return credentials.deny
|
||||||
|
? getCredentialList(credentials.deny, credentialType)
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getInitialValues(
|
||||||
|
ddo: DDO,
|
||||||
|
credentailType: CredentialType
|
||||||
|
): AdvancedSettingsForm {
|
||||||
|
const allowCredential = getAssetCredentials(
|
||||||
|
ddo.credentials,
|
||||||
|
credentailType,
|
||||||
|
'allow'
|
||||||
|
)
|
||||||
|
const denyCredential = getAssetCredentials(
|
||||||
|
ddo.credentials,
|
||||||
|
credentailType,
|
||||||
|
'deny'
|
||||||
|
)
|
||||||
|
const metadata = ddo.findServiceByType('metadata')
|
||||||
|
return {
|
||||||
|
allow: allowCredential,
|
||||||
|
deny: denyCredential,
|
||||||
|
isOrderDisabled: metadata.attributes?.status?.isOrderDisabled || false
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user