mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Multinetwork UI additions (#729)
* add BSC to default chains * searchbar visual tweaks * race condition fix * network name tweaks * beta → v3 * use publish form titles to inform about network * form actions refactor * simplify network name on asset details * visual indicator for selected chains on button * lint fix * more layout flow tinkering, collapsed search by default * search field layout tweaks * unknown network/gaia-x name fixes * put back search cancel button in webkit * space fixes * cross browser visual fixes
This commit is contained in:
parent
ac1c1fd31a
commit
a7998abb99
@ -5,7 +5,7 @@ module.exports = {
|
|||||||
|
|
||||||
// List of chainIds which metadata cache queries will return by default.
|
// List of chainIds which metadata cache queries will return by default.
|
||||||
// This preselects the Chains user preferences.
|
// This preselects the Chains user preferences.
|
||||||
chainIds: [1, 137],
|
chainIds: [1, 137, 56],
|
||||||
|
|
||||||
// List of all supported chainIds. Used to populate the Chains user preferences list.
|
// List of all supported chainIds. Used to populate the Chains user preferences list.
|
||||||
chainIdsSupported: [1, 3, 4, 137, 80001, 1287, 56],
|
chainIdsSupported: [1, 3, 4, 137, 80001, 1287, 56],
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"title": "Publish",
|
"title": "Publish",
|
||||||
"description": "Highlight the important features of your data set or algorithm to make it more discoverable and catch the interest of data consumers.",
|
"description": "Highlight the important features of your data set or algorithm to make it more discoverable and catch the interest of data consumers.",
|
||||||
"warning": "Given the beta status, publishing on Ropsten or Rinkeby first is strongly recommended. Please familiarize yourself with [the market](https://oceanprotocol.com/technology/marketplaces), [the risks](https://blog.oceanprotocol.com/on-staking-on-data-in-ocean-market-3d8e09eb0a13), and the [Terms of Use](/terms)."
|
"warning": "Given the beta status, publishing on Ropsten or Rinkeby first is strongly recommended. Please familiarize yourself with [the market](https://oceanprotocol.com/technology/marketplaces), [the risks](https://blog.oceanprotocol.com/on-staking-on-data-in-ocean-market-3d8e09eb0a13), and the [Terms of Use](/terms).",
|
||||||
|
"tooltipNetwork": "Assets are published into the network your wallet is connected to. Switch your wallet's network to publish into another one."
|
||||||
}
|
}
|
||||||
|
@ -10,19 +10,7 @@
|
|||||||
.typeLabel {
|
.typeLabel {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
border-right: 1px solid var(--border-color);
|
|
||||||
padding-right: calc(var(--spacer) / 3.5);
|
|
||||||
margin-right: calc(var(--spacer) / 4);
|
|
||||||
border-left: 1px solid var(--border-color);
|
border-left: 1px solid var(--border-color);
|
||||||
padding-left: calc(var(--spacer) / 3.5);
|
padding-left: calc(var(--spacer) / 3.5);
|
||||||
margin-left: calc(var(--spacer) / 4);
|
margin-left: calc(var(--spacer) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.network {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.network svg {
|
|
||||||
vertical-align: baseline;
|
|
||||||
margin-bottom: -0.15em;
|
|
||||||
}
|
|
||||||
|
@ -4,19 +4,16 @@ import classNames from 'classnames/bind'
|
|||||||
import { ReactComponent as Compute } from '../../images/compute.svg'
|
import { ReactComponent as Compute } from '../../images/compute.svg'
|
||||||
import { ReactComponent as Download } from '../../images/download.svg'
|
import { ReactComponent as Download } from '../../images/download.svg'
|
||||||
import { ReactComponent as Lock } from '../../images/lock.svg'
|
import { ReactComponent as Lock } from '../../images/lock.svg'
|
||||||
import NetworkName from './NetworkName'
|
|
||||||
|
|
||||||
const cx = classNames.bind(styles)
|
const cx = classNames.bind(styles)
|
||||||
|
|
||||||
export default function AssetType({
|
export default function AssetType({
|
||||||
type,
|
type,
|
||||||
accessType,
|
accessType,
|
||||||
className,
|
className
|
||||||
chainId
|
|
||||||
}: {
|
}: {
|
||||||
type: string
|
type: string
|
||||||
accessType: string
|
accessType: string
|
||||||
chainId: number
|
|
||||||
className?: string
|
className?: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const styleClasses = cx({
|
const styleClasses = cx({
|
||||||
@ -35,10 +32,6 @@ export default function AssetType({
|
|||||||
<div className={styles.typeLabel}>
|
<div className={styles.typeLabel}>
|
||||||
{type === 'dataset' ? 'data set' : 'algorithm'}
|
{type === 'dataset' ? 'data set' : 'algorithm'}
|
||||||
</div>
|
</div>
|
||||||
{/* TODO: networkId needs to come from the multinetwork DDO for each asset */}
|
|
||||||
{chainId && (
|
|
||||||
<NetworkName networkId={chainId} className={styles.network} minimal />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
box-shadow: 0 6px 17px 0 var(--box-shadow-color);
|
box-shadow: 0 6px 17px 0 var(--box-shadow-color);
|
||||||
overflow: hidden;
|
|
||||||
padding: calc(var(--spacer) / 1.5);
|
padding: calc(var(--spacer) / 1.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,6 @@ export interface InputProps {
|
|||||||
defaultChecked?: boolean
|
defaultChecked?: boolean
|
||||||
size?: 'mini' | 'small' | 'large' | 'default'
|
size?: 'mini' | 'small' | 'large' | 'default'
|
||||||
className?: string
|
className?: string
|
||||||
divClassName?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Input(props: Partial<InputProps>): ReactElement {
|
export default function Input(props: Partial<InputProps>): ReactElement {
|
||||||
@ -58,13 +57,10 @@ export default function Input(props: Partial<InputProps>): ReactElement {
|
|||||||
const hasError =
|
const hasError =
|
||||||
props.form?.touched[field.name] && props.form?.errors[field.name]
|
props.form?.touched[field.name] && props.form?.errors[field.name]
|
||||||
|
|
||||||
const styleClasses = cx(
|
const styleClasses = cx({
|
||||||
{
|
field: true,
|
||||||
field: true,
|
hasError: hasError
|
||||||
hasError: hasError
|
})
|
||||||
},
|
|
||||||
props.divClassName
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 1rem;
|
width: 1em;
|
||||||
height: 1rem;
|
height: 1em;
|
||||||
cursor: help;
|
cursor: help;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-bottom: -0.1rem;
|
margin-bottom: -0.1em;
|
||||||
margin-left: calc(var(--spacer) / 6);
|
margin-left: calc(var(--spacer) / 6);
|
||||||
fill: var(--color-secondary);
|
fill: var(--color-secondary);
|
||||||
}
|
}
|
||||||
|
@ -70,5 +70,4 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
right: calc(var(--spacer) / 3);
|
right: calc(var(--spacer) / 3);
|
||||||
bottom: calc(var(--spacer) / 3);
|
bottom: calc(var(--spacer) / 3);
|
||||||
text-transform: uppercase !important;
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({
|
|||||||
ddo,
|
ddo,
|
||||||
price
|
price
|
||||||
}: AssetTeaserProps) => {
|
}: AssetTeaserProps) => {
|
||||||
const { config } = useOcean()
|
|
||||||
const { attributes } = ddo.findServiceByType('metadata')
|
const { attributes } = ddo.findServiceByType('metadata')
|
||||||
const { name, type } = attributes.main
|
const { name, type } = attributes.main
|
||||||
const { dataTokenInfo } = ddo
|
const { dataTokenInfo } = ddo
|
||||||
@ -42,7 +41,6 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({
|
|||||||
type={type}
|
type={type}
|
||||||
accessType={accessType}
|
accessType={accessType}
|
||||||
className={styles.typeDetails}
|
className={styles.typeDetails}
|
||||||
chainId={ddo.chainId}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
@ -55,6 +53,7 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({
|
|||||||
|
|
||||||
<footer className={styles.foot}>
|
<footer className={styles.foot}>
|
||||||
<Price price={price} small />
|
<Price price={price} small />
|
||||||
|
<NetworkName networkId={ddo.chainId} className={styles.network} />
|
||||||
</footer>
|
</footer>
|
||||||
</Link>
|
</Link>
|
||||||
</article>
|
</article>
|
||||||
|
@ -2,88 +2,55 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding: calc(var(--spacer) / 2);
|
padding: calc(var(--spacer) / 2);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
|
order: 1;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 0 auto;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation {
|
.navigation {
|
||||||
width: auto;
|
order: 3;
|
||||||
margin: 0;
|
margin-top: calc(var(--spacer) / 2);
|
||||||
text-align: left;
|
text-align: center;
|
||||||
border: none;
|
border-top: 1px solid var(--border-color);
|
||||||
}
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
margin-left: -1rem;
|
||||||
.search {
|
margin-right: -1rem;
|
||||||
display: flex;
|
width: calc(100% + 2rem);
|
||||||
flex: 1 0 auto;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
align-self: flex-start;
|
|
||||||
padding-left: 20px;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
|
order: 2;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 0 auto;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
align-self: flex-start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 38rem) {
|
|
||||||
.actions {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
.navigation {
|
|
||||||
order: 3;
|
|
||||||
display: block;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: calc(var(--spacer) / 2);
|
|
||||||
text-align: center;
|
|
||||||
border-top: 1px solid var(--border-color);
|
|
||||||
border-bottom: 1px solid var(--border-color);
|
|
||||||
margin-left: -1rem;
|
|
||||||
margin-right: -1rem;
|
|
||||||
width: calc(50% + 2rem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 75rem) {
|
|
||||||
.navigation {
|
|
||||||
flex: 1 0 auto;
|
|
||||||
justify-content: left;
|
|
||||||
align-items: left;
|
|
||||||
}
|
|
||||||
.search {
|
|
||||||
flex: 0 0 100%;
|
|
||||||
padding-top: 10px;
|
|
||||||
order: 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 42rem) {
|
@media screen and (min-width: 42rem) {
|
||||||
|
.menu {
|
||||||
|
justify-content: start;
|
||||||
|
}
|
||||||
|
|
||||||
.navigation {
|
.navigation {
|
||||||
|
order: 2;
|
||||||
width: auto;
|
width: auto;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
order: 3;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 55rem) {
|
@media screen and (min-width: 55rem) {
|
||||||
@ -135,7 +102,7 @@
|
|||||||
.link:hover,
|
.link:hover,
|
||||||
.link:focus,
|
.link:focus,
|
||||||
.link:active {
|
.link:active {
|
||||||
color: var(--brand-grey);
|
color: var(--font-color-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.link[aria-current],
|
.link[aria-current],
|
||||||
|
@ -40,7 +40,7 @@ export default function Menu(): ReactElement {
|
|||||||
<Link to="/" className={styles.logo}>
|
<Link to="/" className={styles.logo}>
|
||||||
<Logo noWordmark />
|
<Logo noWordmark />
|
||||||
<h1 className={styles.title}>
|
<h1 className={styles.title}>
|
||||||
{siteTitle} <Badge label="beta" />
|
{siteTitle} <Badge label="v3" />
|
||||||
</h1>
|
</h1>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
@ -52,10 +52,8 @@ export default function Menu(): ReactElement {
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div className={styles.search}>
|
|
||||||
<SearchBar />
|
|
||||||
</div>
|
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
|
<SearchBar />
|
||||||
<Networks />
|
<Networks />
|
||||||
<Wallet />
|
<Wallet />
|
||||||
<UserPreferences />
|
<UserPreferences />
|
||||||
|
@ -1,49 +1,72 @@
|
|||||||
.search {
|
.search {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 0 auto;
|
position: relative;
|
||||||
align-self: stretch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
padding: calc(var(--spacer) / 6) calc(var(--spacer) / 3);
|
color: var(--color-secondary);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid var(--border-color);
|
background: var(--background-content);
|
||||||
border-radius: var(--border-radius);
|
border: none;
|
||||||
background-color: var(--background-content);
|
box-shadow: none;
|
||||||
border-left: none;
|
padding: 0;
|
||||||
white-space: nowrap;
|
position: absolute;
|
||||||
min-width: 4rem;
|
padding: calc(var(--spacer) / 4);
|
||||||
|
width: 100%;
|
||||||
|
right: 1px;
|
||||||
|
left: 1px;
|
||||||
|
top: 1px;
|
||||||
|
bottom: 1px;
|
||||||
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:hover,
|
.button:hover,
|
||||||
.button:focus {
|
.button:focus {
|
||||||
color: var(--brand-white);
|
color: var(--font-color-text);
|
||||||
text-decoration: none;
|
|
||||||
transform: translate3d(0, -0.05rem, 0);
|
|
||||||
box-shadow: 0 12px 30px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
height: 36px !important;
|
background-color: transparent;
|
||||||
border-top-right-radius: 0px;
|
height: 36px;
|
||||||
border-bottom-right-radius: 0px;
|
margin: 0;
|
||||||
|
outline: 0;
|
||||||
|
padding-right: var(--spacer);
|
||||||
|
width: 0;
|
||||||
|
transition: none;
|
||||||
}
|
}
|
||||||
.searchInput {
|
|
||||||
flex-grow: 2;
|
.input:focus {
|
||||||
margin-bottom: 0px;
|
width: calc(100% - var(--spacer));
|
||||||
|
background-color: var(--background-content);
|
||||||
|
position: fixed;
|
||||||
|
left: calc(var(--spacer) / 2);
|
||||||
|
right: 0;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 78rem) {
|
||||||
|
.input,
|
||||||
|
.input:focus {
|
||||||
|
width: auto;
|
||||||
|
position: relative;
|
||||||
|
left: initial;
|
||||||
|
right: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
width: auto;
|
||||||
|
left: auto;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input:focus + .button {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchIcon {
|
.searchIcon {
|
||||||
fill: var(--brand-grey-light);
|
fill: currentColor;
|
||||||
transition: 0.2s ease-out;
|
transition: 0.2s ease-out;
|
||||||
}
|
width: var(--font-size-h5);
|
||||||
.search > div > div {
|
height: var(--font-size-h5);
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search label {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search input {
|
|
||||||
background-color: var(--background-content);
|
|
||||||
}
|
}
|
||||||
|
@ -3,36 +3,49 @@ import React, {
|
|||||||
useEffect,
|
useEffect,
|
||||||
ChangeEvent,
|
ChangeEvent,
|
||||||
FormEvent,
|
FormEvent,
|
||||||
|
KeyboardEvent,
|
||||||
ReactElement
|
ReactElement
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { navigate } from 'gatsby'
|
import { navigate } from 'gatsby'
|
||||||
import queryString from 'query-string'
|
import queryString from 'query-string'
|
||||||
import styles from './SearchBar.module.css'
|
|
||||||
import Button from '../atoms/Button'
|
|
||||||
import Input from '../atoms/Input'
|
|
||||||
import InputGroup from '../atoms/Input/InputGroup'
|
|
||||||
import { addExistingParamsToUrl } from '../templates/Search/utils'
|
import { addExistingParamsToUrl } from '../templates/Search/utils'
|
||||||
import { ReactComponent as SearchIcon } from '../../images/search.svg'
|
import { ReactComponent as SearchIcon } from '../../images/search.svg'
|
||||||
|
import InputElement from '../atoms/Input/InputElement'
|
||||||
|
import styles from './SearchBar.module.css'
|
||||||
|
|
||||||
|
async function emptySearch() {
|
||||||
|
const searchParams = new URLSearchParams(window.location.href)
|
||||||
|
const text = searchParams.get('text')
|
||||||
|
if (text !== ('' || undefined || null)) {
|
||||||
|
const url = await addExistingParamsToUrl(location, [
|
||||||
|
'text',
|
||||||
|
'owner',
|
||||||
|
'tags'
|
||||||
|
])
|
||||||
|
navigate(`${url}&text=%20`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function SearchBar({
|
export default function SearchBar({
|
||||||
placeholder,
|
placeholder,
|
||||||
initialValue,
|
initialValue
|
||||||
size
|
|
||||||
}: {
|
}: {
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
initialValue?: string
|
initialValue?: string
|
||||||
size?: 'small' | 'large'
|
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
let [value, setValue] = useState(initialValue || '')
|
const [value, setValue] = useState(initialValue || '')
|
||||||
const parsed = queryString.parse(location.search)
|
const parsed = queryString.parse(location.search)
|
||||||
const { text, owner } = parsed
|
const { text, owner } = parsed
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
;(text || owner) && setValue((text || owner) as string)
|
;(text || owner) && setValue((text || owner) as string)
|
||||||
}, [text, owner])
|
}, [text, owner])
|
||||||
|
|
||||||
async function startSearch(e: FormEvent<HTMLButtonElement>) {
|
async function startSearch(e: FormEvent<HTMLButtonElement>) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (value === '') value = ' '
|
|
||||||
|
if (value === '') setValue(' ')
|
||||||
|
|
||||||
const urlEncodedValue = encodeURIComponent(value)
|
const urlEncodedValue = encodeURIComponent(value)
|
||||||
const url = await addExistingParamsToUrl(location, [
|
const url = await addExistingParamsToUrl(location, [
|
||||||
'text',
|
'text',
|
||||||
@ -42,52 +55,38 @@ export default function SearchBar({
|
|||||||
navigate(`${url}&text=${urlEncodedValue}`)
|
navigate(`${url}&text=${urlEncodedValue}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function emptySearch() {
|
|
||||||
const searchParams = new URLSearchParams(window.location.href)
|
|
||||||
const text = searchParams.get('text')
|
|
||||||
if (text !== ('' || undefined || null)) {
|
|
||||||
const url = await addExistingParamsToUrl(location, [
|
|
||||||
'text',
|
|
||||||
'owner',
|
|
||||||
'tags'
|
|
||||||
])
|
|
||||||
navigate(`${url}&text=%20`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleChange(e: ChangeEvent<HTMLInputElement>) {
|
function handleChange(e: ChangeEvent<HTMLInputElement>) {
|
||||||
setValue(e.target.value)
|
setValue(e.target.value)
|
||||||
e.target.value === '' && emptySearch()
|
e.target.value === '' && emptySearch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleKeyPress(e: KeyboardEvent<HTMLInputElement>) {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
await startSearch(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleButtonClick(e: FormEvent<HTMLButtonElement>) {
|
||||||
|
e.preventDefault()
|
||||||
|
await startSearch(e)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className={styles.search}>
|
<form className={styles.search}>
|
||||||
<Input
|
<InputElement
|
||||||
type="search"
|
type="search"
|
||||||
name="search"
|
name="search"
|
||||||
placeholder={placeholder || 'What are you looking for?'}
|
placeholder={placeholder || 'Search...'}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
required
|
required
|
||||||
size="small"
|
size="small"
|
||||||
divClassName={styles.searchInput}
|
|
||||||
className={styles.input}
|
className={styles.input}
|
||||||
onKeyPress={async (e: React.KeyboardEvent<HTMLInputElement>) => {
|
onKeyPress={handleKeyPress}
|
||||||
if (e.key === 'Enter') {
|
|
||||||
await startSearch(e)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<Button
|
<button onClick={handleButtonClick} className={styles.button}>
|
||||||
onClick={async (e: FormEvent<HTMLButtonElement>) =>
|
|
||||||
await startSearch(e)
|
|
||||||
}
|
|
||||||
style="text"
|
|
||||||
size="small"
|
|
||||||
className={styles.button}
|
|
||||||
>
|
|
||||||
<SearchIcon className={styles.searchIcon} />
|
<SearchIcon className={styles.searchIcon} />
|
||||||
</Button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,22 @@
|
|||||||
.network {
|
.networks {
|
||||||
margin-right: calc(var(--spacer) / 3);
|
margin-right: calc(var(--spacer) / 3);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chainsSelected {
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
bottom: -8px;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chainsSelectedIndicator {
|
||||||
|
width: 4px;
|
||||||
|
height: 4px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 0 1px;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import NetworksList from './NetworksList'
|
|||||||
import stylesIndex from '../index.module.css'
|
import stylesIndex from '../index.module.css'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import useNetworkMetadata from '../../../../hooks/useNetworkMetadata'
|
import useNetworkMetadata from '../../../../hooks/useNetworkMetadata'
|
||||||
|
import { useUserPreferences } from '../../../../providers/UserPreferences'
|
||||||
|
|
||||||
export function filterNetworksByType(
|
export function filterNetworksByType(
|
||||||
type: 'mainnet' | 'testnet',
|
type: 'mainnet' | 'testnet',
|
||||||
@ -32,6 +33,7 @@ export function filterNetworksByType(
|
|||||||
export default function Networks(): ReactElement {
|
export default function Networks(): ReactElement {
|
||||||
const { networksList } = useNetworkMetadata()
|
const { networksList } = useNetworkMetadata()
|
||||||
const { appConfig } = useSiteMetadata()
|
const { appConfig } = useSiteMetadata()
|
||||||
|
const { chainIds } = useUserPreferences()
|
||||||
|
|
||||||
const networksMain = filterNetworksByType(
|
const networksMain = filterNetworksByType(
|
||||||
'mainnet',
|
'mainnet',
|
||||||
@ -59,10 +61,16 @@ export default function Networks(): ReactElement {
|
|||||||
</ul>
|
</ul>
|
||||||
}
|
}
|
||||||
trigger="click focus"
|
trigger="click focus"
|
||||||
className={`${stylesIndex.preferences} ${styles.network}`}
|
className={`${stylesIndex.preferences} ${styles.networks}`}
|
||||||
>
|
>
|
||||||
<Network aria-label="Networks" className={stylesIndex.icon} />
|
<Network aria-label="Networks" className={stylesIndex.icon} />
|
||||||
<Caret aria-hidden="true" />
|
<Caret aria-hidden="true" className={stylesIndex.caret} />
|
||||||
|
|
||||||
|
<div className={styles.chainsSelected}>
|
||||||
|
{chainIds.map((chainId) => (
|
||||||
|
<span className={styles.chainsSelectedIndicator} key={chainId} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,21 @@
|
|||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.preferences svg:last-child {
|
.caret,
|
||||||
|
svg.caret {
|
||||||
width: var(--font-size-small);
|
width: var(--font-size-small);
|
||||||
height: var(--font-size-small);
|
height: var(--font-size-small);
|
||||||
fill: var(--border-color);
|
fill: var(--border-color);
|
||||||
margin-left: calc(var(--spacer) / 4);
|
margin-left: calc(var(--spacer) / 4);
|
||||||
transition: transform 0.2s ease-out;
|
transition: transform 0.2s ease-out;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 42rem) {
|
||||||
|
.caret,
|
||||||
|
svg.caret {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
|
@ -26,7 +26,7 @@ export default function UserPreferences(): ReactElement {
|
|||||||
className={styles.preferences}
|
className={styles.preferences}
|
||||||
>
|
>
|
||||||
<Cog aria-label="Preferences" className={styles.icon} />
|
<Cog aria-label="Preferences" className={styles.icon} />
|
||||||
<Caret aria-hidden="true" />
|
<Caret aria-hidden="true" className={styles.caret} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,16 @@
|
|||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button.initial span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 42rem) {
|
||||||
|
.button.initial span {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.blockies {
|
.blockies {
|
||||||
width: var(--font-size-large);
|
width: var(--font-size-large);
|
||||||
height: var(--font-size-large);
|
height: var(--font-size-large);
|
||||||
@ -76,3 +86,15 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
top: 1px;
|
top: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.caret,
|
||||||
|
svg.caret {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 42rem) {
|
||||||
|
.caret,
|
||||||
|
svg.caret {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -35,7 +35,7 @@ const Account = React.forwardRef((props, ref: any) => {
|
|||||||
return !accountId && web3Modal?.cachedProvider ? (
|
return !accountId && web3Modal?.cachedProvider ? (
|
||||||
// Improve user experience for cached provider when connecting takes some time
|
// Improve user experience for cached provider when connecting takes some time
|
||||||
<button className={styles.button} onClick={(e) => e.preventDefault()}>
|
<button className={styles.button} onClick={(e) => e.preventDefault()}>
|
||||||
<Loader message="Reconnecting wallet..." />
|
<Loader message="Reconnecting..." />
|
||||||
</button>
|
</button>
|
||||||
) : accountId ? (
|
) : accountId ? (
|
||||||
<button
|
<button
|
||||||
@ -48,7 +48,7 @@ const Account = React.forwardRef((props, ref: any) => {
|
|||||||
<span className={styles.address} title={accountId}>
|
<span className={styles.address} title={accountId}>
|
||||||
{accountTruncate(accountId)}
|
{accountTruncate(accountId)}
|
||||||
</span>
|
</span>
|
||||||
<Caret aria-hidden="true" />
|
<Caret aria-hidden="true" className={styles.caret} />
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
@ -58,7 +58,7 @@ const Account = React.forwardRef((props, ref: any) => {
|
|||||||
// the Tippy to show in this state.
|
// the Tippy to show in this state.
|
||||||
ref={ref}
|
ref={ref}
|
||||||
>
|
>
|
||||||
Connect Wallet
|
Connect <span>Wallet</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -32,6 +32,8 @@ export default function Details(): ReactElement {
|
|||||||
// const [portisNetwork, setPortisNetwork] = useState<string>()
|
// const [portisNetwork, setPortisNetwork] = useState<string>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!networkId) return
|
||||||
|
|
||||||
const symbol =
|
const symbol =
|
||||||
networkId === 2021000 ? 'GX' : networkData?.nativeCurrency.symbol
|
networkId === 2021000 ? 'GX' : networkData?.nativeCurrency.symbol
|
||||||
setMainCurrency(symbol)
|
setMainCurrency(symbol)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { ReactElement, useState } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import Account from './Account'
|
import Account from './Account'
|
||||||
import Details from './Details'
|
import Details from './Details'
|
||||||
import Tooltip from '../../atoms/Tooltip'
|
import Tooltip from '../../atoms/Tooltip'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.bookmark {
|
.bookmark {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -10px;
|
top: -3px;
|
||||||
right: calc(var(--spacer) / 8);
|
right: calc(var(--spacer) / 8);
|
||||||
appearance: none;
|
appearance: none;
|
||||||
background: none;
|
background: none;
|
||||||
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
.bookmark:hover,
|
.bookmark:hover,
|
||||||
.bookmark:focus {
|
.bookmark:focus {
|
||||||
transform: translate3d(0, 6px, 0);
|
transform: translate3d(0, -3px, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bookmark.active svg {
|
.bookmark.active svg {
|
||||||
|
@ -20,7 +20,6 @@ export default function MetaMain(): ReactElement {
|
|||||||
<AssetType
|
<AssetType
|
||||||
type={type}
|
type={type}
|
||||||
accessType={accessType}
|
accessType={accessType}
|
||||||
chainId={ddo.chainId}
|
|
||||||
className={styles.assetType}
|
className={styles.assetType}
|
||||||
/>
|
/>
|
||||||
<ExplorerLink
|
<ExplorerLink
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
|
.networkWrap {
|
||||||
|
display: block;
|
||||||
|
margin-top: -1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: calc(var(--spacer) * 1.5);
|
gap: calc(var(--spacer) * 1.5);
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-top: -1.5rem;
|
margin-top: -1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid > div {
|
.grid > div {
|
||||||
|
@ -19,6 +19,7 @@ import { useWeb3 } from '../../../providers/Web3'
|
|||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import EditAdvancedSettings from '../AssetActions/Edit/EditAdvancedSettings'
|
import EditAdvancedSettings from '../AssetActions/Edit/EditAdvancedSettings'
|
||||||
import { useSiteMetadata } from '../../../hooks/useSiteMetadata'
|
import { useSiteMetadata } from '../../../hooks/useSiteMetadata'
|
||||||
|
import NetworkName from '../../atoms/NetworkName'
|
||||||
|
|
||||||
export interface AssetContentProps {
|
export interface AssetContentProps {
|
||||||
path?: string
|
path?: string
|
||||||
@ -87,72 +88,82 @@ export default function AssetContent(props: AssetContentProps): ReactElement {
|
|||||||
) : showEditAdvancedSettings ? (
|
) : showEditAdvancedSettings ? (
|
||||||
<EditAdvancedSettings setShowEdit={setShowEditAdvancedSettings} />
|
<EditAdvancedSettings setShowEdit={setShowEditAdvancedSettings} />
|
||||||
) : (
|
) : (
|
||||||
<article className={styles.grid}>
|
<>
|
||||||
<div>
|
<div className={styles.networkWrap}>
|
||||||
{showPricing && <Pricing ddo={ddo} />}
|
<NetworkName networkId={ddo.chainId} className={styles.network} />
|
||||||
<div className={styles.content}>
|
</div>
|
||||||
<MetaMain />
|
|
||||||
<Bookmark did={ddo.id} />
|
|
||||||
|
|
||||||
{isInPurgatory ? (
|
<article className={styles.grid}>
|
||||||
<Alert
|
<div>
|
||||||
title={content.title}
|
{showPricing && <Pricing ddo={ddo} />}
|
||||||
badge={`Reason: ${purgatoryData?.reason}`}
|
<div className={styles.content}>
|
||||||
text={content.description}
|
<MetaMain />
|
||||||
state="error"
|
<Bookmark did={ddo.id} />
|
||||||
/>
|
|
||||||
) : (
|
{isInPurgatory ? (
|
||||||
<>
|
<Alert
|
||||||
<Markdown
|
title={content.title}
|
||||||
className={styles.description}
|
badge={`Reason: ${purgatoryData?.reason}`}
|
||||||
text={metadata?.additionalInformation?.description || ''}
|
text={content.description}
|
||||||
|
state="error"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Markdown
|
||||||
|
className={styles.description}
|
||||||
|
text={metadata?.additionalInformation?.description || ''}
|
||||||
|
/>
|
||||||
|
|
||||||
<MetaSecondary />
|
<MetaSecondary />
|
||||||
|
|
||||||
{isOwner && isAssetNetwork && (
|
{isOwner && isAssetNetwork && (
|
||||||
<div className={styles.ownerActions}>
|
<div className={styles.ownerActions}>
|
||||||
<Button style="text" size="small" onClick={handleEditButton}>
|
<Button
|
||||||
Edit Metadata
|
style="text"
|
||||||
</Button>
|
size="small"
|
||||||
{appConfig.allowAdvancedSettings === 'true' && (
|
onClick={handleEditButton}
|
||||||
<>
|
>
|
||||||
<span className={styles.separator}>|</span>
|
Edit Metadata
|
||||||
<Button
|
</Button>
|
||||||
style="text"
|
{appConfig.allowAdvancedSettings === 'true' && (
|
||||||
size="small"
|
<>
|
||||||
onClick={handleEditAdvancedSettingsButton}
|
<span className={styles.separator}>|</span>
|
||||||
>
|
<Button
|
||||||
Edit Advanced Settings
|
style="text"
|
||||||
</Button>
|
size="small"
|
||||||
</>
|
onClick={handleEditAdvancedSettingsButton}
|
||||||
)}
|
>
|
||||||
{ddo.findServiceByType('compute') && type === 'dataset' && (
|
Edit Advanced Settings
|
||||||
<>
|
</Button>
|
||||||
<span className={styles.separator}>|</span>
|
</>
|
||||||
<Button
|
)}
|
||||||
style="text"
|
{ddo.findServiceByType('compute') && type === 'dataset' && (
|
||||||
size="small"
|
<>
|
||||||
onClick={handleEditComputeButton}
|
<span className={styles.separator}>|</span>
|
||||||
>
|
<Button
|
||||||
Edit Compute Settings
|
style="text"
|
||||||
</Button>
|
size="small"
|
||||||
</>
|
onClick={handleEditComputeButton}
|
||||||
)}
|
>
|
||||||
</div>
|
Edit Compute Settings
|
||||||
)}
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<MetaFull />
|
<MetaFull />
|
||||||
<EditHistory />
|
<EditHistory />
|
||||||
{debug === true && <DebugOutput title="DDO" output={ddo} />}
|
{debug === true && <DebugOutput title="DDO" output={ddo} />}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
<AssetActions />
|
<AssetActions />
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
5
src/components/pages/Publish/FormActions.module.css
Normal file
5
src/components/pages/Publish/FormActions.module.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
32
src/components/pages/Publish/FormActions.tsx
Normal file
32
src/components/pages/Publish/FormActions.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import React, { FormEvent, ReactElement } from 'react'
|
||||||
|
import { useOcean } from '../../../providers/Ocean'
|
||||||
|
import Button from '../../atoms/Button'
|
||||||
|
import styles from './FormActions.module.css'
|
||||||
|
|
||||||
|
export default function FormActions({
|
||||||
|
isValid,
|
||||||
|
resetFormAndClearStorage
|
||||||
|
}: {
|
||||||
|
isValid: boolean
|
||||||
|
resetFormAndClearStorage: (e: FormEvent<Element>) => void
|
||||||
|
}): ReactElement {
|
||||||
|
const { ocean, account } = useOcean()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<footer className={styles.actions}>
|
||||||
|
<Button
|
||||||
|
style="primary"
|
||||||
|
type="submit"
|
||||||
|
disabled={!ocean || !account || !isValid || status === 'empty'}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
{status !== 'empty' && (
|
||||||
|
<Button style="text" size="small" onClick={resetFormAndClearStorage}>
|
||||||
|
Reset Form
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</footer>
|
||||||
|
)
|
||||||
|
}
|
@ -6,15 +6,14 @@ import React, {
|
|||||||
ChangeEvent
|
ChangeEvent
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { useStaticQuery, graphql } from 'gatsby'
|
import { useStaticQuery, graphql } from 'gatsby'
|
||||||
import styles from './FormPublish.module.css'
|
|
||||||
import { useOcean } from '../../../providers/Ocean'
|
|
||||||
import { useFormikContext, Field, Form, FormikContextType } from 'formik'
|
import { useFormikContext, Field, Form, FormikContextType } from 'formik'
|
||||||
import Input from '../../atoms/Input'
|
import Input from '../../atoms/Input'
|
||||||
import Button from '../../atoms/Button'
|
|
||||||
import { FormContent, FormFieldProps } from '../../../@types/Form'
|
import { FormContent, FormFieldProps } from '../../../@types/Form'
|
||||||
import { MetadataPublishFormAlgorithm } from '../../../@types/MetaData'
|
import { MetadataPublishFormAlgorithm } from '../../../@types/MetaData'
|
||||||
import { initialValues as initialValuesAlgorithm } from '../../../models/FormAlgoPublish'
|
import { initialValues as initialValuesAlgorithm } from '../../../models/FormAlgoPublish'
|
||||||
import stylesIndex from './index.module.css'
|
import FormTitle from './FormTitle'
|
||||||
|
import FormActions from './FormActions'
|
||||||
|
import styles from './FormPublish.module.css'
|
||||||
|
|
||||||
const query = graphql`
|
const query = graphql`
|
||||||
query {
|
query {
|
||||||
@ -46,7 +45,7 @@ const query = graphql`
|
|||||||
export default function FormPublish(): ReactElement {
|
export default function FormPublish(): ReactElement {
|
||||||
const data = useStaticQuery(query)
|
const data = useStaticQuery(query)
|
||||||
const content: FormContent = data.content.edges[0].node.childPublishJson
|
const content: FormContent = data.content.edges[0].node.childPublishJson
|
||||||
const { ocean, account } = useOcean()
|
|
||||||
const {
|
const {
|
||||||
status,
|
status,
|
||||||
setStatus,
|
setStatus,
|
||||||
@ -142,7 +141,8 @@ export default function FormPublish(): ReactElement {
|
|||||||
// do we need this?
|
// do we need this?
|
||||||
onChange={() => status === 'empty' && setStatus(null)}
|
onChange={() => status === 'empty' && setStatus(null)}
|
||||||
>
|
>
|
||||||
<h2 className={stylesIndex.formTitle}>{content.title}</h2>
|
<FormTitle title={content.title} />
|
||||||
|
|
||||||
{content.data.map(
|
{content.data.map(
|
||||||
(field: FormFieldProps) =>
|
(field: FormFieldProps) =>
|
||||||
((field.name !== 'entrypoint' &&
|
((field.name !== 'entrypoint' &&
|
||||||
@ -165,21 +165,10 @@ export default function FormPublish(): ReactElement {
|
|||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<footer className={styles.actions}>
|
<FormActions
|
||||||
<Button
|
isValid={isValid}
|
||||||
style="primary"
|
resetFormAndClearStorage={resetFormAndClearStorage}
|
||||||
type="submit"
|
/>
|
||||||
disabled={!ocean || !account || !isValid || status === 'empty'}
|
|
||||||
>
|
|
||||||
Submit
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
{status !== 'empty' && (
|
|
||||||
<Button style="text" size="small" onClick={resetFormAndClearStorage}>
|
|
||||||
Reset Form
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</footer>
|
|
||||||
</Form>
|
</Form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,3 @@
|
|||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
@ -2,14 +2,14 @@ import React, { ReactElement, useEffect, FormEvent, ChangeEvent } from 'react'
|
|||||||
import { useStaticQuery, graphql } from 'gatsby'
|
import { useStaticQuery, graphql } from 'gatsby'
|
||||||
import { useFormikContext, Field, Form, FormikContextType } from 'formik'
|
import { useFormikContext, Field, Form, FormikContextType } from 'formik'
|
||||||
import Input from '../../atoms/Input'
|
import Input from '../../atoms/Input'
|
||||||
import Button from '../../atoms/Button'
|
|
||||||
import { FormContent, FormFieldProps } from '../../../@types/Form'
|
import { FormContent, FormFieldProps } from '../../../@types/Form'
|
||||||
import { MetadataPublishFormDataset } from '../../../@types/MetaData'
|
import { MetadataPublishFormDataset } from '../../../@types/MetaData'
|
||||||
import { initialValues as initialValuesDataset } from '../../../models/FormAlgoPublish'
|
import { initialValues as initialValuesDataset } from '../../../models/FormAlgoPublish'
|
||||||
import { useOcean } from '../../../providers/Ocean'
|
import { useOcean } from '../../../providers/Ocean'
|
||||||
import { ReactComponent as Download } from '../../../images/download.svg'
|
import { ReactComponent as Download } from '../../../images/download.svg'
|
||||||
import { ReactComponent as Compute } from '../../../images/compute.svg'
|
import { ReactComponent as Compute } from '../../../images/compute.svg'
|
||||||
import stylesIndex from './index.module.css'
|
import FormTitle from './FormTitle'
|
||||||
|
import FormActions from './FormActions'
|
||||||
import styles from './FormPublish.module.css'
|
import styles from './FormPublish.module.css'
|
||||||
|
|
||||||
const query = graphql`
|
const query = graphql`
|
||||||
@ -42,6 +42,7 @@ const query = graphql`
|
|||||||
export default function FormPublish(): ReactElement {
|
export default function FormPublish(): ReactElement {
|
||||||
const data = useStaticQuery(query)
|
const data = useStaticQuery(query)
|
||||||
const content: FormContent = data.content.edges[0].node.childPublishJson
|
const content: FormContent = data.content.edges[0].node.childPublishJson
|
||||||
|
|
||||||
const { ocean, account } = useOcean()
|
const { ocean, account } = useOcean()
|
||||||
const {
|
const {
|
||||||
status,
|
status,
|
||||||
@ -50,7 +51,6 @@ export default function FormPublish(): ReactElement {
|
|||||||
setErrors,
|
setErrors,
|
||||||
setTouched,
|
setTouched,
|
||||||
resetForm,
|
resetForm,
|
||||||
initialValues,
|
|
||||||
validateField,
|
validateField,
|
||||||
setFieldValue
|
setFieldValue
|
||||||
}: FormikContextType<MetadataPublishFormDataset> = useFormikContext()
|
}: FormikContextType<MetadataPublishFormDataset> = useFormikContext()
|
||||||
@ -104,7 +104,8 @@ export default function FormPublish(): ReactElement {
|
|||||||
// do we need this?
|
// do we need this?
|
||||||
onChange={() => status === 'empty' && setStatus(null)}
|
onChange={() => status === 'empty' && setStatus(null)}
|
||||||
>
|
>
|
||||||
<h2 className={stylesIndex.formTitle}>{content.title}</h2>
|
<FormTitle title={content.title} />
|
||||||
|
|
||||||
{content.data.map((field: FormFieldProps) => (
|
{content.data.map((field: FormFieldProps) => (
|
||||||
<Field
|
<Field
|
||||||
key={field.name}
|
key={field.name}
|
||||||
@ -119,21 +120,10 @@ export default function FormPublish(): ReactElement {
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<footer className={styles.actions}>
|
<FormActions
|
||||||
<Button
|
isValid={isValid}
|
||||||
style="primary"
|
resetFormAndClearStorage={resetFormAndClearStorage}
|
||||||
type="submit"
|
/>
|
||||||
disabled={!ocean || !account || !isValid || status === 'empty'}
|
|
||||||
>
|
|
||||||
Submit
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
{status !== 'empty' && (
|
|
||||||
<Button style="text" size="small" onClick={resetFormAndClearStorage}>
|
|
||||||
Reset Form
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</footer>
|
|
||||||
</Form>
|
</Form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
21
src/components/pages/Publish/FormTitle.module.css
Normal file
21
src/components/pages/Publish/FormTitle.module.css
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
.title {
|
||||||
|
font-size: var(--font-size-h4);
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network {
|
||||||
|
color: var(--font-color-heading);
|
||||||
|
margin-left: calc(var(--spacer) / 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.network svg {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
margin-top: -0.25em;
|
||||||
|
fill: var(--color-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
width: 0.75em;
|
||||||
|
height: 0.75em;
|
||||||
|
}
|
42
src/components/pages/Publish/FormTitle.tsx
Normal file
42
src/components/pages/Publish/FormTitle.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import React, { ReactElement } from 'react'
|
||||||
|
import NetworkName from '../../atoms/NetworkName'
|
||||||
|
import Tooltip from '../../atoms/Tooltip'
|
||||||
|
import { useWeb3 } from '../../../providers/Web3'
|
||||||
|
import styles from './FormTitle.module.css'
|
||||||
|
|
||||||
|
import { graphql, useStaticQuery } from 'gatsby'
|
||||||
|
|
||||||
|
const query = graphql`
|
||||||
|
query {
|
||||||
|
content: allFile(
|
||||||
|
filter: { relativePath: { eq: "pages/publish/index.json" } }
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
childPublishJson {
|
||||||
|
tooltipNetwork
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export default function FormTitle({ title }: { title: string }): ReactElement {
|
||||||
|
const data = useStaticQuery(query)
|
||||||
|
const contentTooltip =
|
||||||
|
data.content.edges[0].node.childPublishJson.tooltipNetwork
|
||||||
|
const { networkId } = useWeb3()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<h2 className={styles.title}>
|
||||||
|
{title}{' '}
|
||||||
|
{networkId && (
|
||||||
|
<>
|
||||||
|
into <NetworkName networkId={networkId} className={styles.network} />
|
||||||
|
<Tooltip content={contentTooltip} className={styles.tooltip} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</h2>
|
||||||
|
)
|
||||||
|
}
|
@ -39,7 +39,3 @@ div.alert {
|
|||||||
top: calc(var(--spacer) / 2);
|
top: calc(var(--spacer) / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.formTitle {
|
|
||||||
font-size: var(--font-size-h4);
|
|
||||||
}
|
|
||||||
|
@ -1 +1,3 @@
|
|||||||
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"><path d="M15.853 16.56c-1.683 1.517-3.911 2.44-6.353 2.44-5.243 0-9.5-4.257-9.5-9.5s4.257-9.5 9.5-9.5 9.5 4.257 9.5 9.5c0 2.442-.923 4.67-2.44 6.353l7.44 7.44-.707.707-7.44-7.44zm-6.353-15.56c4.691 0 8.5 3.809 8.5 8.5s-3.809 8.5-8.5 8.5-8.5-3.809-8.5-8.5 3.809-8.5 8.5-8.5z"/></svg>
|
<svg width="19" height="19" viewBox="0 0 19 19" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5846 12.6731C10.3622 13.6572 8.81213 14.2501 7.12507 14.2501C3.19599 14.2501 0 11.0534 0 7.12507C0 3.19599 3.19599 0 7.12507 0C11.0542 0 14.2501 3.19599 14.2501 7.12507C14.2501 8.7963 13.6675 10.3329 12.6993 11.549L18.7698 17.6496C19.0778 17.9591 19.077 18.4603 18.7667 18.769C18.4555 19.0778 17.9552 19.077 17.6472 18.7667L11.5846 12.6731ZM12.6668 7.12507C12.6668 4.06921 10.1801 1.58335 7.12507 1.58335C4.06921 1.58335 1.58335 4.06921 1.58335 7.12507C1.58335 10.1801 4.06921 12.6668 7.12507 12.6668C10.1801 12.6668 12.6668 10.1801 12.6668 7.12507Z" />
|
||||||
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 698 B |
@ -40,8 +40,6 @@ export function getNetworkDisplayName(
|
|||||||
data: EthereumListsChain,
|
data: EthereumListsChain,
|
||||||
networkId: number
|
networkId: number
|
||||||
): string {
|
): string {
|
||||||
if (!data) return 'Unknown'
|
|
||||||
|
|
||||||
let displayName
|
let displayName
|
||||||
|
|
||||||
switch (networkId) {
|
switch (networkId) {
|
||||||
@ -61,9 +59,9 @@ export function getNetworkDisplayName(
|
|||||||
displayName = 'GAIA-X'
|
displayName = 'GAIA-X'
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
displayName = `${data.chain} ${
|
displayName = data
|
||||||
data.network === 'mainnet' ? '' : data.network
|
? `${data.chain} ${data.network === 'mainnet' ? '' : data.network}`
|
||||||
}`
|
: 'Unknown'
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user