mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
kinda make file input work
This commit is contained in:
parent
b3e4940d08
commit
482a307f80
@ -16,7 +16,7 @@
|
||||
"label": "Files",
|
||||
"placeholder": "e.g. https://file.com/file.json",
|
||||
"help": "Please provide a URL to your data set file.",
|
||||
"type": "url",
|
||||
"type": "files",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React from 'react'
|
||||
import React, { ReactElement } from 'react'
|
||||
import slugify from '@sindresorhus/slugify'
|
||||
import styles from './InputElement.module.css'
|
||||
import { InputProps } from '.'
|
||||
import FilesInput from '../../molecules/FilesInput'
|
||||
|
||||
export default function InputElement(props: InputProps) {
|
||||
export default function InputElement(props: InputProps): ReactElement {
|
||||
const { type, options, rows, name } = props
|
||||
|
||||
switch (type) {
|
||||
@ -52,6 +53,8 @@ export default function InputElement(props: InputProps) {
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
case 'files':
|
||||
return <FilesInput name={name} {...props} />
|
||||
default:
|
||||
return (
|
||||
<input
|
||||
|
@ -1,3 +1,7 @@
|
||||
.field {
|
||||
margin-bottom: var(--spacer);
|
||||
}
|
||||
|
||||
.field .field {
|
||||
margin-bottom: calc(var(--spacer) / 2);
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ export interface InputProps {
|
||||
}
|
||||
}
|
||||
|
||||
export default function Input(props: InputProps) {
|
||||
export default function Input(props: InputProps): ReactElement {
|
||||
const {
|
||||
required,
|
||||
name,
|
||||
@ -54,6 +54,11 @@ export default function Input(props: InputProps) {
|
||||
|
||||
{help && <Help>{help}</Help>}
|
||||
{additionalComponent && additionalComponent}
|
||||
|
||||
{/* TODO: Make field errors show up here */}
|
||||
{/* {meta && meta.touched && meta.error ? (
|
||||
<div className="error">{meta.error}</div>
|
||||
) : null} */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
40
src/components/molecules/FilesInput/Info.module.css
Normal file
40
src/components/molecules/FilesInput/Info.module.css
Normal file
@ -0,0 +1,40 @@
|
||||
.info {
|
||||
border-radius: var(--border-radius);
|
||||
padding: calc(var(--spacer) / 2);
|
||||
border: 1px solid var(--brand-grey-lighter);
|
||||
background-color: var(--brand-grey-dimmed);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.url {
|
||||
margin: 0;
|
||||
font-size: var(--font-size-base);
|
||||
line-height: var(--line-height);
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
padding-right: calc(var(--spacer) / 2);
|
||||
}
|
||||
|
||||
.info ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info li {
|
||||
display: inline-block;
|
||||
font-size: var(--font-size-small);
|
||||
margin-right: calc(var(--spacer) / 2);
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.removeButton {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
position: absolute;
|
||||
top: -0.2rem;
|
||||
right: 0;
|
||||
font-size: var(--font-size-h3);
|
||||
cursor: pointer;
|
||||
color: var(--brand-grey);
|
||||
background-color: transparent;
|
||||
}
|
27
src/components/molecules/FilesInput/Info.tsx
Normal file
27
src/components/molecules/FilesInput/Info.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { File } from '@oceanprotocol/squid'
|
||||
import { prettySize } from '../../../utils'
|
||||
import cleanupContentType from '../../../utils/cleanupContentType'
|
||||
import styles from './Info.module.css'
|
||||
|
||||
export default function FileInfo({
|
||||
file,
|
||||
removeItem
|
||||
}: {
|
||||
file: File
|
||||
removeItem(): void
|
||||
}): ReactElement {
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<h3 className={styles.url}>{file.url}</h3>
|
||||
<ul>
|
||||
<li>URL confirmed</li>
|
||||
{file.contentLength && <li>{prettySize(+file.contentLength)}</li>}
|
||||
{file.contentType && <li>{cleanupContentType(file.contentType)}</li>}
|
||||
</ul>
|
||||
<button className={styles.removeButton} onClick={() => removeItem()}>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
31
src/components/molecules/FilesInput/Input.tsx
Normal file
31
src/components/molecules/FilesInput/Input.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import isUrl from 'is-url-superb'
|
||||
import Button from '../../atoms/Button'
|
||||
import Input from '../../atoms/Input'
|
||||
import { useField, FormikProps } from 'formik'
|
||||
import { File } from '@oceanprotocol/squid'
|
||||
|
||||
export default function FileInput({
|
||||
handleButtonClick,
|
||||
...props
|
||||
}: {
|
||||
handleButtonClick(e: React.SyntheticEvent, data: string): void
|
||||
props: FormikProps<File>
|
||||
}): ReactElement {
|
||||
const [field, meta, helpers] = useField(props)
|
||||
console.log(field)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Input type="url" name="url" placeholder="e.g." {...field} />
|
||||
|
||||
<Button
|
||||
size="small"
|
||||
onClick={(e: React.SyntheticEvent) => handleButtonClick(e, field.value)}
|
||||
// disabled={!isUrl(field && field.value)}
|
||||
>
|
||||
Add File
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
}
|
57
src/components/molecules/FilesInput/index.tsx
Normal file
57
src/components/molecules/FilesInput/index.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import React, { ReactElement, useState } from 'react'
|
||||
import isUrl from 'is-url-superb'
|
||||
import { useField, FormikProps } from 'formik'
|
||||
import { File } from '@oceanprotocol/squid'
|
||||
import { toast } from 'react-toastify'
|
||||
import Input from '../../atoms/Input'
|
||||
import Button from '../../atoms/Button'
|
||||
import Loader from '../../atoms/Loader'
|
||||
import styles from './index.module.css'
|
||||
import FileInfo from './Info'
|
||||
import FileInput from './Input'
|
||||
import shortid from 'shortid'
|
||||
import { getFileInfo } from '../../../utils'
|
||||
|
||||
interface Values {
|
||||
url: string
|
||||
}
|
||||
|
||||
export default function FilesInput(props: FormikProps<File>): ReactElement {
|
||||
const [field, meta, helpers] = useField(props)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [file, setFile] = useState<File>()
|
||||
|
||||
const handleButtonClick = async (e: React.SyntheticEvent, url: string) => {
|
||||
// File example 'https://oceanprotocol.com/tech-whitepaper.pdf'
|
||||
e.preventDefault()
|
||||
|
||||
try {
|
||||
setIsLoading(true)
|
||||
const newFileInfo = await getFileInfo(url)
|
||||
newFileInfo && setFile(newFileInfo)
|
||||
} catch (error) {
|
||||
toast.error('Could not fetch file info. Please check url and try again')
|
||||
console.error(error.message)
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
function removeItem() {
|
||||
setFile(undefined)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{file ? (
|
||||
<FileInfo file={file} removeItem={removeItem} />
|
||||
) : (
|
||||
<FileInput
|
||||
{...props}
|
||||
{...field}
|
||||
handleButtonClick={handleButtonClick}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import Form, { transformErrors } from '../../../src/components/molecules/Form'
|
||||
import Form, {
|
||||
transformErrors
|
||||
} from '../../../src/components/molecules/FilesInput'
|
||||
import {
|
||||
publishFormData,
|
||||
PublishFormDataInterface,
|
||||
@ -8,7 +10,7 @@ import {
|
||||
PublishFormUiSchema
|
||||
} from '../../../src/models/PublishForm'
|
||||
import testFormData from '../__fixtures__/testFormData'
|
||||
import { transformPublishFormToMetadata } from '../../../src/components/pages/Publish/PublishForm'
|
||||
import { transformPublishFormToMetadata } from '../../../src/components/pages/Publish/utils'
|
||||
import { MetaDataMarket } from '../../../src/@types/MetaData'
|
||||
|
||||
describe('PublishForm', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user