Skip to content

Commit 43f8d82

Browse files
authored
Merge pull request #6 from ensuro/update/transactions-detail-ui
Update: Transactions detail UI
2 parents bddc9d7 + 1ebc4b4 commit 43f8d82

File tree

5 files changed

+1167
-178
lines changed

5 files changed

+1167
-178
lines changed

src/Address.jsx

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,52 @@
11
import React from "react";
2-
import { Typography, Popover } from "@mui/material";
2+
import { Typography, Popover, Link } from "@mui/material";
33
import Chip from "@mui/material/Chip";
44
import { shortAddress } from "./utils";
5+
import { explorerAddressUrl } from "./chain-utils";
6+
import { useSafe } from "./safe-ui";
57

68
function Address({ displayName = null, address }) {
79
const [popAnchor, setPopAnchor] = React.useState(null);
8-
9-
const handlePopoverOpen = (event) => {
10-
setPopAnchor(event.currentTarget);
11-
};
12-
13-
const handlePopoverClose = () => {
14-
setPopAnchor(null);
15-
};
10+
const { chainId } = useSafe();
1611

1712
const popOpen = Boolean(popAnchor);
13+
const url = explorerAddressUrl(chainId, address);
1814

1915
return (
2016
<>
2117
<Chip
2218
label={displayName || shortAddress(address)}
23-
aria-owns={popOpen ? "mouse-over-popover" : undefined}
19+
aria-owns={popOpen ? "address-popover" : undefined}
2420
aria-haspopup="true"
25-
onClick={handlePopoverOpen}
21+
onClick={(e) => setPopAnchor(e.currentTarget)}
22+
onDelete={undefined}
23+
variant="outlined"
2624
/>
2725
<Popover
28-
id="mouse-over-popover"
26+
id="address-popover"
2927
open={popOpen}
3028
anchorEl={popAnchor}
31-
anchorOrigin={{
32-
vertical: "bottom",
33-
horizontal: "left",
34-
}}
35-
transformOrigin={{
36-
vertical: "top",
37-
horizontal: "left",
38-
}}
39-
onClose={handlePopoverClose}
29+
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
30+
transformOrigin={{ vertical: "top", horizontal: "left" }}
31+
onClose={() => setPopAnchor(null)}
4032
disableRestoreFocus
4133
>
42-
<Typography sx={{ p: 1 }}>{address}</Typography>
34+
<Typography sx={{ fontFamily: "monospace", fontSize: 12, wordBreak: "break-all" }}>
35+
{url ? (
36+
<Link
37+
href={url}
38+
target="_blank"
39+
rel="noopener noreferrer"
40+
underline="hover"
41+
sx={{ fontFamily: "monospace", fontSize: 12, wordBreak: "break-all" }}
42+
onClick={() => setPopAnchor(null)}
43+
>
44+
{address}
45+
</Link>
46+
) : (
47+
address
48+
)}
49+
</Typography>
4350
</Popover>
4451
</>
4552
);

src/SearchPage.jsx

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
11
import * as React from "react";
22
import { Box, Stack, TextField, MenuItem, Button, Paper, Typography, Link } from "@mui/material";
33
import { useQuery } from "@tanstack/react-query";
4+
45
import { useSafe } from "./safe-ui";
5-
import { getTransactionDetailsByKey } from "./safe-api";
6+
import { getChangesetAndSafeTxHashByKey, getSafeTransaction } from "./safe-api";
7+
import { chainPrefixFromId } from "./chain-utils";
8+
import TransactionCard from "./TransactionCard";
69

710
const KEY_SEARCH = "tx-search";
811

9-
function chainPrefixFromId(chainId) {
10-
switch (Number(chainId)) {
11-
case 1:
12-
return "eth";
13-
case 137:
14-
return "matic";
15-
case 42161:
16-
return "arb1";
17-
default:
18-
return String(chainId);
19-
}
20-
}
21-
2212
export default function SearchPage() {
23-
const { chainId, safeAddress } = useSafe();
13+
const safe = useSafe();
14+
const { chainId, safeAddress } = safe;
15+
2416
const [mode, setMode] = React.useState("safeTxHash");
2517
const [searchText, setSearchText] = React.useState("");
2618
const [submittedQuery, setSubmittedQuery] = React.useState(null);
@@ -33,16 +25,19 @@ export default function SearchPage() {
3325
enabled: hasSubmitted,
3426
queryFn: async () => {
3527
if (!submittedQuery) return null;
36-
const changeset = await getTransactionDetailsByKey(
37-
{ chainId, safeAddress },
38-
{ type: submittedQuery.mode, key: submittedQuery.text.trim() }
39-
);
40-
const safeTxHash =
41-
submittedQuery.mode === "safeTxHash"
42-
? submittedQuery.text.trim()
43-
: changeset?.safeTxHash || changeset?.safe_tx_hash || submittedQuery.text.trim();
44-
return { safeTxHash, changeset };
28+
29+
const base = await getChangesetAndSafeTxHashByKey(safe, {
30+
type: submittedQuery.mode,
31+
key: submittedQuery.text,
32+
});
33+
34+
if (!base?.safeTxHash) return null;
35+
36+
const txMeta = await getSafeTransaction(safe, base.safeTxHash);
37+
38+
return { ...base, txMeta };
4539
},
40+
refetchOnWindowFocus: false,
4641
});
4742

4843
function onSubmit(e) {
@@ -56,6 +51,7 @@ export default function SearchPage() {
5651
? `https://app.safe.global/transactions/tx?safe=${chainPrefix}:${safeAddress}`
5752
: null;
5853

54+
const isSearching = hasSubmitted && query.fetchStatus === "fetching";
5955
return (
6056
<Stack spacing={2}>
6157
<Paper variant="outlined" sx={{ p: 2 }}>
@@ -89,7 +85,7 @@ export default function SearchPage() {
8985
</Box>
9086
</Paper>
9187

92-
{hasSubmitted && query.fetchStatus === "fetching" && <Typography>Searching…</Typography>}
88+
{isSearching && <Typography>Searching…</Typography>}
9389

9490
{hasSubmitted && query.isError && (
9591
<Paper variant="outlined" sx={{ p: 2 }}>
@@ -112,13 +108,14 @@ export default function SearchPage() {
112108
</Paper>
113109
)}
114110

115-
{hasSubmitted && query.isSuccess && (
116-
<Paper variant="outlined" sx={{ p: 2 }}>
117-
<Typography variant="h6" gutterBottom>
118-
Changeset for safeTxHash {query.data.safeTxHash}
119-
</Typography>
120-
<pre style={{ margin: 0, overflowX: "auto" }}>{JSON.stringify(query.data.changeset, null, 2)}</pre>
121-
</Paper>
111+
{!isSearching && hasSubmitted && query.isSuccess && query.data?.changeset && (
112+
<TransactionCard
113+
key={query.data.safeTxHash}
114+
transaction={query.data.txMeta}
115+
txDetails={query.data.changeset}
116+
safeTxHash={query.data.safeTxHash}
117+
readOnly
118+
/>
122119
)}
123120
</Stack>
124121
);

0 commit comments

Comments
 (0)