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:
parent
b5e2513d53
commit
d9e3b9de99
@ -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_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||||
|
NX_VEGA_URL=https://api.n09.testnet.vega.xyz/graphql
|
||||||
|
@ -14,5 +14,8 @@
|
|||||||
"files": ["*.js", "*.jsx"],
|
"files": ["*.js", "*.jsx"],
|
||||||
"rules": {}
|
"rules": {}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"env": {
|
||||||
|
"jest": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ function App() {
|
|||||||
menuOpen && 'h-[100vh] overflow-hidden'
|
menuOpen && 'h-[100vh] overflow-hidden'
|
||||||
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
|
} 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
|
<Header
|
||||||
theme={theme}
|
theme={theme}
|
||||||
toggleTheme={toggleTheme}
|
toggleTheme={toggleTheme}
|
||||||
|
@ -24,30 +24,35 @@ export const Header = ({
|
|||||||
'md:col-span-2',
|
'md:col-span-2',
|
||||||
'grid grid-rows-2 md:grid-rows-1 grid-cols-[1fr_auto] md:grid-cols-[auto_1fr_auto] items-center',
|
'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',
|
'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 (
|
return (
|
||||||
<header className={headerClasses}>
|
<header className={headerClasses}>
|
||||||
<div className="flex h-full items-center sm:items-stretch gap-4">
|
<div className="flex h-full items-center sm:items-stretch gap-4">
|
||||||
<Link to={Routes.HOME}>
|
<Link to={Routes.HOME}>
|
||||||
<h1
|
<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"
|
data-testid="explorer-header"
|
||||||
>
|
>
|
||||||
{t('Vega Explorer')}
|
{t('Vega Explorer')}
|
||||||
</h1>
|
</h1>
|
||||||
</Link>
|
</Link>
|
||||||
<NetworkSwitcher />
|
<NetworkSwitcher theme="dark" />
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
data-testid="open-menu"
|
data-testid="open-menu"
|
||||||
className="md:hidden"
|
className="md:hidden text-white"
|
||||||
onClick={() => setMenuOpen(!menuOpen)}
|
onClick={() => setMenuOpen(!menuOpen)}
|
||||||
>
|
>
|
||||||
<Icon name={menuOpen ? 'cross' : 'menu'} />
|
<Icon name={menuOpen ? 'cross' : 'menu'} />
|
||||||
</button>
|
</button>
|
||||||
<Search />
|
<Search />
|
||||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
|
<ThemeSwitcher
|
||||||
|
theme={theme}
|
||||||
|
onToggle={toggleTheme}
|
||||||
|
className="-my-4"
|
||||||
|
fixedBg="dark"
|
||||||
|
/>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
1
apps/explorer/src/app/components/info-panel/index.ts
Normal file
1
apps/explorer/src/app/components/info-panel/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './info-panel';
|
55
apps/explorer/src/app/components/info-panel/info-panel.tsx
Normal file
55
apps/explorer/src/app/components/info-panel/info-panel.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
1
apps/explorer/src/app/components/panel/index.ts
Normal file
1
apps/explorer/src/app/components/panel/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './panel';
|
10
apps/explorer/src/app/components/panel/panel.tsx
Normal file
10
apps/explorer/src/app/components/panel/panel.tsx
Normal 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>
|
||||||
|
);
|
@ -63,6 +63,7 @@ export const Search = () => {
|
|||||||
{...register('search')}
|
{...register('search')}
|
||||||
id="search"
|
id="search"
|
||||||
data-testid="search"
|
data-testid="search"
|
||||||
|
className="text-white"
|
||||||
hasError={Boolean(error?.message)}
|
hasError={Boolean(error?.message)}
|
||||||
type="text"
|
type="text"
|
||||||
placeholder={t('Enter block number or transaction hash')}
|
placeholder={t('Enter block number or transaction hash')}
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
import { useQuery } from '@apollo/client';
|
import { useQuery } from '@apollo/client';
|
||||||
import { gql } 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 React from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { RouteTitle } from '../../../components/route-title';
|
import { RouteTitle } from '../../../components/route-title';
|
||||||
import { SubHeading } from '../../../components/sub-heading';
|
import { SubHeading } from '../../../components/sub-heading';
|
||||||
import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { Panel } from '../../../components/panel';
|
||||||
|
import { InfoPanel } from '../../../components/info-panel';
|
||||||
import { DATA_SOURCES } from '../../../config';
|
import { DATA_SOURCES } from '../../../config';
|
||||||
import type { TendermintSearchTransactionResponse } from '../tendermint-transaction-response';
|
import type { TendermintSearchTransactionResponse } from '../tendermint-transaction-response';
|
||||||
import type {
|
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 (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<RouteTitle data-testid="parties-header">{t('Party')}</RouteTitle>
|
<RouteTitle data-testid="parties-header">{t('Party')}</RouteTitle>
|
||||||
{data ? (
|
{data ? (
|
||||||
<>
|
<>
|
||||||
|
{header}
|
||||||
<SubHeading>{t('Asset data')}</SubHeading>
|
<SubHeading>{t('Asset data')}</SubHeading>
|
||||||
|
{accounts}
|
||||||
|
<SubHeading>{t('Staking')}</SubHeading>
|
||||||
|
{staking}
|
||||||
|
<SubHeading>{t('JSON')}</SubHeading>
|
||||||
<SyntaxHighlighter data={data} />
|
<SyntaxHighlighter data={data} />
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
|
Loading…
Reference in New Issue
Block a user