+
{#if isIncoming}
{:else}
@@ -58,7 +64,13 @@
-
+ {#if nonNullish(seconds)}
+
+ {:else if isPending}
+
+ {$i18n.wallet.pending_transaction_timestamp}
+
+ {/if}
@@ -97,6 +109,11 @@
min-width: fit-content;
text-align: right;
+ .pending {
+ // Because DateSeconds also has margin-top: 0.
+ margin-top: 0;
+ }
+
@include media.min-width(small) {
margin-top: var(--padding);
}
@@ -125,6 +142,11 @@
background: var(--background);
color: var(--disable-contrast);
}
+
+ &.pending {
+ color: var(--pending-color);
+ background: var(--pending-background);
+ }
}
@include media.dark-theme {
diff --git a/frontend/src/lib/i18n/en.json b/frontend/src/lib/i18n/en.json
index df9f16d9d8d..894e1685573 100644
--- a/frontend/src/lib/i18n/en.json
+++ b/frontend/src/lib/i18n/en.json
@@ -491,7 +491,8 @@
"no_transactions": "No transactions",
"icp_qrcode_aria_label": "A QR code that renders the address to receive ICP",
"sns_qrcode_aria_label": "A QR code that renders the address to receive $tokenSymbol",
- "token_address": "$tokenSymbol Address"
+ "token_address": "$tokenSymbol Address",
+ "pending_transaction_timestamp": "Pending..."
},
"busy_screen": {
"pending_approval_hw": "Please use your hardware wallet to approve.",
diff --git a/frontend/src/lib/types/i18n.d.ts b/frontend/src/lib/types/i18n.d.ts
index 048c66d414e..6b0985f5699 100644
--- a/frontend/src/lib/types/i18n.d.ts
+++ b/frontend/src/lib/types/i18n.d.ts
@@ -509,6 +509,7 @@ interface I18nWallet {
icp_qrcode_aria_label: string;
sns_qrcode_aria_label: string;
token_address: string;
+ pending_transaction_timestamp: string;
}
interface I18nBusy_screen {
diff --git a/frontend/src/lib/types/transaction.ts b/frontend/src/lib/types/transaction.ts
index 94e5cae24a5..cc178cd93c5 100644
--- a/frontend/src/lib/types/transaction.ts
+++ b/frontend/src/lib/types/transaction.ts
@@ -84,12 +84,13 @@ export interface UiTransaction {
// Used in forEach for consistent rendering.
domKey: string;
isIncoming: boolean;
+ isPending: boolean;
headline: string;
// Where the amount is going to or coming from.
otherParty?: string;
// Always positive.
tokenAmount: TokenAmount;
- timestamp: Date;
+ timestamp?: Date;
}
export enum TransactionNetwork {
diff --git a/frontend/src/lib/utils/icrc-transactions.utils.ts b/frontend/src/lib/utils/icrc-transactions.utils.ts
index 4690dfab1dd..a99a7ce7308 100644
--- a/frontend/src/lib/utils/icrc-transactions.utils.ts
+++ b/frontend/src/lib/utils/icrc-transactions.utils.ts
@@ -210,6 +210,7 @@ export const mapIcrcTransaction = ({
return {
domKey: `${transaction.id}-${toSelfTransaction ? "0" : "1"}`,
isIncoming: isReceive,
+ isPending: false,
headline,
otherParty,
tokenAmount: TokenAmount.fromE8s({
diff --git a/frontend/src/lib/utils/transactions.utils.ts b/frontend/src/lib/utils/transactions.utils.ts
index 98c0d63031b..3341cea80fa 100644
--- a/frontend/src/lib/utils/transactions.utils.ts
+++ b/frontend/src/lib/utils/transactions.utils.ts
@@ -168,6 +168,7 @@ export const toUiTransaction = ({
return {
domKey: `${transactionId}-${toSelfTransaction ? "0" : "1"}`,
isIncoming,
+ isPending: false,
headline,
otherParty,
tokenAmount: TokenAmount.fromE8s({
diff --git a/frontend/src/tests/lib/components/accounts/IcrcTransactionCard.spec.ts b/frontend/src/tests/lib/components/accounts/IcrcTransactionCard.spec.ts
index a69c39f6d20..e4cea1dde93 100644
--- a/frontend/src/tests/lib/components/accounts/IcrcTransactionCard.spec.ts
+++ b/frontend/src/tests/lib/components/accounts/IcrcTransactionCard.spec.ts
@@ -18,6 +18,7 @@ describe("IcrcTransactionCard", () => {
const defaultTransaction = {
domKey: "123-0",
isIncoming: false,
+ isPending: false,
icon: "outgoing",
headline: "Sent",
otherParty: "some-address",
diff --git a/frontend/src/tests/lib/components/accounts/TransactionCard.spec.ts b/frontend/src/tests/lib/components/accounts/TransactionCard.spec.ts
index d26d09c4589..1ddd3eb98ad 100644
--- a/frontend/src/tests/lib/components/accounts/TransactionCard.spec.ts
+++ b/frontend/src/tests/lib/components/accounts/TransactionCard.spec.ts
@@ -10,7 +10,7 @@ describe("TransactionCard", () => {
const defaultTransaction = {
domKey: "234-0",
isIncoming: false,
- icon: "outgoing",
+ isPending: false,
headline: "Sent",
otherParty: "some-address",
tokenAmount: TokenAmount.fromE8s({ amount: 123_000_000n, token: ICPToken }),
@@ -100,6 +100,17 @@ describe("TransactionCard", () => {
expect(normalizeWhitespace(await po.getDate())).toBe(
"Mar 14, 2021 12:00 AM"
);
+ expect(await po.hasPendingIcon()).toBe(false);
+ });
+
+ it("displays pending transaction", async () => {
+ const po = renderComponent({
+ isPending: true,
+ timestamp: null,
+ });
+
+ expect(normalizeWhitespace(await po.getDate())).toBe("Pending...");
+ expect(await po.hasPendingIcon()).toBe(true);
});
it("displays identifier for received", async () => {
diff --git a/frontend/src/tests/lib/utils/icrc-transactions.utils.spec.ts b/frontend/src/tests/lib/utils/icrc-transactions.utils.spec.ts
index fccd2b29871..c7e94c1f001 100644
--- a/frontend/src/tests/lib/utils/icrc-transactions.utils.spec.ts
+++ b/frontend/src/tests/lib/utils/icrc-transactions.utils.spec.ts
@@ -145,6 +145,7 @@ describe("icrc-transaction utils", () => {
domKey: "112-1",
headline: "Sent",
isIncoming: false,
+ isPending: false,
otherParty: mockSnsSubAccount.identifier,
timestamp: defaultTimestamp,
tokenAmount: TokenAmount.fromE8s({
@@ -350,6 +351,7 @@ describe("icrc-transaction utils", () => {
domKey: "1234-1",
headline: "Sent",
isIncoming: false,
+ isPending: false,
otherParty: undefined,
timestamp: new Date(0),
tokenAmount: TokenAmount.fromE8s({
@@ -388,6 +390,7 @@ describe("icrc-transaction utils", () => {
domKey: "1234-1",
headline: "Sent",
isIncoming: false,
+ isPending: false,
otherParty: btcWithdrawalAddress,
timestamp: new Date(0),
tokenAmount: TokenAmount.fromE8s({
@@ -426,6 +429,7 @@ describe("icrc-transaction utils", () => {
domKey: "1234-1",
headline: "Sent",
isIncoming: false,
+ isPending: false,
otherParty: "BTC Network",
timestamp: new Date(0),
tokenAmount: TokenAmount.fromE8s({
@@ -457,6 +461,7 @@ describe("icrc-transaction utils", () => {
domKey: "1234-1",
headline: "Received",
isIncoming: true,
+ isPending: false,
otherParty: "BTC Network",
timestamp: new Date(0),
tokenAmount: TokenAmount.fromE8s({
diff --git a/frontend/src/tests/lib/utils/transactions.utils.spec.ts b/frontend/src/tests/lib/utils/transactions.utils.spec.ts
index 208bc36a39f..70829c7f8f8 100644
--- a/frontend/src/tests/lib/utils/transactions.utils.spec.ts
+++ b/frontend/src/tests/lib/utils/transactions.utils.spec.ts
@@ -403,6 +403,7 @@ describe("transactions-utils", () => {
const defaultExpectedUiTransaction: UiTransaction = {
domKey: "123-1",
isIncoming: false,
+ isPending: false,
headline: "Sent",
otherParty: defaultTo,
tokenAmount: TokenAmount.fromE8s({
diff --git a/frontend/src/tests/mocks/transaction.mock.ts b/frontend/src/tests/mocks/transaction.mock.ts
index c2080a12af6..5bc3868bd70 100644
--- a/frontend/src/tests/mocks/transaction.mock.ts
+++ b/frontend/src/tests/mocks/transaction.mock.ts
@@ -81,6 +81,7 @@ export const mockTransactionSendDataFromMain: Transaction = {
export const createMockUiTransaction = ({
domKey = "123-1",
isIncoming = false,
+ isPending = false,
headline = "Sent",
otherParty = "aaaaa-aa",
tokenAmount = TokenAmount.fromE8s({
@@ -91,6 +92,7 @@ export const createMockUiTransaction = ({
}: Partial