1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00
Jamie Hewitt e26ed0e81a
Issue 582 market rbac integration (#597)
* adding env for RBAC server url to app.config.js

* creating util function for requesting auth from the rbac server

* fixing typing error

* testing rbac request on homepage

* removing console logs

* importing RBAC url from config file

* creating develpment .env file

* return true if no rbac url env is set

* creating permissions parent component

* wrapping homepage content in permission element

* wrapping publish in permissions wrapper

* wrapping search results in permissions wrapper

* wrapping asset actions in permissions element

* creating an error alert for permission denied

* updating react hook dependency

* passing address to rbac component

* sedning address to RBAC server

* wrapping asset in permission component

* removing unused import of Permission component

* sending request based on address

* chaning default permission case to restrict access

* updating eventType as consume

* Adding loader icon while waiting form permission response

* only sending request to RBAC if address is defined

* adding wallet connection info message

* changing the env name and checking for undefined

* updating .env.development

* Check for undefined RBAC_URL in permissions component

* removing .env.development and updating .env.example

* updating .env.example comment

* switching alert messages and reducing return statements

* removing console.log message

* fixing linting issue

* Revert "fixing linting issue"

This reverts commit 8bcb80be3d1ae32731b8c5b81b393dd614017fdc.

* Fixing linting errors

* pull from origin main

* Revert "pull from origin main"

This reverts commit 9535e41a5f5acfa26d2841942c29695855dd65bc.
2021-06-10 12:06:26 +03:00

308 lines
9.6 KiB
TypeScript

import React, { ReactElement, useState, useEffect } from 'react'
import Permission from '../../organisms/Permission'
import { Formik, FormikState } from 'formik'
import { usePublish } from '../../../hooks/usePublish'
import styles from './index.module.css'
import FormPublish from './FormPublish'
import FormAlgoPublish from './FormAlgoPublish'
import Web3Feedback from '../../molecules/Wallet/Feedback'
import Tabs from '../../atoms/Tabs'
import { initialValues, validationSchema } from '../../../models/FormPublish'
import {
initialValues as initialValuesAlgorithm,
validationSchema as validationSchemaAlgorithm
} from '../../../models/FormAlgoPublish'
import {
transformPublishFormToMetadata,
transformPublishAlgorithmFormToMetadata,
mapTimeoutStringToSeconds,
validateDockerImage
} from '../../../utils/metadata'
import {
MetadataPreview,
MetadataAlgorithmPreview
} from '../../molecules/MetadataPreview'
import {
MetadataPublishFormDataset,
MetadataPublishFormAlgorithm
} from '../../../@types/MetaData'
import { useUserPreferences } from '../../../providers/UserPreferences'
import { Logger, Metadata, MetadataMain } from '@oceanprotocol/lib'
import { Persist } from '../../atoms/FormikPersist'
import Debug from './Debug'
import Alert from '../../atoms/Alert'
import MetadataFeedback from '../../molecules/MetadataFeedback'
import { useAccountPurgatory } from '../../../hooks/useAccountPurgatory'
import { useWeb3 } from '../../../providers/Web3'
const formNameDatasets = 'ocean-publish-form-datasets'
const formNameAlgorithms = 'ocean-publish-form-algorithms'
function TabContent({
publishType,
values
}: {
publishType: MetadataMain['type']
values: Partial<MetadataPublishFormAlgorithm | MetadataPublishFormDataset>
}) {
return (
<article className={styles.grid}>
{publishType === 'dataset' ? <FormPublish /> : <FormAlgoPublish />}
<aside>
<div className={styles.sticky}>
{publishType === 'dataset' ? (
<MetadataPreview values={values} />
) : (
<MetadataAlgorithmPreview values={values} />
)}
<Web3Feedback />
</div>
</aside>
</article>
)
}
export default function PublishPage({
content
}: {
content: { warning: string }
}): ReactElement {
const { debug } = useUserPreferences()
const { accountId } = useWeb3()
const { isInPurgatory, purgatoryData } = useAccountPurgatory(accountId)
const { publish, publishError, isLoading, publishStepText } = usePublish()
const [success, setSuccess] = useState<string>()
const [error, setError] = useState<string>()
const [title, setTitle] = useState<string>()
const [did, setDid] = useState<string>()
const [algoInitialValues, setAlgoInitialValues] = useState<
Partial<MetadataPublishFormAlgorithm>
>(
(localStorage.getItem('ocean-publish-form-algorithms') &&
(JSON.parse(localStorage.getItem('ocean-publish-form-algorithms'))
.initialValues as MetadataPublishFormAlgorithm)) ||
initialValuesAlgorithm
)
const [datasetInitialValues, setdatasetInitialValues] = useState<
Partial<MetadataPublishFormDataset>
>(
(localStorage.getItem('ocean-publish-form-datasets') &&
(JSON.parse(localStorage.getItem('ocean-publish-form-datasets'))
.initialValues as MetadataPublishFormDataset)) ||
initialValues
)
const [publishType, setPublishType] =
useState<MetadataMain['type']>('dataset')
const hasFeedback = isLoading || error || success
const emptyAlgoDT = Object.values(algoInitialValues.dataTokenOptions).every(
(value) => value === ''
)
const emptyDatasetDT = Object.values(
datasetInitialValues.dataTokenOptions
).every((value) => value === '')
if (emptyAlgoDT) {
algoInitialValues.dataTokenOptions = datasetInitialValues.dataTokenOptions
} else {
if (emptyDatasetDT)
datasetInitialValues.dataTokenOptions = algoInitialValues.dataTokenOptions
}
useEffect(() => {
publishType === 'dataset'
? setTitle('Publishing Data Set')
: setTitle('Publishing Algorithm')
}, [publishType])
async function handleSubmit(
values: Partial<MetadataPublishFormDataset>,
resetForm: (
nextState?: Partial<FormikState<Partial<MetadataPublishFormDataset>>>
) => void
): Promise<void> {
const metadata = transformPublishFormToMetadata(values)
const timeout = mapTimeoutStringToSeconds(values.timeout)
const serviceType = values.access === 'Download' ? 'access' : 'compute'
try {
Logger.log(
'Publish with ',
metadata,
serviceType,
values.dataTokenOptions
)
const ddo = await publish(
metadata as unknown as Metadata,
serviceType,
values.dataTokenOptions,
timeout
)
// Publish failed
if (!ddo || publishError) {
setError(publishError || 'Publishing DDO failed.')
Logger.error(publishError || 'Publishing DDO failed.')
return
}
// Publish succeeded
setDid(ddo.id)
setSuccess(
'🎉 Successfully published. 🎉 Now create a price on your data set.'
)
resetForm({
values: initialValues as MetadataPublishFormDataset,
status: 'empty'
})
} catch (error) {
setError(error.message)
Logger.error(error.message)
}
}
async function handleAlgorithmSubmit(
values: Partial<MetadataPublishFormAlgorithm>,
resetForm: (
nextState?: Partial<FormikState<Partial<MetadataPublishFormAlgorithm>>>
) => void
): Promise<void> {
const metadata = transformPublishAlgorithmFormToMetadata(values)
const timeout = mapTimeoutStringToSeconds(values.timeout)
// TODO: put back check once #572 is resolved
// https://github.com/oceanprotocol/market/issues/572
const validDockerImage = true
// const validDockerImage =
// values.dockerImage === 'custom image'
// ? await validateDockerImage(values.image, values.containerTag)
// : true
try {
if (validDockerImage) {
Logger.log('Publish algorithm with ', metadata, values.dataTokenOptions)
const ddo = await publish(
metadata as unknown as Metadata,
values.algorithmPrivacy === true ? 'compute' : 'access',
values.dataTokenOptions,
timeout
)
// Publish failed
if (!ddo || publishError) {
setError(publishError || 'Publishing DDO failed.')
Logger.error(publishError || 'Publishing DDO failed.')
return
}
// Publish succeeded
setDid(ddo.id)
setSuccess(
'🎉 Successfully published. 🎉 Now create a price for your algorithm.'
)
resetForm({
values: initialValuesAlgorithm as MetadataPublishFormAlgorithm,
status: 'empty'
})
}
} catch (error) {
setError(error.message)
Logger.error(error.message)
}
}
return isInPurgatory && purgatoryData ? null : (
<Permission eventType="publish">
<Formik
initialValues={
publishType === 'dataset' ? datasetInitialValues : algoInitialValues
}
initialStatus="empty"
validationSchema={
publishType === 'dataset'
? validationSchema
: validationSchemaAlgorithm
}
onSubmit={async (values, { resetForm }) => {
// move user's focus to top of screen
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
// kick off publishing
publishType === 'dataset'
? await handleSubmit(values, resetForm)
: await handleAlgorithmSubmit(values, resetForm)
}}
enableReinitialize
>
{({ values }) => {
const tabs = [
{
title: 'Data Set',
content: <TabContent values={values} publishType={publishType} />
},
{
title: 'Algorithm',
content: <TabContent values={values} publishType={publishType} />
}
]
return (
<>
<Persist
name={
publishType === 'dataset'
? formNameDatasets
: formNameAlgorithms
}
ignoreFields={['isSubmitting']}
/>
{hasFeedback ? (
<MetadataFeedback
title={title}
error={error}
success={success}
loading={publishStepText}
setError={setError}
successAction={{
name: `Go to ${
publishType === 'dataset' ? 'data set' : 'algorithm'
}`,
to: `/asset/${did}`
}}
/>
) : (
<>
<Alert
text={content.warning}
state="info"
className={styles.alert}
/>
<Tabs
className={styles.tabs}
items={tabs}
handleTabChange={(title) => {
setPublishType(
title.toLowerCase().replace(' ', '') as any
)
title === 'Algorithm'
? setdatasetInitialValues(values)
: setAlgoInitialValues(values)
}}
/>
</>
)}
{debug === true && <Debug values={values} />}
</>
)
}}
</Formik>
</Permission>
)
}