Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update metadata, the proper way #292

Merged
merged 29 commits into from
Dec 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0463d36
prototype view switching
kremalicious Dec 4, 2020
544499f
refactor, more UI
kremalicious Dec 4, 2020
85cc90c
formik form setup & data flow
kremalicious Dec 4, 2020
5268d68
debug output, fixes, refactor
kremalicious Dec 4, 2020
c825d43
description preview refactor
kremalicious Dec 4, 2020
a84e1f7
publish/update date changes
kremalicious Dec 7, 2020
8cdeb5a
owner check for edit link
kremalicious Dec 7, 2020
8c822db
all the feedback states and switching between them: loading, error, s…
kremalicious Dec 7, 2020
e973ae1
refactor feedback, one component for publish & edit
kremalicious Dec 7, 2020
ce05c8c
action & date output fixes
kremalicious Dec 7, 2020
a1e7453
move all content, iterate form fields from it
kremalicious Dec 7, 2020
18f65ea
UI updates
kremalicious Dec 7, 2020
3a61ff3
styling tweaks
kremalicious Dec 7, 2020
a6008c3
ddo dataflow refactor, more useAsset usage
kremalicious Dec 8, 2020
644d806
more useAsset usage
kremalicious Dec 8, 2020
cf6ce26
form actions styling
kremalicious Dec 8, 2020
4ed7949
prepare edit history component
kremalicious Dec 8, 2020
cbd270a
metadata output tweaks
kremalicious Dec 8, 2020
0225108
copy
kremalicious Dec 9, 2020
3bfb43b
safeguard against profile urls without protocol defined
kremalicious Dec 9, 2020
6314552
refetch ddo after edit
mihaisc Dec 9, 2020
318768c
Merge branch 'feature/metadata-update' of https://github.com/oceanpro…
mihaisc Dec 9, 2020
f253c19
switch author for dataTokenOptions in metadata preview
kremalicious Dec 9, 2020
285eac4
refactor
kremalicious Dec 9, 2020
ae4cedd
copy
kremalicious Dec 9, 2020
832ac3a
showPricing fix
kremalicious Dec 9, 2020
07f46b3
validation: minimum characters for title & description
kremalicious Dec 9, 2020
5345f25
disable submit button when validation fails
kremalicious Dec 9, 2020
b506a62
form validation fixes
kremalicious Dec 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions content/pages/edit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"description": "Update selected metadata 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": "name",
"label": "New Title",
"placeholder": "e.g. Shapes of Desert Plants",
"help": "Enter a concise title.",
"required": true
},
{
"name": "description",
"label": "New Description",
"help": "Add a thorough description with as much detail as possible. You can use [Markdown](https://daringfireball.net/projects/markdown/basics).",
"type": "textarea",
"rows": 10,
"required": true
}
]
}
}
18 changes: 18 additions & 0 deletions src/components/atoms/DebugOutput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React, { ReactElement } from 'react'

export default function DebugOutput({
title,
output
}: {
title: string
output: any
}): ReactElement {
return (
<div>
<h5>{title}</h5>
<pre>
<code>{JSON.stringify(output, null, 2)}</code>
</pre>
</div>
)
}
12 changes: 2 additions & 10 deletions src/components/atoms/Input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,7 @@ export interface InputProps {
}

