This repository has been archived by the owner on Sep 26, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: beta transaction details view
- Loading branch information
1 parent
e54b668
commit c8b3d68
Showing
18 changed files
with
1,038 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import * as React from "react"; | ||
import Link from "../../utils/Link"; | ||
import { shortenString } from "../../../libraries/formatting"; | ||
import { styled } from "../../../libraries/styles"; | ||
|
||
const AccountLinkWrapper = styled("a", { | ||
whiteSpace: "nowrap", | ||
}); | ||
|
||
export interface Props { | ||
accountId: string; | ||
} | ||
|
||
const AccountLink: React.FC<Props> = React.memo(({ accountId }) => { | ||
return ( | ||
<Link href={`/accounts/${accountId}`} passHref> | ||
<AccountLinkWrapper>{shortenString(accountId)}</AccountLinkWrapper> | ||
</Link> | ||
); | ||
}); | ||
|
||
export default AccountLink; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import * as React from "react"; | ||
import Link from "../../utils/Link"; | ||
import { styled } from "../../../libraries/styles"; | ||
import { TransactionBlockInfo } from "../../../types/common"; | ||
|
||
export interface Props { | ||
block: TransactionBlockInfo; | ||
} | ||
|
||
const LinkWrapper = styled("a", { | ||
whiteSpace: "nowrap", | ||
cursor: "pointer", | ||
}); | ||
|
||
const BlockLink: React.FC<Props> = React.memo(({ block }) => ( | ||
<Link href="/blocks/[hash]" as={`/blocks/${block.hash}`}> | ||
<LinkWrapper>{`#${block.height}`}</LinkWrapper> | ||
</Link> | ||
)); | ||
|
||
export default BlockLink; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import * as React from "react"; | ||
import { hexy } from "hexy"; | ||
|
||
import { styled } from "../../../libraries/styles"; | ||
|
||
import CodePreview from "../../utils/CodePreview"; | ||
import JsonView from "./JsonView"; | ||
|
||
const HexArgs = styled("div", { | ||
padding: "10px 0", | ||
|
||
"& > div": { | ||
background: "#f8f8f8", | ||
borderRadius: 4, | ||
color: "#3f4246", | ||
padding: 20, | ||
fontSize: "$font-m", | ||
fontWeight: 500, | ||
fontFamily: "SF Mono", | ||
|
||
"& textarea, pre": { | ||
background: "inherit", | ||
color: "inherit", | ||
fontFamily: "inherit", | ||
fontSize: "inherit", | ||
border: "none", | ||
padding: 0, | ||
}, | ||
}, | ||
}); | ||
|
||
const CodeArgs: React.FC<{ args: string }> = React.memo(({ args }) => { | ||
const decodedArgs = Buffer.from(args, "base64"); | ||
|
||
let prettyArgs: object | string; | ||
try { | ||
const parsedJSONArgs = JSON.parse(decodedArgs.toString()); | ||
prettyArgs = | ||
typeof parsedJSONArgs === "boolean" | ||
? JSON.stringify(parsedJSONArgs) | ||
: parsedJSONArgs; | ||
} catch { | ||
prettyArgs = hexy(decodedArgs, { format: "twos" }); | ||
} | ||
return typeof prettyArgs === "object" ? ( | ||
<JsonView args={prettyArgs} /> | ||
) : ( | ||
<HexArgs> | ||
<CodePreview collapseHeight={200} maxHeight={600} value={prettyArgs} /> | ||
</HexArgs> | ||
); | ||
}); | ||
|
||
export default CodeArgs; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import * as React from "react"; | ||
import loadable from "@loadable/component"; | ||
// https://github.com/mac-s-g/react-json-view/issues/296#issuecomment-997176256 | ||
const ReactJson = loadable(() => import("react-json-view")); | ||
|
||
type Props = { | ||
args: object; | ||
}; | ||
|
||
const JsonView: React.FC<Props> = React.memo(({ args }) => ( | ||
<ReactJson | ||
src={args} | ||
name={null} | ||
iconStyle="triangle" | ||
displayObjectSize={false} | ||
displayDataTypes={false} | ||
style={{ | ||
fontSize: "14px", | ||
padding: "10px 0", | ||
fontFamily: "SF Mono", | ||
}} | ||
/> | ||
)); | ||
|
||
export default JsonView; |
126 changes: 126 additions & 0 deletions
126
frontend/src/components/beta/transactions/InspectReceipt.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import JSBI from "jsbi"; | ||
import * as React from "react"; | ||
import { styled } from "../../../libraries/styles"; | ||
import * as BI from "../../../libraries/bigint"; | ||
import { TransactionReceipt } from "../../../types/common"; | ||
import { NearAmount } from "../../utils/NearAmount"; | ||
import Gas from "../../utils/Gas"; | ||
import AccountLink from "../common/AccountLink"; | ||
import BlockLink from "../common/BlockLink"; | ||
|
||
type Props = { | ||
receipt: TransactionReceipt; | ||
refundReceipts?: TransactionReceipt[]; | ||
}; | ||
|
||
const Table = styled("table", { | ||
width: "100%", | ||
fontFamily: "SF Mono", | ||
marginVertical: 24, | ||
}); | ||
|
||
const TableElement = styled("td", { | ||
color: "#000000", | ||
fontSize: 14, | ||
lineHeight: "175%", | ||
}); | ||
|
||
const BalanceTitle = styled("div", { | ||
marginTop: 36, | ||
fontWeight: 600, | ||
}); | ||
|
||
const BalanceAmount = styled("div", { | ||
color: "#1A8300", | ||
}); | ||
|
||
const InspectReceipt: React.FC<Props> = React.memo( | ||
({ receipt, refundReceipts }) => { | ||
const refund = | ||
refundReceipts | ||
?.reduce( | ||
(acc, receipt) => JSBI.add(acc, JSBI.BigInt(receipt.deposit || 0)), | ||
BI.zero | ||
) | ||
.toString() ?? "0"; | ||
|
||
return ( | ||
<Table> | ||
<tr> | ||
<TableElement>Receipt ID</TableElement> | ||
<TableElement>{receipt.receiptId}</TableElement> | ||
</tr> | ||
<tr> | ||
<TableElement>Executed in Block</TableElement> | ||
<TableElement> | ||
<BlockLink block={receipt.includedInBlock} /> | ||
</TableElement> | ||
</tr> | ||
<tr> | ||
<TableElement>Predecessor ID</TableElement> | ||
<TableElement> | ||
<AccountLink accountId={receipt.signerId} /> | ||
</TableElement> | ||
</tr> | ||
<tr> | ||
<TableElement>Receiver ID</TableElement> | ||
<TableElement> | ||
<AccountLink accountId={receipt.receiverId} /> | ||
</TableElement> | ||
</tr> | ||
<tr> | ||
<TableElement>Attached Gas</TableElement> | ||
<TableElement> | ||
{"args" in receipt.actions[0] && | ||
"gas" in receipt.actions[0].args ? ( | ||
<Gas gas={JSBI.BigInt(receipt.actions[0].args?.gas)} /> | ||
) : ( | ||
"-" | ||
)} | ||
</TableElement> | ||
</tr> | ||
<tr> | ||
<TableElement>Gas Burned</TableElement> | ||
<TableElement> | ||
<Gas gas={JSBI.BigInt(receipt.gasBurnt || 0)} /> | ||
</TableElement> | ||
</tr> | ||
<tr> | ||
<TableElement>Tokens Burned</TableElement> | ||
<TableElement> | ||
<NearAmount amount={receipt.tokensBurnt} decimalPlaces={2} /> | ||
</TableElement> | ||
</tr> | ||
<tr> | ||
<TableElement>Refunded</TableElement> | ||
<TableElement> | ||
{refund ? <NearAmount amount={refund} decimalPlaces={2} /> : "0"} | ||
</TableElement> | ||
</tr> | ||
<tr> | ||
<TableElement colSpan={2}> | ||
<BalanceTitle>New Balance</BalanceTitle> | ||
</TableElement> | ||
</tr> | ||
<tr> | ||
<TableElement> | ||
<AccountLink accountId={receipt.signerId} /> | ||
</TableElement> | ||
<TableElement> | ||
<BalanceAmount>--.--.--</BalanceAmount> | ||
</TableElement> | ||
</tr> | ||
<tr> | ||
<TableElement> | ||
<AccountLink accountId={receipt.receiverId} /> | ||
</TableElement> | ||
<TableElement> | ||
<BalanceAmount>--.--.--</BalanceAmount> | ||
</TableElement> | ||
</tr> | ||
</Table> | ||
); | ||
} | ||
); | ||
|
||
export default InspectReceipt; |
111 changes: 111 additions & 0 deletions
111
frontend/src/components/beta/transactions/ReceiptDetails.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import * as React from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import CodeArgs from "../common/CodeArgs"; | ||
import JsonView from "../common/JsonView"; | ||
|
||
import { styled } from "../../../libraries/styles"; | ||
import { TransactionReceipt } from "../../../types/common"; | ||
|
||
type Props = { | ||
receipt: TransactionReceipt; | ||
}; | ||
|
||
const DetailsWrapper = styled("div", { | ||
display: "flex", | ||
flexDirection: "column", | ||
marginVertical: 24, | ||
}); | ||
|
||
const Row = styled("div", { | ||
display: "flex", | ||
justifyContent: "space-between", | ||
marginVertical: 20, | ||
|
||
"&:last-child": { | ||
marginVertical: 0, | ||
}, | ||
}); | ||
|
||
const Column = styled("div", { | ||
display: "flex", | ||
flexDirection: "column", | ||
width: "48%", | ||
}); | ||
|
||
const CodeArgsWrapper = styled("div", { | ||
background: "#f8f8f8", | ||
borderRadius: 4, | ||
color: "#3f4246", | ||
padding: 20, | ||
fontSize: "$font-m", | ||
fontWeight: 500, | ||
fontFamily: "SF Mono", | ||
|
||
"& textarea, pre": { | ||
background: "inherit", | ||
color: "inherit", | ||
fontFamily: "inherit", | ||
fontSize: "inherit", | ||
border: "none", | ||
padding: 0, | ||
}, | ||
}); | ||
|
||
const Title = styled("h4", { | ||
fontSize: "$font-m", | ||
fontWeight: 500, | ||
fontFamily: "SF Pro Display", | ||
lineHeight: "175%", | ||
color: "#000000", | ||
}); | ||
|
||
const ReceiptDetails: React.FC<Props> = React.memo(({ receipt }) => { | ||
const { t } = useTranslation(); | ||
let statusInfo; | ||
if ("SuccessValue" in receipt.status) { | ||
const { SuccessValue } = receipt.status; | ||
if (SuccessValue.length === 0) { | ||
statusInfo = ( | ||
<CodeArgsWrapper> | ||
{t("component.transactions.ReceiptRow.empty_result")} | ||
</CodeArgsWrapper> | ||
); | ||
} else { | ||
statusInfo = <CodeArgs args={SuccessValue} />; | ||
} | ||
} else if ("Failure" in receipt.status) { | ||
const { Failure } = receipt.status; | ||
statusInfo = <JsonView args={Failure} />; | ||
} else if ("SuccessReceiptId" in receipt.status) { | ||
const { SuccessReceiptId } = receipt.status; | ||
statusInfo = ( | ||
<CodeArgsWrapper> | ||
<pre>{SuccessReceiptId}</pre> | ||
</CodeArgsWrapper> | ||
); | ||
} | ||
return ( | ||
<DetailsWrapper> | ||
<Row> | ||
<Column> | ||
<div> | ||
<Title>Logs</Title> | ||
<CodeArgsWrapper> | ||
{receipt.logs.length === 0 ? ( | ||
t("component.transactions.ReceiptRow.no_logs") | ||
) : ( | ||
<pre>{receipt.logs.join("\n")}</pre> | ||
)} | ||
</CodeArgsWrapper> | ||
</div> | ||
<div> | ||
<Title>Result</Title> | ||
{statusInfo} | ||
</div> | ||
</Column> | ||
</Row> | ||
</DetailsWrapper> | ||
); | ||
}); | ||
|
||
export default ReceiptDetails; |
Oops, something went wrong.