Feat/1334 replace json (#1459)

* feat(explorer): add panel component

* feat(explorer): add info panel component

* feat(explorer): change layout styles

* feat(explorer): render json data in component for parties

* feat(explorer): change testnet env

* feat(explorer): change eslint json

* feat(explorer): render staking json in info panel component

* fix(explorer): pr comments
This commit is contained in:
Elmar 2022-09-26 10:10:33 +01:00 committed by GitHub
parent b5e2513d53
commit d9e3b9de99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 160 additions and 8 deletions

View File

@ -6,3 +6,4 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
NX_VEGA_ENV=TESTNET
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_VEGA_URL=https://api.n09.testnet.vega.xyz/graphql

View File

@ -14,5 +14,8 @@
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
],
"env": {
"jest": true
}
}

View File

@ -45,7 +45,7 @@ function App() {
menuOpen && 'h-[100vh] overflow-hidden'
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
>
<div className="min-h-[100vh] max-w-[1300px] grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-neutral-700 dark:border-neutral-300 lg:border-l lg:border-r mx-auto">
<div className="grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-neutral-700 dark:border-neutral-300 lg:border-l lg:border-r mx-auto">
<Header
theme={theme}
toggleTheme={toggleTheme}

View File

@ -24,30 +24,35 @@ export const Header = ({
'md:col-span-2',
'grid grid-rows-2 md:grid-rows-1 grid-cols-[1fr_auto] md:grid-cols-[auto_1fr_auto] items-center',
'p-4 gap-2 md:gap-4',
'border-b border-neutral-700 dark:border-neutral-300'
'border-b border-neutral-700 dark:border-neutral-300 bg-black'
);
return (
<header className={headerClasses}>
<div className="flex h-full items-center sm:items-stretch gap-4">
<Link to={Routes.HOME}>
<h1
className="text-3xl font-alpha uppercase calt mb-0"
className="text-white text-3xl font-alpha uppercase calt mb-0"
data-testid="explorer-header"
>
{t('Vega Explorer')}
</h1>
</Link>
<NetworkSwitcher />
<NetworkSwitcher theme="dark" />
</div>
<button
data-testid="open-menu"
className="md:hidden"
className="md:hidden text-white"
onClick={() => setMenuOpen(!menuOpen)}
>
<Icon name={menuOpen ? 'cross' : 'menu'} />
</button>
<Search />
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
<ThemeSwitcher
theme={theme}
onToggle={toggleTheme}
className="-my-4"
fixedBg="dark"
/>
</header>
);
};

View File

@ -0,0 +1 @@
export * from './info-panel';

View File

@ -0,0 +1,55 @@
import React from 'react';
import type { ReactNode } from 'react';
import { Panel } from '../panel';
import {
CopyWithTooltip,
Icon,
Intent,
Lozenge,
Tooltip,
} from '@vegaprotocol/ui-toolkit';
interface InfoPanelProps {
children?: ReactNode | ReactNode[];
title: string;
id: string;
type?: string;
copy?: boolean;
}
export const InfoPanel = ({
children,
title,
id,
type,
copy = true,
}: InfoPanelProps) => {
return (
<Panel>
<section className="flex gap-3 mb-1 items-center">
<h3 className="text-lg font-bold">{title}</h3>
<p title={id} className="truncate ...">
{id}
</p>
{type && (
<Lozenge
className="text-xs leading-relaxed cursor-auto"
variant={Intent.None}
>
<Tooltip side="top" description={type} align="center">
<span>{type}</span>
</Tooltip>
</Lozenge>
)}
{copy && (
<CopyWithTooltip text={id}>
<button className="underline">
<Icon name="duplicate" className="ml-2" />
</button>
</CopyWithTooltip>
)}
</section>
{children}
</Panel>
);
};

View File

@ -0,0 +1 @@
export * from './panel';

View File

@ -0,0 +1,10 @@
import classNames from 'classnames';
import type { ReactNode } from 'react';
interface PanelProps {
children: ReactNode;
className?: string;
}
export const Panel = ({ children, className }: PanelProps) => (
<div className={classNames('border p-5 mb-5', className)}>{children}</div>
);

View File

@ -63,6 +63,7 @@ export const Search = () => {
{...register('search')}
id="search"
data-testid="search"
className="text-white"
hasError={Boolean(error?.message)}
type="text"
placeholder={t('Enter block number or transaction hash')}

View File

@ -1,11 +1,18 @@
import { useQuery } from '@apollo/client';
import { gql } from '@apollo/client';
import { t, useFetch } from '@vegaprotocol/react-helpers';
import {
t,
useFetch,
addDecimalsFormatNumber,
} from '@vegaprotocol/react-helpers';
import { AccountTypeMapping } from '@vegaprotocol/types';
import React from 'react';
import { useParams } from 'react-router-dom';
import { RouteTitle } from '../../../components/route-title';
import { SubHeading } from '../../../components/sub-heading';
import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
import { Panel } from '../../../components/panel';
import { InfoPanel } from '../../../components/info-panel';
import { DATA_SOURCES } from '../../../config';
import type { TendermintSearchTransactionResponse } from '../tendermint-transaction-response';
import type {
@ -69,12 +76,80 @@ const Party = () => {
}
);
const header = data?.party?.id ? (
<InfoPanel
title={t('Address')}
id={data.party.id}
type={data.party.__typename}
/>
) : (
<Panel>
<p>No party found for key {party}</p>
</Panel>
);
const accounts = (
<section>
{data?.party?.accounts?.length ? (
data.party.accounts.map((account) => {
return (
<InfoPanel
title={account.asset.name}
id={account.asset.id}
type={`Account Type - ${AccountTypeMapping[account.type]}`}
>
<section>
<dl className="flex gap-2 font-mono">
<dt className="font-bold">
{t('Balance')} ({account.asset.symbol})
</dt>
<dd>
{addDecimalsFormatNumber(
account.balance,
account.asset.decimals
)}
</dd>
</dl>
</section>
</InfoPanel>
);
})
) : (
<Panel>
<p>No Data</p>
</Panel>
)}
</section>
);
const staking = (
<section>
{data?.party?.stake?.currentStakeAvailable ? (
<InfoPanel
title={t('Current Stake Available')}
id={data?.party?.stake?.currentStakeAvailable}
type={data?.party?.stake.__typename}
copy={false}
/>
) : (
<Panel>
<p>Nothing staked for {party}</p>
</Panel>
)}
</section>
);
return (
<section>
<RouteTitle data-testid="parties-header">{t('Party')}</RouteTitle>
{data ? (
<>
{header}
<SubHeading>{t('Asset data')}</SubHeading>
{accounts}
<SubHeading>{t('Staking')}</SubHeading>
{staking}
<SubHeading>{t('JSON')}</SubHeading>
<SyntaxHighlighter data={data} />
</>
) : null}