export default function Input(props: Partial<InputProps>): ReactElement {
const {
required,
name,
label,
help,
additionalComponent,
size,
field
} = props
const { label, help, additionalComponent, size, field } = props

const hasError =
props.form?.touched[field.name] && props.form?.errors[field.name]
Expand All @@ -67,7 +59,7 @@ export default function Input(props: Partial<InputProps>): ReactElement {
className={styleClasses}
data-is-submitting={props.form?.isSubmitting ? true : null}
>
<Label htmlFor={name} required={required}>
<Label htmlFor={props.name} required={props.required}>
{label}
</Label>
<InputElement size={size} {...field} {...props} />
Expand Down
8 changes: 8 additions & 0 deletions src/components/atoms/Markdown.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
word-break: break-word;
}

.markdown h1,
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5 {
margin-bottom: calc(var(--spacer) / 2);
}

.markdown h1 {
font-size: var(--font-size-h3);
}
Expand Down
4 changes: 3 additions & 1 deletion src/components/atoms/Publisher/PublisherLinks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export default function PublisherLinks({
? `https://twitter.com/${link.value}`
: link.name === 'GitHub'
? `https://github.com/${link.value}`
: link.value
: link.value.includes('http') // safeguard against urls without protocol defined
? link.value
: `//${link.value}`

return (
<a href={href} key={link.name} target="_blank" rel="noreferrer">
Expand Down
9 changes: 5 additions & 4 deletions src/components/atoms/Time.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { ReactElement, useEffect, useState } from 'react'
import { format, formatDistance } from 'date-fns'
import { setDate } from 'date-fns/esm'

export default function Time({
date,
Expand All @@ -15,24 +14,26 @@ export default function Time({
}): ReactElement {
const [dateIso, setDateIso] = useState<string>()
const [dateNew, setDateNew] = useState<Date>()

useEffect(() => {
if (!date) return

const dateNew = isUnix ? new Date(Number(date) * 1000) : new Date(date)
setDateIso(dateNew.toISOString())
setDateNew(dateNew)
}, [date])
}, [date, isUnix])

return !dateIso || !dateNew ? (
<></>
) : (
<time
title={relative ? format(dateNew, 'MMMM d, yyyy') : undefined}
title={format(dateNew, 'PPppp')}
dateTime={dateIso}
className={className || undefined}
>
{relative
? formatDistance(dateNew, Date.now(), { addSuffix: true })
: format(dateNew, 'MMMM d, yyyy')}
: format(dateNew, 'PP')}
</time>
)
}
28 changes: 19 additions & 9 deletions src/components/molecules/FormFields/FilesInput/Info.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import React, { ReactElement } from 'react'
import React, { ReactElement, useEffect } from 'react'
import { File as FileMetadata } from '@oceanprotocol/lib/dist/node/ddo/interfaces/File'
import { prettySize } from '../../../../utils'
import cleanupContentType from '../../../../utils/cleanupContentType'
import styles from './Info.module.css'
import { useField, useFormikContext } from 'formik'

export default function FileInfo({
file,
removeItem
name,
file
}: {
name: string
file: FileMetadata
removeItem?(): void
}): ReactElement {
const { validateField } = useFormikContext()
const [field, meta, helpers] = useField(name)

// On mount, validate the field manually
useEffect(() => {
validateField(name)
}, [name, validateField])

return (
<div className={styles.info}>
<h3 className={styles.url}>{file.url}</h3>
Expand All @@ -19,11 +28,12 @@ export default function FileInfo({
{file.contentLength && <li>{prettySize(+file.contentLength)}</li>}
{file.contentType && <li>{cleanupContentType(file.contentType)}</li>}
</ul>
{removeItem && (
<button className={styles.removeButton} onClick={() => removeItem()}>
&times;
</button>
)}
<button
className={styles.removeButton}
onClick={() => helpers.setValue(undefined)}
>
&times;
</button>
</div>
)
}
10 changes: 5 additions & 5 deletions src/components/molecules/FormFields/FilesInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export default function FilesInput(props: InputProps): ReactElement {
const [isLoading, setIsLoading] = useState(false)

async function handleButtonClick(e: React.SyntheticEvent, url: string) {
// hack so the onBlur-triggered validation does not show,
// like when this field is required
helpers.setTouched(false)

// File example 'https://oceanprotocol.com/tech-whitepaper.pdf'
e.preventDefault()

Expand All @@ -26,14 +30,10 @@ export default function FilesInput(props: InputProps): ReactElement {
}
}

function removeItem() {
helpers.setValue(undefined)
}

return (
<>
{field?.value && field.value[0] && typeof field.value === 'object' ? (
<FileInfo file={field.value[0]} removeItem={removeItem} />
<FileInfo name={props.name} file={field.value[0]} />
) : (
<FileInput
{...props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}

.box {
composes: box from '../../atoms/Box.module.css';
composes: box from '../atoms/Box.module.css';
width: 100%;
}

Expand Down
78 changes: 78 additions & 0 deletions src/components/molecules/MetadataFeedback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import Alert from '../atoms/Alert'
import Button from '../atoms/Button'
import Loader from '../atoms/Loader'
import React, { ReactElement } from 'react'
import styles from './MetadataFeedback.module.css'
import SuccessConfetti from '../atoms/SuccessConfetti'

interface Action {
name: string
onClick?: () => void
to?: string
}

function ActionSuccess({ action }: { action: Action }) {
const { name, onClick, to } = action

return (
<Button
style="primary"
size="small"
onClick={onClick || null}
to={to || null}
className={styles.action}
>
{name}
</Button>
)
}

function ActionError({ setError }: { setError: (error: string) => void }) {
return (
<Button
style="primary"
size="small"
className={styles.action}
onClick={() => setError(undefined)}
>
Try Again
</Button>
)
}

export default function MetadataFeedback({
title,
error,
success,
loading,
successAction,
setError
}: {
title: string
error: string
success: string
loading?: string
successAction: Action
setError: (error: string) => void
}): ReactElement {
return (
<div className={styles.feedback}>
<div className={styles.box}>
<h3>{title}</h3>
{error ? (
<>
<Alert text={error} state="error" />
<ActionError setError={setError} />
</>
) : success ? (
<SuccessConfetti
success={success}
action={<ActionSuccess action={successAction} />}
/>
) : (
<Loader message={loading} />
)}
</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@
margin: 0;
}

.author {
.datatoken {
margin-top: calc(var(--spacer) / 8);
margin-bottom: 0;
color: var(--color-secondary);
font-weight: var(--font-weight-bold);
}

.preview [class*='MetaItem-module--metaItem'] h3 {
Expand Down
Loading