Display timestamp unavailable
This commit is contained in:
parent
d842d161cf
commit
62e330213f
|
@ -31,7 +31,7 @@ function Copyable({ bottom, text, children }: CopyableProps) {
|
|||
|
||||
return (
|
||||
<div
|
||||
className="copyable"
|
||||
className="popoover-container"
|
||||
onClick={handleClick}
|
||||
onMouseOver={() => setState("copy")}
|
||||
onMouseOut={() => state === "copy" && setState("hide")}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import React, { useState, ReactNode } from "react";
|
||||
|
||||
type Props = {
|
||||
text: string;
|
||||
children: ReactNode;
|
||||
bottom?: boolean;
|
||||
right?: boolean;
|
||||
};
|
||||
|
||||
type State = "hide" | "show";
|
||||
|
||||
function Popover({ state, bottom, right, text }: { state: State; bottom?: boolean, right?: boolean, text: string }) {
|
||||
if (state === "hide") return null;
|
||||
return (
|
||||
<div className={`popover bs-popover-${bottom ? "bottom" : "top"}${right ? " right" : ""} show`}>
|
||||
<div className={`arrow${right ? " right" : ""}`} />
|
||||
<div className="popover-body">{text}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function InfoTooltip({ bottom, right, text, children }: Props) {
|
||||
const [state, setState] = useState<State>("hide");
|
||||
|
||||
return (
|
||||
<div
|
||||
className="popover-container w-100"
|
||||
onMouseOver={() => setState("show")}
|
||||
onMouseOut={() => setState("hide")}
|
||||
>
|
||||
<div className="d-flex align-items-center justify-content-end">
|
||||
{children}
|
||||
<span className="fe fe-help-circle ml-2"></span>
|
||||
</div>
|
||||
<Popover bottom={bottom} right={right} state={state} text={text} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default InfoTooltip;
|
|
@ -25,6 +25,7 @@ import ErrorCard from "./common/ErrorCard";
|
|||
import LoadingCard from "./common/LoadingCard";
|
||||
import TableCardBody from "./common/TableCardBody";
|
||||
import { displayTimestamp } from "utils/date";
|
||||
import InfoTooltip from "components/InfoTooltip";
|
||||
|
||||
type Props = { signature: TransactionSignature };
|
||||
export default function TransactionDetails({ signature }: Props) {
|
||||
|
@ -146,12 +147,16 @@ function StatusCard({ signature }: Props) {
|
|||
<td className="text-right">{renderResult()}</td>
|
||||
</tr>
|
||||
|
||||
{info.timestamp && (
|
||||
<tr>
|
||||
<td>Timestamp</td>
|
||||
<td className="text-right">{displayTimestamp(info.timestamp)}</td>
|
||||
</tr>
|
||||
)}
|
||||
<tr>
|
||||
<td>Timestamp</td>
|
||||
<td className="text-right">
|
||||
{info.timestamp !== "unavailable" ? displayTimestamp(info.timestamp) : (
|
||||
<InfoTooltip text="Timestamps older than 5 epochs are not available at this time">
|
||||
Unavailable
|
||||
</InfoTooltip>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Confirmations</td>
|
||||
|
|
|
@ -26,10 +26,12 @@ export enum FetchStatus {
|
|||
|
||||
export type Confirmations = number | "max";
|
||||
|
||||
export type Timestamp = number | "unavailable";
|
||||
|
||||
export interface TransactionStatusInfo {
|
||||
slot: number;
|
||||
result: SignatureResult;
|
||||
timestamp: number | null;
|
||||
timestamp: Timestamp;
|
||||
confirmations: Confirmations;
|
||||
}
|
||||
|
||||
|
@ -236,7 +238,20 @@ export async function fetchTransactionStatus(
|
|||
});
|
||||
|
||||
if (value !== null) {
|
||||
let timestamp = await connection.getBlockTime(value.slot);
|
||||
let blockTime = await connection.getBlockTime(value.slot);
|
||||
|
||||
let timestamp: Timestamp;
|
||||
if (blockTime !== null) {
|
||||
timestamp = blockTime;
|
||||
} else {
|
||||
const epochInfo = await connection.getEpochInfo();
|
||||
if (value.slot < epochInfo.absoluteSlot - epochInfo.slotsInEpoch) {
|
||||
timestamp = "unavailable";
|
||||
} else {
|
||||
throw new Error("Unable to fetch timestamp");
|
||||
}
|
||||
}
|
||||
|
||||
let confirmations: Confirmations;
|
||||
if (typeof value.confirmations === "number") {
|
||||
confirmations = value.confirmations;
|
||||
|
|
|
@ -10,15 +10,19 @@ code {
|
|||
color: $black;
|
||||
}
|
||||
|
||||
.copyable {
|
||||
.popover-container {
|
||||
position: relative;
|
||||
display: inline;
|
||||
cursor: pointer;
|
||||
|
||||
.popover {
|
||||
&.bs-popover-top {
|
||||
background-color: $dark;
|
||||
top: -4rem;
|
||||
top: auto;
|
||||
bottom: 1.5rem;
|
||||
}
|
||||
|
||||
&.right {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&.bs-popover-bottom {
|
||||
|
@ -30,6 +34,10 @@ code {
|
|||
color: white;
|
||||
}
|
||||
|
||||
.arrow.right {
|
||||
right: 1rem;
|
||||
}
|
||||
|
||||
.arrow::after {
|
||||
border-top-color: $dark;
|
||||
border-bottom-color: $dark;
|
||||
|
@ -45,7 +53,7 @@ code {
|
|||
display: block;
|
||||
}
|
||||
|
||||
.modal .close {
|
||||
.c-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue