Feat/519: Add copy button to transaction content in explorer (#1016)

* Feat/519: Add copy button to transaction content in explorer

* Feat/519: Adjusted copy of the button title

* Update apps/explorer/src/app/routes/txs/id/tx-details.tsx

Co-authored-by: botond <105208209+notbot00@users.noreply.github.com>

Co-authored-by: botond <105208209+notbot00@users.noreply.github.com>
This commit is contained in:
Sam Keen 2022-08-15 10:32:06 +01:00 committed by GitHub
parent 445897eb2b
commit 4b51ef57e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 7 deletions

View File

@ -0,0 +1,65 @@
import { BrowserRouter as Router } from 'react-router-dom';
import { render, screen } from '@testing-library/react';
import { truncateByChars } from '@vegaprotocol/react-helpers';
import { TxDetails, txDetailsTruncateLength } from './tx-details';
import type { Result } from '../tendermint-transaction-response.d';
const pubKey = 'test';
const hash = '7416753A30622A9E24A06F0172D6C33A95186B36806D96345C6DC5A23FA3F283';
const height = '52987';
const tx =
'ClMIpeWjmKnn77FNEPedA5J9QhJAOGI3YjQzMWNlMmNhNzc4MWMzMTQ1M2IyYjc0MWYwMTJlNzQ1MzBhZDhjMDgzODVkMWQ1YjRiY2VkMTJiNDc1MhKTAQqAATM5NDFlNmExMzQ3MGVhNTlhNGExNmQzMjRiYzlkZjI5YWZkMzYxMDRiZjQ5MzEwZWMxM2ZiOTMxNTM2NGY3ZjU2ZTQyOTJmYTAyZDlhNTBlZDc0OWE0ZjExMzJiNjM2ZTZmMzQ3YzQ2NjdkYmM5OThmYzcyZjYzYzQxMzU4ZTAzEgx2ZWdhL2VkMjU1MTkYAYB9AtI+QDA5MzFhOGZkOGNjOTM1NDU4ZjQ3MGU0MzVhMDU0MTQzODdjZWE2ZjMyOWQ2NDhiZTg5NGZjZDQ0YmQ1MTdhMmI=';
const txData = {
hash,
height,
tx,
index: 0,
tx_result: {
code: 0,
data: null,
log: '',
info: '',
events: [],
gas_wanted: '0',
gas_used: '0',
codespace: '',
},
};
const renderComponent = (txData: Result) => (
<Router>
<TxDetails txData={txData} pubKey={pubKey} />
</Router>
);
describe('Transaction details', () => {
it('Renders the tx hash', () => {
render(renderComponent(txData));
expect(screen.getByText(hash)).toBeInTheDocument();
});
it('Renders the pubKey', () => {
render(renderComponent(txData));
expect(screen.getByText(pubKey)).toBeInTheDocument();
});
it('Renders the height', () => {
render(renderComponent(txData));
expect(screen.getByText(height)).toBeInTheDocument();
});
it('Renders the truncated tx text', () => {
render(renderComponent(txData));
expect(
screen.getByText(
truncateByChars(tx, txDetailsTruncateLength, txDetailsTruncateLength)
)
).toBeInTheDocument();
});
it('Renders a copy button', () => {
render(renderComponent(txData));
expect(screen.getByTestId('copy-tx-to-clipboard')).toBeInTheDocument();
});
});

View File

@ -1,5 +1,5 @@
import { Routes } from '../../route-names'; import { Routes } from '../../route-names';
import type { Result } from '../tendermint-transaction-response.d'; import { Button, CopyWithTooltip } from '@vegaprotocol/ui-toolkit';
import { import {
TableWithTbody, TableWithTbody,
TableCell, TableCell,
@ -8,15 +8,16 @@ import {
} from '../../../components/table'; } from '../../../components/table';
import { TruncateInline } from '../../../components/truncate/truncate'; import { TruncateInline } from '../../../components/truncate/truncate';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { HighlightedLink } from '../../../components/highlighted-link'; import { HighlightedLink } from '../../../components/highlighted-link';
import type { Result } from '../tendermint-transaction-response.d';
interface TxDetailsProps { interface TxDetailsProps {
txData: Result | undefined; txData: Result | undefined;
pubKey: string | undefined; pubKey: string | undefined;
className?: string; className?: string;
} }
const truncateLength = 30; export const txDetailsTruncateLength = 30;
export const TxDetails = ({ txData, pubKey, className }: TxDetailsProps) => { export const TxDetails = ({ txData, pubKey, className }: TxDetailsProps) => {
if (!txData) { if (!txData) {
@ -50,12 +51,25 @@ export const TxDetails = ({ txData, pubKey, className }: TxDetailsProps) => {
</TableRow> </TableRow>
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Encoded txn')}</TableCell> <TableCell>{t('Encoded txn')}</TableCell>
<TableCell modifier="bordered" data-testid="encoded-tnx"> <TableCell
modifier="bordered"
data-testid="encoded-tnx"
className="flex justify-between"
>
<TruncateInline <TruncateInline
text={txData.tx} text={txData.tx}
startChars={truncateLength} startChars={txDetailsTruncateLength}
endChars={truncateLength} endChars={txDetailsTruncateLength}
/> />
<CopyWithTooltip text="">
<Button
variant="inline-link"
prependIconName="duplicate"
title={t('Copy tx to clipboard')}
onClick={() => navigator.clipboard.writeText(txData.tx)}
data-testid="copy-tx-to-clipboard"
/>
</CopyWithTooltip>
</TableCell> </TableCell>
</TableRow> </TableRow>
</TableWithTbody> </TableWithTbody>

View File

@ -31,7 +31,7 @@ export function CopyWithTooltip({ children, text }: CopyWithTooltipProps) {
return ( return (
<CopyToClipboard text={text} onCopy={() => setCopied(true)}> <CopyToClipboard text={text} onCopy={() => setCopied(true)}>
{/* Needs this wrapping div as tooltip component interfers with element used to capture click for copy */} {/* Needs this wrapping div as tooltip component interfers with element used to capture click for copy */}
<span> <span className="inline-flex content-center">
<Tooltip description="Copied" open={copied} align="center"> <Tooltip description="Copied" open={copied} align="center">
{children} {children}
</Tooltip> </Tooltip>