feat: polish app (#669)

This commit is contained in:
Cafe137
2024-07-17 06:49:22 -07:00
committed by GitHub
parent b4ebfc7c3f
commit 8558860f0a
18 changed files with 304 additions and 417 deletions
+1 -2
View File
@@ -9,7 +9,6 @@
"file-loader", "file-loader",
"ts-node", "ts-node",
"webpack-cli", "webpack-cli",
"assert",
"buffer", "buffer",
"crypto*", "crypto*",
"stream*", "stream*",
@@ -17,4 +16,4 @@
"open", "open",
"base64-inline-loader" "base64-inline-loader"
] ]
} }
+2 -6
View File
@@ -13,12 +13,8 @@
**Warning: This project is in alpha state. There might (and most probably will) be changes in the future to its API and **Warning: This project is in alpha state. There might (and most probably will) be changes in the future to its API and
working. Also, no guarantees can be made about its stability, efficiency, and security at this stage.** working. Also, no guarantees can be made about its stability, efficiency, and security at this stage.**
This project is intended to be used with \*\*Bee version Stay up to date by joining the [official Discord](https://discord.gg/GU22h2utj6) and by keeping an eye on the
[releases tab](https://github.com/ethersphere/bee-dashboard/releases).
<!-- SUPPORTED_BEE_START -->1.12.0-88c1d236<!-- SUPPORTED_BEE_END -->**. Using it with older or newer Bee versions is
not recommended and may not work. Stay up to date by joining the [official Discord](https://discord.gg/GU22h2utj6) and
by keeping an eye on the [releases tab](https://github.com/ethersphere/bee-dashboard/releases).
![Status page](/ui_samples/info.png) ![Status page](/ui_samples/info.png)
+203 -366
View File
File diff suppressed because it is too large Load Diff
+5 -6
View File
@@ -26,14 +26,13 @@
"url": "https://github.com/ethersphere/bee-dashboard.git" "url": "https://github.com/ethersphere/bee-dashboard.git"
}, },
"dependencies": { "dependencies": {
"@ethersphere/bee-js": "^7.0.3", "@ethersphere/bee-js": "^7.1.0",
"@ethersphere/swarm-cid": "^0.1.0", "@ethersphere/swarm-cid": "^0.1.0",
"@material-ui/core": "4.12.3", "@material-ui/core": "4.12.3",
"@material-ui/icons": "4.11.2", "@material-ui/icons": "4.11.2",
"@material-ui/lab": "4.0.0-alpha.57", "@material-ui/lab": "4.0.0-alpha.57",
"assert": "^2.0.0", "axios": "^0.28.1",
"axios": "0.24.0", "bignumber.js": "^9.1.2",
"bignumber.js": "9.0.1",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"crypto": "npm:crypto-browserify", "crypto": "npm:crypto-browserify",
"crypto-browserify": "^3.12.0", "crypto-browserify": "^3.12.0",
@@ -42,10 +41,10 @@
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"formik": "2.2.9", "formik": "2.2.9",
"formik-material-ui": "3.0.1", "formik-material-ui": "3.0.1",
"jszip": "^3.7.1", "jszip": "^3.10.1",
"mantaray-js": "^1.0.3", "mantaray-js": "^1.0.3",
"material-ui-dropzone": "3.5.0", "material-ui-dropzone": "3.5.0",
"notistack": "1.0.10", "notistack": "^3.0.1",
"opener": "1.5.2", "opener": "1.5.2",
"qrcode.react": "1.0.1", "qrcode.react": "1.0.1",
"react": ">= 17.0.2", "react": ">= 17.0.2",
+25
View File
@@ -0,0 +1,25 @@
import { ChainState } from '@ethersphere/bee-js'
import { useContext, useEffect, useState } from 'react'
import { Context } from '../providers/Settings'
import ExpandableListItem from './ExpandableListItem'
export function ChainSync() {
const { beeApi } = useContext(Context)
const [chainState, setChainState] = useState<ChainState | null>(null)
useEffect(() => {
const interval = setInterval(() => {
if (!beeApi) {
return
}
beeApi.getChainState().then(setChainState).catch(console.error) // eslint-disable-line
}, 3_000)
return () => clearInterval(interval)
})
return (
<ExpandableListItem label="Chain state" value={chainState ? `${chainState.block} / ${chainState.chainTip}` : '-'} />
)
}
+9 -7
View File
@@ -1,9 +1,11 @@
import { Utils } from '@ethersphere/bee-js'
import { Typography } from '@material-ui/core/' import { Typography } from '@material-ui/core/'
import { ReactElement } from 'react' import { ReactElement } from 'react'
import Identicon from 'react-identicons' import Identicon from 'react-identicons'
import ClipboardCopy from './ClipboardCopy'
import QRCodeModal from './QRCodeModal'
import { BLOCKCHAIN_EXPLORER_URL } from '../constants' import { BLOCKCHAIN_EXPLORER_URL } from '../constants'
import ClipboardCopy from './ClipboardCopy'
import { Flex } from './Flex'
import QRCodeModal from './QRCodeModal'
interface Props { interface Props {
address: string | undefined address: string | undefined
@@ -16,10 +18,10 @@ export default function EthereumAddress(props: Props): ReactElement {
return ( return (
<Typography component="div" variant="subtitle1"> <Typography component="div" variant="subtitle1">
{props.address ? ( {props.address ? (
<div style={{ display: 'flex' }}> <Flex>
{props.hideBlockie ? null : ( {props.hideBlockie ? null : (
<div style={{ paddingTop: '5px', marginRight: '10px' }}> <div style={{ paddingTop: '5px', marginRight: '10px' }}>
<Identicon size={20} string={props.address} /> <Identicon size={20} string={Utils.capitalizeAddressERC55(props.address)} />
</div> </div>
)} )}
<div> <div>
@@ -43,9 +45,9 @@ export default function EthereumAddress(props: Props): ReactElement {
{props.address} {props.address}
</a> </a>
</div> </div>
<QRCodeModal value={props.address} label={'Ethereum Address'} /> <QRCodeModal value={Utils.capitalizeAddressERC55(props.address)} label={'Ethereum Address'} />
<ClipboardCopy value={props.address} /> <ClipboardCopy value={Utils.capitalizeAddressERC55(props.address)} />
</div> </Flex>
) : ( ) : (
'-' '-'
)} )}
+5 -4
View File
@@ -1,7 +1,8 @@
import { ReactElement, ReactNode, useState } from 'react'
import { makeStyles, Theme, createStyles } from '@material-ui/core/styles'
import { Collapse, ListItem, ListItemText, Typography } from '@material-ui/core' import { Collapse, ListItem, ListItemText, Typography } from '@material-ui/core'
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
import { ExpandLess, ExpandMore } from '@material-ui/icons' import { ExpandLess, ExpandMore } from '@material-ui/icons'
import { ReactElement, ReactNode, useState } from 'react'
import { Flex } from './Flex'
const useStyles = makeStyles((theme: Theme) => const useStyles = makeStyles((theme: Theme) =>
createStyles({ createStyles({
@@ -65,14 +66,14 @@ export default function ExpandableList({ children, label, level, defaultOpen, in
<div className={`${classes.root} ${rootLevelClass}`}> <div className={`${classes.root} ${rootLevelClass}`}>
<ListItem button onClick={handleClick} className={classes.header}> <ListItem button onClick={handleClick} className={classes.header}>
<ListItemText primary={<Typography variant={typographyVariant}>{label}</Typography>} /> <ListItemText primary={<Typography variant={typographyVariant}>{label}</Typography>} />
<div style={{ display: 'flex' }}> <Flex>
{!open && ( {!open && (
<Typography variant="body2" className={classes.infoText}> <Typography variant="body2" className={classes.infoText}>
{info} {info}
</Typography> </Typography>
)} )}
{open ? <ExpandLess /> : <ExpandMore />} {open ? <ExpandLess /> : <ExpandMore />}
</div> </Flex>
</ListItem> </ListItem>
<Collapse in={open} timeout="auto" unmountOnExit> <Collapse in={open} timeout="auto" unmountOnExit>
<div className={contentLevelClass}>{children}</div> <div className={contentLevelClass}>{children}</div>
+9
View File
@@ -0,0 +1,9 @@
import { ReactNode } from 'react'
interface Props {
children: ReactNode
}
export function Flex({ children }: Props) {
return <div style={{ display: 'flex' }}>{children}</div>
}
+1 -1
View File
@@ -133,7 +133,7 @@ export default function SideBar(): ReactElement {
<SideBarItem <SideBarItem
iconStart={<GithubIcon className={classes.icon} />} iconStart={<GithubIcon className={classes.icon} />}
iconEnd={<ExternalLinkIcon className={classes.icon} color="#595959" />} iconEnd={<ExternalLinkIcon className={classes.icon} color="#595959" />}
label={<span>Github repository</span>} label={<span>GitHub</span>}
/> />
</MUILink> </MUILink>
</List> </List>
+3 -2
View File
@@ -4,6 +4,7 @@ import { useSnackbar } from 'notistack'
import React, { ReactElement, useContext, useEffect } from 'react' import React, { ReactElement, useContext, useEffect } from 'react'
import CloseIcon from 'remixicon-react/CloseCircleLineIcon' import CloseIcon from 'remixicon-react/CloseCircleLineIcon'
import ErrorBoundary from '../components/ErrorBoundary' import ErrorBoundary from '../components/ErrorBoundary'
import { Flex } from '../components/Flex'
import SideBar from '../components/SideBar' import SideBar from '../components/SideBar'
import { BEE_DESKTOP_LATEST_RELEASE_PAGE } from '../constants' import { BEE_DESKTOP_LATEST_RELEASE_PAGE } from '../constants'
import { useBeeDesktop, useNewBeeDesktopVersion } from '../hooks/apiHooks' import { useBeeDesktop, useNewBeeDesktopVersion } from '../hooks/apiHooks'
@@ -81,13 +82,13 @@ const Dashboard = (props: Props): ReactElement => {
) )
return ( return (
<div style={{ display: 'flex' }}> <Flex>
<SideBar /> <SideBar />
<Container className={classes.content}> <Container className={classes.content}>
{' '} {' '}
<ErrorBoundary errorReporting={props.errorReporting}>{content}</ErrorBoundary> <ErrorBoundary errorReporting={props.errorReporting}>{content}</ErrorBoundary>
</Container> </Container>
</div> </Flex>
) )
} }
+8 -7
View File
@@ -81,17 +81,18 @@ export class Token {
return asString.slice(0, indexOfSignificantDigit + digits) return asString.slice(0, indexOfSignificantDigit + digits)
} }
minusBaseUnits(amount: string): Token { minusBaseUnits(amount: string | BigNumber | bigint): Token {
const baseUnits = makeBigNumber(amount)
return new Token( return new Token(
this.toBigNumber.minus(new BigNumber(amount).multipliedBy(new BigNumber(10).pow(this.decimals))), this.toBigNumber.minus(baseUnits.multipliedBy(new BigNumber(10).pow(this.decimals))),
this.decimals, this.decimals,
) )
} }
plusBaseUnits(amount: string): Token { plusBaseUnits(amount: string | BigNumber | bigint): Token {
return new Token( const baseUnits = makeBigNumber(amount)
this.toBigNumber.plus(new BigNumber(amount).multipliedBy(new BigNumber(10).pow(this.decimals))),
this.decimals, return new Token(this.toBigNumber.plus(baseUnits.multipliedBy(new BigNumber(10).pow(this.decimals))), this.decimals)
)
} }
} }
@@ -1,3 +1,4 @@
import { Utils } from '@ethersphere/bee-js'
import { Box } from '@material-ui/core' import { Box } from '@material-ui/core'
import { ReactElement, useContext } from 'react' import { ReactElement, useContext } from 'react'
import ExpandableList from '../../../components/ExpandableList' import ExpandableList from '../../../components/ExpandableList'
@@ -57,7 +58,10 @@ export function AccountChequebook(): ReactElement {
</ExpandableList> </ExpandableList>
)} )}
<ExpandableList label="Blockchain" defaultOpen> <ExpandableList label="Blockchain" defaultOpen>
<ExpandableListItemKey label="Ethereum address" value={nodeAddresses?.ethereum || ''} /> <ExpandableListItemKey
label="Ethereum address"
value={nodeAddresses?.ethereum ? Utils.capitalizeAddressERC55(nodeAddresses.ethereum) : ''}
/>
<ExpandableListItemKey <ExpandableListItemKey
label="Chequebook contract address" label="Chequebook contract address"
value={chequebookAddress?.chequebookAddress || ''} value={chequebookAddress?.chequebookAddress || ''}
+8 -4
View File
@@ -1,4 +1,4 @@
import { BeeModes } from '@ethersphere/bee-js' import { BeeModes, Utils } from '@ethersphere/bee-js'
import { Box, Grid, Typography } from '@material-ui/core' import { Box, Grid, Typography } from '@material-ui/core'
import { ReactElement, useContext } from 'react' import { ReactElement, useContext } from 'react'
import { useNavigate } from 'react-router' import { useNavigate } from 'react-router'
@@ -26,7 +26,7 @@ export function AccountWallet(): ReactElement {
const navigate = useNavigate() const navigate = useNavigate()
function onCheckTransactions() { function onCheckTransactions() {
window.open(`https://blockscout.com/xdai/mainnet/address/${nodeAddresses?.ethereum}/transactions`, '_blank') window.open(`https://gnosisscan.io/address/${nodeAddresses?.ethereum}`, '_blank')
} }
function onInvite() { function onInvite() {
@@ -56,7 +56,11 @@ export function AccountWallet(): ReactElement {
{balance && nodeAddresses ? ( {balance && nodeAddresses ? (
<> <>
<Box mb={0.25}> <Box mb={0.25}>
<ExpandableListItemKey label="Node wallet address" value={nodeAddresses.ethereum} expanded /> <ExpandableListItemKey
label="Node wallet address"
value={Utils.capitalizeAddressERC55(nodeAddresses.ethereum)}
expanded
/>
</Box> </Box>
<Box mb={0.25}> <Box mb={0.25}>
<ExpandableListItem label="xDAI balance" value={`${balance.dai.toSignificantDigits(4)} xDAI`} /> <ExpandableListItem label="xDAI balance" value={`${balance.dai.toSignificantDigits(4)} xDAI`} />
@@ -72,7 +76,7 @@ export function AccountWallet(): ReactElement {
)} )}
<ExpandableListItemActions> <ExpandableListItemActions>
<SwarmButton onClick={onCheckTransactions} iconType={Link}> <SwarmButton onClick={onCheckTransactions} iconType={Link}>
Check transactions on Blockscout Check transactions
</SwarmButton> </SwarmButton>
{isDesktop && ( {isDesktop && (
<SwarmButton onClick={onInvite} iconType={Gift}> <SwarmButton onClick={onInvite} iconType={Gift}>
+3 -3
View File
@@ -17,12 +17,12 @@ export function ChequebookInfoCard() {
<Card <Card
buttonProps={{ buttonProps={{
iconType: ExchangeFunds, iconType: ExchangeFunds,
children: 'View chequebook', children: 'Manage chequebook',
onClick: () => navigate(ROUTES.ACCOUNT_CHEQUEBOOK), onClick: () => navigate(ROUTES.ACCOUNT_CHEQUEBOOK),
}} }}
icon={<ExchangeFunds />} icon={<ExchangeFunds />}
title={`${chequebookBalance?.availableBalance.toSignificantDigits(4)} xBZZ`} title={`${chequebookBalance?.availableBalance.toSignificantDigits(4)} xBZZ`}
subtitle="Current chequebook balance." subtitle="Network transfer balance."
status="ok" status="ok"
/> />
) )
@@ -32,7 +32,7 @@ export function ChequebookInfoCard() {
<Card <Card
buttonProps={{ buttonProps={{
iconType: ExchangeFunds, iconType: ExchangeFunds,
children: 'View chequebook', children: 'Manage chequebook',
onClick: () => navigate(ROUTES.ACCOUNT_CHEQUEBOOK), onClick: () => navigate(ROUTES.ACCOUNT_CHEQUEBOOK),
}} }}
icon={<ExchangeFunds />} icon={<ExchangeFunds />}
+13 -3
View File
@@ -1,5 +1,6 @@
import { Button } from '@material-ui/core' import { Button } from '@material-ui/core'
import { ReactElement, useContext } from 'react' import { ReactElement, useContext } from 'react'
import { ChainSync } from '../../components/ChainSync'
import ExpandableListItem from '../../components/ExpandableListItem' import ExpandableListItem from '../../components/ExpandableListItem'
import Map from '../../components/Map' import Map from '../../components/Map'
import { BEE_DESKTOP_LATEST_RELEASE_PAGE } from '../../constants' import { BEE_DESKTOP_LATEST_RELEASE_PAGE } from '../../constants'
@@ -19,11 +20,17 @@ export default function Status(): ReactElement {
return ( return (
<div> <div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'stretch', alignContent: 'stretch' }}> <div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'stretch',
alignContent: 'stretch',
gap: '8px',
}}
>
<NodeInfoCard /> <NodeInfoCard />
<div style={{ width: '8px' }}></div>
<WalletInfoCard /> <WalletInfoCard />
<div style={{ width: '8px' }}></div>
<ChequebookInfoCard /> <ChequebookInfoCard />
</div> </div>
<div style={{ height: '16px' }} /> <div style={{ height: '16px' }} />
@@ -31,6 +38,9 @@ export default function Status(): ReactElement {
<div style={{ height: '2px' }} /> <div style={{ height: '2px' }} />
<ExpandableListItem label="Connected peers" value={topology?.connected ?? '-'} /> <ExpandableListItem label="Connected peers" value={topology?.connected ?? '-'} />
<ExpandableListItem label="Population" value={topology?.population ?? '-'} /> <ExpandableListItem label="Population" value={topology?.population ?? '-'} />
<ExpandableListItem label="Depth" value={topology?.depth ?? '-'} />
<ChainSync />
<div style={{ height: '16px' }} /> <div style={{ height: '16px' }} />
{isDesktop && ( {isDesktop && (
<ExpandableListItem <ExpandableListItem
@@ -72,7 +72,7 @@ export function PostageStampAdvancedCreation({ onFinished }: Props): ReactElemen
return `${secondsToTimeString( return `${secondsToTimeString(
convertAmountToSeconds(amount, pricePerBlock), convertAmountToSeconds(amount, pricePerBlock),
)} (with price of ${pricePerBlock.toFixed(0)} per block)` )} (with price of ${pricePerBlock.toFixed(0)} PLUR per block)`
} }
function getPrice(depth: number, amount: bigint): string { function getPrice(depth: number, amount: bigint): string {
@@ -67,7 +67,7 @@ export function PostageStampStandardCreation({ onFinished }: Props): ReactElemen
return `${secondsToTimeString( return `${secondsToTimeString(
convertAmountToSeconds(parseInt(amount, 10), pricePerBlock), convertAmountToSeconds(parseInt(amount, 10), pricePerBlock),
)} (with price of ${pricePerBlock.toFixed(0)} per block)` )} (with price of ${pricePerBlock.toFixed(0)} PLUR per block)`
} }
function getPrice(depth: number, amount: bigint): string { function getPrice(depth: number, amount: bigint): string {
@@ -196,7 +196,7 @@ export function PostageStampStandardCreation({ onFinished }: Props): ReactElemen
</Box> </Box>
<Box display="flex" justifyContent={'right'} mt={0.5}> <Box display="flex" justifyContent={'right'} mt={0.5}>
<Typography style={{ fontSize: '10px', color: 'rgba(0, 0, 0, 0.26)' }}> <Typography style={{ fontSize: '10px', color: 'rgba(0, 0, 0, 0.26)' }}>
Current price of 24000 per block Current price of 24000 PLUR per block
</Typography> </Typography>
</Box> </Box>
</Box> </Box>
+1 -2
View File
@@ -31,8 +31,7 @@ export function makeBigNumber(value: BigNumber | bigint | number | string): BigN
if (typeof value === 'bigint') return new BigNumber(value.toString()) if (typeof value === 'bigint') return new BigNumber(value.toString())
// FIXME: bee-js still returns some values as numbers and even outside of SAFE INTEGER bounds if (typeof value === 'number') return new BigNumber(value)
if (typeof value === 'number' /* && Number.isSafeInteger(value)*/) return new BigNumber(value)
throw new TypeError(`Not a BigNumber or BigNumber convertible value. Type: ${typeof value} value: ${value}`) throw new TypeError(`Not a BigNumber or BigNumber convertible value. Type: ${typeof value} value: ${value}`)
} }