mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
#638 Initial design
This commit is contained in:
parent
f5e01d7c0c
commit
1dccac1412
17
content/pages/editAdvanceSettings.json
Normal file
17
content/pages/editAdvanceSettings.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"description": "Update credential of this data set. Updating metadata 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": "Wallet Address",
|
||||
"placeholder": "e.g. 0x12345678901234567890abcd",
|
||||
"help": "Enter wallet address and click ADD button to append the list",
|
||||
"type": "credential"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import classNames from 'classnames/bind'
|
||||
import AssetSelection, {
|
||||
AssetSelectionAsset
|
||||
} from '../../molecules/FormFields/AssetSelection'
|
||||
import Credential from '../../molecules/FormFields/Credential'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
||||
@ -137,6 +138,8 @@ export default function InputElement({
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
case 'credential':
|
||||
return <Credential name={name} {...field} {...props} />
|
||||
default:
|
||||
return prefix || postfix ? (
|
||||
<div className={`${prefix ? styles.prefixGroup : styles.postfixGroup}`}>
|
||||
|
@ -0,0 +1,24 @@
|
||||
.chip {
|
||||
display: flex;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.input {
|
||||
font-size: var(--font-size-base);
|
||||
font-family: var(--font-family-base);
|
||||
font-weight: var(--font-weight-bold);
|
||||
color: var(--font-color-heading);
|
||||
border: 1px solid var(--border-color);
|
||||
box-shadow: none;
|
||||
width: 100%;
|
||||
background: var(--background-body);
|
||||
padding: calc(var(--spacer) / 3);
|
||||
margin: 0;
|
||||
border-radius: var(--border-radius);
|
||||
transition: 0.2s ease-out;
|
||||
height: 43px;
|
||||
min-width: 0;
|
||||
appearance: none;
|
||||
display: block;
|
||||
}
|
74
src/components/molecules/FormFields/Credential/index.tsx
Normal file
74
src/components/molecules/FormFields/Credential/index.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
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'
|
||||
|
||||
export default function Credential(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 handleChange(e: ChangeEvent<HTMLInputElement>) {
|
||||
setValue(e.target.value)
|
||||
}
|
||||
|
||||
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>
|
||||
<InputGroup>
|
||||
<input
|
||||
className={styles.input}
|
||||
placeholder={props.placeholder}
|
||||
name="search"
|
||||
onChange={handleChange}
|
||||
value={value}
|
||||
/>
|
||||
<Button
|
||||
onClick={(e: FormEvent<HTMLButtonElement>) => handleAddValue(e)}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</InputGroup>
|
||||
{arrayInput &&
|
||||
arrayInput.map((value) => {
|
||||
return (
|
||||
<div className={styles.chip} key={value}>
|
||||
{/* <Chip
|
||||
label={value}
|
||||
onDelete={(even) => handleDeleteChip(value)}
|
||||
variant="outlined"
|
||||
/> */}
|
||||
value
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
import { DDO, ServiceComputePrivacy } from '@oceanprotocol/lib'
|
||||
import React, { ReactElement, useEffect, useState } from 'react'
|
||||
import { AdvanceSettingsForm } from '../../../../models/FormEditCredential'
|
||||
import { useOcean } from '../../../../providers/Ocean'
|
||||
import DebugOutput from '../../../atoms/DebugOutput'
|
||||
import { Credential } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Credentials'
|
||||
|
||||
export default function DebugEditCredential({
|
||||
values,
|
||||
ddo
|
||||
}: {
|
||||
values: AdvanceSettingsForm
|
||||
ddo: DDO
|
||||
}): ReactElement {
|
||||
const { ocean } = useOcean()
|
||||
const [credential, setCredential] = useState<Credential>()
|
||||
|
||||
useEffect(() => {
|
||||
if (!ocean) return
|
||||
|
||||
async function transformValues() {
|
||||
// const credential = await transformComputeFormToServiceComputePrivacy(
|
||||
// values,
|
||||
// ocean
|
||||
// )
|
||||
// setCredential(credential)
|
||||
}
|
||||
transformValues()
|
||||
}, [values, ddo, ocean])
|
||||
|
||||
return (
|
||||
<>
|
||||
<DebugOutput title="Collected Form Values" output={values} />
|
||||
<DebugOutput title="Transformed Form Values" output={ddo.credentials} />
|
||||
</>
|
||||
)
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
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 { DDO, Logger } from '@oceanprotocol/lib'
|
||||
import MetadataFeedback from '../../../molecules/MetadataFeedback'
|
||||
import { graphql, useStaticQuery } from 'gatsby'
|
||||
import { useWeb3 } from '../../../../providers/Web3'
|
||||
import { useOcean } from '../../../../providers/Ocean'
|
||||
import FormAdvanceSettings from './FormAdvanceSettings'
|
||||
import {
|
||||
AdvanceSettingsForm,
|
||||
getInitialValues,
|
||||
validationSchema
|
||||
} from '../../../../models/FormEditCredential'
|
||||
import DebugEditAdvanceSettings from './DebugEditAdvanceSettings'
|
||||
import { CredentialType } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Credentials'
|
||||
|
||||
const contentQuery = graphql`
|
||||
query EditAvanceSettingsQuery {
|
||||
content: allFile(
|
||||
filter: { relativePath: { eq: "pages/editAdvanceSettings.json" } }
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
childPagesJson {
|
||||
description
|
||||
form {
|
||||
success
|
||||
successAction
|
||||
error
|
||||
data {
|
||||
name
|
||||
placeholder
|
||||
label
|
||||
help
|
||||
type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export default function EditAdvanceSettings({
|
||||
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, price } = useAsset()
|
||||
const [success, setSuccess] = useState<string>()
|
||||
const [error, setError] = useState<string>()
|
||||
|
||||
const hasFeedback = error || success
|
||||
// TODO : get from env
|
||||
//const credentialType = CredentialType.address
|
||||
|
||||
async function handleSubmit(
|
||||
values: Partial<AdvanceSettingsForm>,
|
||||
resetForm: () => void
|
||||
) {
|
||||
try {
|
||||
// const ddoEditedCredential = await ocean.assets.updateCredentials(
|
||||
// ddo,
|
||||
// credentialType,
|
||||
// values.allowCredentail,
|
||||
// []
|
||||
// )
|
||||
|
||||
const storedddo = await ocean.assets.updateMetadata(ddo, 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
|
||||
// TODO: get credential from DDO
|
||||
initialValues={getInitialValues([])}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={async (values, { resetForm }) => {
|
||||
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
||||
await handleSubmit(values, resetForm)
|
||||
}}
|
||||
>
|
||||
{({ isSubmitting, values, initialValues }) =>
|
||||
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}>
|
||||
<FormAdvanceSettings
|
||||
data={content.form.data}
|
||||
setShowEdit={setShowEdit}
|
||||
values={initialValues}
|
||||
/>
|
||||
</article>
|
||||
|
||||
{debug === true && (
|
||||
<div className={styles.grid}>
|
||||
<DebugEditAdvanceSettings values={values} ddo={ddo} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
</Formik>
|
||||
)
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
import React, { ChangeEvent, ReactElement } from 'react'
|
||||
import styles from './FormEditMetadata.module.css' //TODO
|
||||
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 { AdvanceSettingsForm } from '../../../../models/FormEditCredential'
|
||||
|
||||
export default function FormAdvanceSettings({
|
||||
data,
|
||||
setShowEdit,
|
||||
values
|
||||
}: {
|
||||
data: FormFieldProps[]
|
||||
setShowEdit: (show: boolean) => void
|
||||
values: Partial<AdvanceSettingsForm>
|
||||
}): ReactElement {
|
||||
const { accountId } = useWeb3()
|
||||
const { ocean, config } = useOcean()
|
||||
const {
|
||||
isValid,
|
||||
validateField,
|
||||
setFieldValue
|
||||
}: FormikContextType<Partial<AdvanceSettingsForm>> = useFormikContext()
|
||||
|
||||
function handleFieldChange(
|
||||
e: ChangeEvent<HTMLInputElement>,
|
||||
field: FormFieldProps
|
||||
) {
|
||||
validateField(field.name)
|
||||
setFieldValue(field.name, e.target.value)
|
||||
}
|
||||
|
||||
return (
|
||||
<Form className={styles.form}>
|
||||
{data.map((field: FormFieldProps) => (
|
||||
<Field
|
||||
key={field.name}
|
||||
{...field}
|
||||
component={Input}
|
||||
prefix={field.name === 'price' && config.oceanTokenSymbol}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
handleFieldChange(e, field)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
|
||||
<footer className={styles.actions}>
|
||||
<Button style="text" onClick={() => setShowEdit(false)}>
|
||||
Cancel
|
||||
</Button>
|
||||
</footer>
|
||||
</Form>
|
||||
)
|
||||
}
|
@ -17,6 +17,7 @@ import MetaMain from './MetaMain'
|
||||
import EditHistory from './EditHistory'
|
||||
import { useWeb3 } from '../../../providers/Web3'
|
||||
import styles from './index.module.css'
|
||||
import EditAdvanceSettings from '../AssetActions/Edit/EditAdvanceSettings'
|
||||
|
||||
export interface AssetContentProps {
|
||||
path?: string
|
||||
@ -48,6 +49,10 @@ export default function AssetContent(props: AssetContentProps): ReactElement {
|
||||
const [showPricing, setShowPricing] = useState(false)
|
||||
const [showEdit, setShowEdit] = useState<boolean>()
|
||||
const [showEditCompute, setShowEditCompute] = useState<boolean>()
|
||||
const [
|
||||
showEditAdvanceSettings,
|
||||
setShowEditAdvanceSettings
|
||||
] = useState<boolean>()
|
||||
const [isOwner, setIsOwner] = useState(false)
|
||||
const { ddo, price, metadata, type } = useAsset()
|
||||
|
||||
@ -70,10 +75,17 @@ export default function AssetContent(props: AssetContentProps): ReactElement {
|
||||
setShowEditCompute(true)
|
||||
}
|
||||
|
||||
function handleEditAdvanceSettingsButton() {
|
||||
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
||||
setShowEditAdvanceSettings(true)
|
||||
}
|
||||
|
||||
return showEdit ? (
|
||||
<Edit setShowEdit={setShowEdit} />
|
||||
) : showEditCompute ? (
|
||||
<EditComputeDataset setShowEdit={setShowEditCompute} />
|
||||
) : showEditAdvanceSettings ? (
|
||||
<EditAdvanceSettings setShowEdit={setShowEditCompute} />
|
||||
) : (
|
||||
<article className={styles.grid}>
|
||||
<div>
|
||||
@ -103,6 +115,14 @@ export default function AssetContent(props: AssetContentProps): ReactElement {
|
||||
<Button style="text" size="small" onClick={handleEditButton}>
|
||||
Edit Metadata
|
||||
</Button>
|
||||
<span className={styles.separator}>|</span>
|
||||
<Button
|
||||
style="text"
|
||||
size="small"
|
||||
onClick={handleEditAdvanceSettingsButton}
|
||||
>
|
||||
Edit Advanced Settings
|
||||
</Button>
|
||||
{ddo.findServiceByType('compute') && type === 'dataset' && (
|
||||
<>
|
||||
<span className={styles.separator}>|</span>
|
||||
|
17
src/models/FormEditCredential.ts
Normal file
17
src/models/FormEditCredential.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import * as Yup from 'yup'
|
||||
|
||||
export interface AdvanceSettingsForm {
|
||||
allowCredentail: string[]
|
||||
}
|
||||
|
||||
export const validationSchema: Yup.SchemaOf<AdvanceSettingsForm> = Yup.object().shape(
|
||||
{
|
||||
allowCredentail: Yup.array().nullable()
|
||||
}
|
||||
)
|
||||
|
||||
export function getInitialValues(
|
||||
allowCredentail: string[]
|
||||
): AdvanceSettingsForm {
|
||||
return { allowCredentail }
|
||||
}
|
Loading…
Reference in New Issue
Block a user