From 78252f4a2d0857abbbea48189854013040075998 Mon Sep 17 00:00:00 2001 From: refi93 Date: Mon, 9 Oct 2023 17:43:11 +0200 Subject: [PATCH 01/31] feat(staking): include pool rewards in wallet activity --- .../transaction-detail-slice.test.ts | 2 +- .../stores/slices/transaction-detail-slice.ts | 22 ++- .../stores/slices/wallet-activities-slice.ts | 161 ++++++++++++------ .../src/stores/types.ts | 30 +++- apps/browser-extension-wallet/src/types/tx.ts | 2 +- .../activity/components/TransactionDetail.tsx | 9 +- .../__tests__/pending-tx-transformer.test.ts | 10 +- .../__tests__/tx-history-transformer.test.ts | 11 +- .../activity/helpers/common-tx-transformer.ts | 19 ++- .../helpers/pending-tx-transformer.ts | 8 +- .../helpers/reward-history-transformer.ts | 50 ++++++ .../helpers/tx-history-transformer.ts | 9 +- .../__tests__/AssetDetails.test.tsx | 48 +++++- .../components/Activity/AssetActivityItem.tsx | 14 +- .../__tests__/AssetActivityItem.test.tsx | 3 + .../__tests__/AssetActivityList.test.tsx | 4 +- .../GroupedAssetActivityList.test.tsx | 3 + .../components/Transactions/Transaction.tsx | 2 +- .../Transactions/TransactionDetailBrowser.tsx | 10 +- 19 files changed, 301 insertions(+), 116 deletions(-) create mode 100644 apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts diff --git a/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts b/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts index 78b9f087c..3b8a8ef88 100644 --- a/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts +++ b/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts @@ -42,7 +42,7 @@ describe('Testing createStoreHook slice', () => { const { result, waitForValueToChange } = renderHook(() => useTransactionsStore()); act(() => { - result.current.setTransactionDetail(transactionMock.tx, transactionMock.direction); + result.current.setTransactionDetail({ tx: transactionMock.tx, direction: transactionMock.direction }); }); waitForValueToChange(() => result.current.transactionDetail); expect(result.current.transactionDetail).toBeDefined(); diff --git a/apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts b/apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts index f62cabbcf..e59fb7911 100644 --- a/apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts @@ -16,7 +16,8 @@ import { inspectTxValues } from '@src/utils/tx-inspection'; import { firstValueFrom } from 'rxjs'; import { getAssetsInformation } from '@src/utils/get-assets-information'; import { MAX_POOLS_COUNT } from '@lace/staking'; -import { TransactionType } from '@lace/core'; +import type { TransactionType } from '@lace/core'; +import { formatDate, formatTime } from '@src/utils/format-date'; /** * validates if the transaction is confirmed @@ -70,10 +71,24 @@ const getTransactionDetail = const { blockchainProvider: { chainHistoryProvider, stakePoolProvider, assetProvider }, inMemoryWallet: wallet, - transactionDetail: { tx, status, direction, type }, + transactionDetail: { tx, epochRewards, status, direction, type }, walletInfo } = get(); + if (type === 'rewards') { + return { + tx: { + includedUtcDate: formatDate({ date: epochRewards.time, format: 'MM/DD/YYYY', type: 'utc' }), + includedUtcTime: `${formatTime({ date: epochRewards.time, type: 'utc' })} UTC`, + rewards: Wallet.util.lovelacesToAdaString( + Wallet.BigIntMath.sum(epochRewards.rewards?.map(({ rewards }) => rewards) || []).toString() + ) + }, + status, + type + }; + } + const walletAssets = await firstValueFrom(wallet.assetInfo$); const protocolParameters = await firstValueFrom(wallet.protocolParameters$); set({ fetchingTransactionInfo: true }); @@ -190,6 +205,7 @@ export const transactionDetailSlice: SliceCreator< transactionDetail: undefined, fetchingTransactionInfo: true, getTransactionDetails: getTransactionDetail({ set, get }), - setTransactionDetail: (tx, direction, status, type) => set({ transactionDetail: { tx, direction, status, type } }), + setTransactionDetail: ({ tx, epochRewards, direction, status, type }) => + set({ transactionDetail: { tx, epochRewards, direction, status, type } }), resetTransactionState: () => set({ transactionDetail: undefined, fetchingTransactionInfo: false }) }); diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index 20c9ea541..29180c0c9 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -6,14 +6,21 @@ import groupBy from 'lodash/groupBy'; import { mergeMap, combineLatest, tap, Observable, firstValueFrom } from 'rxjs'; import { map } from 'rxjs/operators'; import { Wallet } from '@lace/cardano'; -import { EraSummary, TxCBOR } from '@cardano-sdk/core'; +import { EraSummary, Reward, TxCBOR, epochSlotsCalc } from '@cardano-sdk/core'; import { pendingTxTransformer, txHistoryTransformer, filterOutputsByTxDirection, - isTxWithAssets + isTxWithAssets, + TransformedTx } from '@src/views/browser-view/features/activity/helpers'; -import { AssetActivityItemProps, AssetActivityListProps, ActivityAssetProp, TransactionType } from '@lace/core'; +import { + AssetActivityItemProps, + AssetActivityListProps, + ActivityAssetProp, + TransactionType, + TransactionStatus +} from '@lace/core'; import { CurrencyInfo, TxDirections } from '@src/types'; import { getTxDirection, inspectTxType } from '@src/utils/tx-inspection'; import { assetTransformer } from '@src/utils/assets-transformers'; @@ -28,6 +35,8 @@ import { SliceCreator } from '../types'; import { getAssetsInformation } from '@src/utils/get-assets-information'; +import { rewardHistoryTransformer } from '@src/views/browser-view/features/activity/helpers/reward-history-transformer'; +import { EpochNo } from '@cardano-sdk/core/dist/cjs/Cardano'; export interface FetchWalletActivitiesProps { fiatCurrency: CurrencyInfo; @@ -102,7 +111,13 @@ const getWalletActivitiesObservable = async ({ assetDetails, blockchainProvider: { assetProvider } } = get(); - const { transactions, eraSummaries$, protocolParameters$, assetInfo$ } = inMemoryWallet; + const { + transactions, + eraSummaries$, + protocolParameters$, + assetInfo$, + delegation: { rewardsHistory$ } + } = inMemoryWallet; const protocolParameters = await firstValueFrom(protocolParameters$); const walletAssets = await firstValueFrom(assetInfo$); const historicalTransactions$ = transactions.history$; @@ -113,50 +128,45 @@ const getWalletActivitiesObservable = async ({ const historicTransactionMapper = ( tx: Wallet.Cardano.HydratedTx, eraSummaries: EraSummary[] - ): AssetActivityItemProps | Array => { + ): Array => { const slotTimeCalc = Wallet.createSlotTimeCalc(eraSummaries); - const time = slotTimeCalc(tx.blockHeader.slot); + const date = slotTimeCalc(tx.blockHeader.slot); const transformedTransaction = txHistoryTransformer({ tx, walletAddresses: addresses, fiatCurrency, fiatPrice: cardanoFiatPrice, - time, + date, protocolParameters, cardanoCoin }); - const extendWithClickHandler = (transformedTx: Omit) => ({ + const extendWithClickHandler = (transformedTx: TransformedTx) => ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); - setTransactionDetail(tx, transformedTx.direction, transformedTx.status, transformedTx.type); + setTransactionDetail({ + tx, + direction: transformedTx.direction, + status: transformedTx.status, + type: transformedTx.type + }); } }); - /* - considering the current SDK logic for automatically withdraw rewards when building a transaction and such behavior has to be transparent for the user, - we will remove the withdrawal from the transaction history as it is implemented today. - Instead, we will show rewards in the transaction history whenever the user receives them. - To make this happen we need to create a new record Rewards and added to the transaction history - */ - if (Array.isArray(transformedTransaction)) { - return transformedTransaction.map((tt) => extendWithClickHandler(tt)); - } - - return extendWithClickHandler(transformedTransaction); + return transformedTransaction.map((tt) => extendWithClickHandler(tt)); }; const pendingTransactionMapper = ( tx: Wallet.TxInFlight, eraSummaries: EraSummary[] - ): AssetActivityItemProps | Array => { - let time; + ): Array => { + let date; try { const slotTimeCalc = Wallet.createSlotTimeCalc(eraSummaries); - time = slotTimeCalc(tx.submittedAt); + date = slotTimeCalc(tx.submittedAt); } catch { - time = new Date(); + date = new Date(); } const transformedTransaction = pendingTxTransformer({ tx, @@ -165,28 +175,60 @@ const getWalletActivitiesObservable = async ({ fiatCurrency, protocolParameters, cardanoCoin, - time + date }); - const extendWithClickHandler = (transformedTx: Omit) => ({ + const extendWithClickHandler = (transformedTx: TransformedTx) => ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); const deserializedTx: Wallet.Cardano.Tx = TxCBOR.deserialize(tx.cbor); - setTransactionDetail( - deserializedTx, - TxDirections.Outgoing, - Wallet.TransactionStatus.PENDING, - transformedTx.type - ); + setTransactionDetail({ + tx: deserializedTx, + direction: TxDirections.Outgoing, + status: Wallet.TransactionStatus.PENDING, + type: transformedTx.type + }); } }); - if (Array.isArray(transformedTransaction)) { - return transformedTransaction.map((tt) => extendWithClickHandler(tt)); - } + return transformedTransaction.map((tt) => extendWithClickHandler(tt)); + }; + + const epochRewardsMapper = ( + earnedEpoch: EpochNo, + rewards: Reward[], + eraSummaries: EraSummary[] + ): AssetActivityItemProps => { + const REWARD_SPENDABLE_DELAY_EPOCHS = 2; + const spendableEpoch = (earnedEpoch + REWARD_SPENDABLE_DELAY_EPOCHS) as EpochNo; + const slotTimeCalc = Wallet.createSlotTimeCalc(eraSummaries); + const rewardSpendableDate = slotTimeCalc(epochSlotsCalc(spendableEpoch, eraSummaries).firstSlot); + + const transformedEpochRewards = rewardHistoryTransformer({ + rewards, + fiatCurrency, + fiatPrice: cardanoFiatPrice, + cardanoCoin, + date: rewardSpendableDate + }); - return extendWithClickHandler(transformedTransaction); + return { + ...transformedEpochRewards, + onClick: () => { + if (sendAnalytics) sendAnalytics(); + setTransactionDetail({ + direction: transformedEpochRewards.direction, + status: transformedEpochRewards.status, + type: transformedEpochRewards.type, + epochRewards: { + rewards, + spendableEpoch, + time: rewardSpendableDate + } + }); + } + }; }; const filterTransactionByAssetId = (tx: Wallet.Cardano.HydratedTx[]) => @@ -200,7 +242,7 @@ const getWalletActivitiesObservable = async ({ }); /** - * Sorts and sanitizes historical transactions data + * Sanitizes historical transactions data */ const getHistoricalTransactions = (eraSummaries: EraSummary[]) => historicalTransactions$.pipe( @@ -210,12 +252,6 @@ const getWalletActivitiesObservable = async ({ ? allTransactions : filterTransactionByAssetId(allTransactions) ), - map((allTransactions: Wallet.Cardano.HydratedTx[]) => - allTransactions.sort( - (firstTransaction, secondTransaction) => - secondTransaction.blockHeader.slot.valueOf() - firstTransaction.blockHeader.slot.valueOf() - ) - ), map((allTransactions: Wallet.Cardano.HydratedTx[]) => flattenDeep(allTransactions.map((tx) => historicTransactionMapper(tx, eraSummaries))) ) @@ -231,16 +267,32 @@ const getWalletActivitiesObservable = async ({ ) ); + /** + * Sanitizes historical rewards data + */ + const getRewardsHistory = (eraSummaries: EraSummary[]) => + rewardsHistory$.pipe( + map((allRewards: Wallet.RewardsHistory) => + Object.entries(groupBy(allRewards.all, ({ epoch }) => epoch.toString())).map(([epoch, rewards]) => + epochRewardsMapper(Number(epoch) as EpochNo, rewards, eraSummaries) + ) + ) + ); + /** * 1. Listens for time settings - * 2. Passes it to historical transactions and pending transactions lists - * 3. Emits both lists combined and sets current state for Zustand + * 2. Passes it to historical transactions, pending transactions and rewards history lists + * 3. Emits the lists combined and sets current state for Zustand */ - return combineLatest([eraSummaries$, pendingTransactions$, historicalTransactions$]).pipe( + return combineLatest([eraSummaries$, pendingTransactions$, historicalTransactions$, rewardsHistory$]).pipe( mergeMap(([eraSummaries]) => - combineLatest([getHistoricalTransactions(eraSummaries), getPendingTransactions(eraSummaries)]) + combineLatest([ + getHistoricalTransactions(eraSummaries), + getPendingTransactions(eraSummaries), + getRewardsHistory(eraSummaries) + ]) ), - map(async ([historicalTransactions, pendingTransactions]) => { + map(async ([historicalTransactions, pendingTransactions, rewards]) => { const confirmedTxs = await historicalTransactions; const pendingTxs = await pendingTransactions; /* After the transaction is confirmed is not being removed from pendingTransactions$, so we have to remove it manually from pending list @@ -249,9 +301,18 @@ const getWalletActivitiesObservable = async ({ const filteredPendingTxs = pendingTxs.filter((pending) => confirmedTxs.some((confirmed) => confirmed?.id !== pending?.id) ); - return [...filteredPendingTxs, ...confirmedTxs]; + return [...filteredPendingTxs, ...confirmedTxs, ...rewards]; }), - map(async (allTransactions: Promise) => groupBy(await allTransactions, 'date')), + map(async (allTransactions: Promise) => + (await allTransactions).sort((firstTx, secondTx) => { + // ensure pending txs are always first + if (firstTx.status === TransactionStatus.PENDING && secondTx.status !== TransactionStatus.PENDING) return 1; + if (secondTx.status === TransactionStatus.PENDING && firstTx.status !== TransactionStatus.PENDING) return -1; + // otherwise sort by date + return secondTx.date.getTime() - firstTx.date.getTime(); + }) + ), + map(async (allTransactions: Promise) => groupBy(await allTransactions, 'formattedDate')), map(async (lists) => Object.entries(await lists).map(([listName, transactionsList]) => ({ title: listName, diff --git a/apps/browser-extension-wallet/src/stores/types.ts b/apps/browser-extension-wallet/src/stores/types.ts index 8221bba96..e177accd4 100644 --- a/apps/browser-extension-wallet/src/stores/types.ts +++ b/apps/browser-extension-wallet/src/stores/types.ts @@ -16,6 +16,8 @@ import { FetchWalletActivitiesProps, FetchWalletActivitiesReturn, IBlockchainPro import { IAssetDetails } from '@src/views/browser-view/features/assets/types'; import { TokenInfo } from '@src/utils/get-assets-information'; import { WalletManagerUi } from '@cardano-sdk/web-extension'; +import { Reward } from '@cardano-sdk/core'; +import { EpochNo } from '@cardano-sdk/core/dist/cjs/Cardano'; export enum StateStatus { IDLE = 'idle', @@ -122,18 +124,28 @@ export interface UISlice { export interface TransactionDetailSlice { transactionDetail?: { + type: TransactionType; + status: Wallet.TransactionStatus; + direction: TxDirection; + tx?: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; + epochRewards?: { spendableEpoch: EpochNo; time: Date; rewards: Reward[] }; + } & ( + | { + type: 'rewards'; + epochRewards: NonNullable; + } + | { + tx: NonNullable; + } + ); + fetchingTransactionInfo: boolean; + setTransactionDetail: (params: { + tx?: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; + epochRewards?: { spendableEpoch: EpochNo; time: Date; rewards: Reward[] }; direction: TxDirection; - tx: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; status?: Wallet.TransactionStatus; type?: TransactionType; - }; - fetchingTransactionInfo: boolean; - setTransactionDetail: ( - tx: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx, - direction: TxDirection, - status?: Wallet.TransactionStatus, - type?: TransactionType - ) => void; + }) => void; getTransactionDetails: (params: { coinPrices: PriceResult; fiatCurrency: CurrencyInfo; diff --git a/apps/browser-extension-wallet/src/types/tx.ts b/apps/browser-extension-wallet/src/types/tx.ts index 776d21d3f..1aa9e6855 100644 --- a/apps/browser-extension-wallet/src/types/tx.ts +++ b/apps/browser-extension-wallet/src/types/tx.ts @@ -17,7 +17,7 @@ export type TransactionPool = { export interface TransactionDetail { tx: { - hash: string; + hash?: string; includedUtcDate?: string; includedUtcTime?: string; totalOutput?: string; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetail.tsx index fda580fcb..2af906a53 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetail.tsx @@ -70,7 +70,7 @@ export const getTransactionData = ({ const getCurrentTransactionStatus = ( activities: AssetActivityListProps[], txId: Wallet.Cardano.TransactionId -): TransactionStatus => { +): TransactionStatus | undefined => { const todayActivity = activities.find((activity) => activity.title === 'Today'); const transaction = todayActivity?.items.find((item) => item.id === String(txId)); return transaction?.status; @@ -101,8 +101,11 @@ export const TransactionDetail = withAddressBookContext( ); const currentTransactionStatus = useMemo( - () => getCurrentTransactionStatus(walletActivities, transactionDetail.tx.id) || transactionInfo?.status, - [transactionDetail.tx.id, transactionInfo?.status, walletActivities] + () => + transactionDetail.tx?.id + ? getCurrentTransactionStatus(walletActivities, transactionDetail.tx.id) ?? transactionInfo?.status + : transactionInfo?.status, + [transactionDetail.tx?.id, transactionInfo?.status, walletActivities] ); const fetchTransactionInfo = useCallback(async () => { diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/pending-tx-transformer.test.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/pending-tx-transformer.test.ts index ae3023817..62a80e0bc 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/pending-tx-transformer.test.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/pending-tx-transformer.test.ts @@ -80,7 +80,7 @@ describe('Testing tx transformers utils', () => { }; test('should return parsed pending tx', async () => { mockLovelacesToAdaString.mockImplementation(actualLovelacesToAdaString); - const time = new Date(); + const date = new Date(); const result = pendingTxTransformer({ tx: { ...pendingTx, cbor: TxCBOR.serialize(pendingTx) }, walletAddresses: [ @@ -98,13 +98,12 @@ describe('Testing tx transformers utils', () => { fiatPrice: 1, protocolParameters: { poolDeposit: 3, stakeKeyDeposit: 2 } as Wallet.ProtocolParameters, cardanoCoin, - time + date }); expect(result).toStrictEqual([ { type: 'outgoing', status: 'sending', - date: 'Sending', deposit: undefined, depositReclaim: undefined, direction: 'Outgoing', @@ -119,8 +118,9 @@ describe('Testing tx transformers utils', () => { } ], assetsNumber: 2, - timestamp: formatTime({ - date: time, + formattedDate: 'Sending', + formattedTimestamp: formatTime({ + date, format: DEFAULT_TIME_FORMAT, type: 'local' }) diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/tx-history-transformer.test.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/tx-history-transformer.test.ts index 760719867..41f818555 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/tx-history-transformer.test.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/tx-history-transformer.test.ts @@ -100,7 +100,7 @@ describe('Testing txHistoryTransformer function', () => { ) } ] as Wallet.KeyManagement.GroupedAddress[], - time: date, + date, fiatCurrency: { code: 'USD', symbol: '$' @@ -127,7 +127,7 @@ describe('Testing txHistoryTransformer function', () => { ) } ] as Wallet.KeyManagement.GroupedAddress[], - time: date, + date, fiatCurrency: { code: 'USD', symbol: '$' @@ -164,7 +164,7 @@ describe('Testing txHistoryTransformer function', () => { ) } ] as Wallet.KeyManagement.GroupedAddress[], - time: date, + date, fiatCurrency: { code: 'USD', symbol: '$' @@ -187,12 +187,11 @@ describe('Testing txHistoryTransformer function', () => { walletAddresses: props.walletAddresses, fiatCurrency: props.fiatCurrency, fiatPrice: props.fiatPrice, - time: props.time, + date: props.date, protocolParameters: props.protocolParameters, cardanoCoin: props.cardanoCoin, status: Wallet.TransactionStatus.SUCCESS, - direction, - date: '01 February 2022' + direction }); expect(result.length).toBe(1); expect(result[0].status).toBe('success'); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts index 59f09077d..5700be3a4 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts @@ -2,8 +2,11 @@ import BigNumber from 'bignumber.js'; import { Wallet } from '@lace/cardano'; import { CurrencyInfo, TxDirections } from '@types'; import { inspectTxValues, inspectTxType } from '@src/utils/tx-inspection'; -import { formatTime } from '@src/utils/format-date'; +import { formatDate, formatTime } from '@src/utils/format-date'; import type { TransformedTx } from './types'; +import { TransactionStatus } from '@lace/core'; +import capitalize from 'lodash/capitalize'; +import dayjs from 'dayjs'; export interface TxTransformerInput { tx: Wallet.TxInFlight | Wallet.Cardano.HydratedTx; @@ -12,10 +15,9 @@ export interface TxTransformerInput { fiatPrice?: number; protocolParameters: Wallet.ProtocolParameters; cardanoCoin: Wallet.CoinId; - time: Date; + date: Date; direction?: TxDirections; status?: Wallet.TransactionStatus; - date?: string; } export const getFormattedFiatAmount = ({ @@ -93,7 +95,6 @@ export const txTransformer = ({ fiatPrice, protocolParameters, cardanoCoin, - time, date, direction, status @@ -110,8 +111,11 @@ export const txTransformer = ({ direction }); const outputAmount = new BigNumber(coins.toString()); - const timestamp = formatTime({ - date: time, + const formattedDate = dayjs().isSame(date, 'day') + ? 'Today' + : formatDate({ date, format: 'DD MMMM YYYY', type: 'local' }); + const formattedTimestamp = formatTime({ + date, type: 'local' }); @@ -132,7 +136,8 @@ export const txTransformer = ({ assets: assetsEntries, assetsNumber: (assets?.size ?? 0) + 1, date, - timestamp + formattedDate: status === TransactionStatus.PENDING ? capitalize(Wallet.TransactionStatus.PENDING) : formattedDate, + formattedTimestamp }; // Note that TxInFlight at type level does not expose its inputs with address, diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts index 7b985cad8..f057f0cb9 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts @@ -1,7 +1,6 @@ import { TxTransformerInput, txTransformer } from './common-tx-transformer'; import { Wallet } from '@lace/cardano'; import type { TransformedTx } from './types'; -import capitalize from 'lodash/capitalize'; import { TxDirections } from '@types'; interface TxHistoryTransformerInput extends Omit { @@ -15,7 +14,7 @@ export const pendingTxTransformer = ({ fiatPrice, protocolParameters, cardanoCoin, - time + date }: TxHistoryTransformerInput): TransformedTx[] => txTransformer({ tx, @@ -24,8 +23,7 @@ export const pendingTxTransformer = ({ fiatPrice, protocolParameters, cardanoCoin, - time, + date, status: Wallet.TransactionStatus.PENDING, - direction: TxDirections.Outgoing, - date: capitalize(Wallet.TransactionStatus.PENDING) + direction: TxDirections.Outgoing }); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts new file mode 100644 index 000000000..a58ea3109 --- /dev/null +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts @@ -0,0 +1,50 @@ +import { Wallet } from '@lace/cardano'; +import { getFormattedFiatAmount } from './common-tx-transformer'; +import type { TransformedTx } from './types'; +import dayjs from 'dayjs'; +import { formatDate, formatTime } from '@src/utils/format-date'; +import BigNumber from 'bignumber.js'; +import type { CurrencyInfo } from '@src/types'; +import type { Reward } from '@cardano-sdk/core'; + +interface RewardHistoryTransformerInput { + rewards: Reward[]; // TODO this supposes rewards grouped by epoch which is a bit fragile + fiatCurrency: CurrencyInfo; + fiatPrice: number; + date: Date; + cardanoCoin: Wallet.CoinId; +} + +export const rewardHistoryTransformer = ({ + rewards, + fiatCurrency, + fiatPrice, + date, + cardanoCoin +}: RewardHistoryTransformerInput): TransformedTx => { + const formattedTimestamp = formatTime({ + date, + type: 'local' + }); + const formattedDate = dayjs().isSame(date, 'day') + ? 'Today' + : formatDate({ date, format: 'DD MMMM YYYY', type: 'local' }); + + const totalRewardsAmount = Wallet.BigIntMath.sum(rewards.map(({ rewards: _rewards }) => _rewards)); + + return { + type: 'rewards', + direction: 'Incoming', + amount: Wallet.util.getFormattedAmount({ amount: totalRewardsAmount.toString(), cardanoCoin }), + fiatAmount: getFormattedFiatAmount({ + amount: new BigNumber(totalRewardsAmount.toString()), + fiatCurrency, + fiatPrice + }), + status: Wallet.TransactionStatus.SPENDABLE, + assets: [], + date, + formattedTimestamp, + formattedDate + }; +}; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts index 24192fc12..a9498b20b 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts @@ -1,6 +1,4 @@ import { Wallet } from '@lace/cardano'; -import dayjs from 'dayjs'; -import { formatDate } from '@src/utils/format-date'; import { getTxDirection, inspectTxType } from '@src/utils/tx-inspection'; import { txTransformer, TxTransformerInput } from './common-tx-transformer'; import type { TransformedTx } from './types'; @@ -14,7 +12,7 @@ export const txHistoryTransformer = ({ walletAddresses, fiatCurrency, fiatPrice, - time, + date, protocolParameters, cardanoCoin }: TxHistoryTransformerInput): TransformedTx[] => { @@ -26,11 +24,10 @@ export const txHistoryTransformer = ({ walletAddresses, fiatCurrency, fiatPrice, - time, + date, protocolParameters, cardanoCoin, status: Wallet.TransactionStatus.SUCCESS, - direction, - date: dayjs().isSame(time, 'day') ? 'Today' : formatDate({ date: time, format: 'DD MMMM YYYY', type: 'local' }) + direction }); }; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx index 265746950..12a629f03 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx @@ -57,8 +57,20 @@ describe('AssetDetails', () => { balanceInFiat="1000 USD" fiatPriceVariation="0" activityList={[ - { amount: '100', fiatAmount: '450' }, - { amount: '200', fiatAmount: '400' } + { + amount: '100', + fiatAmount: '450', + date: new Date('2021-01-01'), + formattedDate: 'Date', + formattedTimestamp: 'Timestamp' + }, + { + amount: '200', + fiatAmount: '400', + date: new Date('2021-01-01'), + formattedDate: 'Date', + formattedTimestamp: 'Timestamp' + } ]} /> ); @@ -75,8 +87,20 @@ describe('AssetDetails', () => { balanceInFiat="1000 USD" fiatPriceVariation="0" activityList={[ - { amount: '100', fiatAmount: '450' }, - { amount: '200', fiatAmount: '400' } + { + amount: '100', + fiatAmount: '450', + date: new Date('2021-01-01'), + formattedDate: 'Date', + formattedTimestamp: 'Timestamp' + }, + { + amount: '200', + fiatAmount: '400', + date: new Date('2021-01-01'), + formattedDate: 'Date', + formattedTimestamp: 'Timestamp' + } ]} activityListStatus={StateStatus.LOADING} /> @@ -94,8 +118,20 @@ describe('AssetDetails', () => { balanceInFiat="1000 USD" fiatPriceVariation="0" activityList={[ - { amount: '100', fiatAmount: '450' }, - { amount: '200', fiatAmount: '400' } + { + amount: '100', + fiatAmount: '450', + date: new Date('2021-01-01'), + formattedDate: 'Date', + formattedTimestamp: 'Timestamp' + }, + { + amount: '200', + fiatAmount: '400', + date: new Date('2021-01-01'), + formattedDate: 'Date', + formattedTimestamp: 'Timestamp' + } ]} activityListStatus={StateStatus.IDLE} /> diff --git a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx index cfc4c18c3..81ddf98ea 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx @@ -34,6 +34,10 @@ export interface AssetActivityItemProps { * Amount formated with symbol (e.g. 50 ADA) */ amount: string; + /** + * Date of the activity + */ + date: Date; /** * Amount in Fiat currency (e.g. 125$) */ @@ -58,7 +62,8 @@ export interface AssetActivityItemProps { * Number of assets (default: 1) */ assetsNumber?: number; - date?: string; + formattedDate: string; + formattedTimestamp: string; /** * Direction: 'Incoming' | 'Outgoing' | 'Self' * TODO: Create a separate package for common types across apps/packages @@ -68,7 +73,6 @@ export interface AssetActivityItemProps { * assets details */ assets?: ActivityAssetProp[]; - timestamp?: string; } const DelegationTransactionTypes = new Set(['delegation', 'delegationRegistration', 'delegationDeregistration']); @@ -116,7 +120,7 @@ export const AssetActivityItem = ({ type, assetsNumber = 1, assets, - timestamp + formattedTimestamp }: AssetActivityItemProps): React.ReactElement => { const { t } = useTranslate(); const ref = useRef(null); @@ -178,9 +182,9 @@ export const AssetActivityItem = ({ {pluralize('package.core.assetActivityItem.entry.token', assetsNumber, true)}

); - const descriptionContent = timestamp ? ( + const descriptionContent = formattedTimestamp ? (

- {timestamp} + {formattedTimestamp}

) : ( assetAmountContent diff --git a/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx b/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx index 0740bb167..cc36a16e2 100644 --- a/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx +++ b/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx @@ -13,6 +13,9 @@ describe('Testing AssetActivityItem component', () => { type: 'outgoing', amount: '100', fiatAmount: '300 $', + date: new Date('2021-01-01'), + formattedDate: 'Date', + formattedTimestamp: 'Timestamp', status: TransactionStatus.ERROR, onClick: jest.fn(), assetsNumber: 1, diff --git a/packages/core/src/ui/components/Activity/__tests__/AssetActivityList.test.tsx b/packages/core/src/ui/components/Activity/__tests__/AssetActivityList.test.tsx index 4dded5d6b..aeddeeba0 100644 --- a/packages/core/src/ui/components/Activity/__tests__/AssetActivityList.test.tsx +++ b/packages/core/src/ui/components/Activity/__tests__/AssetActivityList.test.tsx @@ -25,7 +25,9 @@ describe('Testing AssetActivityList component', () => { type: 'outgoing', name: 'Sent', description: 'ADA', - date: '19:47', + date: new Date('2021-01-01'), + formattedDate: 'Date', + formattedTimestamp: '19:47', amount: '100 ADA', fiatAmount: '300 $', status: TransactionStatus.ERROR, diff --git a/packages/core/src/ui/components/Activity/__tests__/GroupedAssetActivityList.test.tsx b/packages/core/src/ui/components/Activity/__tests__/GroupedAssetActivityList.test.tsx index 43cafcb26..ee6c1ffe3 100644 --- a/packages/core/src/ui/components/Activity/__tests__/GroupedAssetActivityList.test.tsx +++ b/packages/core/src/ui/components/Activity/__tests__/GroupedAssetActivityList.test.tsx @@ -9,6 +9,9 @@ const activityItem: AssetActivityItemProps = { type: 'outgoing', amount: '100 ADA', fiatAmount: '300 $', + formattedDate: 'FormattedDate', + formattedTimestamp: 'FormattedTimestamp', + date: new Date('2021-01-01'), assetsNumber: 1, assets: [{ id: '1', val: '1' }] }; diff --git a/packages/core/src/ui/components/Transactions/Transaction.tsx b/packages/core/src/ui/components/Transactions/Transaction.tsx index a3591ee3f..6ebc2ea7b 100644 --- a/packages/core/src/ui/components/Transactions/Transaction.tsx +++ b/packages/core/src/ui/components/Transactions/Transaction.tsx @@ -17,7 +17,7 @@ import CopyToClipboard from 'react-copy-to-clipboard'; const displayMetadataMsg = (value: any[]): string => value?.find((val: any) => val.hasOwnProperty('msg'))?.msg || ''; export interface TransactionProps { - hash: string; + hash?: string; name: string; status?: TransactionStatus; /** diff --git a/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.tsx b/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.tsx index e60c0b3cb..070b39843 100644 --- a/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.tsx +++ b/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.tsx @@ -2,7 +2,7 @@ import React from 'react'; import styles from './TransactionDetailBrowser.module.scss'; import { TransactionDetailHeaderBrowser } from './TransactionDetailHeaderBrowser'; import { TransactionStatus } from '../Activity/AssetActivityItem'; -import { RewardDetailsProps } from './RewardDetails'; +import { RewardDetails, RewardDetailsProps } from './RewardDetails'; import { Transaction, TransactionProps } from './Transaction'; import { TransactionType } from './TransactionType'; import { useTranslate } from '@src/ui/hooks'; @@ -33,6 +33,7 @@ export const TransactionDetailBrowser = ({ coinSymbol, type, isPopupView, + rewards, ...props }: TransactionDetailBrowserProps): React.ReactElement => { const { t } = useTranslate(); @@ -52,8 +53,6 @@ export const TransactionDetailBrowser = ({ isPopupView }; - // temporarily unused as part of (LW-8315), rewards to be reintroduced with LW-8751 - /* const rewardProps: RewardDetailsProps = { name, status, @@ -63,15 +62,12 @@ export const TransactionDetailBrowser = ({ coinSymbol, rewards }; - */ return (
{status === TransactionStatus.SPENDABLE ? ( - // temporarily unused as part of (LW-8315), rewards to be reintroduced with LW-8751 - // - <> + ) : ( )} From 083c4451778ee901e9ed3c6b428fa8f18d8ebe38 Mon Sep 17 00:00:00 2001 From: refi93 Date: Mon, 16 Oct 2023 18:09:12 +0200 Subject: [PATCH 02/31] feat(staking): expose reward amount breakdown in activity detail --- .../src/lib/translations/en.json | 3 +- .../stores/slices/transaction-detail-slice.ts | 68 +++++++++++++------ .../stores/slices/wallet-activities-slice.ts | 8 +-- .../src/stores/types.ts | 4 +- apps/browser-extension-wallet/src/types/tx.ts | 3 +- .../components/Transactions/RewardDetails.tsx | 58 +++++++++++++++- .../ui/components/Transactions/RewardsInfo.ts | 10 +++ .../components/Transactions/Transaction.tsx | 3 +- .../TransactionDetailBrowser.module.scss | 13 ++++ .../src/ui/components/Transactions/index.ts | 1 + packages/core/src/ui/lib/translations/en.json | 3 +- 11 files changed, 142 insertions(+), 32 deletions(-) create mode 100644 packages/core/src/ui/components/Transactions/RewardsInfo.ts diff --git a/apps/browser-extension-wallet/src/lib/translations/en.json b/apps/browser-extension-wallet/src/lib/translations/en.json index c5f487242..3c9c36a11 100644 --- a/apps/browser-extension-wallet/src/lib/translations/en.json +++ b/apps/browser-extension-wallet/src/lib/translations/en.json @@ -55,7 +55,8 @@ "from": "From", "to": "To", "multipleAddresses": "Multiple addresses", - "pools": "Pool(s)" + "pools": "Pool(s)", + "epoch": "Epoch" }, "walletNameAndPasswordSetupStep": { "title": "Let's set up your new wallet", diff --git a/apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts b/apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts index e59fb7911..4d052b109 100644 --- a/apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts @@ -56,8 +56,26 @@ const shouldIncludeFee = ( (type === 'delegationDeregistration' && !!delegationInfo?.length) ); +const getPoolInfos = async (poolIds: Wallet.Cardano.PoolId[], stakePoolProvider: Wallet.StakePoolProvider) => { + const filters: Wallet.QueryStakePoolsArgs = { + filters: { + identifier: { + _condition: 'or', + values: poolIds.map((poolId) => ({ id: poolId })) + } + }, + pagination: { + startAt: 0, + limit: MAX_POOLS_COUNT + } + }; + const { pageResults: pools } = await stakePoolProvider.queryStakePools(filters); + + return pools; +}; + /** - * fetchs asset information + * fetches asset information */ const getTransactionDetail = ({ @@ -76,13 +94,34 @@ const getTransactionDetail = } = get(); if (type === 'rewards') { + const poolInfos = await getPoolInfos( + epochRewards.rewards.map(({ poolId }) => poolId), + stakePoolProvider + ); + return { tx: { - includedUtcDate: formatDate({ date: epochRewards.time, format: 'MM/DD/YYYY', type: 'utc' }), - includedUtcTime: `${formatTime({ date: epochRewards.time, type: 'utc' })} UTC`, - rewards: Wallet.util.lovelacesToAdaString( - Wallet.BigIntMath.sum(epochRewards.rewards?.map(({ rewards }) => rewards) || []).toString() - ) + includedUtcDate: formatDate({ date: epochRewards.spendableDate, format: 'MM/DD/YYYY', type: 'utc' }), + includedUtcTime: `${formatTime({ date: epochRewards.spendableDate, type: 'utc' })} UTC`, + rewards: { + totalAmount: Wallet.util.lovelacesToAdaString( + Wallet.BigIntMath.sum(epochRewards.rewards?.map(({ rewards }) => rewards) || []).toString() + ), + spendableEpoch: epochRewards.spendableEpoch, + rewards: epochRewards.rewards.map((r) => { + const poolInfo = poolInfos.find((p) => p.id === r.poolId); + return { + amount: Wallet.util.lovelacesToAdaString(r.rewards.toString()), + pool: r.poolId + ? { + id: r.poolId, + name: poolInfo?.metadata?.name || '-', + ticker: poolInfo?.metadata?.ticker || '-' + } + : undefined + }; + }) + } }, status, type @@ -163,19 +202,10 @@ const getTransactionDetail = }; if (type === 'delegation' && delegationInfo) { - const filters: Wallet.QueryStakePoolsArgs = { - filters: { - identifier: { - _condition: 'or', - values: delegationInfo.map((certificate) => ({ id: certificate.poolId })) - } - }, - pagination: { - startAt: 0, - limit: MAX_POOLS_COUNT - } - }; - const { pageResults: pools } = await stakePoolProvider.queryStakePools(filters); + const pools = await getPoolInfos( + delegationInfo.map(({ poolId }) => poolId), + stakePoolProvider + ); if (pools.length === 0) { console.error('Stake pool was not found for delegation tx'); diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index 29180c0c9..8bbbe598b 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -224,7 +224,7 @@ const getWalletActivitiesObservable = async ({ epochRewards: { rewards, spendableEpoch, - time: rewardSpendableDate + spendableDate: rewardSpendableDate } }); } @@ -273,9 +273,9 @@ const getWalletActivitiesObservable = async ({ const getRewardsHistory = (eraSummaries: EraSummary[]) => rewardsHistory$.pipe( map((allRewards: Wallet.RewardsHistory) => - Object.entries(groupBy(allRewards.all, ({ epoch }) => epoch.toString())).map(([epoch, rewards]) => - epochRewardsMapper(Number(epoch) as EpochNo, rewards, eraSummaries) - ) + Object.entries(groupBy(allRewards.all, ({ epoch }) => epoch.toString())) + .map(([epoch, rewards]) => epochRewardsMapper(Number(epoch) as EpochNo, rewards, eraSummaries)) + .filter((reward) => reward.date.getTime() < Date.now()) ) ); diff --git a/apps/browser-extension-wallet/src/stores/types.ts b/apps/browser-extension-wallet/src/stores/types.ts index e177accd4..190045c96 100644 --- a/apps/browser-extension-wallet/src/stores/types.ts +++ b/apps/browser-extension-wallet/src/stores/types.ts @@ -128,7 +128,7 @@ export interface TransactionDetailSlice { status: Wallet.TransactionStatus; direction: TxDirection; tx?: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; - epochRewards?: { spendableEpoch: EpochNo; time: Date; rewards: Reward[] }; + epochRewards?: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; } & ( | { type: 'rewards'; @@ -141,7 +141,7 @@ export interface TransactionDetailSlice { fetchingTransactionInfo: boolean; setTransactionDetail: (params: { tx?: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; - epochRewards?: { spendableEpoch: EpochNo; time: Date; rewards: Reward[] }; + epochRewards?: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; direction: TxDirection; status?: Wallet.TransactionStatus; type?: TransactionType; diff --git a/apps/browser-extension-wallet/src/types/tx.ts b/apps/browser-extension-wallet/src/types/tx.ts index 1aa9e6855..5293baee1 100644 --- a/apps/browser-extension-wallet/src/types/tx.ts +++ b/apps/browser-extension-wallet/src/types/tx.ts @@ -1,5 +1,6 @@ import { TransactionMetadataProps, TxOutputInput, TransactionType } from '@lace/core'; import { Wallet } from '@lace/cardano'; +import { RewardsInfo } from '@lace/core/dist/ui/components/Transactions/RewardsInfo'; export enum TxDirections { Outgoing = 'Outgoing', @@ -28,7 +29,7 @@ export interface TransactionDetail { addrOutputs?: TxOutputInput[]; metadata?: TransactionMetadataProps['metadata']; pools?: TransactionPool[]; - rewards?: string; + rewards?: RewardsInfo; }; blocks?: { isPopup?: boolean; diff --git a/packages/core/src/ui/components/Transactions/RewardDetails.tsx b/packages/core/src/ui/components/Transactions/RewardDetails.tsx index 857b9c9df..4172d45ef 100644 --- a/packages/core/src/ui/components/Transactions/RewardDetails.tsx +++ b/packages/core/src/ui/components/Transactions/RewardDetails.tsx @@ -3,6 +3,8 @@ import cn from 'classnames'; import styles from './TransactionDetailBrowser.module.scss'; import { useTranslate } from '@src/ui/hooks'; import { TransactionStatus } from '../Activity/AssetActivityItem'; +import type { RewardsInfo } from './RewardsInfo'; +import { Ellipsis } from '@lace/common'; export interface RewardDetailsProps { name: string; @@ -11,7 +13,7 @@ export interface RewardDetailsProps { includedTime?: string; amountTransformer: (amount: string) => string; coinSymbol: string; - rewards?: string; + rewards?: RewardsInfo; } export const RewardDetails = ({ @@ -24,6 +26,8 @@ export const RewardDetails = ({ rewards }: RewardDetailsProps): React.ReactElement => { const { t } = useTranslate(); + const poolRewards = rewards?.rewards.filter((reward) => !!reward.pool); + return (
{t('package.core.transactionDetailBrowser.header')}
@@ -34,13 +38,57 @@ export const RewardDetails = ({
{name}
- {`${rewards} ${coinSymbol}`} - {`${amountTransformer(rewards)}`} + {`${rewards.totalAmount} ${coinSymbol}`} + {`${amountTransformer( + rewards.totalAmount + )}`}
+ {poolRewards.length > 0 && ( +
+
+ {t('package.core.transactionDetailBrowser.pools')} +
+
+ {poolRewards?.map(({ pool, amount }) => ( +
+
+ {pool.name && ( +
+ {pool.name} +
+ )} + {pool.ticker && ( +
+ ({pool.ticker}) +
+ )} +
+ {pool.id && ( +
+ +
+ )} +
+ + {amount} {coinSymbol} + + + {amountTransformer(amount)} + +
+
+ ))} +
+
+ )} +
{t('package.core.transactionDetailBrowser.status')}
{status && ( @@ -49,6 +97,10 @@ export const RewardDetails = ({ )}`}
)} +
+
{t('package.core.transactionDetailBrowser.epoch')}
+ {
{`${rewards.spendableEpoch}`}
} +
{t('package.core.transactionDetailBrowser.timestamp')} diff --git a/packages/core/src/ui/components/Transactions/RewardsInfo.ts b/packages/core/src/ui/components/Transactions/RewardsInfo.ts new file mode 100644 index 000000000..3ef050a8f --- /dev/null +++ b/packages/core/src/ui/components/Transactions/RewardsInfo.ts @@ -0,0 +1,10 @@ +type RewardItem = { + pool?: { name: string; ticker: string; id: string }; + amount: string; +}; + +export type RewardsInfo = { + totalAmount: string; + spendableEpoch: number; + rewards: RewardItem[]; +}; diff --git a/packages/core/src/ui/components/Transactions/Transaction.tsx b/packages/core/src/ui/components/Transactions/Transaction.tsx index 6ebc2ea7b..6ae173e64 100644 --- a/packages/core/src/ui/components/Transactions/Transaction.tsx +++ b/packages/core/src/ui/components/Transactions/Transaction.tsx @@ -12,6 +12,7 @@ import { ReactComponent as Info } from '../../assets/icons/info-icon.component.s import { TransactionInputOutput } from './TransactionInputOutput'; import { useTranslate } from '@src/ui/hooks'; import CopyToClipboard from 'react-copy-to-clipboard'; +import type { RewardsInfo } from './RewardsInfo'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const displayMetadataMsg = (value: any[]): string => value?.find((val: any) => val.hasOwnProperty('msg'))?.msg || ''; @@ -63,7 +64,7 @@ export interface TransactionProps { txSummary?: TxSummary[]; coinSymbol: string; tooltipContent?: string; - rewards?: string; + rewards?: RewardsInfo; addressToNameMap: Map; isPopupView?: boolean; openExternalLink?: () => void; diff --git a/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.module.scss b/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.module.scss index 39ebb2777..a11c7e8b6 100644 --- a/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.module.scss +++ b/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.module.scss @@ -283,6 +283,19 @@ $border-bottom: 1px solid var(--light-mode-light-grey-plus, var(--dark-mode-mid- gap: size_unit(1) } + .poolRewardAmount { + display: flex; + flex-direction: column; + font-size: var(--bodySmall); + .ada { + color: var(--text-color-primary, #ffffff); + } + + .fiat { + color: var(--text-color-secondary, #878e9e); + } + } + .lightLabel { color: var(--light-mode-dark-grey, var(--dark-mode-light-grey)); } diff --git a/packages/core/src/ui/components/Transactions/index.ts b/packages/core/src/ui/components/Transactions/index.ts index d5e9a348d..212b51ae6 100644 --- a/packages/core/src/ui/components/Transactions/index.ts +++ b/packages/core/src/ui/components/Transactions/index.ts @@ -3,3 +3,4 @@ export * from './TransactionType'; export * from './TransactionTypeIcon'; export * from './TransactionDetailAsset'; export * from './TransactionInputOutput'; +export * from './RewardsInfo'; diff --git a/packages/core/src/ui/lib/translations/en.json b/packages/core/src/ui/lib/translations/en.json index 705ebbb01..6dcab838f 100644 --- a/packages/core/src/ui/lib/translations/en.json +++ b/packages/core/src/ui/lib/translations/en.json @@ -79,7 +79,8 @@ "rewards": "Rewards", "rewardsDescription": "When available, your rewards will be withdrawn automatically every time you send Tokens.", "copiedToClipboard": "Copied to clipboard", - "pools": "Pool(s)" + "pools": "Pool(s)", + "epoch": "Epoch" }, "authorizeDapp": { "title": "Allow this site to", From aa09aa6ac56d98a8b1b92373c84ad20221d9bc92 Mon Sep 17 00:00:00 2001 From: refi93 Date: Tue, 17 Oct 2023 12:42:19 +0200 Subject: [PATCH 03/31] refactor(all): generalize "Transaction" name to "Activity" --- apps/browser-extension-wallet/.env.swp | Bin 0 -> 12288 bytes .../src/api/transformers.ts | 4 +- .../features/activity/components/Activity.tsx | 14 +- .../src/stores/createWalletStore.ts | 4 +- .../transaction-detail-slice.test.ts | 38 ++--- .../__tests__/wallet-activities-slice.test.ts | 6 +- ...tail-slice.ts => activity-detail-slice.ts} | 44 +++-- .../src/stores/slices/index.ts | 2 +- .../stores/slices/wallet-activities-slice.ts | 19 +-- .../src/stores/types.ts | 19 +-- apps/browser-extension-wallet/src/types/tx.ts | 2 +- .../src/utils/mocks/store.tsx | 8 +- .../src/utils/mocks/test-helpers.tsx | 4 +- ...ansactionDetail.tsx => ActivityDetail.tsx} | 70 ++++---- .../activity/components/ActivityLayout.tsx | 16 +- ...etail.test.tsx => ActivityDetail.test.tsx} | 2 +- .../features/activity/components/index.tsx | 2 +- .../AssetActivityDetails.tsx} | 12 +- .../AssetTransactionDetails.test.tsx | 16 +- .../features/assets/components/Assets.tsx | 46 ++--- .../TransactionDetailBrowser.test.tsx | 2 +- .../src/assert/transactionDetailsAssert.ts | 158 +++++++++--------- .../src/elements/transactionDetails.ts | 6 +- .../src/steps/multidelegationSteps.ts | 4 +- .../e2e-tests/src/steps/nftsCommonSteps.ts | 4 +- .../src/steps/sendTransactionSimpleSteps.ts | 14 +- packages/e2e-tests/src/steps/stakingSteps.ts | 4 +- .../e2e-tests/src/steps/transactionsSteps.ts | 32 ++-- 28 files changed, 268 insertions(+), 284 deletions(-) create mode 100644 apps/browser-extension-wallet/.env.swp rename apps/browser-extension-wallet/src/stores/slices/{transaction-detail-slice.ts => activity-detail-slice.ts} (87%) rename apps/browser-extension-wallet/src/views/browser-view/features/activity/components/{TransactionDetail.tsx => ActivityDetail.tsx} (68%) rename apps/browser-extension-wallet/src/views/browser-view/features/activity/components/__tests__/{TransactionDetail.test.tsx => ActivityDetail.test.tsx} (96%) rename apps/browser-extension-wallet/src/views/browser-view/features/assets/components/{AssetTransactionDetails/AssetTransactionDetails.tsx => AssetActivityDetails/AssetActivityDetails.tsx} (69%) rename apps/browser-extension-wallet/src/views/browser-view/features/assets/components/{AssetTransactionDetails => AssetActivityDetails}/__tests__/AssetTransactionDetails.test.tsx (87%) diff --git a/apps/browser-extension-wallet/.env.swp b/apps/browser-extension-wallet/.env.swp new file mode 100644 index 0000000000000000000000000000000000000000..76278a5b7671cd04b3df58dd888dad094554fcda GIT binary patch literal 12288 zcmeHNyN~l&6~7D8e!LbC6lf_{fvF&yIFrod8>Fy%W8cJ{_%(iHCev7sa}zsuY>(~4 znJJ*9MF{aX0HQ?{fDjErG#~^m^b{Z=wpj{}oy^W;V0PJZC0qL0vF~~Q&bil#awn~k zAl1&AEdmLysAe7iMn+ATAOzgB6e(umpxwIkKPA`i5hMGjpAad;B ziNd!Y8)Wh*@#DaDC{v#7I8K>K66GmP8g!G}t4qZ|#X!YC#X!YC#X!YC#X!YC#X!YC#X!YC#lT090egzj*Iz~G%P$~! z`2YX@_y0dWhtOXDzXkjl@LfO*7y#;k7l2m*?|c@aKLdUV_z~cHfCz96=mEY4cmeq5 zYaj>s6W}+15b!0y-#>%UuK_;*cz|yL-T-_Y@VifgZ@?1J0{rV!2>k-^bHEP)HsE!@ zA3llD?*YF8d>=3YFo1u50-<*Se*^p!P~`Y}k!N*O3{(tM3{(tM3_Qz#h*@HhD}%_o zpvcycjJuK`^n?YLdvpKB^}WGa-s<5C(#Kd~@x@DAjI;A0d?whpPg>{vhQDe#`CvSj z#^Q}A-u0C$XLzedt@Cp%-Ar00IdrqlY;zoShP{hHqPT&3H#7N6mpz^DZKk8TL?VHm zL~~xfUNLK}Uq2dZ*tjE$X`N{gS#cOI!uDo8=-9XQ%XQy7Ub}bxOSd&Wr-3*Wu3iRO zi|rit>b!XrdAVBWa@AM_5)rj)>EtE9VXv;+=3;y_68wpLd$|}c)8)#{)wX}S3QpD> zb4*oYJ11vDtuLHi*KOg{pSR3#G~vec`r@2h#e6UtWSel3EYe<1T$2~{{`F+A(id6S z=j2&i?QovPMQ7xVdrT|dv=z#7Z$|t+c~JQ zb~3fYsHW3o?Ku>3m9U{miiK6dA~L5cg8WdvrJY5~sOj7%#Oxl#Zj20~NxG%^sG;6F<+Ki_-^AAeO3#0y}QYTY-~jvu8$jw0eYUu_n5_>AeX5}WF zg01;k!oUsV*qI&NrdeYhWnKvBPY;g|PmfMJowL)of-Vgo%nlS~AVM37c)y8YL-cKP z9!2w=| z95zUIW(O%n#USSJPN175tL-z%6b-@Rh)4$5C|-HGfro-Tc#z-)j#$#z>R}PfEO{8% zs ({ +export const blockTransformer = (block: Wallet.BlockInfo): ActivityDetail['blocks'] => ({ blockId: block.header.hash.toString(), epoch: block.epoch.toString(), block: block.header.blockNo.toString(), diff --git a/apps/browser-extension-wallet/src/features/activity/components/Activity.tsx b/apps/browser-extension-wallet/src/features/activity/components/Activity.tsx index c666541ab..570b6cd92 100644 --- a/apps/browser-extension-wallet/src/features/activity/components/Activity.tsx +++ b/apps/browser-extension-wallet/src/features/activity/components/Activity.tsx @@ -5,7 +5,7 @@ import { StateStatus, useWalletStore } from '@src/stores'; import { useFetchCoinPrice, useRedirection } from '@hooks'; import { Drawer, DrawerNavigation } from '@lace/common'; import { GroupedAssetActivityList } from '@lace/core'; -import { TransactionDetail } from '@src/views/browser-view/features/activity'; +import { ActivityDetail } from '@src/views/browser-view/features/activity'; import styles from './Activity.module.scss'; import { FundWalletBanner } from '@src/views/browser-view/components'; import { walletRoutePaths } from '@routes'; @@ -21,7 +21,7 @@ import { useWalletActivities } from '@hooks/useWalletActivities'; export const Activity = (): React.ReactElement => { const { t } = useTranslation(); const { priceResult } = useFetchCoinPrice(); - const { walletInfo, transactionDetail, resetTransactionState } = useWalletStore(); + const { walletInfo, activityDetail, resetActivityState } = useWalletStore(); const layoutTitle = `${t('browserView.activity.title')}`; const redirectToAssets = useRedirection(walletRoutePaths.assets); const analytics = useAnalyticsContext(); @@ -43,21 +43,21 @@ export const Activity = (): React.ReactElement => { return ( { analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailXClick); - resetTransactionState(); + resetActivityState(); redirectToAssets(); }} /> } popupView > - {transactionDetail && priceResult && } + {activityDetail && priceResult && }
{hasActivities ? ( diff --git a/apps/browser-extension-wallet/src/stores/createWalletStore.ts b/apps/browser-extension-wallet/src/stores/createWalletStore.ts index 5e8f8c45d..27e6e46ba 100644 --- a/apps/browser-extension-wallet/src/stores/createWalletStore.ts +++ b/apps/browser-extension-wallet/src/stores/createWalletStore.ts @@ -8,7 +8,7 @@ import { stakePoolSearchSlice, walletInfoSlice, lockSlice, - transactionDetailSlice, + activityDetailSlice, uiSlice, blockchainProviderSlice } from './slices'; @@ -34,7 +34,7 @@ export const createWalletStore = ( ...networkSlice({ set, get }), ...stakePoolSearchSlice({ set, get }), ...lockSlice({ set, get }), - ...transactionDetailSlice({ set, get }), + ...activityDetailSlice({ set, get }), ...assetDetailsSlice({ set, get }) })); }; diff --git a/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts b/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts index 3b8a8ef88..c0f382b4d 100644 --- a/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts +++ b/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts @@ -1,50 +1,50 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { renderHook, act } from '@testing-library/react-hooks'; -import { BlockchainProviderSlice, TransactionDetailSlice, WalletInfoSlice } from '../../types'; +import { BlockchainProviderSlice, ActivityDetailSlice, WalletInfoSlice } from '../../types'; import { transactionMock } from '../../../utils/mocks/test-helpers'; -import { transactionDetailSlice } from '../transaction-detail-slice'; +import { activityDetailSlice } from '../activity-detail-slice'; import '@testing-library/jest-dom'; import create, { GetState, SetState } from 'zustand'; import { mockBlockchainProviders } from '@src/utils/mocks/blockchain-providers'; -const mockTransactionDetailSlice = ( - set: SetState, - get: GetState -): TransactionDetailSlice => { +const mockActivityDetailSlice = ( + set: SetState, + get: GetState +): ActivityDetailSlice => { get = () => ({ blockchainProvider: mockBlockchainProviders() } as BlockchainProviderSlice & - TransactionDetailSlice & + ActivityDetailSlice & WalletInfoSlice); - return transactionDetailSlice({ set, get }); + return activityDetailSlice({ set, get }); }; describe('Testing createStoreHook slice', () => { test('should create store hook with transaction slices slice', () => { - const useTransactionsStore = create(mockTransactionDetailSlice); + const useTransactionsStore = create(mockActivityDetailSlice); const { result } = renderHook(() => useTransactionsStore()); expect(result).toBeDefined(); }); test('should return transaction state and state handlers', () => { - const useTransactionsStore = create(mockTransactionDetailSlice); + const useTransactionsStore = create(mockActivityDetailSlice); const { result } = renderHook(() => useTransactionsStore()); expect(result.current).toBeDefined(); - expect(result.current.transactionDetail).not.toBeDefined(); - expect(result.current.fetchingTransactionInfo).toBeDefined(); - expect(result.current.getTransactionDetails).toBeDefined(); - expect(result.current.resetTransactionState).toBeDefined(); - expect(result.current.setTransactionDetail).toBeDefined(); + expect(result.current.activityDetail).not.toBeDefined(); + expect(result.current.fetchingActivityInfo).toBeDefined(); + expect(result.current.getActivityDetails).toBeDefined(); + expect(result.current.resetActivityState).toBeDefined(); + expect(result.current.setActivityDetail).toBeDefined(); }); test('should set transaction detail', () => { - const useTransactionsStore = create(mockTransactionDetailSlice); + const useTransactionsStore = create(mockActivityDetailSlice); const { result, waitForValueToChange } = renderHook(() => useTransactionsStore()); act(() => { - result.current.setTransactionDetail({ tx: transactionMock.tx, direction: transactionMock.direction }); + result.current.setActivityDetail({ tx: transactionMock.tx, direction: transactionMock.direction }); }); - waitForValueToChange(() => result.current.transactionDetail); - expect(result.current.transactionDetail).toBeDefined(); + waitForValueToChange(() => result.current.activityDetail); + expect(result.current.activityDetail).toBeDefined(); }); }); diff --git a/apps/browser-extension-wallet/src/stores/slices/__tests__/wallet-activities-slice.test.ts b/apps/browser-extension-wallet/src/stores/slices/__tests__/wallet-activities-slice.test.ts index c9cd1bad2..51c5a3546 100644 --- a/apps/browser-extension-wallet/src/stores/slices/__tests__/wallet-activities-slice.test.ts +++ b/apps/browser-extension-wallet/src/stores/slices/__tests__/wallet-activities-slice.test.ts @@ -5,7 +5,7 @@ import { StateStatus, AssetDetailsSlice, BlockchainProviderSlice, - TransactionDetailSlice, + ActivityDetailSlice, UISlice, WalletInfoSlice } from '@stores/types'; @@ -21,7 +21,7 @@ const mockActivitiesSlice = ( get: GetState< WalletInfoSlice & WalletActivitiesSlice & - TransactionDetailSlice & + ActivityDetailSlice & AssetDetailsSlice & UISlice & BlockchainProviderSlice @@ -35,7 +35,7 @@ const mockActivitiesSlice = ( walletInfo: mockWalletInfoTestnet } as WalletInfoSlice & WalletActivitiesSlice & - TransactionDetailSlice & + ActivityDetailSlice & AssetDetailsSlice & UISlice & BlockchainProviderSlice); diff --git a/apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts similarity index 87% rename from apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts rename to apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts index 4d052b109..ecd1bb357 100644 --- a/apps/browser-extension-wallet/src/stores/slices/transaction-detail-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts @@ -1,14 +1,8 @@ /* eslint-disable complexity */ /* eslint-disable unicorn/no-array-reduce */ import isEmpty from 'lodash/isEmpty'; -import { - TransactionDetailSlice, - ZustandHandlers, - BlockchainProviderSlice, - WalletInfoSlice, - SliceCreator -} from '../types'; -import { CardanoTxOut, Transaction, TransactionDetail } from '../../types'; +import { ActivityDetailSlice, ZustandHandlers, BlockchainProviderSlice, WalletInfoSlice, SliceCreator } from '../types'; +import { CardanoTxOut, Transaction, ActivityDetail } from '../../types'; import { blockTransformer, inputOutputTransformer } from '../../api/transformers'; import { Wallet } from '@lace/cardano'; import { getTransactionTotalOutput } from '../../utils/get-transaction-total-output'; @@ -41,7 +35,7 @@ const getTransactionAssetsId = (outputs: CardanoTxOut[]) => { return assetIds; }; -const transactionMetadataTransformer = (metadata: Wallet.Cardano.TxMetadata): TransactionDetail['tx']['metadata'] => +const transactionMetadataTransformer = (metadata: Wallet.Cardano.TxMetadata): ActivityDetail['tx']['metadata'] => [...metadata.entries()].map(([key, value]) => ({ key: key.toString(), value: Wallet.cardanoMetadatumToObj(value) })); const shouldIncludeFee = ( @@ -77,19 +71,19 @@ const getPoolInfos = async (poolIds: Wallet.Cardano.PoolId[], stakePoolProvider: /** * fetches asset information */ -const getTransactionDetail = +const getActivityDetail = ({ set, get }: ZustandHandlers< - TransactionDetailSlice & BlockchainProviderSlice & WalletInfoSlice - >): TransactionDetailSlice['getTransactionDetails'] => + ActivityDetailSlice & BlockchainProviderSlice & WalletInfoSlice + >): ActivityDetailSlice['getActivityDetails'] => // eslint-disable-next-line max-statements, sonarjs/cognitive-complexity async ({ coinPrices, fiatCurrency }) => { const { blockchainProvider: { chainHistoryProvider, stakePoolProvider, assetProvider }, inMemoryWallet: wallet, - transactionDetail: { tx, epochRewards, status, direction, type }, + activityDetail: { tx, epochRewards, status, direction, type }, walletInfo } = get(); @@ -130,7 +124,7 @@ const getTransactionDetail = const walletAssets = await firstValueFrom(wallet.assetInfo$); const protocolParameters = await firstValueFrom(wallet.protocolParameters$); - set({ fetchingTransactionInfo: true }); + set({ fetchingActivityInfo: true }); // Assets const assetIds = getTransactionAssetsId(tx.body.outputs); @@ -188,7 +182,7 @@ const getTransactionDetail = (certificate) => certificate.__typename === 'StakeDelegationCertificate' ) as Wallet.Cardano.StakeDelegationCertificate[]; - let transaction: TransactionDetail['tx'] = { + let transaction: ActivityDetail['tx'] = { hash: tx.id.toString(), totalOutput: totalOutputInAda, fee: shouldIncludeFee(type, delegationInfo) ? feeInAda : undefined, @@ -221,21 +215,21 @@ const getTransactionDetail = } } - set({ fetchingTransactionInfo: false }); + set({ fetchingActivityInfo: false }); return { tx: transaction, blocks, status, assetAmount, type }; }; /** * has all transactions search related actions and states */ -export const transactionDetailSlice: SliceCreator< - TransactionDetailSlice & BlockchainProviderSlice & WalletInfoSlice, - TransactionDetailSlice +export const activityDetailSlice: SliceCreator< + ActivityDetailSlice & BlockchainProviderSlice & WalletInfoSlice, + ActivityDetailSlice > = ({ set, get }) => ({ - transactionDetail: undefined, - fetchingTransactionInfo: true, - getTransactionDetails: getTransactionDetail({ set, get }), - setTransactionDetail: ({ tx, epochRewards, direction, status, type }) => - set({ transactionDetail: { tx, epochRewards, direction, status, type } }), - resetTransactionState: () => set({ transactionDetail: undefined, fetchingTransactionInfo: false }) + activityDetail: undefined, + fetchingActivityInfo: true, + getActivityDetails: getActivityDetail({ set, get }), + setActivityDetail: ({ tx, epochRewards, direction, status, type }) => + set({ activityDetail: { tx, epochRewards, direction, status, type } }), + resetActivityState: () => set({ activityDetail: undefined, fetchingActivityInfo: false }) }); diff --git a/apps/browser-extension-wallet/src/stores/slices/index.ts b/apps/browser-extension-wallet/src/stores/slices/index.ts index 5a62742c7..15e4ec3dd 100644 --- a/apps/browser-extension-wallet/src/stores/slices/index.ts +++ b/apps/browser-extension-wallet/src/stores/slices/index.ts @@ -3,6 +3,6 @@ export * from './stake-pool-search-slice'; export * from './wallet-activities-slice'; export * from './wallet-info-slice'; export * from './lock-slice'; -export * from './transaction-detail-slice'; +export * from './activity-detail-slice'; export * from './ui-slice'; export * from './blockchain-provider-slice'; diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index 8bbbe598b..2c3c643c9 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -29,7 +29,7 @@ import { StateStatus, WalletInfoSlice, AssetDetailsSlice, - TransactionDetailSlice, + ActivityDetailSlice, UISlice, BlockchainProviderSlice, SliceCreator @@ -49,7 +49,7 @@ interface FetchWalletActivitiesPropsWithSetter extends FetchWalletActivitiesProp get: GetState< WalletInfoSlice & WalletActivitiesSlice & - TransactionDetailSlice & + ActivityDetailSlice & AssetDetailsSlice & UISlice & BlockchainProviderSlice @@ -107,7 +107,7 @@ const getWalletActivitiesObservable = async ({ walletInfo, walletUI: { cardanoCoin }, inMemoryWallet, - setTransactionDetail, + setActivityDetail, assetDetails, blockchainProvider: { assetProvider } } = get(); @@ -145,7 +145,7 @@ const getWalletActivitiesObservable = async ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); - setTransactionDetail({ + setActivityDetail({ tx, direction: transformedTx.direction, status: transformedTx.status, @@ -183,7 +183,7 @@ const getWalletActivitiesObservable = async ({ onClick: () => { if (sendAnalytics) sendAnalytics(); const deserializedTx: Wallet.Cardano.Tx = TxCBOR.deserialize(tx.cbor); - setTransactionDetail({ + setActivityDetail({ tx: deserializedTx, direction: TxDirections.Outgoing, status: Wallet.TransactionStatus.PENDING, @@ -217,7 +217,7 @@ const getWalletActivitiesObservable = async ({ ...transformedEpochRewards, onClick: () => { if (sendAnalytics) sendAnalytics(); - setTransactionDetail({ + setActivityDetail({ direction: transformedEpochRewards.direction, status: transformedEpochRewards.status, type: transformedEpochRewards.type, @@ -389,12 +389,7 @@ const getWalletActivitiesObservable = async ({ * has all wallet activities related actions and states */ export const walletActivitiesSlice: SliceCreator< - WalletInfoSlice & - WalletActivitiesSlice & - TransactionDetailSlice & - AssetDetailsSlice & - UISlice & - BlockchainProviderSlice, + WalletInfoSlice & WalletActivitiesSlice & ActivityDetailSlice & AssetDetailsSlice & UISlice & BlockchainProviderSlice, WalletActivitiesSlice > = ({ set, get }) => ({ getWalletActivitiesObservable: ({ diff --git a/apps/browser-extension-wallet/src/stores/types.ts b/apps/browser-extension-wallet/src/stores/types.ts index 190045c96..94c1aef94 100644 --- a/apps/browser-extension-wallet/src/stores/types.ts +++ b/apps/browser-extension-wallet/src/stores/types.ts @@ -7,7 +7,7 @@ import { WalletInfo, WalletLocked, TxDirection, - TransactionDetail, + ActivityDetail, WalletUI, NetworkConnectionStates, CurrencyInfo @@ -122,8 +122,8 @@ export interface UISlice { setBalancesVisibility: (visible: boolean) => void; } -export interface TransactionDetailSlice { - transactionDetail?: { +export interface ActivityDetailSlice { + activityDetail?: { type: TransactionType; status: Wallet.TransactionStatus; direction: TxDirection; @@ -138,19 +138,16 @@ export interface TransactionDetailSlice { tx: NonNullable; } ); - fetchingTransactionInfo: boolean; - setTransactionDetail: (params: { + fetchingActivityInfo: boolean; + setActivityDetail: (params: { tx?: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; epochRewards?: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; direction: TxDirection; status?: Wallet.TransactionStatus; type?: TransactionType; }) => void; - getTransactionDetails: (params: { - coinPrices: PriceResult; - fiatCurrency: CurrencyInfo; - }) => Promise; - resetTransactionState: () => void; + getActivityDetails: (params: { coinPrices: PriceResult; fiatCurrency: CurrencyInfo }) => Promise; + resetActivityState: () => void; } export interface AssetDetailsSlice { @@ -171,7 +168,7 @@ export type WalletStore = WalletActivitiesSlice & StakePoolSearchSlice & LockSlice & WalletInfoSlice & - TransactionDetailSlice & + ActivityDetailSlice & AssetDetailsSlice & UISlice & BlockchainProviderSlice; diff --git a/apps/browser-extension-wallet/src/types/tx.ts b/apps/browser-extension-wallet/src/types/tx.ts index 5293baee1..21b991176 100644 --- a/apps/browser-extension-wallet/src/types/tx.ts +++ b/apps/browser-extension-wallet/src/types/tx.ts @@ -16,7 +16,7 @@ export type TransactionPool = { id: string; }; -export interface TransactionDetail { +export interface ActivityDetail { tx: { hash?: string; includedUtcDate?: string; diff --git a/apps/browser-extension-wallet/src/utils/mocks/store.tsx b/apps/browser-extension-wallet/src/utils/mocks/store.tsx index 1ce426959..52db3ddb0 100644 --- a/apps/browser-extension-wallet/src/utils/mocks/store.tsx +++ b/apps/browser-extension-wallet/src/utils/mocks/store.tsx @@ -34,20 +34,20 @@ export const walletStoreMock = async ( resetStakePools: jest.fn(), fetchStakePools: jest.fn(), getWalletActivitiesObservable: jest.fn(), - fetchingTransactionInfo: false, - getTransactionDetails: jest.fn(), + fetchingActivityInfo: false, + getActivityDetails: jest.fn(), inMemoryWallet: wallet as Wallet.ObservableWallet, getKeyAgentType: jest.fn(() => Wallet.KeyManagement.KeyAgentType.InMemory), // TODO: mock [LW-5454] cardanoWallet: undefined, isWalletLocked: jest.fn(() => false), networkStateStatus: StateStatus.LOADED, - resetTransactionState: jest.fn(), + resetActivityState: jest.fn(), resetWalletLock: jest.fn(), selectedStakePool: undefined, setCardanoWallet: jest.fn(), setSelectedStakePool: jest.fn(), - setTransactionDetail: jest.fn(), + setActivityDetail: jest.fn(), setWalletLock: jest.fn(), stakePoolSearchResults: { pageResults: [], totalResultCount: 0 }, stakePoolSearchResultsStatus: StateStatus.LOADED, diff --git a/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx b/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx index a1a6d7e2b..cf6483055 100644 --- a/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx +++ b/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx @@ -5,7 +5,7 @@ import React, { FunctionComponent } from 'react'; import { Wallet } from '@lace/cardano'; import { SendStoreProvider } from '../../features/send/stores'; import { createSignal } from '@react-rxjs/utils'; -import { Balance, CardanoTxBuild, WalletInfo, TxDirection, TransactionDetail } from '@types'; +import { Balance, CardanoTxBuild, WalletInfo, TxDirection, ActivityDetail } from '@types'; import { DisplayedCoinDetail, IAssetInfo } from '../../features/send/types'; import { APP_MODE_POPUP, cardanoCoin } from '../constants'; import { fakeApiRequest } from './fake-api-request'; @@ -409,7 +409,7 @@ export const blockMock: Wallet.BlockInfo = { date: new Date(1_638_829_263_730) }; -export const formatBlockMock: TransactionDetail['blocks'] = { +export const formatBlockMock: ActivityDetail['blocks'] = { block: '3114964', blockId: '717ca157f1e696a612af87109ba1f30cd4bb311ded5b504c78a6face463def95', confirmations: '17013', diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx similarity index 68% rename from apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetail.tsx rename to apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index 2af906a53..79835ebb5 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -15,7 +15,7 @@ import { } from '@lace/core'; import { PriceResult } from '@hooks'; import { useWalletStore } from '@stores'; -import { TransactionDetail as TransactionDetailType } from '@src/types'; +import { ActivityDetail as ActivityDetailType } from '@src/types'; import { useAddressBookContext, withAddressBookContext } from '@src/features/address-book/context'; import { APP_MODE_POPUP } from '@src/utils/constants'; import { useAnalyticsContext, useCurrencyStore, useExternalLinkOpener } from '@providers'; @@ -44,7 +44,7 @@ export const getTransactionData = ({ return []; } - // For incomming type of tx the sender addresses will be all addresses available in transactionInfo?.tx.addrInputs list (except the current one) + // For incomming type of tx the sender addresses will be all addresses available in activityInfo?.tx.addrInputs list (except the current one) if (isIncomingTransaction) { const outputData = addrOutputs.filter((input) => walletAddresses.includes(input.addr)); const addrs = uniq( @@ -58,7 +58,7 @@ export const getTransactionData = ({ })); } - // For outgoing/sent type of tx the receiver addresses will be all addresses available in transactionInfo?.tx.addrOutputs list (except the current one) + // For outgoing/sent type of tx the receiver addresses will be all addresses available in activityInfo?.tx.addrOutputs list (except the current one) return addrOutputs .filter((output) => !walletAddresses.includes(output.addr)) .map((output) => ({ @@ -76,19 +76,19 @@ const getCurrentTransactionStatus = ( return transaction?.status; }; -interface TransactionDetailProps { +interface ActivityDetailProps { price: PriceResult; } -export const TransactionDetail = withAddressBookContext(({ price }): ReactElement => { +export const ActivityDetail = withAddressBookContext(({ price }): ReactElement => { const { walletInfo, walletUI: { cardanoCoin, appMode }, environmentName } = useWalletStore(); const isPopupView = appMode === APP_MODE_POPUP; - const { getTransactionDetails, transactionDetail, fetchingTransactionInfo, walletActivities } = useWalletStore(); - const [transactionInfo, setTransactionInfo] = useState(); + const { getActivityDetails, activityDetail, fetchingActivityInfo, walletActivities } = useWalletStore(); + const [activityInfo, setActivityInfo] = useState(); const { fiatCurrency } = useCurrencyStore(); const { list: addressList } = useAddressBookContext(); const { CEXPLORER_BASE_URL, CEXPLORER_URL_PATHS } = config(); @@ -102,19 +102,19 @@ export const TransactionDetail = withAddressBookContext( const currentTransactionStatus = useMemo( () => - transactionDetail.tx?.id - ? getCurrentTransactionStatus(walletActivities, transactionDetail.tx.id) ?? transactionInfo?.status - : transactionInfo?.status, - [transactionDetail.tx?.id, transactionInfo?.status, walletActivities] + activityDetail.tx?.id + ? getCurrentTransactionStatus(walletActivities, activityDetail.tx.id) ?? activityInfo?.status + : activityInfo?.status, + [activityDetail.tx?.id, activityInfo?.status, walletActivities] ); - const fetchTransactionInfo = useCallback(async () => { - const result = await getTransactionDetails({ coinPrices: price, fiatCurrency }); - setTransactionInfo(result); - }, [getTransactionDetails, setTransactionInfo, price, fiatCurrency]); + const fetchActivityInfo = useCallback(async () => { + const result = await getActivityDetails({ coinPrices: price, fiatCurrency }); + setActivityInfo(result); + }, [getActivityDetails, setActivityInfo, price, fiatCurrency]); useEffect(() => { - fetchTransactionInfo(); + fetchActivityInfo(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -123,8 +123,8 @@ export const TransactionDetail = withAddressBookContext( [addressList] ); - const isIncomingTransaction = transactionDetail.direction === 'Incoming'; - const { addrOutputs, addrInputs } = transactionInfo?.tx || {}; + const isIncomingTransaction = activityDetail.direction === 'Incoming'; + const { addrOutputs, addrInputs } = activityInfo?.tx || {}; const txSummary = useMemo( () => getTransactionData({ @@ -136,33 +136,33 @@ export const TransactionDetail = withAddressBookContext( [isIncomingTransaction, addrOutputs, addrInputs, walletInfo.addresses] ); - if (fetchingTransactionInfo || !transactionInfo) return ; + if (fetchingActivityInfo || !activityInfo) return ; const getHeaderDescription = () => { - if (transactionInfo.type === 'rewards') return ''; - if (transactionInfo.type === 'delegation') return '1 token'; - return ` (${transactionInfo?.assetAmount})`; + if (activityInfo.type === 'rewards') return ''; + if (activityInfo.type === 'delegation') return '1 token'; + return ` (${activityInfo?.assetAmount})`; }; const handleOpenExternalLink = () => { analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailTransactionHashClick); - const externalLink = `${explorerBaseUrl}/${transactionInfo.tx.hash}`; + const externalLink = `${explorerBaseUrl}/${activityInfo.tx.hash}`; externalLink && currentTransactionStatus === 'success' && openExternalLink(externalLink); }; return ( `${Wallet.util.convertAdaToFiat({ ada, fiat: price?.cardano?.price })} ${fiatCurrency?.code}` } @@ -170,8 +170,8 @@ export const TransactionDetail = withAddressBookContext( txSummary={txSummary} addressToNameMap={addressToNameMap} coinSymbol={cardanoCoin.symbol} - rewards={transactionInfo.tx?.rewards} - type={transactionInfo?.type} + rewards={activityInfo.tx?.rewards} + type={activityInfo?.type} isPopupView={isPopupView} openExternalLink={handleOpenExternalLink} sendAnalyticsInputs={() => analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailInputsClick)} diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityLayout.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityLayout.tsx index 5193e2c39..619e7fc61 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityLayout.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityLayout.tsx @@ -5,7 +5,7 @@ import { GroupedAssetActivityList } from '@lace/core'; import { useFetchCoinPrice } from '../../../../../hooks'; import { StateStatus, useWalletStore } from '../../../../../stores'; import { Drawer, DrawerNavigation, useObservable } from '@lace/common'; -import { TransactionDetail } from './TransactionDetail'; +import { ActivityDetail } from './ActivityDetail'; import { useTranslation } from 'react-i18next'; import { FundWalletBanner, EducationalList, SectionLayout, Layout } from '@src/views/browser-view/components'; import { SectionTitle } from '@components/Layout/SectionTitle'; @@ -25,7 +25,7 @@ import { useWalletActivities } from '@hooks/useWalletActivities'; export const ActivityLayout = (): ReactElement => { const { t } = useTranslation(); const { priceResult } = useFetchCoinPrice(); - const { inMemoryWallet, walletInfo, transactionDetail, resetTransactionState, blockchainProvider } = useWalletStore(); + const { inMemoryWallet, walletInfo, activityDetail, resetActivityState, blockchainProvider } = useWalletStore(); const analytics = useAnalyticsContext(); const sendAnalytics = useCallback(() => { analytics.sendEventToMatomo({ @@ -73,8 +73,8 @@ export const ActivityLayout = (): ReactElement => { // Reset current transaction details and close drawer if network (blockchainProvider) has changed useEffect(() => { - resetTransactionState(); - }, [resetTransactionState, blockchainProvider]); + resetActivityState(); + }, [resetActivityState, blockchainProvider]); const isLoadingFirstTime = isNil(total); return ( @@ -87,19 +87,19 @@ export const ActivityLayout = (): ReactElement => { sideText={activitiesCount ? `(${activitiesCount})` : ''} /> { analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailXClick); - resetTransactionState(); + resetActivityState(); }} /> } > - {transactionDetail && priceResult && } + {activityDetail && priceResult && } {walletActivities?.length > 0 ? ( diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/__tests__/TransactionDetail.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/__tests__/ActivityDetail.test.tsx similarity index 96% rename from apps/browser-extension-wallet/src/views/browser-view/features/activity/components/__tests__/TransactionDetail.test.tsx rename to apps/browser-extension-wallet/src/views/browser-view/features/activity/components/__tests__/ActivityDetail.test.tsx index edd6d5ef5..0b05f37f9 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/__tests__/TransactionDetail.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/__tests__/ActivityDetail.test.tsx @@ -1,5 +1,5 @@ import '@testing-library/jest-dom'; -import { getTransactionData } from '../TransactionDetail'; +import { getTransactionData } from '../ActivityDetail'; import { incomingTransactionOutput, missingDataTransactionOutput, diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/index.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/index.tsx index 3fefcef14..a1e9cab57 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/index.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/index.tsx @@ -1,2 +1,2 @@ export * from './ActivityLayout'; -export * from './TransactionDetail'; +export * from './ActivityDetail'; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetTransactionDetails/AssetTransactionDetails.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetActivityDetails/AssetActivityDetails.tsx similarity index 69% rename from apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetTransactionDetails/AssetTransactionDetails.tsx rename to apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetActivityDetails/AssetActivityDetails.tsx index d870133ea..6486b8e6b 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetTransactionDetails/AssetTransactionDetails.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetActivityDetails/AssetActivityDetails.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { Drawer, DrawerNavigation } from '@lace/common'; -import { TransactionDetail } from '@views/browser/features/activity'; +import { ActivityDetail } from '@views/browser/features/activity'; import { APP_MODE_POPUP, AppMode } from '@src/utils/constants'; import { useWalletStore } from '@src/stores'; import { useFetchCoinPrice } from '@hooks/useFetchCoinPrice'; -export interface AssetTransactionDetailsProps { +export interface AssetActivityDetailsProps { afterVisibleChange: (visible: boolean) => void; appMode: AppMode; onBack: () => void; @@ -13,15 +13,15 @@ export interface AssetTransactionDetailsProps { isVisible?: boolean; } -export const AssetTransactionDetails = ({ +export const AssetActivityDetails = ({ afterVisibleChange, appMode, onBack, onClose, isVisible -}: AssetTransactionDetailsProps): React.ReactElement => { +}: AssetActivityDetailsProps): React.ReactElement => { const { priceResult } = useFetchCoinPrice(); - const { transactionDetail } = useWalletStore(); + const { activityDetail } = useWalletStore(); return ( } popupView={appMode === APP_MODE_POPUP} > - {transactionDetail && priceResult && } + {activityDetail && priceResult && } ); }; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetTransactionDetails/__tests__/AssetTransactionDetails.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetActivityDetails/__tests__/AssetTransactionDetails.test.tsx similarity index 87% rename from apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetTransactionDetails/__tests__/AssetTransactionDetails.test.tsx rename to apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetActivityDetails/__tests__/AssetTransactionDetails.test.tsx index 8cd46ec2c..d74a7d9e6 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetTransactionDetails/__tests__/AssetTransactionDetails.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetActivityDetails/__tests__/AssetTransactionDetails.test.tsx @@ -1,10 +1,10 @@ const mockUseFetchCoinPrice = jest.fn().mockReturnValue({ priceResult: { cardano: { price: 2 }, tokens: new Map() } }); -const mockUseWalletStore = jest.fn().mockReturnValue({ transactionDetail: {} } as Stores.WalletStore); +const mockUseWalletStore = jest.fn().mockReturnValue({ activityDetail: {} } as Stores.WalletStore); /* eslint-disable import/imports-first */ import React from 'react'; import '@testing-library/jest-dom'; import { render } from '@testing-library/react'; -import { AssetTransactionDetails } from '../AssetTransactionDetails'; +import { AssetActivityDetails } from '../AssetActivityDetails'; import { APP_MODE_BROWSER } from '@src/utils/constants'; import * as UseFetchCoinPrice from '@hooks/useFetchCoinPrice'; import * as Stores from '@stores'; @@ -12,7 +12,7 @@ import * as ActivityComponents from '@views/browser/features/activity'; jest.mock('@views/browser/features/activity', (): typeof ActivityComponents => ({ ...jest.requireActual('@views/browser/features/activity'), - TransactionDetail: () =>
+ ActivityDetail: () =>
})); jest.mock('@hooks/useFetchCoinPrice', (): typeof UseFetchCoinPrice => ({ ...jest.requireActual('@hooks/useFetchCoinPrice'), @@ -23,14 +23,14 @@ jest.mock('@stores', (): typeof Stores => ({ useWalletStore: mockUseWalletStore })); -describe('AssetTransactionDetails', () => { +describe('AssetActivityDetails', () => { const afterVisibleChangeMock = jest.fn(); const onBackMock = jest.fn(); const onCloseMock = jest.fn(); test('renders transaction detail drawer if visible and price result and transaction detail are defined', () => { const { queryByTestId } = render( - { mockUseFetchCoinPrice.mockReturnValueOnce({}); const { queryByTestId } = render( - { mockUseWalletStore.mockReturnValueOnce({}); const { queryByTestId } = render( - { test('does not render the transaction detail drawer if not visible', () => { const { queryByTestId } = render( - { walletUI: { cardanoCoin, appMode, areBalancesVisible, getHiddenBalancePlaceholder }, setAssetDetails, assetDetails, - transactionDetail, - resetTransactionState, + activityDetail, + resetActivityState, blockchainProvider, environmentName } = useWalletStore(); @@ -63,7 +63,7 @@ export const Assets = ({ topSection }: AssetsProps): React.ReactElement => { const { setPickedCoin } = useCoinStateSelector(SEND_COIN_OUTPUT_ID); const { setTriggerPoint } = useAnalyticsSendFlowTriggerPoint(); - const [isTransactionDetailsOpen, setIsTransactionDetailsOpen] = useState(false); + const [isActivityDetailsOpen, setIsActivityDetailsOpen] = useState(false); const [fullAssetList, setFullAssetList] = useState(); const [listItemsAmount, setListItemsAmount] = useState(LIST_CHUNK_SIZE); const [selectedAssetId, setSelectedAssetId] = useState(); @@ -202,21 +202,21 @@ export const Assets = ({ topSection }: AssetsProps): React.ReactElement => { ] ); - const closeTransactionDetailsDrawer = () => setIsTransactionDetailsOpen(false); - const onTransactionDetailsBack = useCallback(() => { - resetTransactionState(); - closeTransactionDetailsDrawer(); + const closeActivityDetailsDrawer = () => setIsActivityDetailsOpen(false); + const onActivityDetailsBack = useCallback(() => { + resetActivityState(); + closeActivityDetailsDrawer(); setAssetDetails(fullAssetList.find((item) => item.id === selectedAssetId)); - }, [selectedAssetId, fullAssetList, resetTransactionState, setAssetDetails]); + }, [selectedAssetId, fullAssetList, resetActivityState, setAssetDetails]); - const onTransactionDetailsVisibleChange = useCallback( + const onActivityDetailsVisibleChange = useCallback( (visible: boolean) => { // Clear transaction details from state after drawer is closed - if (!visible && transactionDetail) { - resetTransactionState(); + if (!visible && activityDetail) { + resetActivityState(); } }, - [transactionDetail, resetTransactionState] + [activityDetail, resetActivityState] ); const onSendAssetClick = (id: string) => { @@ -242,14 +242,14 @@ export const Assets = ({ topSection }: AssetsProps): React.ReactElement => { }; useEffect(() => { - if (transactionDetail) { + if (activityDetail) { setAssetDetails(); } - if (!assetDetails && transactionDetail) { - setIsTransactionDetailsOpen(true); + if (!assetDetails && activityDetail) { + setIsActivityDetailsOpen(true); } - }, [assetDetails, transactionDetail, setAssetDetails]); + }, [assetDetails, activityDetail, setAssetDetails]); // TODO: move this to store once LW-1494 is done useEffect(() => { @@ -285,7 +285,7 @@ export const Assets = ({ topSection }: AssetsProps): React.ReactElement => { useEffect(() => { // Close asset tx details drawer if network (blockchainProvider) has changed - closeTransactionDetailsDrawer(); + closeActivityDetailsDrawer(); }, [blockchainProvider]); const assetsPortfolio = ( @@ -302,12 +302,12 @@ export const Assets = ({ topSection }: AssetsProps): React.ReactElement => { ); const drawers = ( <> - { +describe('Testing ActivityDetailsBrowser component', () => { const addrListProps: TransactionDetailBrowserProps = { isPopupView: false, hash: '5e58ad7aa10667c05c3ffdb9ae65fe22c77e5145db823715217b775b4344839f', diff --git a/packages/e2e-tests/src/assert/transactionDetailsAssert.ts b/packages/e2e-tests/src/assert/transactionDetailsAssert.ts index 7c2db0db7..62688bd9e 100644 --- a/packages/e2e-tests/src/assert/transactionDetailsAssert.ts +++ b/packages/e2e-tests/src/assert/transactionDetailsAssert.ts @@ -1,11 +1,11 @@ import TransactionsPage from '../elements/transactionsPage'; -import TransactionDetailsPage from '../elements/transactionDetails'; +import ActivityDetailsPage from '../elements/transactionDetails'; import { expect } from 'chai'; import testContext from '../utils/testContext'; import { browser } from '@wdio/globals'; import { t } from '../utils/translationService'; -export type ExpectedTransactionDetails = { +export type ExpectedActivityDetails = { transactionDescription: string; hash?: string; transactionData?: transactionData[]; @@ -29,40 +29,38 @@ class TransactionsDetailsAssert { }); }; - async assertSeeTransactionDetailsDrawer(shouldBeDisplayed: boolean) { - await TransactionDetailsPage.transactionDetails.waitForDisplayed({ reverse: !shouldBeDisplayed }); - await TransactionDetailsPage.transactionHeader.waitForDisplayed({ reverse: !shouldBeDisplayed }); + async assertSeeActivityDetailsDrawer(shouldBeDisplayed: boolean) { + await ActivityDetailsPage.transactionDetails.waitForDisplayed({ reverse: !shouldBeDisplayed }); + await ActivityDetailsPage.transactionHeader.waitForDisplayed({ reverse: !shouldBeDisplayed }); if (shouldBeDisplayed) { - expect(await TransactionDetailsPage.transactionHeader.getText()).to.equal( + expect(await ActivityDetailsPage.transactionHeader.getText()).to.equal( await t('package.core.transactionDetailBrowser.header') ); } } - async assertSeeTransactionDetails(expectedTransactionDetails: ExpectedTransactionDetails) { - await TransactionDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); + async assertSeeActivityDetails(expectedActivityDetails: ExpectedActivityDetails) { + await ActivityDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); - expect(await TransactionDetailsPage.transactionDetailsDescription.getText()).contains( - `${expectedTransactionDetails.transactionDescription}` + expect(await ActivityDetailsPage.transactionDetailsDescription.getText()).contains( + `${expectedActivityDetails.transactionDescription}` ); - if (expectedTransactionDetails.hash) { - expect(await TransactionDetailsPage.transactionDetailsHash.getText()).to.equal( - String(expectedTransactionDetails.hash) - ); + if (expectedActivityDetails.hash) { + expect(await ActivityDetailsPage.transactionDetailsHash.getText()).to.equal(String(expectedActivityDetails.hash)); } - expect(await TransactionDetailsPage.transactionDetailsStatus.getText()).to.equal(expectedTransactionDetails.status); - if (expectedTransactionDetails.transactionData) { - for (let i = 0; i < expectedTransactionDetails.transactionData.length; i++) { - if (expectedTransactionDetails.transactionData[i].assets) { - const actualAssets = await TransactionDetailsPage.getTransactionSentTokensForBundle(i); - expect(actualAssets.toString()).to.equal(String(expectedTransactionDetails.transactionData[i].assets)); + expect(await ActivityDetailsPage.transactionDetailsStatus.getText()).to.equal(expectedActivityDetails.status); + if (expectedActivityDetails.transactionData) { + for (let i = 0; i < expectedActivityDetails.transactionData.length; i++) { + if (expectedActivityDetails.transactionData[i].assets) { + const actualAssets = await ActivityDetailsPage.getTransactionSentTokensForBundle(i); + expect(actualAssets.toString()).to.equal(String(expectedActivityDetails.transactionData[i].assets)); } - expect(await TransactionDetailsPage.transactionDetailsSentAda(i).getText()).to.equal( - expectedTransactionDetails.transactionData[i].ada + expect(await ActivityDetailsPage.transactionDetailsSentAda(i).getText()).to.equal( + expectedActivityDetails.transactionData[i].ada ); - const expectedAddress = expectedTransactionDetails.transactionData[i].address; - const actualAddressSplit = (await TransactionDetailsPage.transactionDetailsToAddress(i).getText()).split('...'); + const expectedAddress = expectedActivityDetails.transactionData[i].address; + const actualAddressSplit = (await ActivityDetailsPage.transactionDetailsToAddress(i).getText()).split('...'); if (actualAddressSplit.length === 1) { expect(expectedAddress).to.equal(actualAddressSplit[0]); } else { @@ -71,68 +69,68 @@ class TransactionsDetailsAssert { } } } - if (expectedTransactionDetails.poolName) { - expect(await TransactionDetailsPage.transactionDetailsStakepoolName.getText()).to.equal( - expectedTransactionDetails.poolName + if (expectedActivityDetails.poolName) { + expect(await ActivityDetailsPage.transactionDetailsStakepoolName.getText()).to.equal( + expectedActivityDetails.poolName ); } - if (expectedTransactionDetails.poolTicker) { - expect(await TransactionDetailsPage.transactionDetailsStakepoolTicker.getText()).to.equal( - `(${expectedTransactionDetails.poolTicker})` + if (expectedActivityDetails.poolTicker) { + expect(await ActivityDetailsPage.transactionDetailsStakepoolTicker.getText()).to.equal( + `(${expectedActivityDetails.poolTicker})` ); } - if (expectedTransactionDetails.poolID) { - expect(await TransactionDetailsPage.transactionDetailsStakePoolId.getText()).to.equal( - expectedTransactionDetails.poolID + if (expectedActivityDetails.poolID) { + expect(await ActivityDetailsPage.transactionDetailsStakePoolId.getText()).to.equal( + expectedActivityDetails.poolID ); } } - async assertSeeTransactionDetailsUnfolded(mode: 'extended' | 'popup') { + async assertSeeActivityDetailsUnfolded(mode: 'extended' | 'popup') { await this.waitForTransactionsLoaded(); const rowsNumber = (await TransactionsPage.rows).length; for (let i = 0; i <= rowsNumber && i < 10; i++) { await TransactionsPage.clickOnTransactionRow(i); - await TransactionDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); - await TransactionDetailsPage.transactionDetailsHash.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsStatus.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsTimestamp.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsInputsSection.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsOutputsSection.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsFeeADA.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsFeeFiat.waitForDisplayed(); - const txType = await TransactionDetailsPage.transactionDetailsDescription.getText(); + await ActivityDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); + await ActivityDetailsPage.transactionDetailsHash.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsStatus.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsTimestamp.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsInputsSection.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsOutputsSection.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsFeeADA.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsFeeFiat.waitForDisplayed(); + const txType = await ActivityDetailsPage.transactionDetailsDescription.getText(); if (txType.includes('Delegation')) { - await TransactionDetailsPage.transactionDetailsStakepoolName.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsStakepoolTicker.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsStakePoolId.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsStakepoolName.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsStakepoolTicker.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsStakePoolId.waitForDisplayed(); } - await TransactionDetailsPage.closeTransactionDetails(mode); + await ActivityDetailsPage.closeActivityDetails(mode); } } - async assertSeeTransactionDetailsInputAndOutputs(mode: 'extended' | 'popup') { + async assertSeeActivityDetailsInputAndOutputs(mode: 'extended' | 'popup') { await this.waitForTransactionsLoaded(); const rowsNumber = (await TransactionsPage.rows).length; for (let i = 0; i <= rowsNumber && i < 10; i++) { await TransactionsPage.clickOnTransactionRow(i); - await TransactionDetailsPage.transactionDetailsInputsDropdown.click(); - await TransactionDetailsPage.transactionDetailsOutputsDropdown.click(); - await TransactionDetailsPage.transactionDetailsInputAddress.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsInputAdaAmount.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsInputFiatAmount.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsInputsDropdown.click(); + await ActivityDetailsPage.transactionDetailsOutputsDropdown.click(); + await ActivityDetailsPage.transactionDetailsInputAddress.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsInputAdaAmount.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsInputFiatAmount.waitForDisplayed(); // TODO refactor steps below // some transactions (ADA only) don't have this field - // await TransactionDetailsPage.transactionDetailsInputTokens.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsOutputAddress.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsOutputAdaAmount.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsOutputFiatAmount.waitForDisplayed(); - // await TransactionDetailsPage.transactionDetailsOutputTokens.waitForDisplayed(); + // await ActivityDetailsPage.transactionDetailsInputTokens.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsOutputAddress.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsOutputAdaAmount.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsOutputFiatAmount.waitForDisplayed(); + // await ActivityDetailsPage.transactionDetailsOutputTokens.waitForDisplayed(); - await TransactionDetailsPage.closeTransactionDetails(mode); + await ActivityDetailsPage.closeActivityDetails(mode); } } @@ -142,25 +140,25 @@ class TransactionsDetailsAssert { for (let i = 0; i <= rowsNumber && i < 10; i++) { await TransactionsPage.clickOnTransactionRow(i); - await TransactionDetailsPage.transactionDetailsInputsDropdown.click(); - await TransactionDetailsPage.transactionDetailsOutputsDropdown.click(); + await ActivityDetailsPage.transactionDetailsInputsDropdown.click(); + await ActivityDetailsPage.transactionDetailsOutputsDropdown.click(); - const txDetailsInputADAValueString = await TransactionDetailsPage.transactionDetailsInputAdaAmount.getText(); + const txDetailsInputADAValueString = await ActivityDetailsPage.transactionDetailsInputAdaAmount.getText(); const txDetailsInputADAValue = Number(txDetailsInputADAValueString.split(' ', 1)); - const txDetailsInputFiatValueString = await TransactionDetailsPage.transactionDetailsInputFiatAmount.getText(); + const txDetailsInputFiatValueString = await ActivityDetailsPage.transactionDetailsInputFiatAmount.getText(); const txDetailsInputFiatValue = Number(txDetailsInputFiatValueString.slice(1).split(' ', 1)); - const txDetailsOutputADAValueString = await TransactionDetailsPage.transactionDetailsOutputAdaAmount.getText(); + const txDetailsOutputADAValueString = await ActivityDetailsPage.transactionDetailsOutputAdaAmount.getText(); const txDetailsOutputADAValue = Number(txDetailsOutputADAValueString.split(' ', 1)); - const txDetailsOutputFiatValueString = await TransactionDetailsPage.transactionDetailsOutputFiatAmount.getText(); + const txDetailsOutputFiatValueString = await ActivityDetailsPage.transactionDetailsOutputFiatAmount.getText(); const txDetailsOutputFiatValue = Number(txDetailsOutputFiatValueString.slice(1).split(' ', 1)); - const txDetailsFeeADAValueString = await TransactionDetailsPage.transactionDetailsFeeADA.getText(); + const txDetailsFeeADAValueString = await ActivityDetailsPage.transactionDetailsFeeADA.getText(); const txDetailsFeeADAValue = Number(txDetailsFeeADAValueString.split(' ', 1)); - const txDetailsFeeFiatValueString = await TransactionDetailsPage.transactionDetailsFeeFiat.getText(); + const txDetailsFeeFiatValueString = await ActivityDetailsPage.transactionDetailsFeeFiat.getText(); const txDetailsFeeFiatValue = Number(txDetailsFeeFiatValueString.slice(1).split(' ', 1)); expect(txDetailsInputADAValue).to.be.greaterThan(0); @@ -170,32 +168,32 @@ class TransactionsDetailsAssert { expect(txDetailsFeeADAValue).to.be.greaterThan(0); expect(txDetailsFeeFiatValue).to.be.greaterThan(0); - await TransactionDetailsPage.closeTransactionDetails(mode); + await ActivityDetailsPage.closeActivityDetails(mode); } } - async assertSeeTransactionDetailsSummary(mode: 'extended' | 'popup') { + async assertSeeActivityDetailsSummary(mode: 'extended' | 'popup') { await this.waitForTransactionsLoaded(); const rowsNumber = (await TransactionsPage.rows).length; for (let i = 0; i <= rowsNumber && i < 10; i++) { const transactionType = await TransactionsPage.transactionsTableItemType(i).getText(); await TransactionsPage.clickOnTransactionRow(i); - await TransactionDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); + await ActivityDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); if ( !['Delegation', 'Stake Key De-Registration', 'Stake Key Registration', 'Self Transaction'].includes( transactionType ) ) { - await TransactionDetailsPage.transactionDetailsSent.waitForDisplayed(); - await TransactionDetailsPage.transactionDetailsToAddress(0).waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsSent.waitForDisplayed(); + await ActivityDetailsPage.transactionDetailsToAddress(0).waitForDisplayed(); } - await TransactionDetailsPage.closeTransactionDetails(mode); + await ActivityDetailsPage.closeActivityDetails(mode); } } - async assertSeeTransactionDetailsSummaryAmounts(mode: 'extended' | 'popup') { + async assertSeeActivityDetailsSummaryAmounts(mode: 'extended' | 'popup') { await this.waitForTransactionsLoaded(); const rowsNumber = (await TransactionsPage.rows).length; @@ -203,23 +201,23 @@ class TransactionsDetailsAssert { // TODO Cover self transaction details with automation if ((await TransactionsPage.transactionsTableItemType(i).getText()) !== 'Self Transaction') { await TransactionsPage.clickOnTransactionRow(i); - await TransactionDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); - const txType = await TransactionDetailsPage.transactionDetailsDescription.getText(); + await ActivityDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); + const txType = await ActivityDetailsPage.transactionDetailsDescription.getText(); if (!txType.includes('Delegation')) { const tokensAmountSummary = - (await TransactionDetailsPage.getTransactionSentTokensWithoutDuplicates()).length + 1; - let tokensDescriptionAmount = await TransactionDetailsPage.transactionDetailsAmountOfTokens.getText(); + (await ActivityDetailsPage.getTransactionSentTokensWithoutDuplicates()).length + 1; + let tokensDescriptionAmount = await ActivityDetailsPage.transactionDetailsAmountOfTokens.getText(); tokensDescriptionAmount = tokensDescriptionAmount.replace('(', '').replace(')', ''); expect(tokensAmountSummary).to.equal(Number(tokensDescriptionAmount)); } - await TransactionDetailsPage.closeTransactionDetails(mode); + await ActivityDetailsPage.closeActivityDetails(mode); } } } async assertTxMetadata() { - const currentMetadata = await TransactionDetailsPage.transactionDetailsMetadata.getText(); + const currentMetadata = await ActivityDetailsPage.transactionDetailsMetadata.getText(); expect(currentMetadata).to.equal(testContext.load('metadata')); } } diff --git a/packages/e2e-tests/src/elements/transactionDetails.ts b/packages/e2e-tests/src/elements/transactionDetails.ts index 54c69981a..eb3fd6cfb 100644 --- a/packages/e2e-tests/src/elements/transactionDetails.ts +++ b/packages/e2e-tests/src/elements/transactionDetails.ts @@ -2,7 +2,7 @@ import { ChainablePromiseElement } from 'webdriverio'; import CommonDrawerElements from './CommonDrawerElements'; -class TransactionDetailsPage extends CommonDrawerElements { +class ActivityDetailsPage extends CommonDrawerElements { protected CONTAINER = '[data-testid="custom-drawer"]'; private TRANSACTION_DETAILS = '[data-testid="transaction-detail"]'; private TRANSACTION_DETAILS_SKELETON = '.ant-drawer-body .ant-skeleton'; @@ -172,7 +172,7 @@ class TransactionDetailsPage extends CommonDrawerElements { return [...new Set(await arr)]; } - async closeTransactionDetails(mode: 'extended' | 'popup'): Promise { + async closeActivityDetails(mode: 'extended' | 'popup'): Promise { mode === 'popup' ? await this.clickHeaderBackButton() : await this.clickHeaderCloseButton(); } @@ -185,4 +185,4 @@ class TransactionDetailsPage extends CommonDrawerElements { } } -export default new TransactionDetailsPage(); +export default new ActivityDetailsPage(); diff --git a/packages/e2e-tests/src/steps/multidelegationSteps.ts b/packages/e2e-tests/src/steps/multidelegationSteps.ts index 6f9e48687..b71f2eb30 100644 --- a/packages/e2e-tests/src/steps/multidelegationSteps.ts +++ b/packages/e2e-tests/src/steps/multidelegationSteps.ts @@ -163,7 +163,7 @@ Then(/^I click "Close" button on staking success drawer$/, async () => { Then( /^the transaction details are displayed for staking (with|without) metadata$/, async (metadata: 'with' | 'without') => { - const expectedTransactionDetails = + const expectedActivityDetails = metadata === 'with' ? { transactionDescription: 'Delegation\n1 token', @@ -178,7 +178,7 @@ Then( poolID: testContext.load('poolID') as string }; - await transactionDetailsAssert.assertSeeTransactionDetails(expectedTransactionDetails); + await transactionDetailsAssert.assertSeeActivityDetails(expectedActivityDetails); } ); diff --git a/packages/e2e-tests/src/steps/nftsCommonSteps.ts b/packages/e2e-tests/src/steps/nftsCommonSteps.ts index 21ea78ecd..788304b26 100644 --- a/packages/e2e-tests/src/steps/nftsCommonSteps.ts +++ b/packages/e2e-tests/src/steps/nftsCommonSteps.ts @@ -60,7 +60,7 @@ Then( const typeTranslationKey = type === 'sent' ? 'package.core.transactionDetailBrowser.sent' : 'package.core.transactionDetailBrowser.received'; - const expectedTransactionDetails = { + const expectedActivityDetails = { transactionDescription: `${await t(typeTranslationKey)}\n(2)`, hash: String(testContext.load('txHashValue')), sentAssets: [`1 ${nftName}`], @@ -68,7 +68,7 @@ Then( recipientAddress: getTestWallet(walletName).address, status: 'Success' }; - await transactionDetailsAssert.assertSeeTransactionDetails(expectedTransactionDetails); + await transactionDetailsAssert.assertSeeActivityDetails(expectedActivityDetails); } ); diff --git a/packages/e2e-tests/src/steps/sendTransactionSimpleSteps.ts b/packages/e2e-tests/src/steps/sendTransactionSimpleSteps.ts index 34861a621..36c85eb97 100644 --- a/packages/e2e-tests/src/steps/sendTransactionSimpleSteps.ts +++ b/packages/e2e-tests/src/steps/sendTransactionSimpleSteps.ts @@ -23,7 +23,7 @@ import indexedDB from '../fixture/indexedDB'; import transactionBundleAssert from '../assert/transaction/transactionBundleAssert'; import { getTestWallet, TestWalletName } from '../support/walletConfiguration'; import testContext from '../utils/testContext'; -import transactionDetailsAssert, { ExpectedTransactionDetails } from '../assert/transactionDetailsAssert'; +import transactionDetailsAssert, { ExpectedActivityDetails } from '../assert/transactionDetailsAssert'; import { t } from '../utils/translationService'; import nftsPageObject from '../pageobject/nftsPageObject'; import transactionsPageObject from '../pageobject/transactionsPageObject'; @@ -376,7 +376,7 @@ When(/^I save fee value$/, async () => { Then( /^The Tx details are displayed as "([^"]*)" for ADA with value: ([^"]*) and wallet: "([^"]*)" address$/, async (type: string, adaValue: string, walletName: string) => { - const expectedTransactionDetails: ExpectedTransactionDetails = { + const expectedActivityDetails: ExpectedActivityDetails = { transactionDescription: `${await t(type)}\n(1)`, hash: testContext.load('txHashValue'), transactionData: [ @@ -384,14 +384,14 @@ Then( ], status: 'Success' }; - await transactionDetailsAssert.assertSeeTransactionDetails(expectedTransactionDetails); + await transactionDetailsAssert.assertSeeActivityDetails(expectedActivityDetails); } ); Then( /^The Tx details are displayed as "([^"]*)" for ADA with value: "([^"]*)" and LaceCoin2 with value: "([^"]*)" and wallet: "([^"]*)" address$/, async (type: string, adaValue: string, laceCoin2Value: string, walletName: string) => { - const expectedTransactionDetails: ExpectedTransactionDetails = { + const expectedActivityDetails: ExpectedActivityDetails = { transactionDescription: `${await t(type)}\n(2)`, hash: testContext.load('txHashValue'), transactionData: [ @@ -403,7 +403,7 @@ Then( ], status: 'Success' }; - await transactionDetailsAssert.assertSeeTransactionDetails(expectedTransactionDetails); + await transactionDetailsAssert.assertSeeActivityDetails(expectedActivityDetails); } ); @@ -415,13 +415,13 @@ Then( entry.address = getTestWallet(entry.address).address; entry.assets = entry.assets.split(','); } - const expectedTransactionDetails = { + const expectedActivityDetails = { transactionDescription: `${await t(type)}\n(${numberOfTokens})`, hash: String(testContext.load('txHashValue')), transactionData: txData, status: 'Success' }; - await transactionDetailsAssert.assertSeeTransactionDetails(expectedTransactionDetails); + await transactionDetailsAssert.assertSeeActivityDetails(expectedActivityDetails); } ); diff --git a/packages/e2e-tests/src/steps/stakingSteps.ts b/packages/e2e-tests/src/steps/stakingSteps.ts index d30c35cef..044fef4a8 100644 --- a/packages/e2e-tests/src/steps/stakingSteps.ts +++ b/packages/e2e-tests/src/steps/stakingSteps.ts @@ -163,7 +163,7 @@ Then(/^Each stake pool list item contains:$/, async (_ignored: string) => { }); Then(/^The Tx details are displayed for Staking (with|without) metadata$/, async (metadata: 'with' | 'without') => { - const expectedTransactionDetails = + const expectedActivityDetails = metadata === 'with' ? { transactionDescription: 'Delegation\n1 token', @@ -178,7 +178,7 @@ Then(/^The Tx details are displayed for Staking (with|without) metadata$/, async poolID: testContext.load('poolID') as string }; - await transactionDetailsAssert.assertSeeTransactionDetails(expectedTransactionDetails); + await transactionDetailsAssert.assertSeeActivityDetails(expectedActivityDetails); }); Then( diff --git a/packages/e2e-tests/src/steps/transactionsSteps.ts b/packages/e2e-tests/src/steps/transactionsSteps.ts index 38b57fd3b..e321a45ed 100644 --- a/packages/e2e-tests/src/steps/transactionsSteps.ts +++ b/packages/e2e-tests/src/steps/transactionsSteps.ts @@ -5,7 +5,7 @@ import mainMenuPageObject from '../pageobject/mainMenuPageObject'; import transactionBundleAssert from '../assert/transaction/transactionBundleAssert'; import NewTransactionExtendedPageObject from '../pageobject/newTransactionExtendedPageObject'; import testContext from '../utils/testContext'; -import TransactionDetailsPage from '../elements/transactionDetails'; +import ActivityDetailsPage from '../elements/transactionDetails'; import simpleTxSideDrawerPageObject from '../pageobject/simpleTxSideDrawerPageObject'; import TransactionsPage from '../elements/transactionsPage'; @@ -53,12 +53,12 @@ When(/^I click on a transaction: (\d)$/, async (rowNumber: number) => { }); When(/^I click on a transaction hash and save hash information$/, async () => { - testContext.save('txHashValue', await TransactionDetailsPage.transactionDetailsHash.getText()); - await TransactionDetailsPage.transactionDetailsHash.click(); + testContext.save('txHashValue', await ActivityDetailsPage.transactionDetailsHash.getText()); + await ActivityDetailsPage.transactionDetailsHash.click(); }); When(/^I click on a transaction hash$/, async () => { - await TransactionDetailsPage.transactionDetailsHash.click(); + await ActivityDetailsPage.transactionDetailsHash.click(); }); Then(/^I see cexplorer url with correct transaction hash$/, async () => { @@ -74,12 +74,12 @@ When( let actualValue; let expectedValue; await TransactionsPage.clickOnTransactionRow(i); - await TransactionDetailsPage.transactionDetailsSkeleton.waitForDisplayed({ timeout: 30_000, reverse: true }); + await ActivityDetailsPage.transactionDetailsSkeleton.waitForDisplayed({ timeout: 30_000, reverse: true }); if (valueForCheck === 'hash') { - actualValue = await TransactionDetailsPage.transactionDetailsHash.getText(); + actualValue = await ActivityDetailsPage.transactionDetailsHash.getText(); expectedValue = String(testContext.load('txHashValue')); } else { - actualValue = await TransactionDetailsPage.transactionDetailsStakePoolId.getText(); + actualValue = await ActivityDetailsPage.transactionDetailsStakePoolId.getText(); expectedValue = String(testContext.load('poolID')); } if (actualValue !== expectedValue) { @@ -99,7 +99,7 @@ Then( /^a side drawer is displayed showing the following information in (extended|popup) mode$/, // eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars async (mode: 'extended' | 'popup', _item: DataTable) => { - await transactionDetailsAssert.assertSeeTransactionDetailsUnfolded(mode); + await transactionDetailsAssert.assertSeeActivityDetailsUnfolded(mode); } ); @@ -108,17 +108,17 @@ When(/^I click on a transaction and click on both dropdowns$/, async () => { }); When(/^I click on inputs dropdowns$/, async () => { - TransactionDetailsPage.clickInputsDropdown(); + ActivityDetailsPage.clickInputsDropdown(); }); When(/^I click on outputs dropdowns$/, async () => { - TransactionDetailsPage.clickOutputsDropdown(); + ActivityDetailsPage.clickOutputsDropdown(); }); Then( /^all inputs and outputs of the transactions are displayed in (extended|popup) mode$/, async (mode: 'extended' | 'popup') => { - await transactionDetailsAssert.assertSeeTransactionDetailsInputAndOutputs(mode); + await transactionDetailsAssert.assertSeeActivityDetailsInputAndOutputs(mode); } ); @@ -137,7 +137,7 @@ Then(/none of the input and output values is zero in (extended|popup) mode$/, as Then( /the amounts sent or received are displayed below the Tx hash in (extended|popup) mode$/, async (mode: 'extended' | 'popup') => { - await transactionDetailsAssert.assertSeeTransactionDetailsSummary(mode); + await transactionDetailsAssert.assertSeeActivityDetailsSummary(mode); } ); @@ -148,7 +148,7 @@ Then(/the Sender or Receiver is displayed$/, async () => { Then( /the amounts summary shows as many rows as assets sent or received minus 1 -ADA- in (extended|popup) mode$/, async (mode: 'extended' | 'popup') => { - await transactionDetailsAssert.assertSeeTransactionDetailsSummaryAmounts(mode); + await transactionDetailsAssert.assertSeeActivityDetailsSummaryAmounts(mode); } ); @@ -201,15 +201,15 @@ Then( /^I can see transaction (\d) has type "([^"]*)" and value "([^"]*)"$/, async (txIndex: number, txType: string, txAdaValue: string) => { await transactionsPageAssert.assertTableItemDetails(txIndex - 1, txType); - const expectedTransactionDetails: ExpectedTransactionRowAssetDetails = { + const expectedActivityDetails: ExpectedTransactionRowAssetDetails = { type: txType, tokensAmount: txAdaValue, tokensCount: 0 }; - await transactionsPageAssert.assertSeeTransactionRowWithAssetDetails(txIndex - 1, expectedTransactionDetails); + await transactionsPageAssert.assertSeeTransactionRowWithAssetDetails(txIndex - 1, expectedActivityDetails); } ); Then(/^Transaction details drawer (is|is not) displayed$/, async (state: 'is' | 'is not') => { - await transactionDetailsAssert.assertSeeTransactionDetailsDrawer(state === 'is'); + await transactionDetailsAssert.assertSeeActivityDetailsDrawer(state === 'is'); }); From a0dfca9c413f039c2f3adaebccbc2dc2c8bfcbfe Mon Sep 17 00:00:00 2001 From: refi93 Date: Tue, 17 Oct 2023 13:05:40 +0200 Subject: [PATCH 04/31] refactor(all): rename getActivityDetails to getActivityDetail --- .../slices/__tests__/transaction-detail-slice.test.ts | 2 +- .../src/stores/slices/activity-detail-slice.ts | 6 +++--- apps/browser-extension-wallet/src/stores/types.ts | 2 +- apps/browser-extension-wallet/src/utils/mocks/store.tsx | 2 +- .../features/activity/components/ActivityDetail.tsx | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts b/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts index c0f382b4d..58db72407 100644 --- a/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts +++ b/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts @@ -32,7 +32,7 @@ describe('Testing createStoreHook slice', () => { expect(result.current.activityDetail).not.toBeDefined(); expect(result.current.fetchingActivityInfo).toBeDefined(); - expect(result.current.getActivityDetails).toBeDefined(); + expect(result.current.getActivityDetail).toBeDefined(); expect(result.current.resetActivityState).toBeDefined(); expect(result.current.setActivityDetail).toBeDefined(); }); diff --git a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts index ecd1bb357..b3ae2da9c 100644 --- a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts @@ -71,13 +71,13 @@ const getPoolInfos = async (poolIds: Wallet.Cardano.PoolId[], stakePoolProvider: /** * fetches asset information */ -const getActivityDetail = +const buildGetActivityDetail = ({ set, get }: ZustandHandlers< ActivityDetailSlice & BlockchainProviderSlice & WalletInfoSlice - >): ActivityDetailSlice['getActivityDetails'] => + >): ActivityDetailSlice['getActivityDetail'] => // eslint-disable-next-line max-statements, sonarjs/cognitive-complexity async ({ coinPrices, fiatCurrency }) => { const { @@ -228,7 +228,7 @@ export const activityDetailSlice: SliceCreator< > = ({ set, get }) => ({ activityDetail: undefined, fetchingActivityInfo: true, - getActivityDetails: getActivityDetail({ set, get }), + getActivityDetail: buildGetActivityDetail({ set, get }), setActivityDetail: ({ tx, epochRewards, direction, status, type }) => set({ activityDetail: { tx, epochRewards, direction, status, type } }), resetActivityState: () => set({ activityDetail: undefined, fetchingActivityInfo: false }) diff --git a/apps/browser-extension-wallet/src/stores/types.ts b/apps/browser-extension-wallet/src/stores/types.ts index 94c1aef94..a2f1604ee 100644 --- a/apps/browser-extension-wallet/src/stores/types.ts +++ b/apps/browser-extension-wallet/src/stores/types.ts @@ -146,7 +146,7 @@ export interface ActivityDetailSlice { status?: Wallet.TransactionStatus; type?: TransactionType; }) => void; - getActivityDetails: (params: { coinPrices: PriceResult; fiatCurrency: CurrencyInfo }) => Promise; + getActivityDetail: (params: { coinPrices: PriceResult; fiatCurrency: CurrencyInfo }) => Promise; resetActivityState: () => void; } diff --git a/apps/browser-extension-wallet/src/utils/mocks/store.tsx b/apps/browser-extension-wallet/src/utils/mocks/store.tsx index 52db3ddb0..ed924f4b0 100644 --- a/apps/browser-extension-wallet/src/utils/mocks/store.tsx +++ b/apps/browser-extension-wallet/src/utils/mocks/store.tsx @@ -35,7 +35,7 @@ export const walletStoreMock = async ( fetchStakePools: jest.fn(), getWalletActivitiesObservable: jest.fn(), fetchingActivityInfo: false, - getActivityDetails: jest.fn(), + getActivityDetail: jest.fn(), inMemoryWallet: wallet as Wallet.ObservableWallet, getKeyAgentType: jest.fn(() => Wallet.KeyManagement.KeyAgentType.InMemory), // TODO: mock [LW-5454] diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index 79835ebb5..96a2bdff3 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -87,7 +87,7 @@ export const ActivityDetail = withAddressBookContext(({ pri environmentName } = useWalletStore(); const isPopupView = appMode === APP_MODE_POPUP; - const { getActivityDetails, activityDetail, fetchingActivityInfo, walletActivities } = useWalletStore(); + const { getActivityDetail, activityDetail, fetchingActivityInfo, walletActivities } = useWalletStore(); const [activityInfo, setActivityInfo] = useState(); const { fiatCurrency } = useCurrencyStore(); const { list: addressList } = useAddressBookContext(); @@ -109,9 +109,9 @@ export const ActivityDetail = withAddressBookContext(({ pri ); const fetchActivityInfo = useCallback(async () => { - const result = await getActivityDetails({ coinPrices: price, fiatCurrency }); + const result = await getActivityDetail({ coinPrices: price, fiatCurrency }); setActivityInfo(result); - }, [getActivityDetails, setActivityInfo, price, fiatCurrency]); + }, [getActivityDetail, setActivityInfo, price, fiatCurrency]); useEffect(() => { fetchActivityInfo(); From 285358c78ff127ad57437a370838f2ff5482f7ad Mon Sep 17 00:00:00 2001 From: refi93 Date: Tue, 17 Oct 2023 13:43:32 +0200 Subject: [PATCH 05/31] refactor(ui): clean up "Transactions" component naming - rename to ActivityDetail --- .../stores/slices/activity-detail-slice.ts | 4 +-- .../stores/slices/wallet-activities-slice.ts | 4 +-- .../src/stores/types.ts | 6 ++--- apps/browser-extension-wallet/src/types/tx.ts | 4 +-- .../src/utils/tx-inspection.ts | 6 ++--- .../activity/components/ActivityDetail.tsx | 10 ++----- packages/core/src/index.ts | 2 +- .../components/Activity/AssetActivityItem.tsx | 12 ++++----- .../ActivityDetailBrowser.module.scss} | 0 .../ActivityDetailBrowser.tsx} | 26 +++++++++---------- .../ActivityDetailHeaderBrowser.module.scss} | 0 .../ActivityDetailHeaderBrowser.tsx} | 8 +++--- .../ActivityType.ts} | 2 +- .../ActivityTypeIcon.tsx} | 10 +++---- .../RewardDetails.tsx | 2 +- .../RewardsInfo.ts | 0 .../TransactionDetailAsset.ts | 0 .../TransactionDetails.tsx} | 8 +++--- .../TransactionInputOutput.module.scss | 0 .../TransactionInputOutput.tsx | 0 .../TransactionDetailBrowser.test.tsx | 16 ++++++------ .../src/ui/components/ActivityDetail/index.ts | 6 +++++ .../src/ui/components/Transactions/index.ts | 6 ----- .../hasPendingDelegationTransaction.ts | 4 +-- 24 files changed, 65 insertions(+), 71 deletions(-) rename packages/core/src/ui/components/{Transactions/TransactionDetailBrowser.module.scss => ActivityDetail/ActivityDetailBrowser.module.scss} (100%) rename packages/core/src/ui/components/{Transactions/TransactionDetailBrowser.tsx => ActivityDetail/ActivityDetailBrowser.tsx} (68%) rename packages/core/src/ui/components/{Transactions/TransactionDetailHeaderBrowser.module.scss => ActivityDetail/ActivityDetailHeaderBrowser.module.scss} (100%) rename packages/core/src/ui/components/{Transactions/TransactionDetailHeaderBrowser.tsx => ActivityDetail/ActivityDetailHeaderBrowser.tsx} (73%) rename packages/core/src/ui/components/{Transactions/TransactionType.ts => ActivityDetail/ActivityType.ts} (81%) rename packages/core/src/ui/components/{Transactions/TransactionTypeIcon.tsx => ActivityDetail/ActivityTypeIcon.tsx} (79%) rename packages/core/src/ui/components/{Transactions => ActivityDetail}/RewardDetails.tsx (98%) rename packages/core/src/ui/components/{Transactions => ActivityDetail}/RewardsInfo.ts (100%) rename packages/core/src/ui/components/{Transactions => ActivityDetail}/TransactionDetailAsset.ts (100%) rename packages/core/src/ui/components/{Transactions/Transaction.tsx => ActivityDetail/TransactionDetails.tsx} (98%) rename packages/core/src/ui/components/{Transactions => ActivityDetail}/TransactionInputOutput.module.scss (100%) rename packages/core/src/ui/components/{Transactions => ActivityDetail}/TransactionInputOutput.tsx (100%) rename packages/core/src/ui/components/{Transactions => ActivityDetail}/__tests__/TransactionDetailBrowser.test.tsx (76%) create mode 100644 packages/core/src/ui/components/ActivityDetail/index.ts delete mode 100644 packages/core/src/ui/components/Transactions/index.ts diff --git a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts index b3ae2da9c..c419c15f9 100644 --- a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts @@ -10,7 +10,7 @@ import { inspectTxValues } from '@src/utils/tx-inspection'; import { firstValueFrom } from 'rxjs'; import { getAssetsInformation } from '@src/utils/get-assets-information'; import { MAX_POOLS_COUNT } from '@lace/staking'; -import type { TransactionType } from '@lace/core'; +import type { ActivityType } from '@lace/core'; import { formatDate, formatTime } from '@src/utils/format-date'; /** @@ -39,7 +39,7 @@ const transactionMetadataTransformer = (metadata: Wallet.Cardano.TxMetadata): Ac [...metadata.entries()].map(([key, value]) => ({ key: key.toString(), value: Wallet.cardanoMetadatumToObj(value) })); const shouldIncludeFee = ( - type: TransactionType, + type: ActivityType, delegationInfo: Wallet.Cardano.StakeDelegationCertificate[] | undefined ) => !( diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index 2c3c643c9..8d5145437 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -18,7 +18,7 @@ import { AssetActivityItemProps, AssetActivityListProps, ActivityAssetProp, - TransactionType, + ActivityType, TransactionStatus } from '@lace/core'; import { CurrencyInfo, TxDirections } from '@src/types'; @@ -59,7 +59,7 @@ interface FetchWalletActivitiesPropsWithSetter extends FetchWalletActivitiesProp export type FetchWalletActivitiesReturn = Observable>; export type DelegationTransactionType = Extract< - TransactionType, + ActivityType, 'delegation' | 'delegationRegistration' | 'delegationDeregistration' >; diff --git a/apps/browser-extension-wallet/src/stores/types.ts b/apps/browser-extension-wallet/src/stores/types.ts index a2f1604ee..55e21fc63 100644 --- a/apps/browser-extension-wallet/src/stores/types.ts +++ b/apps/browser-extension-wallet/src/stores/types.ts @@ -1,6 +1,6 @@ import { SetState, State, GetState, StoreApi } from 'zustand'; import { Wallet, StakePoolSortOptions } from '@lace/cardano'; -import { AssetActivityListProps, TransactionType } from '@lace/core'; +import { AssetActivityListProps, ActivityType } from '@lace/core'; import { PriceResult } from '../hooks'; import { NetworkInformation, @@ -124,7 +124,7 @@ export interface UISlice { export interface ActivityDetailSlice { activityDetail?: { - type: TransactionType; + type: ActivityType; status: Wallet.TransactionStatus; direction: TxDirection; tx?: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; @@ -144,7 +144,7 @@ export interface ActivityDetailSlice { epochRewards?: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; direction: TxDirection; status?: Wallet.TransactionStatus; - type?: TransactionType; + type?: ActivityType; }) => void; getActivityDetail: (params: { coinPrices: PriceResult; fiatCurrency: CurrencyInfo }) => Promise; resetActivityState: () => void; diff --git a/apps/browser-extension-wallet/src/types/tx.ts b/apps/browser-extension-wallet/src/types/tx.ts index 21b991176..9420dc629 100644 --- a/apps/browser-extension-wallet/src/types/tx.ts +++ b/apps/browser-extension-wallet/src/types/tx.ts @@ -1,4 +1,4 @@ -import { TransactionMetadataProps, TxOutputInput, TransactionType } from '@lace/core'; +import { TransactionMetadataProps, TxOutputInput, ActivityType } from '@lace/core'; import { Wallet } from '@lace/cardano'; import { RewardsInfo } from '@lace/core/dist/ui/components/Transactions/RewardsInfo'; @@ -48,5 +48,5 @@ export interface ActivityDetail { }; status?: Wallet.TransactionStatus; assetAmount?: number; - type?: TransactionType; + type?: ActivityType; } diff --git a/apps/browser-extension-wallet/src/utils/tx-inspection.ts b/apps/browser-extension-wallet/src/utils/tx-inspection.ts index b940dc594..bac087f37 100644 --- a/apps/browser-extension-wallet/src/utils/tx-inspection.ts +++ b/apps/browser-extension-wallet/src/utils/tx-inspection.ts @@ -9,7 +9,7 @@ import { totalAddressOutputsValueInspector } from '@cardano-sdk/core'; import { Wallet } from '@lace/cardano'; -import { TransactionType } from '@lace/core'; +import { ActivityType } from '@lace/core'; import { TxDirection, TxDirections } from '@src/types'; const hasWalletStakeAddress = ( @@ -18,7 +18,7 @@ const hasWalletStakeAddress = ( ) => withdrawals.some((item) => item.stakeAddress === stakeAddress); interface TxTypeProps { - type: TransactionType; + type: ActivityType; } export const getTxDirection = ({ type }: TxTypeProps): TxDirections => { @@ -47,7 +47,7 @@ export const inspectTxType = ({ }: { walletAddresses: Wallet.KeyManagement.GroupedAddress[]; tx: Wallet.Cardano.HydratedTx; -}): Exclude => { +}): Exclude => { const { paymentAddresses, rewardAccounts } = walletAddresses.reduce( (acc, curr) => ({ paymentAddresses: [...acc.paymentAddresses, curr.address], diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index 96a2bdff3..61d6bf8b7 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -6,13 +6,7 @@ import flatMap from 'lodash/flatMap'; import { Skeleton } from 'antd'; import { config } from '@src/config'; import { Wallet } from '@lace/cardano'; -import { - AssetActivityListProps, - TransactionDetailBrowser, - TransactionStatus, - TxOutputInput, - TxSummary -} from '@lace/core'; +import { AssetActivityListProps, ActivityDetailBrowser, TransactionStatus, TxOutputInput, TxSummary } from '@lace/core'; import { PriceResult } from '@hooks'; import { useWalletStore } from '@stores'; import { ActivityDetail as ActivityDetailType } from '@src/types'; @@ -151,7 +145,7 @@ export const ActivityDetail = withAddressBookContext(({ pri }; return ( - const iconStyle = { fontSize: txIconSize() }; switch (status) { case TransactionStatus.SUCCESS: - return ; + return ; case TransactionStatus.SPENDABLE: - return ; + return ; case TransactionStatus.PENDING: return ; case TransactionStatus.ERROR: diff --git a/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.module.scss b/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.module.scss similarity index 100% rename from packages/core/src/ui/components/Transactions/TransactionDetailBrowser.module.scss rename to packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.module.scss diff --git a/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx similarity index 68% rename from packages/core/src/ui/components/Transactions/TransactionDetailBrowser.tsx rename to packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx index 070b39843..0b99afd43 100644 --- a/packages/core/src/ui/components/Transactions/TransactionDetailBrowser.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import styles from './TransactionDetailBrowser.module.scss'; -import { TransactionDetailHeaderBrowser } from './TransactionDetailHeaderBrowser'; +import styles from './ActivityDetailBrowser.module.scss'; +import { ActivityDetailHeaderBrowser } from './ActivityDetailHeaderBrowser'; import { TransactionStatus } from '../Activity/AssetActivityItem'; import { RewardDetails, RewardDetailsProps } from './RewardDetails'; -import { Transaction, TransactionProps } from './Transaction'; -import { TransactionType } from './TransactionType'; +import { TransactionDetails, TransactionDetailsProps } from './TransactionDetails'; +import { ActivityType } from './ActivityType'; import { useTranslate } from '@src/ui/hooks'; -const getTypeLabel = (type: TransactionType, t: ReturnType['t']) => { +const getTypeLabel = (type: ActivityType, t: ReturnType['t']) => { if (type === 'rewards') return t('package.core.transactionDetailBrowser.rewards'); if (type === 'delegation') return t('package.core.transactionDetailBrowser.delegation'); if (type === 'delegationRegistration') return t('package.core.transactionDetailBrowser.registration'); @@ -16,15 +16,15 @@ const getTypeLabel = (type: TransactionType, t: ReturnType[ return t('package.core.transactionDetailBrowser.sent'); }; -export type TransactionDetailBrowserProps = Omit & - Omit & { +export type ActivityDetailBrowserProps = Omit & + Omit & { headerDescription?: string; - type?: TransactionType; + type?: ActivityType; addressToNameMap: Map; isPopupView?: boolean; }; -export const TransactionDetailBrowser = ({ +export const ActivityDetailBrowser = ({ status, headerDescription, includedDate, @@ -35,14 +35,14 @@ export const TransactionDetailBrowser = ({ isPopupView, rewards, ...props -}: TransactionDetailBrowserProps): React.ReactElement => { +}: ActivityDetailBrowserProps): React.ReactElement => { const { t } = useTranslate(); const name = status === TransactionStatus.PENDING ? t('package.core.transactionDetailBrowser.sending') : getTypeLabel(type, t); const tooltipContent = type === 'rewards' ? t('package.core.transactionDetailBrowser.rewardsDescription') : undefined; - const transactionProps: TransactionProps = { + const transactionProps: TransactionDetailsProps = { ...props, includedDate, includedTime, @@ -65,11 +65,11 @@ export const TransactionDetailBrowser = ({ return (
- + {status === TransactionStatus.SPENDABLE ? ( ) : ( - + )}
); diff --git a/packages/core/src/ui/components/Transactions/TransactionDetailHeaderBrowser.module.scss b/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeaderBrowser.module.scss similarity index 100% rename from packages/core/src/ui/components/Transactions/TransactionDetailHeaderBrowser.module.scss rename to packages/core/src/ui/components/ActivityDetail/ActivityDetailHeaderBrowser.module.scss diff --git a/packages/core/src/ui/components/Transactions/TransactionDetailHeaderBrowser.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeaderBrowser.tsx similarity index 73% rename from packages/core/src/ui/components/Transactions/TransactionDetailHeaderBrowser.tsx rename to packages/core/src/ui/components/ActivityDetail/ActivityDetailHeaderBrowser.tsx index 5a2c7b438..7185f8722 100644 --- a/packages/core/src/ui/components/Transactions/TransactionDetailHeaderBrowser.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeaderBrowser.tsx @@ -1,19 +1,19 @@ import React from 'react'; import { ReactComponent as Info } from '../../assets/icons/info.component.svg'; import { Tooltip } from 'antd'; -import styles from './TransactionDetailHeaderBrowser.module.scss'; +import styles from './ActivityDetailHeaderBrowser.module.scss'; -export interface TransactionDetailHeaderBrowserProps { +export interface ActivityDetailHeaderBrowserProps { name: string; description: string; tooltipContent?: string; } -export const TransactionDetailHeaderBrowser = ({ +export const ActivityDetailHeaderBrowser = ({ name, description, tooltipContent -}: TransactionDetailHeaderBrowserProps): React.ReactElement => ( +}: ActivityDetailHeaderBrowserProps): React.ReactElement => (
{name}
diff --git a/packages/core/src/ui/components/Transactions/TransactionType.ts b/packages/core/src/ui/components/ActivityDetail/ActivityType.ts similarity index 81% rename from packages/core/src/ui/components/Transactions/TransactionType.ts rename to packages/core/src/ui/components/ActivityDetail/ActivityType.ts index 78a878580..b376b5331 100644 --- a/packages/core/src/ui/components/Transactions/TransactionType.ts +++ b/packages/core/src/ui/components/ActivityDetail/ActivityType.ts @@ -1,4 +1,4 @@ -export type TransactionType = +export type ActivityType = | 'outgoing' | 'incoming' | 'delegation' diff --git a/packages/core/src/ui/components/Transactions/TransactionTypeIcon.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx similarity index 79% rename from packages/core/src/ui/components/Transactions/TransactionTypeIcon.tsx rename to packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx index 116b88e95..c8afa5464 100644 --- a/packages/core/src/ui/components/Transactions/TransactionTypeIcon.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { TransactionType } from './TransactionType'; +import { ActivityType } from './ActivityType'; import { ReactComponent as OutgoingIcon } from '../../assets/icons/outgoing.component.svg'; import { ReactComponent as IncomingIcon } from '../../assets/icons/incoming.component.svg'; import { ReactComponent as SelfIcon } from '../../assets/icons/self-transaction.component.svg'; @@ -10,11 +10,11 @@ import { ReactComponent as RewardsIcon } from '../../assets/icons/rewards.compon import Icon, { QuestionOutlined } from '@ant-design/icons'; import { txIconSize } from '@src/ui/utils/icon-size'; -export interface TransactionTypeIconProps { - type: TransactionType; +export interface ActivityTypeIconProps { + type: ActivityType; } -const transactionTypeIcon: Record>> = { +const transactionTypeIcon: Record>> = { outgoing: OutgoingIcon, incoming: IncomingIcon, self: SelfIcon, @@ -24,7 +24,7 @@ const transactionTypeIcon: Record { +export const ActivityTypeIcon = ({ type }: ActivityTypeIconProps): React.ReactElement => { const icon = type && transactionTypeIcon[type]; const iconStyle = { fontSize: txIconSize() }; diff --git a/packages/core/src/ui/components/Transactions/RewardDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardDetails.tsx similarity index 98% rename from packages/core/src/ui/components/Transactions/RewardDetails.tsx rename to packages/core/src/ui/components/ActivityDetail/RewardDetails.tsx index 4172d45ef..55d10dd1c 100644 --- a/packages/core/src/ui/components/Transactions/RewardDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardDetails.tsx @@ -1,6 +1,6 @@ import React from 'react'; import cn from 'classnames'; -import styles from './TransactionDetailBrowser.module.scss'; +import styles from './ActivityDetailBrowser.module.scss'; import { useTranslate } from '@src/ui/hooks'; import { TransactionStatus } from '../Activity/AssetActivityItem'; import type { RewardsInfo } from './RewardsInfo'; diff --git a/packages/core/src/ui/components/Transactions/RewardsInfo.ts b/packages/core/src/ui/components/ActivityDetail/RewardsInfo.ts similarity index 100% rename from packages/core/src/ui/components/Transactions/RewardsInfo.ts rename to packages/core/src/ui/components/ActivityDetail/RewardsInfo.ts diff --git a/packages/core/src/ui/components/Transactions/TransactionDetailAsset.ts b/packages/core/src/ui/components/ActivityDetail/TransactionDetailAsset.ts similarity index 100% rename from packages/core/src/ui/components/Transactions/TransactionDetailAsset.ts rename to packages/core/src/ui/components/ActivityDetail/TransactionDetailAsset.ts diff --git a/packages/core/src/ui/components/Transactions/Transaction.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx similarity index 98% rename from packages/core/src/ui/components/Transactions/Transaction.tsx rename to packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index 6ae173e64..064c61149 100644 --- a/packages/core/src/ui/components/Transactions/Transaction.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -4,7 +4,7 @@ import React from 'react'; import cn from 'classnames'; import { InfoCircleOutlined } from '@ant-design/icons'; import { Tooltip } from 'antd'; -import styles from './TransactionDetailBrowser.module.scss'; +import styles from './ActivityDetailBrowser.module.scss'; import { TransactionDetailAsset, TxOutputInput, TransactionMetadataProps, TxSummary } from './TransactionDetailAsset'; import { TransactionStatus } from '../Activity'; import { Ellipsis, toast } from '@lace/common'; @@ -17,7 +17,7 @@ import type { RewardsInfo } from './RewardsInfo'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const displayMetadataMsg = (value: any[]): string => value?.find((val: any) => val.hasOwnProperty('msg'))?.msg || ''; -export interface TransactionProps { +export interface TransactionDetailsProps { hash?: string; name: string; status?: TransactionStatus; @@ -90,7 +90,7 @@ const CopiableHash = ({ hash, copiedText }: { hash: string; copiedText: string } ); // eslint-disable-next-line react/no-multi-comp,complexity -export const Transaction = ({ +export const TransactionDetails = ({ hash, name, status, @@ -111,7 +111,7 @@ export const Transaction = ({ openExternalLink, sendAnalyticsInputs, sendAnalyticsOutputs -}: TransactionProps): React.ReactElement => { +}: TransactionDetailsProps): React.ReactElement => { const { t } = useTranslate(); const isSending = status === 'sending'; const isSuccess = status === 'success'; diff --git a/packages/core/src/ui/components/Transactions/TransactionInputOutput.module.scss b/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss similarity index 100% rename from packages/core/src/ui/components/Transactions/TransactionInputOutput.module.scss rename to packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss diff --git a/packages/core/src/ui/components/Transactions/TransactionInputOutput.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.tsx similarity index 100% rename from packages/core/src/ui/components/Transactions/TransactionInputOutput.tsx rename to packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.tsx diff --git a/packages/core/src/ui/components/Transactions/__tests__/TransactionDetailBrowser.test.tsx b/packages/core/src/ui/components/ActivityDetail/__tests__/TransactionDetailBrowser.test.tsx similarity index 76% rename from packages/core/src/ui/components/Transactions/__tests__/TransactionDetailBrowser.test.tsx rename to packages/core/src/ui/components/ActivityDetail/__tests__/TransactionDetailBrowser.test.tsx index a8a0547f0..3898ac8d1 100644 --- a/packages/core/src/ui/components/Transactions/__tests__/TransactionDetailBrowser.test.tsx +++ b/packages/core/src/ui/components/ActivityDetail/__tests__/TransactionDetailBrowser.test.tsx @@ -1,13 +1,13 @@ /* eslint-disable no-magic-numbers */ import * as React from 'react'; import { render, within, fireEvent } from '@testing-library/react'; -import { TransactionDetailBrowser, TransactionDetailBrowserProps } from '../TransactionDetailBrowser'; +import { ActivityDetailBrowser, ActivityDetailBrowserProps } from '../ActivityDetailBrowser'; import '@testing-library/jest-dom'; const transactionDate = '2021/09/10'; describe('Testing ActivityDetailsBrowser component', () => { - const addrListProps: TransactionDetailBrowserProps = { + const addrListProps: ActivityDetailBrowserProps = { isPopupView: false, hash: '5e58ad7aa10667c05c3ffdb9ae65fe22c77e5145db823715217b775b4344839f', totalOutput: '38038.963341 ADA', @@ -39,21 +39,21 @@ describe('Testing ActivityDetailsBrowser component', () => { }; test('should display transaction hash and copy button', async () => { - const { findByTestId } = render(); + const { findByTestId } = render(); const container = await findByTestId('tx-hash'); expect(container).toBeVisible(); }); test('should display transaction date and time', async () => { - const { findByTestId } = render(); + const { findByTestId } = render(); const dateContainer = await findByTestId('tx-date'); expect(dateContainer).toBeVisible(); }); test('should display transaction inputs and outputs list', async () => { - const { findByTestId } = render(); + const { findByTestId } = render(); const inputContainer = await findByTestId('tx-inputs'); const listToggle = await findByTestId('tx-addr-list_toggle'); @@ -65,7 +65,7 @@ describe('Testing ActivityDetailsBrowser component', () => { }); test('should display transaction and fee', async () => { - const { findByTestId } = render(); + const { findByTestId } = render(); const feeContainer = await findByTestId('tx-fee'); expect(feeContainer).toBeVisible(); @@ -73,14 +73,14 @@ describe('Testing ActivityDetailsBrowser component', () => { test('should display transaction metadata if available', async () => { const { findByTestId } = render( - + ); const txMetadata = await findByTestId('tx-metadata'); expect(txMetadata).toBeVisible(); }); test('should not display transaction metadata if not available', async () => { - const { queryByTestId: query } = render(); + const { queryByTestId: query } = render(); expect(query('tx-metadata')).not.toBeInTheDocument(); }); }); diff --git a/packages/core/src/ui/components/ActivityDetail/index.ts b/packages/core/src/ui/components/ActivityDetail/index.ts new file mode 100644 index 000000000..f49a9fffa --- /dev/null +++ b/packages/core/src/ui/components/ActivityDetail/index.ts @@ -0,0 +1,6 @@ +export * from './ActivityDetailBrowser'; +export * from './ActivityType'; +export * from './ActivityTypeIcon'; +export * from './TransactionDetailAsset'; +export * from './TransactionInputOutput'; +export * from './RewardsInfo'; diff --git a/packages/core/src/ui/components/Transactions/index.ts b/packages/core/src/ui/components/Transactions/index.ts deleted file mode 100644 index 212b51ae6..000000000 --- a/packages/core/src/ui/components/Transactions/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './TransactionDetailBrowser'; -export * from './TransactionType'; -export * from './TransactionTypeIcon'; -export * from './TransactionDetailAsset'; -export * from './TransactionInputOutput'; -export * from './RewardsInfo'; diff --git a/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts b/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts index 608765424..b8296022e 100644 --- a/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts +++ b/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts @@ -1,7 +1,7 @@ -import { AssetActivityListProps, TransactionType } from '@lace/core'; +import { ActivityType, AssetActivityListProps } from '@lace/core'; import flatMap from 'lodash/flatMap'; -const DelegationTransactionTypes: Set = new Set([ +const DelegationTransactionTypes: Set = new Set([ 'delegation', 'delegationRegistration', 'delegationDeregistration', From 1e689fc40f1d90bac22578d164afb8a0b77387a2 Mon Sep 17 00:00:00 2001 From: refi93 Date: Tue, 17 Oct 2023 14:00:05 +0200 Subject: [PATCH 06/31] refactor(all): rename TransactionStatus to ActivityStatus --- .../stores/slices/wallet-activities-slice.ts | 8 +++---- .../src/stores/types.ts | 6 ++--- apps/browser-extension-wallet/src/types/tx.ts | 5 ++-- .../src/utils/assert-unreachable.ts | 4 ++++ .../activity/components/ActivityDetail.tsx | 4 ++-- .../activity/helpers/common-tx-transformer.ts | 23 ++++++++++++++++--- .../helpers/reward-history-transformer.ts | 3 ++- .../components/Activity/AssetActivityItem.tsx | 20 ++++++++-------- .../__tests__/AssetActivityItem.test.tsx | 6 ++--- .../__tests__/AssetActivityList.test.tsx | 4 ++-- .../ActivityDetail/ActivityDetailBrowser.tsx | 14 +++++------ .../{RewardDetails.tsx => RewardsDetails.tsx} | 10 ++++---- .../ActivityDetail/TransactionDetails.tsx | 4 ++-- 13 files changed, 66 insertions(+), 45 deletions(-) create mode 100644 apps/browser-extension-wallet/src/utils/assert-unreachable.ts rename packages/core/src/ui/components/ActivityDetail/{RewardDetails.tsx => RewardsDetails.tsx} (95%) diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index 8d5145437..e6c4f81e6 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -19,7 +19,7 @@ import { AssetActivityListProps, ActivityAssetProp, ActivityType, - TransactionStatus + ActivityStatus } from '@lace/core'; import { CurrencyInfo, TxDirections } from '@src/types'; import { getTxDirection, inspectTxType } from '@src/utils/tx-inspection'; @@ -186,7 +186,7 @@ const getWalletActivitiesObservable = async ({ setActivityDetail({ tx: deserializedTx, direction: TxDirections.Outgoing, - status: Wallet.TransactionStatus.PENDING, + status: ActivityStatus.PENDING, type: transformedTx.type }); } @@ -306,8 +306,8 @@ const getWalletActivitiesObservable = async ({ map(async (allTransactions: Promise) => (await allTransactions).sort((firstTx, secondTx) => { // ensure pending txs are always first - if (firstTx.status === TransactionStatus.PENDING && secondTx.status !== TransactionStatus.PENDING) return 1; - if (secondTx.status === TransactionStatus.PENDING && firstTx.status !== TransactionStatus.PENDING) return -1; + if (firstTx.status === ActivityStatus.PENDING && secondTx.status !== ActivityStatus.PENDING) return 1; + if (secondTx.status === ActivityStatus.PENDING && firstTx.status !== ActivityStatus.PENDING) return -1; // otherwise sort by date return secondTx.date.getTime() - firstTx.date.getTime(); }) diff --git a/apps/browser-extension-wallet/src/stores/types.ts b/apps/browser-extension-wallet/src/stores/types.ts index 55e21fc63..37ea891f7 100644 --- a/apps/browser-extension-wallet/src/stores/types.ts +++ b/apps/browser-extension-wallet/src/stores/types.ts @@ -1,6 +1,6 @@ import { SetState, State, GetState, StoreApi } from 'zustand'; import { Wallet, StakePoolSortOptions } from '@lace/cardano'; -import { AssetActivityListProps, ActivityType } from '@lace/core'; +import { AssetActivityListProps, ActivityType, ActivityStatus } from '@lace/core'; import { PriceResult } from '../hooks'; import { NetworkInformation, @@ -125,7 +125,7 @@ export interface UISlice { export interface ActivityDetailSlice { activityDetail?: { type: ActivityType; - status: Wallet.TransactionStatus; + status: ActivityStatus; direction: TxDirection; tx?: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; epochRewards?: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; @@ -143,7 +143,7 @@ export interface ActivityDetailSlice { tx?: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; epochRewards?: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; direction: TxDirection; - status?: Wallet.TransactionStatus; + status?: ActivityStatus; type?: ActivityType; }) => void; getActivityDetail: (params: { coinPrices: PriceResult; fiatCurrency: CurrencyInfo }) => Promise; diff --git a/apps/browser-extension-wallet/src/types/tx.ts b/apps/browser-extension-wallet/src/types/tx.ts index 9420dc629..ffbf895e0 100644 --- a/apps/browser-extension-wallet/src/types/tx.ts +++ b/apps/browser-extension-wallet/src/types/tx.ts @@ -1,5 +1,4 @@ -import { TransactionMetadataProps, TxOutputInput, ActivityType } from '@lace/core'; -import { Wallet } from '@lace/cardano'; +import { TransactionMetadataProps, TxOutputInput, ActivityType, ActivityStatus } from '@lace/core'; import { RewardsInfo } from '@lace/core/dist/ui/components/Transactions/RewardsInfo'; export enum TxDirections { @@ -46,7 +45,7 @@ export interface ActivityDetail { prevBlock?: string; createdBy?: string; }; - status?: Wallet.TransactionStatus; + status?: ActivityStatus; assetAmount?: number; type?: ActivityType; } diff --git a/apps/browser-extension-wallet/src/utils/assert-unreachable.ts b/apps/browser-extension-wallet/src/utils/assert-unreachable.ts new file mode 100644 index 000000000..21997a569 --- /dev/null +++ b/apps/browser-extension-wallet/src/utils/assert-unreachable.ts @@ -0,0 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export const assertUnreachable = (_x: never): never => { + throw new Error("Didn't expect to get here"); +}; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index 61d6bf8b7..fb5bf1582 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -6,7 +6,7 @@ import flatMap from 'lodash/flatMap'; import { Skeleton } from 'antd'; import { config } from '@src/config'; import { Wallet } from '@lace/cardano'; -import { AssetActivityListProps, ActivityDetailBrowser, TransactionStatus, TxOutputInput, TxSummary } from '@lace/core'; +import { AssetActivityListProps, ActivityDetailBrowser, ActivityStatus, TxOutputInput, TxSummary } from '@lace/core'; import { PriceResult } from '@hooks'; import { useWalletStore } from '@stores'; import { ActivityDetail as ActivityDetailType } from '@src/types'; @@ -64,7 +64,7 @@ export const getTransactionData = ({ const getCurrentTransactionStatus = ( activities: AssetActivityListProps[], txId: Wallet.Cardano.TransactionId -): TransactionStatus | undefined => { +): ActivityStatus | undefined => { const todayActivity = activities.find((activity) => activity.title === 'Today'); const transaction = todayActivity?.items.find((item) => item.id === String(txId)); return transaction?.status; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts index 5700be3a4..f3b361c93 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts @@ -4,9 +4,10 @@ import { CurrencyInfo, TxDirections } from '@types'; import { inspectTxValues, inspectTxType } from '@src/utils/tx-inspection'; import { formatDate, formatTime } from '@src/utils/format-date'; import type { TransformedTx } from './types'; -import { TransactionStatus } from '@lace/core'; +import { ActivityStatus } from '@lace/core'; import capitalize from 'lodash/capitalize'; import dayjs from 'dayjs'; +import { assertUnreachable } from '@src/utils/assert-unreachable'; export interface TxTransformerInput { tx: Wallet.TxInFlight | Wallet.Cardano.HydratedTx; @@ -73,6 +74,21 @@ const splitDelegationTx = (tx: TransformedTx): TransformedTx[] => { return []; }; +// eslint-disable-next-line consistent-return +const transformTransactionStatus = (status: Wallet.TransactionStatus): ActivityStatus => { + switch (status) { + case Wallet.TransactionStatus.PENDING: + return ActivityStatus.PENDING; + case Wallet.TransactionStatus.ERROR: + return ActivityStatus.ERROR; + case Wallet.TransactionStatus.SUCCESS: + return ActivityStatus.SUCCESS; + case Wallet.TransactionStatus.SPENDABLE: + return ActivityStatus.SPENDABLE; + default: + assertUnreachable(status); + } +}; /** Simplifies the transaction object to be used in the activity list @@ -130,13 +146,14 @@ export const txTransformer = ({ deposit, depositReclaim, fee: Wallet.util.lovelacesToAdaString(tx.body.fee.toString()), - status, + status: transformTransactionStatus(status), amount: Wallet.util.getFormattedAmount({ amount: outputAmount.toString(), cardanoCoin }), fiatAmount: getFormattedFiatAmount({ amount: outputAmount, fiatCurrency, fiatPrice }), assets: assetsEntries, assetsNumber: (assets?.size ?? 0) + 1, date, - formattedDate: status === TransactionStatus.PENDING ? capitalize(Wallet.TransactionStatus.PENDING) : formattedDate, + formattedDate: + status === Wallet.TransactionStatus.PENDING ? capitalize(Wallet.TransactionStatus.PENDING) : formattedDate, formattedTimestamp }; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts index a58ea3109..dd8590271 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts @@ -6,6 +6,7 @@ import { formatDate, formatTime } from '@src/utils/format-date'; import BigNumber from 'bignumber.js'; import type { CurrencyInfo } from '@src/types'; import type { Reward } from '@cardano-sdk/core'; +import { ActivityStatus } from '@lace/core'; interface RewardHistoryTransformerInput { rewards: Reward[]; // TODO this supposes rewards grouped by epoch which is a bit fragile @@ -41,7 +42,7 @@ export const rewardHistoryTransformer = ({ fiatCurrency, fiatPrice }), - status: Wallet.TransactionStatus.SPENDABLE, + status: ActivityStatus.SPENDABLE, assets: [], date, formattedTimestamp, diff --git a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx index ffda83400..3e6021f6f 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx @@ -16,7 +16,7 @@ import { useTranslate } from '@src/ui/hooks'; export type ActivityAssetInfo = { ticker: string }; export type ActivityAssetProp = { id: string; val: string; info?: ActivityAssetInfo }; -export enum TransactionStatus { +export enum ActivityStatus { SUCCESS = 'success', PENDING = 'sending', ERROR = 'error', @@ -49,7 +49,7 @@ export interface AssetActivityItemProps { /** * Activity status: `sending` | `success` | 'error */ - status?: TransactionStatus; + status?: ActivityStatus; /** * Activity or asset custom icon */ @@ -78,23 +78,23 @@ export interface AssetActivityItemProps { const DelegationTransactionTypes = new Set(['delegation', 'delegationRegistration', 'delegationDeregistration']); const DELEGATION_ASSET_NUMBER = 1; -interface TransactionStatusIconProps { +interface ActivityStatusIconProps { status: string; type: ActivityType; } const offsetMargin = 10; -const TransactionStatusIcon = ({ status, type }: TransactionStatusIconProps) => { +const ActivityStatusIcon = ({ status, type }: ActivityStatusIconProps) => { const iconStyle = { fontSize: txIconSize() }; switch (status) { - case TransactionStatus.SUCCESS: + case ActivityStatus.SUCCESS: return ; - case TransactionStatus.SPENDABLE: + case ActivityStatus.SPENDABLE: return ; - case TransactionStatus.PENDING: + case ActivityStatus.PENDING: return ; - case TransactionStatus.ERROR: + case ActivityStatus.ERROR: default: return ; } @@ -170,7 +170,7 @@ export const AssetActivityItem = ({ }; }, [debouncedSetText]); - const isPendingTx = status === TransactionStatus.PENDING; + const isPendingTx = status === ActivityStatus.PENDING; const assetsText = useMemo(() => getText(assetsToShow), [getText, assetsToShow]); const assetAmountContent = DelegationTransactionTypes.has(type) ? ( @@ -197,7 +197,7 @@ export const AssetActivityItem = ({ {customIcon ? ( asset image ) : ( - + )}
diff --git a/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx b/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx index cc36a16e2..70dc047a3 100644 --- a/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx +++ b/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { render, within, fireEvent, queryByTestId } from '@testing-library/react'; import '@testing-library/jest-dom'; -import { AssetActivityItem, AssetActivityItemProps, TransactionStatus } from '../AssetActivityItem'; +import { AssetActivityItem, AssetActivityItemProps, ActivityStatus } from '../AssetActivityItem'; const assetsAmountTestId = 'asset-amount'; @@ -16,7 +16,7 @@ describe('Testing AssetActivityItem component', () => { date: new Date('2021-01-01'), formattedDate: 'Date', formattedTimestamp: 'Timestamp', - status: TransactionStatus.ERROR, + status: ActivityStatus.ERROR, onClick: jest.fn(), assetsNumber: 1, assets: [{ id: '1', val: '1', info: { ticker: 'testTicker' } }] @@ -78,7 +78,7 @@ describe('Testing AssetActivityItem component', () => { }); test('should hide status when successful transaction', async () => { - const { findByTestId } = render(); + const { findByTestId } = render(); const activityItem = await findByTestId(assetActivityItemId); expect(queryByTestId(activityItem, 'activity-status')).not.toBeInTheDocument(); }); diff --git a/packages/core/src/ui/components/Activity/__tests__/AssetActivityList.test.tsx b/packages/core/src/ui/components/Activity/__tests__/AssetActivityList.test.tsx index aeddeeba0..bc29dd131 100644 --- a/packages/core/src/ui/components/Activity/__tests__/AssetActivityList.test.tsx +++ b/packages/core/src/ui/components/Activity/__tests__/AssetActivityList.test.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { render, fireEvent } from '@testing-library/react'; import '@testing-library/jest-dom'; import { AssetActivityList, AssetActivityListProps } from '../AssetActivityList'; -import { TransactionStatus } from '../AssetActivityItem'; +import { ActivityStatus } from '../AssetActivityItem'; const activityTranslations = { asset: 'asset', @@ -30,7 +30,7 @@ describe('Testing AssetActivityList component', () => { formattedTimestamp: '19:47', amount: '100 ADA', fiatAmount: '300 $', - status: TransactionStatus.ERROR, + status: ActivityStatus.ERROR, assets: [{ id: '1', val: '1' }], translations: activityTranslations })) diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx index 0b99afd43..7e89e0b52 100644 --- a/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx @@ -1,8 +1,8 @@ import React from 'react'; import styles from './ActivityDetailBrowser.module.scss'; import { ActivityDetailHeaderBrowser } from './ActivityDetailHeaderBrowser'; -import { TransactionStatus } from '../Activity/AssetActivityItem'; -import { RewardDetails, RewardDetailsProps } from './RewardDetails'; +import { ActivityStatus } from '../Activity/AssetActivityItem'; +import { RewardsDetails, RewardsDetailsProps } from './RewardsDetails'; import { TransactionDetails, TransactionDetailsProps } from './TransactionDetails'; import { ActivityType } from './ActivityType'; import { useTranslate } from '@src/ui/hooks'; @@ -16,7 +16,7 @@ const getTypeLabel = (type: ActivityType, t: ReturnType['t' return t('package.core.transactionDetailBrowser.sent'); }; -export type ActivityDetailBrowserProps = Omit & +export type ActivityDetailBrowserProps = Omit & Omit & { headerDescription?: string; type?: ActivityType; @@ -39,7 +39,7 @@ export const ActivityDetailBrowser = ({ const { t } = useTranslate(); const name = - status === TransactionStatus.PENDING ? t('package.core.transactionDetailBrowser.sending') : getTypeLabel(type, t); + status === ActivityStatus.PENDING ? t('package.core.transactionDetailBrowser.sending') : getTypeLabel(type, t); const tooltipContent = type === 'rewards' ? t('package.core.transactionDetailBrowser.rewardsDescription') : undefined; const transactionProps: TransactionDetailsProps = { @@ -53,7 +53,7 @@ export const ActivityDetailBrowser = ({ isPopupView }; - const rewardProps: RewardDetailsProps = { + const rewardsProps: RewardsDetailsProps = { name, status, includedDate, @@ -66,8 +66,8 @@ export const ActivityDetailBrowser = ({ return (
- {status === TransactionStatus.SPENDABLE ? ( - + {status === ActivityStatus.SPENDABLE ? ( + ) : ( )} diff --git a/packages/core/src/ui/components/ActivityDetail/RewardDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx similarity index 95% rename from packages/core/src/ui/components/ActivityDetail/RewardDetails.tsx rename to packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index 55d10dd1c..1199347b8 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -2,13 +2,13 @@ import React from 'react'; import cn from 'classnames'; import styles from './ActivityDetailBrowser.module.scss'; import { useTranslate } from '@src/ui/hooks'; -import { TransactionStatus } from '../Activity/AssetActivityItem'; +import { ActivityStatus } from '../Activity/AssetActivityItem'; import type { RewardsInfo } from './RewardsInfo'; import { Ellipsis } from '@lace/common'; -export interface RewardDetailsProps { +export interface RewardsDetailsProps { name: string; - status?: TransactionStatus; + status?: ActivityStatus; includedDate?: string; includedTime?: string; amountTransformer: (amount: string) => string; @@ -16,7 +16,7 @@ export interface RewardDetailsProps { rewards?: RewardsInfo; } -export const RewardDetails = ({ +export const RewardsDetails = ({ name, status, includedDate = '-', @@ -24,7 +24,7 @@ export const RewardDetails = ({ amountTransformer, coinSymbol, rewards -}: RewardDetailsProps): React.ReactElement => { +}: RewardsDetailsProps): React.ReactElement => { const { t } = useTranslate(); const poolRewards = rewards?.rewards.filter((reward) => !!reward.pool); diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index 064c61149..eec9a01bb 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -6,7 +6,7 @@ import { InfoCircleOutlined } from '@ant-design/icons'; import { Tooltip } from 'antd'; import styles from './ActivityDetailBrowser.module.scss'; import { TransactionDetailAsset, TxOutputInput, TransactionMetadataProps, TxSummary } from './TransactionDetailAsset'; -import { TransactionStatus } from '../Activity'; +import { ActivityStatus } from '../Activity'; import { Ellipsis, toast } from '@lace/common'; import { ReactComponent as Info } from '../../assets/icons/info-icon.component.svg'; import { TransactionInputOutput } from './TransactionInputOutput'; @@ -20,7 +20,7 @@ const displayMetadataMsg = (value: any[]): string => value?.find((val: any) => v export interface TransactionDetailsProps { hash?: string; name: string; - status?: TransactionStatus; + status?: ActivityStatus; /** * Transaction generation date */ From 722cf396c8b14ee26dc114a9741a471770a9d968 Mon Sep 17 00:00:00 2001 From: refi93 Date: Tue, 17 Oct 2023 16:46:23 +0200 Subject: [PATCH 07/31] refactor(all): rename TransformedTx to TransformedActivity --- .../src/stores/slices/wallet-activities-slice.ts | 6 +++--- .../activity/helpers/common-tx-transformer.ts | 12 ++++++------ .../activity/helpers/pending-tx-transformer.ts | 4 ++-- .../activity/helpers/reward-history-transformer.ts | 4 ++-- .../activity/helpers/tx-history-transformer.ts | 4 ++-- .../browser-view/features/activity/helpers/types.ts | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index e6c4f81e6..12a21ee85 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -12,7 +12,7 @@ import { txHistoryTransformer, filterOutputsByTxDirection, isTxWithAssets, - TransformedTx + TransformedActivity } from '@src/views/browser-view/features/activity/helpers'; import { AssetActivityItemProps, @@ -141,7 +141,7 @@ const getWalletActivitiesObservable = async ({ cardanoCoin }); - const extendWithClickHandler = (transformedTx: TransformedTx) => ({ + const extendWithClickHandler = (transformedTx: TransformedActivity) => ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); @@ -178,7 +178,7 @@ const getWalletActivitiesObservable = async ({ date }); - const extendWithClickHandler = (transformedTx: TransformedTx) => ({ + const extendWithClickHandler = (transformedTx: TransformedActivity) => ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts index f3b361c93..3de730219 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts @@ -3,7 +3,7 @@ import { Wallet } from '@lace/cardano'; import { CurrencyInfo, TxDirections } from '@types'; import { inspectTxValues, inspectTxType } from '@src/utils/tx-inspection'; import { formatDate, formatTime } from '@src/utils/format-date'; -import type { TransformedTx } from './types'; +import type { TransformedActivity } from './types'; import { ActivityStatus } from '@lace/core'; import capitalize from 'lodash/capitalize'; import dayjs from 'dayjs'; @@ -36,7 +36,7 @@ export const getFormattedFiatAmount = ({ return fiatAmount ? `${fiatAmount} ${fiatCurrency.code}` : '-'; }; -const splitDelegationTx = (tx: TransformedTx): TransformedTx[] => { +const splitDelegationTx = (tx: TransformedActivity): TransformedActivity[] => { if (tx.deposit) { return [ { @@ -114,7 +114,7 @@ export const txTransformer = ({ date, direction, status -}: TxTransformerInput): TransformedTx[] => { +}: TxTransformerInput): TransformedActivity[] => { const implicitCoin = Wallet.Cardano.util.computeImplicitCoin(protocolParameters, tx.body); const deposit = implicitCoin.deposit ? Wallet.util.lovelacesToAdaString(implicitCoin.deposit.toString()) : undefined; const depositReclaimValue = Wallet.util.calculateDepositReclaim(implicitCoin); @@ -141,7 +141,7 @@ export const txTransformer = ({ .sort((a, b) => Number(b.val) - Number(a.val)) : []; - const baseTransformedTx = { + const baseTransformedActivity = { id: tx.id.toString(), deposit, depositReclaim, @@ -164,12 +164,12 @@ export const txTransformer = ({ const type = inspectTxType({ walletAddresses, tx: tx as unknown as Wallet.Cardano.HydratedTx }); if (type === 'delegation') { - return splitDelegationTx(baseTransformedTx); + return splitDelegationTx(baseTransformedActivity); } return [ { - ...baseTransformedTx, + ...baseTransformedActivity, type, direction } diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts index f057f0cb9..503ea4862 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts @@ -1,6 +1,6 @@ import { TxTransformerInput, txTransformer } from './common-tx-transformer'; import { Wallet } from '@lace/cardano'; -import type { TransformedTx } from './types'; +import type { TransformedActivity } from './types'; import { TxDirections } from '@types'; interface TxHistoryTransformerInput extends Omit { @@ -15,7 +15,7 @@ export const pendingTxTransformer = ({ protocolParameters, cardanoCoin, date -}: TxHistoryTransformerInput): TransformedTx[] => +}: TxHistoryTransformerInput): TransformedActivity[] => txTransformer({ tx, walletAddresses, diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts index dd8590271..41ecfc232 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts @@ -1,6 +1,6 @@ import { Wallet } from '@lace/cardano'; import { getFormattedFiatAmount } from './common-tx-transformer'; -import type { TransformedTx } from './types'; +import type { TransformedActivity } from './types'; import dayjs from 'dayjs'; import { formatDate, formatTime } from '@src/utils/format-date'; import BigNumber from 'bignumber.js'; @@ -22,7 +22,7 @@ export const rewardHistoryTransformer = ({ fiatPrice, date, cardanoCoin -}: RewardHistoryTransformerInput): TransformedTx => { +}: RewardHistoryTransformerInput): TransformedActivity => { const formattedTimestamp = formatTime({ date, type: 'local' diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts index a9498b20b..c1460403b 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts @@ -1,7 +1,7 @@ import { Wallet } from '@lace/cardano'; import { getTxDirection, inspectTxType } from '@src/utils/tx-inspection'; import { txTransformer, TxTransformerInput } from './common-tx-transformer'; -import type { TransformedTx } from './types'; +import type { TransformedActivity } from './types'; interface TxHistoryTransformerInput extends Omit { tx: Wallet.Cardano.HydratedTx; @@ -15,7 +15,7 @@ export const txHistoryTransformer = ({ date, protocolParameters, cardanoCoin -}: TxHistoryTransformerInput): TransformedTx[] => { +}: TxHistoryTransformerInput): TransformedActivity[] => { const type = inspectTxType({ walletAddresses, tx }); const direction = getTxDirection({ type }); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/types.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/types.ts index ce438b040..5055b9bd2 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/types.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/types.ts @@ -1,3 +1,3 @@ import type { AssetActivityItemProps } from '@lace/core'; -export type TransformedTx = Omit; +export type TransformedActivity = Omit; From fecc78586c2e3a26ae75347f2ca7a367009fa8fe Mon Sep 17 00:00:00 2001 From: refi93 Date: Tue, 17 Oct 2023 17:36:17 +0200 Subject: [PATCH 08/31] refactor(all): split transaction from reward activity detail --- .../transaction-detail-slice.test.ts | 11 ++++++-- .../stores/slices/activity-detail-slice.ts | 6 +++-- .../stores/slices/wallet-activities-slice.ts | 17 +++++++----- .../src/stores/types.ts | 26 ++++++++++++------- .../src/utils/mocks/store.tsx | 3 ++- .../activity/helpers/common-tx-transformer.ts | 8 +++--- .../helpers/pending-tx-transformer.ts | 3 ++- .../helpers/reward-history-transformer.ts | 4 +-- .../helpers/tx-history-transformer.ts | 3 ++- 9 files changed, 53 insertions(+), 28 deletions(-) diff --git a/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts b/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts index 58db72407..f8bedb349 100644 --- a/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts +++ b/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts @@ -6,6 +6,7 @@ import { activityDetailSlice } from '../activity-detail-slice'; import '@testing-library/jest-dom'; import create, { GetState, SetState } from 'zustand'; import { mockBlockchainProviders } from '@src/utils/mocks/blockchain-providers'; +import { ActivityStatus } from '@lace/core'; const mockActivityDetailSlice = ( set: SetState, @@ -34,7 +35,8 @@ describe('Testing createStoreHook slice', () => { expect(result.current.fetchingActivityInfo).toBeDefined(); expect(result.current.getActivityDetail).toBeDefined(); expect(result.current.resetActivityState).toBeDefined(); - expect(result.current.setActivityDetail).toBeDefined(); + expect(result.current.setTransactionActivityDetail).toBeDefined(); + expect(result.current.setRewardsActivityDetail).toBeDefined(); }); test('should set transaction detail', () => { @@ -42,7 +44,12 @@ describe('Testing createStoreHook slice', () => { const { result, waitForValueToChange } = renderHook(() => useTransactionsStore()); act(() => { - result.current.setActivityDetail({ tx: transactionMock.tx, direction: transactionMock.direction }); + result.current.setTransactionActivityDetail({ + type: 'incoming', + status: ActivityStatus.SUCCESS, + tx: transactionMock.tx, + direction: transactionMock.direction + }); }); waitForValueToChange(() => result.current.activityDetail); expect(result.current.activityDetail).toBeDefined(); diff --git a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts index c419c15f9..47b900362 100644 --- a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts @@ -229,7 +229,9 @@ export const activityDetailSlice: SliceCreator< activityDetail: undefined, fetchingActivityInfo: true, getActivityDetail: buildGetActivityDetail({ set, get }), - setActivityDetail: ({ tx, epochRewards, direction, status, type }) => - set({ activityDetail: { tx, epochRewards, direction, status, type } }), + setTransactionActivityDetail: ({ tx, direction, status, type }) => + set({ activityDetail: { tx, direction, status, type } }), + setRewardsActivityDetail: ({ epochRewards, direction, status, type }) => + set({ activityDetail: { epochRewards, direction, status, type } }), resetActivityState: () => set({ activityDetail: undefined, fetchingActivityInfo: false }) }); diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index 12a21ee85..8a66f3428 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -107,7 +107,8 @@ const getWalletActivitiesObservable = async ({ walletInfo, walletUI: { cardanoCoin }, inMemoryWallet, - setActivityDetail, + setTransactionActivityDetail, + setRewardsActivityDetail, assetDetails, blockchainProvider: { assetProvider } } = get(); @@ -141,11 +142,13 @@ const getWalletActivitiesObservable = async ({ cardanoCoin }); - const extendWithClickHandler = (transformedTx: TransformedActivity) => ({ + const extendWithClickHandler = ( + transformedTx: TransformedActivity & { type: Exclude } + ) => ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); - setActivityDetail({ + setTransactionActivityDetail({ tx, direction: transformedTx.direction, status: transformedTx.status, @@ -178,12 +181,14 @@ const getWalletActivitiesObservable = async ({ date }); - const extendWithClickHandler = (transformedTx: TransformedActivity) => ({ + const extendWithClickHandler = ( + transformedTx: TransformedActivity & { type: Exclude } + ) => ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); const deserializedTx: Wallet.Cardano.Tx = TxCBOR.deserialize(tx.cbor); - setActivityDetail({ + setTransactionActivityDetail({ tx: deserializedTx, direction: TxDirections.Outgoing, status: ActivityStatus.PENDING, @@ -217,7 +222,7 @@ const getWalletActivitiesObservable = async ({ ...transformedEpochRewards, onClick: () => { if (sendAnalytics) sendAnalytics(); - setActivityDetail({ + setRewardsActivityDetail({ direction: transformedEpochRewards.direction, status: transformedEpochRewards.status, type: transformedEpochRewards.type, diff --git a/apps/browser-extension-wallet/src/stores/types.ts b/apps/browser-extension-wallet/src/stores/types.ts index 37ea891f7..3c206e54f 100644 --- a/apps/browser-extension-wallet/src/stores/types.ts +++ b/apps/browser-extension-wallet/src/stores/types.ts @@ -127,24 +127,30 @@ export interface ActivityDetailSlice { type: ActivityType; status: ActivityStatus; direction: TxDirection; - tx?: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; - epochRewards?: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; } & ( | { - type: 'rewards'; - epochRewards: NonNullable; + type: Extract; + epochRewards: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; + tx?: never; } | { - tx: NonNullable; + type: Exclude; + tx: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; + epochRewards?: never; } ); fetchingActivityInfo: boolean; - setActivityDetail: (params: { - tx?: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; - epochRewards?: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; + setTransactionActivityDetail: (params: { + tx: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; direction: TxDirection; - status?: ActivityStatus; - type?: ActivityType; + status: ActivityStatus; + type: Exclude; + }) => void; + setRewardsActivityDetail: (params: { + epochRewards: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; + direction: TxDirection; + status: ActivityStatus; + type: Extract; }) => void; getActivityDetail: (params: { coinPrices: PriceResult; fiatCurrency: CurrencyInfo }) => Promise; resetActivityState: () => void; diff --git a/apps/browser-extension-wallet/src/utils/mocks/store.tsx b/apps/browser-extension-wallet/src/utils/mocks/store.tsx index ed924f4b0..2a689b5c2 100644 --- a/apps/browser-extension-wallet/src/utils/mocks/store.tsx +++ b/apps/browser-extension-wallet/src/utils/mocks/store.tsx @@ -47,7 +47,8 @@ export const walletStoreMock = async ( selectedStakePool: undefined, setCardanoWallet: jest.fn(), setSelectedStakePool: jest.fn(), - setActivityDetail: jest.fn(), + setRewardsActivityDetail: jest.fn(), + setTransactionActivityDetail: jest.fn(), setWalletLock: jest.fn(), stakePoolSearchResults: { pageResults: [], totalResultCount: 0 }, stakePoolSearchResultsStatus: StateStatus.LOADED, diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts index 3de730219..8468a26f7 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts @@ -4,7 +4,7 @@ import { CurrencyInfo, TxDirections } from '@types'; import { inspectTxValues, inspectTxType } from '@src/utils/tx-inspection'; import { formatDate, formatTime } from '@src/utils/format-date'; import type { TransformedActivity } from './types'; -import { ActivityStatus } from '@lace/core'; +import { ActivityStatus, ActivityType } from '@lace/core'; import capitalize from 'lodash/capitalize'; import dayjs from 'dayjs'; import { assertUnreachable } from '@src/utils/assert-unreachable'; @@ -36,7 +36,9 @@ export const getFormattedFiatAmount = ({ return fiatAmount ? `${fiatAmount} ${fiatCurrency.code}` : '-'; }; -const splitDelegationTx = (tx: TransformedActivity): TransformedActivity[] => { +const splitDelegationTx = ( + tx: TransformedActivity +): (TransformedActivity & { type: Exclude })[] => { if (tx.deposit) { return [ { @@ -114,7 +116,7 @@ export const txTransformer = ({ date, direction, status -}: TxTransformerInput): TransformedActivity[] => { +}: TxTransformerInput): (TransformedActivity & { type: Exclude })[] => { const implicitCoin = Wallet.Cardano.util.computeImplicitCoin(protocolParameters, tx.body); const deposit = implicitCoin.deposit ? Wallet.util.lovelacesToAdaString(implicitCoin.deposit.toString()) : undefined; const depositReclaimValue = Wallet.util.calculateDepositReclaim(implicitCoin); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts index 503ea4862..4bd629668 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts @@ -2,6 +2,7 @@ import { TxTransformerInput, txTransformer } from './common-tx-transformer'; import { Wallet } from '@lace/cardano'; import type { TransformedActivity } from './types'; import { TxDirections } from '@types'; +import { ActivityType } from '@lace/core'; interface TxHistoryTransformerInput extends Omit { tx: Wallet.TxInFlight; @@ -15,7 +16,7 @@ export const pendingTxTransformer = ({ protocolParameters, cardanoCoin, date -}: TxHistoryTransformerInput): TransformedActivity[] => +}: TxHistoryTransformerInput): (TransformedActivity & { type: Exclude })[] => txTransformer({ tx, walletAddresses, diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts index 41ecfc232..baf1cd55a 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts @@ -6,7 +6,7 @@ import { formatDate, formatTime } from '@src/utils/format-date'; import BigNumber from 'bignumber.js'; import type { CurrencyInfo } from '@src/types'; import type { Reward } from '@cardano-sdk/core'; -import { ActivityStatus } from '@lace/core'; +import { ActivityStatus, ActivityType } from '@lace/core'; interface RewardHistoryTransformerInput { rewards: Reward[]; // TODO this supposes rewards grouped by epoch which is a bit fragile @@ -22,7 +22,7 @@ export const rewardHistoryTransformer = ({ fiatPrice, date, cardanoCoin -}: RewardHistoryTransformerInput): TransformedActivity => { +}: RewardHistoryTransformerInput): TransformedActivity & { type: Extract } => { const formattedTimestamp = formatTime({ date, type: 'local' diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts index c1460403b..8bea7ec8a 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts @@ -2,6 +2,7 @@ import { Wallet } from '@lace/cardano'; import { getTxDirection, inspectTxType } from '@src/utils/tx-inspection'; import { txTransformer, TxTransformerInput } from './common-tx-transformer'; import type { TransformedActivity } from './types'; +import { ActivityType } from '@lace/core'; interface TxHistoryTransformerInput extends Omit { tx: Wallet.Cardano.HydratedTx; @@ -15,7 +16,7 @@ export const txHistoryTransformer = ({ date, protocolParameters, cardanoCoin -}: TxHistoryTransformerInput): TransformedActivity[] => { +}: TxHistoryTransformerInput): (TransformedActivity & { type: Exclude })[] => { const type = inspectTxType({ walletAddresses, tx }); const direction = getTxDirection({ type }); From 6a981809dfedf34833105c8f25677cbd6dc96e6c Mon Sep 17 00:00:00 2001 From: refi93 Date: Wed, 18 Oct 2023 13:08:55 +0200 Subject: [PATCH 09/31] refactor(staking): split rendering logic of reward and tx details --- apps/browser-extension-wallet/.env.swp | Bin 12288 -> 0 bytes .../src/api/transformers.ts | 6 +- .../transaction-detail-slice.test.ts | 2 +- .../stores/slices/activity-detail-slice.ts | 40 +- .../stores/slices/wallet-activities-slice.ts | 23 +- .../src/stores/types.ts | 32 +- .../src/types/activity-detail.ts | 74 ++++ .../src/types/index.ts | 2 +- apps/browser-extension-wallet/src/types/tx.ts | 51 --- .../src/utils/mocks/test-helpers.tsx | 4 +- .../src/utils/tx-inspection.ts | 2 +- .../activity/components/ActivityDetail.tsx | 221 ++++++---- .../activity/helpers/common-tx-transformer.ts | 8 +- .../helpers/pending-tx-transformer.ts | 2 +- .../helpers/reward-history-transformer.ts | 4 +- .../helpers/tx-history-transformer.ts | 4 +- .../ActivityDetail/ActivityDetailBrowser.tsx | 76 ---- .../components/ActivityDetail/ActivityType.ts | 7 +- .../ActivityDetail/ActivityTypeIcon.tsx | 4 +- .../ActivityDetail/RewardsDetails.tsx | 145 +++---- ...le.scss => TransactionDetails.module.scss} | 0 .../ActivityDetail/TransactionDetails.tsx | 388 +++++++++--------- ...r.test.tsx => TransactionDetails.test.tsx} | 18 +- .../src/ui/components/ActivityDetail/index.ts | 3 +- 24 files changed, 576 insertions(+), 540 deletions(-) delete mode 100644 apps/browser-extension-wallet/.env.swp create mode 100644 apps/browser-extension-wallet/src/types/activity-detail.ts delete mode 100644 apps/browser-extension-wallet/src/types/tx.ts delete mode 100644 packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx rename packages/core/src/ui/components/ActivityDetail/{ActivityDetailBrowser.module.scss => TransactionDetails.module.scss} (100%) rename packages/core/src/ui/components/ActivityDetail/__tests__/{TransactionDetailBrowser.test.tsx => TransactionDetails.test.tsx} (76%) diff --git a/apps/browser-extension-wallet/.env.swp b/apps/browser-extension-wallet/.env.swp deleted file mode 100644 index 76278a5b7671cd04b3df58dd888dad094554fcda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeHNyN~l&6~7D8e!LbC6lf_{fvF&yIFrod8>Fy%W8cJ{_%(iHCev7sa}zsuY>(~4 znJJ*9MF{aX0HQ?{fDjErG#~^m^b{Z=wpj{}oy^W;V0PJZC0qL0vF~~Q&bil#awn~k zAl1&AEdmLysAe7iMn+ATAOzgB6e(umpxwIkKPA`i5hMGjpAad;B ziNd!Y8)Wh*@#DaDC{v#7I8K>K66GmP8g!G}t4qZ|#X!YC#X!YC#X!YC#X!YC#X!YC#X!YC#lT090egzj*Iz~G%P$~! z`2YX@_y0dWhtOXDzXkjl@LfO*7y#;k7l2m*?|c@aKLdUV_z~cHfCz96=mEY4cmeq5 zYaj>s6W}+15b!0y-#>%UuK_;*cz|yL-T-_Y@VifgZ@?1J0{rV!2>k-^bHEP)HsE!@ zA3llD?*YF8d>=3YFo1u50-<*Se*^p!P~`Y}k!N*O3{(tM3{(tM3_Qz#h*@HhD}%_o zpvcycjJuK`^n?YLdvpKB^}WGa-s<5C(#Kd~@x@DAjI;A0d?whpPg>{vhQDe#`CvSj z#^Q}A-u0C$XLzedt@Cp%-Ar00IdrqlY;zoShP{hHqPT&3H#7N6mpz^DZKk8TL?VHm zL~~xfUNLK}Uq2dZ*tjE$X`N{gS#cOI!uDo8=-9XQ%XQy7Ub}bxOSd&Wr-3*Wu3iRO zi|rit>b!XrdAVBWa@AM_5)rj)>EtE9VXv;+=3;y_68wpLd$|}c)8)#{)wX}S3QpD> zb4*oYJ11vDtuLHi*KOg{pSR3#G~vec`r@2h#e6UtWSel3EYe<1T$2~{{`F+A(id6S z=j2&i?QovPMQ7xVdrT|dv=z#7Z$|t+c~JQ zb~3fYsHW3o?Ku>3m9U{miiK6dA~L5cg8WdvrJY5~sOj7%#Oxl#Zj20~NxG%^sG;6F<+Ki_-^AAeO3#0y}QYTY-~jvu8$jw0eYUu_n5_>AeX5}WF zg01;k!oUsV*qI&NrdeYhWnKvBPY;g|PmfMJowL)of-Vgo%nlS~AVM37c)y8YL-cKP z9!2w=| z95zUIW(O%n#USSJPN175tL-z%6b-@Rh)4$5C|-HGfro-Tc#z-)j#$#z>R}PfEO{8% zs ({ +export const blockTransformer = (block: Wallet.BlockInfo): TransactionActivityDetail['blocks'] => ({ blockId: block.header.hash.toString(), epoch: block.epoch.toString(), block: block.header.blockNo.toString(), diff --git a/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts b/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts index f8bedb349..88c16ff1b 100644 --- a/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts +++ b/apps/browser-extension-wallet/src/stores/slices/__tests__/transaction-detail-slice.test.ts @@ -47,7 +47,7 @@ describe('Testing createStoreHook slice', () => { result.current.setTransactionActivityDetail({ type: 'incoming', status: ActivityStatus.SUCCESS, - tx: transactionMock.tx, + activity: transactionMock.tx, direction: transactionMock.direction }); }); diff --git a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts index 47b900362..726edac52 100644 --- a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts @@ -2,7 +2,7 @@ /* eslint-disable unicorn/no-array-reduce */ import isEmpty from 'lodash/isEmpty'; import { ActivityDetailSlice, ZustandHandlers, BlockchainProviderSlice, WalletInfoSlice, SliceCreator } from '../types'; -import { CardanoTxOut, Transaction, ActivityDetail } from '../../types'; +import { CardanoTxOut, Transaction, ActivityDetail, TransactionActivityDetail } from '../../types'; import { blockTransformer, inputOutputTransformer } from '../../api/transformers'; import { Wallet } from '@lace/cardano'; import { getTransactionTotalOutput } from '../../utils/get-transaction-total-output'; @@ -10,7 +10,7 @@ import { inspectTxValues } from '@src/utils/tx-inspection'; import { firstValueFrom } from 'rxjs'; import { getAssetsInformation } from '@src/utils/get-assets-information'; import { MAX_POOLS_COUNT } from '@lace/staking'; -import type { ActivityType } from '@lace/core'; +import { ActivityStatus, ActivityType } from '@lace/core'; import { formatDate, formatTime } from '@src/utils/format-date'; /** @@ -35,7 +35,9 @@ const getTransactionAssetsId = (outputs: CardanoTxOut[]) => { return assetIds; }; -const transactionMetadataTransformer = (metadata: Wallet.Cardano.TxMetadata): ActivityDetail['tx']['metadata'] => +const transactionMetadataTransformer = ( + metadata: Wallet.Cardano.TxMetadata +): TransactionActivityDetail['activity']['metadata'] => [...metadata.entries()].map(([key, value]) => ({ key: key.toString(), value: Wallet.cardanoMetadatumToObj(value) })); const shouldIncludeFee = ( @@ -83,26 +85,27 @@ const buildGetActivityDetail = const { blockchainProvider: { chainHistoryProvider, stakePoolProvider, assetProvider }, inMemoryWallet: wallet, - activityDetail: { tx, epochRewards, status, direction, type }, + activityDetail, walletInfo } = get(); - if (type === 'rewards') { + if (activityDetail.type === 'rewards') { + const { activity, status, type } = activityDetail; const poolInfos = await getPoolInfos( - epochRewards.rewards.map(({ poolId }) => poolId), + activity.rewards.map(({ poolId }) => poolId), stakePoolProvider ); return { - tx: { - includedUtcDate: formatDate({ date: epochRewards.spendableDate, format: 'MM/DD/YYYY', type: 'utc' }), - includedUtcTime: `${formatTime({ date: epochRewards.spendableDate, type: 'utc' })} UTC`, + activity: { + includedUtcDate: formatDate({ date: activity.spendableDate, format: 'MM/DD/YYYY', type: 'utc' }), + includedUtcTime: `${formatTime({ date: activity.spendableDate, type: 'utc' })} UTC`, rewards: { totalAmount: Wallet.util.lovelacesToAdaString( - Wallet.BigIntMath.sum(epochRewards.rewards?.map(({ rewards }) => rewards) || []).toString() + Wallet.BigIntMath.sum(activity.rewards?.map(({ rewards }) => rewards) || []).toString() ), - spendableEpoch: epochRewards.spendableEpoch, - rewards: epochRewards.rewards.map((r) => { + spendableEpoch: activity.spendableEpoch, + rewards: activity.rewards.map((r) => { const poolInfo = poolInfos.find((p) => p.id === r.poolId); return { amount: Wallet.util.lovelacesToAdaString(r.rewards.toString()), @@ -122,6 +125,7 @@ const buildGetActivityDetail = }; } + const { activity: tx, status, type, direction } = activityDetail; const walletAssets = await firstValueFrom(wallet.assetInfo$); const protocolParameters = await firstValueFrom(wallet.protocolParameters$); set({ fetchingActivityInfo: true }); @@ -182,7 +186,7 @@ const buildGetActivityDetail = (certificate) => certificate.__typename === 'StakeDelegationCertificate' ) as Wallet.Cardano.StakeDelegationCertificate[]; - let transaction: ActivityDetail['tx'] = { + let transaction: ActivityDetail['activity'] = { hash: tx.id.toString(), totalOutput: totalOutputInAda, fee: shouldIncludeFee(type, delegationInfo) ? feeInAda : undefined, @@ -216,7 +220,7 @@ const buildGetActivityDetail = } set({ fetchingActivityInfo: false }); - return { tx: transaction, blocks, status, assetAmount, type }; + return { activity: transaction, blocks, status, assetAmount, type }; }; /** @@ -229,9 +233,9 @@ export const activityDetailSlice: SliceCreator< activityDetail: undefined, fetchingActivityInfo: true, getActivityDetail: buildGetActivityDetail({ set, get }), - setTransactionActivityDetail: ({ tx, direction, status, type }) => - set({ activityDetail: { tx, direction, status, type } }), - setRewardsActivityDetail: ({ epochRewards, direction, status, type }) => - set({ activityDetail: { epochRewards, direction, status, type } }), + setTransactionActivityDetail: ({ activity, direction, status, type }) => + set({ activityDetail: { activity, direction, status, type } }), + setRewardsActivityDetail: ({ activity }) => + set({ activityDetail: { activity, status: ActivityStatus.SPENDABLE, type: 'rewards' } }), resetActivityState: () => set({ activityDetail: undefined, fetchingActivityInfo: false }) }); diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index 8a66f3428..44f480b15 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -18,8 +18,8 @@ import { AssetActivityItemProps, AssetActivityListProps, ActivityAssetProp, - ActivityType, - ActivityStatus + ActivityStatus, + TransactionActivityType } from '@lace/core'; import { CurrencyInfo, TxDirections } from '@src/types'; import { getTxDirection, inspectTxType } from '@src/utils/tx-inspection'; @@ -59,7 +59,7 @@ interface FetchWalletActivitiesPropsWithSetter extends FetchWalletActivitiesProp export type FetchWalletActivitiesReturn = Observable>; export type DelegationTransactionType = Extract< - ActivityType, + TransactionActivityType, 'delegation' | 'delegationRegistration' | 'delegationDeregistration' >; @@ -142,14 +142,12 @@ const getWalletActivitiesObservable = async ({ cardanoCoin }); - const extendWithClickHandler = ( - transformedTx: TransformedActivity & { type: Exclude } - ) => ({ + const extendWithClickHandler = (transformedTx: TransformedActivity & { type: TransactionActivityType }) => ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); setTransactionActivityDetail({ - tx, + activity: tx, direction: transformedTx.direction, status: transformedTx.status, type: transformedTx.type @@ -181,15 +179,13 @@ const getWalletActivitiesObservable = async ({ date }); - const extendWithClickHandler = ( - transformedTx: TransformedActivity & { type: Exclude } - ) => ({ + const extendWithClickHandler = (transformedTx: TransformedActivity & { type: TransactionActivityType }) => ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); const deserializedTx: Wallet.Cardano.Tx = TxCBOR.deserialize(tx.cbor); setTransactionActivityDetail({ - tx: deserializedTx, + activity: deserializedTx, direction: TxDirections.Outgoing, status: ActivityStatus.PENDING, type: transformedTx.type @@ -223,10 +219,7 @@ const getWalletActivitiesObservable = async ({ onClick: () => { if (sendAnalytics) sendAnalytics(); setRewardsActivityDetail({ - direction: transformedEpochRewards.direction, - status: transformedEpochRewards.status, - type: transformedEpochRewards.type, - epochRewards: { + activity: { rewards, spendableEpoch, spendableDate: rewardSpendableDate diff --git a/apps/browser-extension-wallet/src/stores/types.ts b/apps/browser-extension-wallet/src/stores/types.ts index 3c206e54f..c6894715e 100644 --- a/apps/browser-extension-wallet/src/stores/types.ts +++ b/apps/browser-extension-wallet/src/stores/types.ts @@ -1,6 +1,12 @@ import { SetState, State, GetState, StoreApi } from 'zustand'; import { Wallet, StakePoolSortOptions } from '@lace/cardano'; -import { AssetActivityListProps, ActivityType, ActivityStatus } from '@lace/core'; +import { + AssetActivityListProps, + ActivityStatus, + RewardsActivityType, + TransactionActivityType, + ActivityType +} from '@lace/core'; import { PriceResult } from '../hooks'; import { NetworkInformation, @@ -126,31 +132,29 @@ export interface ActivityDetailSlice { activityDetail?: { type: ActivityType; status: ActivityStatus; - direction: TxDirection; + direction?: TxDirection; } & ( | { - type: Extract; - epochRewards: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; - tx?: never; + type: RewardsActivityType; + status: ActivityStatus.SPENDABLE; + direction?: never; + activity: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; } | { - type: Exclude; - tx: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; - epochRewards?: never; + type: TransactionActivityType; + activity: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; + direction: TxDirection; } ); fetchingActivityInfo: boolean; setTransactionActivityDetail: (params: { - tx: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; + activity: Wallet.Cardano.HydratedTx | Wallet.Cardano.Tx; direction: TxDirection; status: ActivityStatus; - type: Exclude; + type: TransactionActivityType; }) => void; setRewardsActivityDetail: (params: { - epochRewards: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; - direction: TxDirection; - status: ActivityStatus; - type: Extract; + activity: { spendableEpoch: EpochNo; spendableDate: Date; rewards: Reward[] }; }) => void; getActivityDetail: (params: { coinPrices: PriceResult; fiatCurrency: CurrencyInfo }) => Promise; resetActivityState: () => void; diff --git a/apps/browser-extension-wallet/src/types/activity-detail.ts b/apps/browser-extension-wallet/src/types/activity-detail.ts new file mode 100644 index 000000000..2339669fe --- /dev/null +++ b/apps/browser-extension-wallet/src/types/activity-detail.ts @@ -0,0 +1,74 @@ +import type { + TransactionMetadataProps, + TxOutputInput, + ActivityStatus, + RewardsInfo, + TransactionActivityType, + RewardsActivityType +} from '@lace/core'; + +export enum TxDirections { + Outgoing = 'Outgoing', + Incoming = 'Incoming', + Self = 'Self' +} + +export type TxDirection = keyof typeof TxDirections; + +export type TransactionPool = { + name: string; + ticker: string; + id: string; +}; + +type TransactionActivity = { + hash: string; + includedUtcDate?: string; + includedUtcTime?: string; + totalOutput?: string; + fee?: string; + depositReclaim?: string; + deposit?: string; + addrInputs?: TxOutputInput[]; + addrOutputs?: TxOutputInput[]; + metadata?: TransactionMetadataProps['metadata']; + pools?: TransactionPool[]; +}; + +type RewardsActivity = { + rewards: RewardsInfo; + includedUtcDate: string; + includedUtcTime: string; +}; + +type BlocksInfo = { + isPopup?: boolean; + blockId?: string; + epoch?: string; + block?: string; + slot?: string; + confirmations?: string; + size?: string; + transactions?: string; + utcDate?: string; + utcTime?: string; + nextBlock?: string; + prevBlock?: string; + createdBy?: string; +}; + +export type TransactionActivityDetail = { + type: TransactionActivityType; + status: ActivityStatus; + activity: TransactionActivity; + blocks?: BlocksInfo; + assetAmount?: number; +}; + +export type RewardsActivityDetail = { + type: RewardsActivityType; + status: ActivityStatus.SPENDABLE; + activity: RewardsActivity; +}; + +export type ActivityDetail = TransactionActivityDetail | RewardsActivityDetail; diff --git a/apps/browser-extension-wallet/src/types/index.ts b/apps/browser-extension-wallet/src/types/index.ts index f16cdfb6e..24679b487 100644 --- a/apps/browser-extension-wallet/src/types/index.ts +++ b/apps/browser-extension-wallet/src/types/index.ts @@ -4,7 +4,7 @@ export * from './network-information'; export * from './util'; export * from './wallet-balance'; export * from './wallet'; -export * from './tx'; +export * from './activity-detail'; export * from './dappConnector'; export * from './ui'; export * from './side-menu'; diff --git a/apps/browser-extension-wallet/src/types/tx.ts b/apps/browser-extension-wallet/src/types/tx.ts deleted file mode 100644 index ffbf895e0..000000000 --- a/apps/browser-extension-wallet/src/types/tx.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { TransactionMetadataProps, TxOutputInput, ActivityType, ActivityStatus } from '@lace/core'; -import { RewardsInfo } from '@lace/core/dist/ui/components/Transactions/RewardsInfo'; - -export enum TxDirections { - Outgoing = 'Outgoing', - Incoming = 'Incoming', - Self = 'Self' -} - -export type TxDirection = keyof typeof TxDirections; - -export type TransactionPool = { - name: string; - ticker: string; - id: string; -}; - -export interface ActivityDetail { - tx: { - hash?: string; - includedUtcDate?: string; - includedUtcTime?: string; - totalOutput?: string; - fee?: string; - depositReclaim?: string; - deposit?: string; - addrInputs?: TxOutputInput[]; - addrOutputs?: TxOutputInput[]; - metadata?: TransactionMetadataProps['metadata']; - pools?: TransactionPool[]; - rewards?: RewardsInfo; - }; - blocks?: { - isPopup?: boolean; - blockId?: string; - epoch?: string; - block?: string; - slot?: string; - confirmations?: string; - size?: string; - transactions?: string; - utcDate?: string; - utcTime?: string; - nextBlock?: string; - prevBlock?: string; - createdBy?: string; - }; - status?: ActivityStatus; - assetAmount?: number; - type?: ActivityType; -} diff --git a/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx b/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx index cf6483055..c9df42a62 100644 --- a/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx +++ b/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx @@ -5,7 +5,7 @@ import React, { FunctionComponent } from 'react'; import { Wallet } from '@lace/cardano'; import { SendStoreProvider } from '../../features/send/stores'; import { createSignal } from '@react-rxjs/utils'; -import { Balance, CardanoTxBuild, WalletInfo, TxDirection, ActivityDetail } from '@types'; +import { Balance, CardanoTxBuild, WalletInfo, TxDirection, TransactionActivityDetail } from '@types'; import { DisplayedCoinDetail, IAssetInfo } from '../../features/send/types'; import { APP_MODE_POPUP, cardanoCoin } from '../constants'; import { fakeApiRequest } from './fake-api-request'; @@ -409,7 +409,7 @@ export const blockMock: Wallet.BlockInfo = { date: new Date(1_638_829_263_730) }; -export const formatBlockMock: ActivityDetail['blocks'] = { +export const formatBlockMock: TransactionActivityDetail['blocks'] = { block: '3114964', blockId: '717ca157f1e696a612af87109ba1f30cd4bb311ded5b504c78a6face463def95', confirmations: '17013', diff --git a/apps/browser-extension-wallet/src/utils/tx-inspection.ts b/apps/browser-extension-wallet/src/utils/tx-inspection.ts index bac087f37..23f169980 100644 --- a/apps/browser-extension-wallet/src/utils/tx-inspection.ts +++ b/apps/browser-extension-wallet/src/utils/tx-inspection.ts @@ -47,7 +47,7 @@ export const inspectTxType = ({ }: { walletAddresses: Wallet.KeyManagement.GroupedAddress[]; tx: Wallet.Cardano.HydratedTx; -}): Exclude => { +}): TransactionActivityType => { const { paymentAddresses, rewardAccounts } = walletAddresses.reduce( (acc, curr) => ({ paymentAddresses: [...acc.paymentAddresses, curr.address], diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index fb5bf1582..7a8857ea9 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -1,4 +1,3 @@ -/* eslint-disable sonarjs/cognitive-complexity */ /* eslint-disable @typescript-eslint/ban-ts-comment */ import React, { ReactElement, useCallback, useEffect, useMemo, useState } from 'react'; import uniq from 'lodash/uniq'; @@ -6,10 +5,19 @@ import flatMap from 'lodash/flatMap'; import { Skeleton } from 'antd'; import { config } from '@src/config'; import { Wallet } from '@lace/cardano'; -import { AssetActivityListProps, ActivityDetailBrowser, ActivityStatus, TxOutputInput, TxSummary } from '@lace/core'; +import { + AssetActivityListProps, + ActivityStatus, + TxOutputInput, + TxSummary, + ActivityType, + useTranslate, + RewardsDetails, + TransactionDetails +} from '@lace/core'; import { PriceResult } from '@hooks'; import { useWalletStore } from '@stores'; -import { ActivityDetail as ActivityDetailType } from '@src/types'; +import { ActivityDetail as ActivityDetailType, TransactionActivityDetail, TxDirection } from '@src/types'; import { useAddressBookContext, withAddressBookContext } from '@src/features/address-book/context'; import { APP_MODE_POPUP } from '@src/utils/constants'; import { useAnalyticsContext, useCurrencyStore, useExternalLinkOpener } from '@providers'; @@ -74,32 +82,122 @@ interface ActivityDetailProps { price: PriceResult; } -export const ActivityDetail = withAddressBookContext(({ price }): ReactElement => { +const getTypeLabel = (type: ActivityType, t: ReturnType['t']) => { + if (type === 'rewards') return t('package.core.transactionDetailBrowser.rewards'); + if (type === 'delegation') return t('package.core.transactionDetailBrowser.delegation'); + if (type === 'delegationRegistration') return t('package.core.transactionDetailBrowser.registration'); + if (type === 'delegationDeregistration') return t('package.core.transactionDetailBrowser.deregistration'); + if (type === 'incoming') return t('package.core.transactionDetailBrowser.received'); + return t('package.core.transactionDetailBrowser.sent'); +}; + +type _TransactionDetailsProps = { + name: string; + activityInfo: TransactionActivityDetail; + direction: TxDirection; + status: ActivityStatus; + amountTransformer: (amount: string) => string; +}; +const _TransactionDetails = withAddressBookContext<_TransactionDetailsProps>( + ({ name, activityInfo, direction, status, amountTransformer }: _TransactionDetailsProps): ReactElement => { + const analytics = useAnalyticsContext(); + const { + walletInfo, + environmentName, + walletUI: { cardanoCoin, appMode } + } = useWalletStore(); + const isPopupView = appMode === APP_MODE_POPUP; + const openExternalLink = useExternalLinkOpener(); + const { list: addressList } = useAddressBookContext(); + + const { CEXPLORER_BASE_URL, CEXPLORER_URL_PATHS } = config(); + const explorerBaseUrl = useMemo( + () => `${CEXPLORER_BASE_URL[environmentName]}/${CEXPLORER_URL_PATHS.Tx}`, + [CEXPLORER_BASE_URL, CEXPLORER_URL_PATHS.Tx, environmentName] + ); + const getHeaderDescription = () => { + if (activityInfo.type === 'delegation') return '1 token'; + return ` (${activityInfo?.assetAmount})`; + }; + const isIncomingTransaction = direction === 'Incoming'; + const { + addrOutputs, + addrInputs, + hash, + includedUtcDate, + includedUtcTime, + fee, + pools, + deposit, + depositReclaim, + metadata + } = activityInfo.activity; + const txSummary = useMemo( + () => + getTransactionData({ + addrOutputs, + addrInputs, + walletAddresses: walletInfo.addresses.map((addr) => addr.address.toString()), + isIncomingTransaction + }), + [isIncomingTransaction, addrOutputs, addrInputs, walletInfo.addresses] + ); + + const handleOpenExternalLink = () => { + analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailTransactionHashClick); + const externalLink = `${explorerBaseUrl}/${hash}`; + externalLink && status === 'success' && openExternalLink(externalLink); + }; + + const addressToNameMap = useMemo( + () => new Map(addressList?.map((item: AddressListType) => [item.address, item.name])), + [addressList] + ); + + return ( + // eslint-disable-next-line react/jsx-pascal-case + analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailInputsClick)} + sendAnalyticsOutputs={() => analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailOutputsClick)} + /> + ); + } +); + +export const ActivityDetail = ({ price }: ActivityDetailProps): ReactElement => { const { - walletInfo, - walletUI: { cardanoCoin, appMode }, - environmentName + walletUI: { cardanoCoin } } = useWalletStore(); - const isPopupView = appMode === APP_MODE_POPUP; + const { t } = useTranslate(); const { getActivityDetail, activityDetail, fetchingActivityInfo, walletActivities } = useWalletStore(); const [activityInfo, setActivityInfo] = useState(); const { fiatCurrency } = useCurrencyStore(); - const { list: addressList } = useAddressBookContext(); - const { CEXPLORER_BASE_URL, CEXPLORER_URL_PATHS } = config(); - const openExternalLink = useExternalLinkOpener(); - const analytics = useAnalyticsContext(); - - const explorerBaseUrl = useMemo( - () => `${CEXPLORER_BASE_URL[environmentName]}/${CEXPLORER_URL_PATHS.Tx}`, - [CEXPLORER_BASE_URL, CEXPLORER_URL_PATHS.Tx, environmentName] - ); const currentTransactionStatus = useMemo( () => - activityDetail.tx?.id - ? getCurrentTransactionStatus(walletActivities, activityDetail.tx.id) ?? activityInfo?.status + activityDetail.type !== 'rewards' + ? getCurrentTransactionStatus(walletActivities, activityDetail.activity.id) ?? activityInfo?.status : activityInfo?.status, - [activityDetail.tx?.id, activityInfo?.status, walletActivities] + [activityDetail.activity, activityDetail.type, activityInfo?.status, walletActivities] ); const fetchActivityInfo = useCallback(async () => { @@ -112,64 +210,37 @@ export const ActivityDetail = withAddressBookContext(({ pri // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const addressToNameMap = useMemo( - () => new Map(addressList?.map((item: AddressListType) => [item.address, item.name])), - [addressList] - ); - - const isIncomingTransaction = activityDetail.direction === 'Incoming'; - const { addrOutputs, addrInputs } = activityInfo?.tx || {}; - const txSummary = useMemo( - () => - getTransactionData({ - addrOutputs, - addrInputs, - walletAddresses: walletInfo.addresses.map((addr) => addr.address.toString()), - isIncomingTransaction - }), - [isIncomingTransaction, addrOutputs, addrInputs, walletInfo.addresses] - ); - if (fetchingActivityInfo || !activityInfo) return ; - const getHeaderDescription = () => { - if (activityInfo.type === 'rewards') return ''; - if (activityInfo.type === 'delegation') return '1 token'; - return ` (${activityInfo?.assetAmount})`; - }; + const name = + activityInfo.status === ActivityStatus.PENDING + ? t('package.core.transactionDetailBrowser.sending') + : getTypeLabel(activityInfo.type, t); - const handleOpenExternalLink = () => { - analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailTransactionHashClick); - const externalLink = `${explorerBaseUrl}/${activityInfo.tx.hash}`; - externalLink && currentTransactionStatus === 'success' && openExternalLink(externalLink); - }; + const amountTransformer = (ada: string) => + `${Wallet.util.convertAdaToFiat({ ada, fiat: price?.cardano?.price })} ${fiatCurrency?.code}`; return ( - - `${Wallet.util.convertAdaToFiat({ ada, fiat: price?.cardano?.price })} ${fiatCurrency?.code}` - } - headerDescription={getHeaderDescription() || cardanoCoin.symbol} - txSummary={txSummary} - addressToNameMap={addressToNameMap} - coinSymbol={cardanoCoin.symbol} - rewards={activityInfo.tx?.rewards} - type={activityInfo?.type} - isPopupView={isPopupView} - openExternalLink={handleOpenExternalLink} - sendAnalyticsInputs={() => analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailInputsClick)} - sendAnalyticsOutputs={() => analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailOutputsClick)} - /> + <> + {activityInfo.type === 'rewards' ? ( + + ) : ( + // eslint-disable-next-line react/jsx-pascal-case + <_TransactionDetails + name={name} + activityInfo={activityInfo} + direction={activityDetail.direction} + status={currentTransactionStatus} + amountTransformer={amountTransformer} + /> + )} + ); -}); +}; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts index 8468a26f7..53df6bbf4 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts @@ -4,7 +4,7 @@ import { CurrencyInfo, TxDirections } from '@types'; import { inspectTxValues, inspectTxType } from '@src/utils/tx-inspection'; import { formatDate, formatTime } from '@src/utils/format-date'; import type { TransformedActivity } from './types'; -import { ActivityStatus, ActivityType } from '@lace/core'; +import { ActivityStatus, TransactionActivityType } from '@lace/core'; import capitalize from 'lodash/capitalize'; import dayjs from 'dayjs'; import { assertUnreachable } from '@src/utils/assert-unreachable'; @@ -36,9 +36,7 @@ export const getFormattedFiatAmount = ({ return fiatAmount ? `${fiatAmount} ${fiatCurrency.code}` : '-'; }; -const splitDelegationTx = ( - tx: TransformedActivity -): (TransformedActivity & { type: Exclude })[] => { +const splitDelegationTx = (tx: TransformedActivity): (TransformedActivity & { type: TransactionActivityType })[] => { if (tx.deposit) { return [ { @@ -116,7 +114,7 @@ export const txTransformer = ({ date, direction, status -}: TxTransformerInput): (TransformedActivity & { type: Exclude })[] => { +}: TxTransformerInput): (TransformedActivity & { type: TransactionActivityType })[] => { const implicitCoin = Wallet.Cardano.util.computeImplicitCoin(protocolParameters, tx.body); const deposit = implicitCoin.deposit ? Wallet.util.lovelacesToAdaString(implicitCoin.deposit.toString()) : undefined; const depositReclaimValue = Wallet.util.calculateDepositReclaim(implicitCoin); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts index 4bd629668..718cd3252 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts @@ -16,7 +16,7 @@ export const pendingTxTransformer = ({ protocolParameters, cardanoCoin, date -}: TxHistoryTransformerInput): (TransformedActivity & { type: Exclude })[] => +}: TxHistoryTransformerInput): (TransformedActivity & { type: TransactionActivityType })[] => txTransformer({ tx, walletAddresses, diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts index baf1cd55a..151fef733 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts @@ -6,7 +6,7 @@ import { formatDate, formatTime } from '@src/utils/format-date'; import BigNumber from 'bignumber.js'; import type { CurrencyInfo } from '@src/types'; import type { Reward } from '@cardano-sdk/core'; -import { ActivityStatus, ActivityType } from '@lace/core'; +import { ActivityStatus, RewardsActivityType } from '@lace/core'; interface RewardHistoryTransformerInput { rewards: Reward[]; // TODO this supposes rewards grouped by epoch which is a bit fragile @@ -22,7 +22,7 @@ export const rewardHistoryTransformer = ({ fiatPrice, date, cardanoCoin -}: RewardHistoryTransformerInput): TransformedActivity & { type: Extract } => { +}: RewardHistoryTransformerInput): TransformedActivity & { type: RewardsActivityType } => { const formattedTimestamp = formatTime({ date, type: 'local' diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts index 8bea7ec8a..fc68a382a 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts @@ -2,7 +2,7 @@ import { Wallet } from '@lace/cardano'; import { getTxDirection, inspectTxType } from '@src/utils/tx-inspection'; import { txTransformer, TxTransformerInput } from './common-tx-transformer'; import type { TransformedActivity } from './types'; -import { ActivityType } from '@lace/core'; +import { TransactionActivityType } from '@lace/core'; interface TxHistoryTransformerInput extends Omit { tx: Wallet.Cardano.HydratedTx; @@ -16,7 +16,7 @@ export const txHistoryTransformer = ({ date, protocolParameters, cardanoCoin -}: TxHistoryTransformerInput): (TransformedActivity & { type: Exclude })[] => { +}: TxHistoryTransformerInput): (TransformedActivity & { type: TransactionActivityType })[] => { const type = inspectTxType({ walletAddresses, tx }); const direction = getTxDirection({ type }); diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx deleted file mode 100644 index 7e89e0b52..000000000 --- a/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; -import styles from './ActivityDetailBrowser.module.scss'; -import { ActivityDetailHeaderBrowser } from './ActivityDetailHeaderBrowser'; -import { ActivityStatus } from '../Activity/AssetActivityItem'; -import { RewardsDetails, RewardsDetailsProps } from './RewardsDetails'; -import { TransactionDetails, TransactionDetailsProps } from './TransactionDetails'; -import { ActivityType } from './ActivityType'; -import { useTranslate } from '@src/ui/hooks'; - -const getTypeLabel = (type: ActivityType, t: ReturnType['t']) => { - if (type === 'rewards') return t('package.core.transactionDetailBrowser.rewards'); - if (type === 'delegation') return t('package.core.transactionDetailBrowser.delegation'); - if (type === 'delegationRegistration') return t('package.core.transactionDetailBrowser.registration'); - if (type === 'delegationDeregistration') return t('package.core.transactionDetailBrowser.deregistration'); - if (type === 'incoming') return t('package.core.transactionDetailBrowser.received'); - return t('package.core.transactionDetailBrowser.sent'); -}; - -export type ActivityDetailBrowserProps = Omit & - Omit & { - headerDescription?: string; - type?: ActivityType; - addressToNameMap: Map; - isPopupView?: boolean; - }; - -export const ActivityDetailBrowser = ({ - status, - headerDescription, - includedDate, - includedTime, - amountTransformer, - coinSymbol, - type, - isPopupView, - rewards, - ...props -}: ActivityDetailBrowserProps): React.ReactElement => { - const { t } = useTranslate(); - - const name = - status === ActivityStatus.PENDING ? t('package.core.transactionDetailBrowser.sending') : getTypeLabel(type, t); - const tooltipContent = type === 'rewards' ? t('package.core.transactionDetailBrowser.rewardsDescription') : undefined; - - const transactionProps: TransactionDetailsProps = { - ...props, - includedDate, - includedTime, - status, - name, - amountTransformer, - coinSymbol, - isPopupView - }; - - const rewardsProps: RewardsDetailsProps = { - name, - status, - includedDate, - includedTime, - amountTransformer, - coinSymbol, - rewards - }; - - return ( -
- - {status === ActivityStatus.SPENDABLE ? ( - - ) : ( - - )} -
- ); -}; diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityType.ts b/packages/core/src/ui/components/ActivityDetail/ActivityType.ts index b376b5331..dc440c7f4 100644 --- a/packages/core/src/ui/components/ActivityDetail/ActivityType.ts +++ b/packages/core/src/ui/components/ActivityDetail/ActivityType.ts @@ -1,8 +1,11 @@ -export type ActivityType = +export type TransactionActivityType = | 'outgoing' | 'incoming' | 'delegation' | 'delegationRegistration' | 'delegationDeregistration' - | 'rewards' | 'self'; + +export type RewardsActivityType = 'rewards'; + +export type ActivityType = TransactionActivityType | RewardsActivityType; diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx index c8afa5464..b27a35732 100644 --- a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx @@ -14,7 +14,7 @@ export interface ActivityTypeIconProps { type: ActivityType; } -const transactionTypeIcon: Record>> = { +const activityTypeIcon: Record>> = { outgoing: OutgoingIcon, incoming: IncomingIcon, self: SelfIcon, @@ -25,7 +25,7 @@ const transactionTypeIcon: Record { - const icon = type && transactionTypeIcon[type]; + const icon = type && activityTypeIcon[type]; const iconStyle = { fontSize: txIconSize() }; return icon ? : ; diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index 1199347b8..589c4a350 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -1,13 +1,15 @@ import React from 'react'; import cn from 'classnames'; -import styles from './ActivityDetailBrowser.module.scss'; +import styles from './TransactionDetails.module.scss'; import { useTranslate } from '@src/ui/hooks'; import { ActivityStatus } from '../Activity/AssetActivityItem'; import type { RewardsInfo } from './RewardsInfo'; import { Ellipsis } from '@lace/common'; +import { ActivityDetailHeaderBrowser } from './ActivityDetailHeaderBrowser'; export interface RewardsDetailsProps { name: string; + headerDescription?: string; status?: ActivityStatus; includedDate?: string; includedTime?: string; @@ -18,6 +20,7 @@ export interface RewardsDetailsProps { export const RewardsDetails = ({ name, + headerDescription, status, includedDate = '-', includedTime = '-', @@ -27,87 +30,91 @@ export const RewardsDetails = ({ }: RewardsDetailsProps): React.ReactElement => { const { t } = useTranslate(); const poolRewards = rewards?.rewards.filter((reward) => !!reward.pool); + const tooltipContent = t('package.core.transactionDetailBrowser.rewardsDescription'); return ( -
-
{t('package.core.transactionDetailBrowser.header')}
-

{t('package.core.transactionDetailBrowser.summary')}

-
-
-
-
{name}
-
-
- {`${rewards.totalAmount} ${coinSymbol}`} - {`${amountTransformer( - rewards.totalAmount - )}`} +
+ +
+
{t('package.core.transactionDetailBrowser.header')}
+

{t('package.core.transactionDetailBrowser.summary')}

+
+
+
+
{name}
+
+
+ {`${rewards.totalAmount} ${coinSymbol}`} + {`${amountTransformer( + rewards.totalAmount + )}`} +
-
- {poolRewards.length > 0 && ( -
-
- {t('package.core.transactionDetailBrowser.pools')} -
-
- {poolRewards?.map(({ pool, amount }) => ( -
-
- {pool.name && ( -
- {pool.name} -
- )} - {pool.ticker && ( -
- ({pool.ticker}) + {poolRewards.length > 0 && ( +
+
+ {t('package.core.transactionDetailBrowser.pools')} +
+
+ {poolRewards?.map(({ pool, amount }) => ( +
+
+ {pool.name && ( +
+ {pool.name} +
+ )} + {pool.ticker && ( +
+ ({pool.ticker}) +
+ )} +
+ {pool.id && ( +
+
)} -
- {pool.id && ( -
- +
+ + {amount} {coinSymbol} + + + {amountTransformer(amount)} +
- )} -
- - {amount} {coinSymbol} - - - {amountTransformer(amount)} -
-
- ))} + ))} +
-
- )} - -
-
{t('package.core.transactionDetailBrowser.status')}
- {status && ( -
{`${status.charAt(0).toUpperCase()}${status.slice( - 1 - )}`}
)} -
-
-
{t('package.core.transactionDetailBrowser.epoch')}
- {
{`${rewards.spendableEpoch}`}
} -
-
-
- {t('package.core.transactionDetailBrowser.timestamp')} + +
+
{t('package.core.transactionDetailBrowser.status')}
+ {status && ( +
{`${status.charAt(0).toUpperCase()}${status.slice( + 1 + )}`}
+ )} +
+
+
{t('package.core.transactionDetailBrowser.epoch')}
+ {
{`${rewards.spendableEpoch}`}
}
-
- {includedDate} -  {includedTime} +
+
+ {t('package.core.transactionDetailBrowser.timestamp')} +
+
+ {includedDate} +  {includedTime} +
diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.module.scss b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.module.scss similarity index 100% rename from packages/core/src/ui/components/ActivityDetail/ActivityDetailBrowser.module.scss rename to packages/core/src/ui/components/ActivityDetail/TransactionDetails.module.scss diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index eec9a01bb..4a75ec05e 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -4,7 +4,7 @@ import React from 'react'; import cn from 'classnames'; import { InfoCircleOutlined } from '@ant-design/icons'; import { Tooltip } from 'antd'; -import styles from './ActivityDetailBrowser.module.scss'; +import styles from './TransactionDetails.module.scss'; import { TransactionDetailAsset, TxOutputInput, TransactionMetadataProps, TxSummary } from './TransactionDetailAsset'; import { ActivityStatus } from '../Activity'; import { Ellipsis, toast } from '@lace/common'; @@ -13,6 +13,7 @@ import { TransactionInputOutput } from './TransactionInputOutput'; import { useTranslate } from '@src/ui/hooks'; import CopyToClipboard from 'react-copy-to-clipboard'; import type { RewardsInfo } from './RewardsInfo'; +import { ActivityDetailHeaderBrowser } from './ActivityDetailHeaderBrowser'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const displayMetadataMsg = (value: any[]): string => value?.find((val: any) => val.hasOwnProperty('msg'))?.msg || ''; @@ -94,6 +95,7 @@ export const TransactionDetails = ({ hash, name, status, + headerDescription, includedDate = '-', includedTime = '-', fee = '-', @@ -129,218 +131,224 @@ export const TransactionDetails = ({ ); return ( -
-
- {t('package.core.transactionDetailBrowser.header')} -
-
-
-
-
{t('package.core.transactionDetailBrowser.transactionHash')}
-
-
-
- {isSending ? ( - - ) : ( - hash - )} +
+ +
+
+ {t('package.core.transactionDetailBrowser.header')} +
+
+
+
+
{t('package.core.transactionDetailBrowser.transactionHash')}
+
+
+
+ {isSending ? ( + + ) : ( + hash + )} +
-
-

{t('package.core.transactionDetailBrowser.summary')}

- {pools?.length > 0 && ( -
-
- {t('package.core.transactionDetailBrowser.pools')} -
-
- {pools?.map((pool) => ( -
-
- {pool.name && ( -
- {pool.name} -
- )} - {pool.ticker && ( -
- ({pool.ticker}) +

{t('package.core.transactionDetailBrowser.summary')}

+ {pools?.length > 0 && ( +
+
+ {t('package.core.transactionDetailBrowser.pools')} +
+
+ {pools?.map((pool) => ( +
+
+ {pool.name && ( +
+ {pool.name} +
+ )} + {pool.ticker && ( +
+ ({pool.ticker}) +
+ )} +
+ {pool.id && ( +
+
)}
- {pool.id && ( -
- -
- )} -
- ))} + ))} +
-
- )} - {txSummary.map((summary, index) => ( -
-
-
{name}
-
- {summary.assetList?.map((asset, i) => ( -
- - {asset.amount} {asset.symbol} - - {asset?.fiatBalance && ( - - {asset.fiatBalance} + )} + {txSummary.map((summary, index) => ( +
+
+
{name}
+
+ {summary.assetList?.map((asset, i) => ( +
+ + {asset.amount} {asset.symbol} - )} + {asset?.fiatBalance && ( + + {asset.fiatBalance} + + )} +
+ ))} +
+ {`${summary.amount} ${coinSymbol}`} + {`${amountTransformer( + summary.amount + )}`}
- ))} -
- {`${summary.amount} ${coinSymbol}`} - {`${amountTransformer( - summary.amount - )}`}
-
-
-
- {t(`package.core.transactionDetailBrowser.${name.toLowerCase() === 'sent' ? 'to' : 'from'}`)} -
-
- {summary.addr.length > 1 && ( -
- {t('package.core.transactionDetailBrowser.multipleAddresses')} -
- )} - {(summary.addr as string[]).map((addr) => { - const addrName = addressToNameMap?.get(addr); - const address = isPopupView ? ( - - ) : ( - {addr} - ); - return ( -
- {addrName ? ( -
- {addrName} - {address} -
- ) : ( - address - )} +
+
+ {t(`package.core.transactionDetailBrowser.${name.toLowerCase() === 'sent' ? 'to' : 'from'}`)} +
+
+ {summary.addr.length > 1 && ( +
+ {t('package.core.transactionDetailBrowser.multipleAddresses')}
- ); - })} + )} + {(summary.addr as string[]).map((addr) => { + const addrName = addressToNameMap?.get(addr); + const address = isPopupView ? ( + + ) : ( + {addr} + ); + return ( +
+ {addrName ? ( +
+ {addrName} + {address} +
+ ) : ( + address + )} +
+ ); + })} +
+ ))} +
+
{t('package.core.transactionDetailBrowser.status')}
+ {status && ( +
{`${status.charAt(0).toUpperCase()}${status.slice( + 1 + )}`}
+ )}
- ))} -
-
{t('package.core.transactionDetailBrowser.status')}
- {status && ( -
{`${status.charAt(0).toUpperCase()}${status.slice( - 1 - )}`}
- )} -
-
-
- {t('package.core.transactionDetailBrowser.timestamp')} -
-
- {includedDate} -  {includedTime} +
+
+ {t('package.core.transactionDetailBrowser.timestamp')} +
+
+ {includedDate} +  {includedTime} +
-
- {fee && fee !== '-' && ( -
-
-
{t('package.core.transactionDetailBrowser.transactionFee')}
- - {Info ? ( - - ) : ( - - )} - -
+ {fee && fee !== '-' && ( +
+
+
{t('package.core.transactionDetailBrowser.transactionFee')}
+ + {Info ? ( + + ) : ( + + )} + +
-
-
- {`${fee} ${coinSymbol}`} - - {amountTransformer(fee)} - +
+
+ {`${fee} ${coinSymbol}`} + + {amountTransformer(fee)} + +
-
- )} + )} - {deposit && - renderDepositValueSection({ value: deposit, label: t('package.core.transactionDetailBrowser.deposit') })} - {depositReclaim && - renderDepositValueSection({ - value: depositReclaim, - label: t('package.core.transactionDetailBrowser.depositReclaim') - })} -
+ {deposit && + renderDepositValueSection({ value: deposit, label: t('package.core.transactionDetailBrowser.deposit') })} + {depositReclaim && + renderDepositValueSection({ + value: depositReclaim, + label: t('package.core.transactionDetailBrowser.depositReclaim') + })} +
- {addrInputs?.length > 0 && ( - - )} - {addrOutputs?.length > 0 && ( - - )} - {metadata?.length > 0 && ( -
-
{t('package.core.transactionDetailBrowser.metadata')}
-
- {metadata?.map((item) => ( -
- {/* there are two options here item.value could be an array or string, if it is an array format item.value using displayMetadataMsg, if not just use item.value */} - {Array.isArray(item.value) ? displayMetadataMsg(item.value) : item.value} -
- ))} + {addrInputs?.length > 0 && ( + + )} + {addrOutputs?.length > 0 && ( + + )} + {metadata?.length > 0 && ( +
+
{t('package.core.transactionDetailBrowser.metadata')}
+
+ {metadata?.map((item) => ( +
+ {/* there are two options here item.value could be an array or string, if it is an array format item.value using displayMetadataMsg, if not just use item.value */} + {Array.isArray(item.value) ? displayMetadataMsg(item.value) : item.value} +
+ ))} +
-
- )} + )} +
); }; diff --git a/packages/core/src/ui/components/ActivityDetail/__tests__/TransactionDetailBrowser.test.tsx b/packages/core/src/ui/components/ActivityDetail/__tests__/TransactionDetails.test.tsx similarity index 76% rename from packages/core/src/ui/components/ActivityDetail/__tests__/TransactionDetailBrowser.test.tsx rename to packages/core/src/ui/components/ActivityDetail/__tests__/TransactionDetails.test.tsx index 3898ac8d1..73522e5c2 100644 --- a/packages/core/src/ui/components/ActivityDetail/__tests__/TransactionDetailBrowser.test.tsx +++ b/packages/core/src/ui/components/ActivityDetail/__tests__/TransactionDetails.test.tsx @@ -1,13 +1,14 @@ /* eslint-disable no-magic-numbers */ import * as React from 'react'; import { render, within, fireEvent } from '@testing-library/react'; -import { ActivityDetailBrowser, ActivityDetailBrowserProps } from '../ActivityDetailBrowser'; import '@testing-library/jest-dom'; +import { TransactionDetails, TransactionDetailsProps } from '../TransactionDetails'; const transactionDate = '2021/09/10'; describe('Testing ActivityDetailsBrowser component', () => { - const addrListProps: ActivityDetailBrowserProps = { + const addrListProps: TransactionDetailsProps = { + name: 'Name', isPopupView: false, hash: '5e58ad7aa10667c05c3ffdb9ae65fe22c77e5145db823715217b775b4344839f', totalOutput: '38038.963341 ADA', @@ -34,26 +35,25 @@ describe('Testing ActivityDetailsBrowser component', () => { ], amountTransformer: (amount) => `${amount} $`, coinSymbol: 'ADA', - type: 'incoming', addressToNameMap: new Map() }; test('should display transaction hash and copy button', async () => { - const { findByTestId } = render(); + const { findByTestId } = render(); const container = await findByTestId('tx-hash'); expect(container).toBeVisible(); }); test('should display transaction date and time', async () => { - const { findByTestId } = render(); + const { findByTestId } = render(); const dateContainer = await findByTestId('tx-date'); expect(dateContainer).toBeVisible(); }); test('should display transaction inputs and outputs list', async () => { - const { findByTestId } = render(); + const { findByTestId } = render(); const inputContainer = await findByTestId('tx-inputs'); const listToggle = await findByTestId('tx-addr-list_toggle'); @@ -65,7 +65,7 @@ describe('Testing ActivityDetailsBrowser component', () => { }); test('should display transaction and fee', async () => { - const { findByTestId } = render(); + const { findByTestId } = render(); const feeContainer = await findByTestId('tx-fee'); expect(feeContainer).toBeVisible(); @@ -73,14 +73,14 @@ describe('Testing ActivityDetailsBrowser component', () => { test('should display transaction metadata if available', async () => { const { findByTestId } = render( - + ); const txMetadata = await findByTestId('tx-metadata'); expect(txMetadata).toBeVisible(); }); test('should not display transaction metadata if not available', async () => { - const { queryByTestId: query } = render(); + const { queryByTestId: query } = render(); expect(query('tx-metadata')).not.toBeInTheDocument(); }); }); diff --git a/packages/core/src/ui/components/ActivityDetail/index.ts b/packages/core/src/ui/components/ActivityDetail/index.ts index f49a9fffa..f2f069340 100644 --- a/packages/core/src/ui/components/ActivityDetail/index.ts +++ b/packages/core/src/ui/components/ActivityDetail/index.ts @@ -1,4 +1,5 @@ -export * from './ActivityDetailBrowser'; +export * from './TransactionDetails'; +export * from './RewardsDetails'; export * from './ActivityType'; export * from './ActivityTypeIcon'; export * from './TransactionDetailAsset'; From 0497b1ee80ea4d2fa0965540ea2963e2827897d4 Mon Sep 17 00:00:00 2001 From: refi93 Date: Wed, 18 Oct 2023 16:27:54 +0200 Subject: [PATCH 10/31] fix(all): fix broken type import --- apps/browser-extension-wallet/src/utils/tx-inspection.ts | 2 +- .../features/activity/helpers/pending-tx-transformer.ts | 2 +- .../features/activity/helpers/tx-history-transformer.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/browser-extension-wallet/src/utils/tx-inspection.ts b/apps/browser-extension-wallet/src/utils/tx-inspection.ts index 23f169980..f9ceba29b 100644 --- a/apps/browser-extension-wallet/src/utils/tx-inspection.ts +++ b/apps/browser-extension-wallet/src/utils/tx-inspection.ts @@ -9,7 +9,7 @@ import { totalAddressOutputsValueInspector } from '@cardano-sdk/core'; import { Wallet } from '@lace/cardano'; -import { ActivityType } from '@lace/core'; +import { ActivityType, TransactionActivityType } from '@lace/core'; import { TxDirection, TxDirections } from '@src/types'; const hasWalletStakeAddress = ( diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts index 718cd3252..18e32e820 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts @@ -2,7 +2,7 @@ import { TxTransformerInput, txTransformer } from './common-tx-transformer'; import { Wallet } from '@lace/cardano'; import type { TransformedActivity } from './types'; import { TxDirections } from '@types'; -import { ActivityType } from '@lace/core'; +import type { TransactionActivityType } from '@lace/core'; interface TxHistoryTransformerInput extends Omit { tx: Wallet.TxInFlight; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts index fc68a382a..fe2d60a98 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts @@ -2,7 +2,7 @@ import { Wallet } from '@lace/cardano'; import { getTxDirection, inspectTxType } from '@src/utils/tx-inspection'; import { txTransformer, TxTransformerInput } from './common-tx-transformer'; import type { TransformedActivity } from './types'; -import { TransactionActivityType } from '@lace/core'; +import type { TransactionActivityType } from '@lace/core'; interface TxHistoryTransformerInput extends Omit { tx: Wallet.Cardano.HydratedTx; From f512ca369e7dc2021c763360b4db00455aba70a1 Mon Sep 17 00:00:00 2001 From: refi93 Date: Thu, 19 Oct 2023 10:31:05 +0200 Subject: [PATCH 11/31] refactor(all): rename _TransactionDetails to _TransactionDetailsProxy --- .../features/activity/components/ActivityDetail.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index 7a8857ea9..fa0c0b9a7 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -91,15 +91,15 @@ const getTypeLabel = (type: ActivityType, t: ReturnType['t' return t('package.core.transactionDetailBrowser.sent'); }; -type _TransactionDetailsProps = { +type TransactionDetailsProxyProps = { name: string; activityInfo: TransactionActivityDetail; direction: TxDirection; status: ActivityStatus; amountTransformer: (amount: string) => string; }; -const _TransactionDetails = withAddressBookContext<_TransactionDetailsProps>( - ({ name, activityInfo, direction, status, amountTransformer }: _TransactionDetailsProps): ReactElement => { +const TransactionDetailsProxy = withAddressBookContext( + ({ name, activityInfo, direction, status, amountTransformer }: TransactionDetailsProxyProps): ReactElement => { const analytics = useAnalyticsContext(); const { walletInfo, @@ -232,8 +232,7 @@ export const ActivityDetail = ({ price }: ActivityDetailProps): ReactElement => rewards={activityInfo.activity.rewards} /> ) : ( - // eslint-disable-next-line react/jsx-pascal-case - <_TransactionDetails + Date: Thu, 19 Oct 2023 15:52:42 +0200 Subject: [PATCH 12/31] fix(all): fix wallet activity unit tests --- .../src/utils/mocks/test-helpers.tsx | 5 ++++- .../helpers/__tests__/pending-tx-transformer.test.ts | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx b/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx index c9df42a62..ae4d125cd 100644 --- a/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx +++ b/apps/browser-extension-wallet/src/utils/mocks/test-helpers.tsx @@ -109,7 +109,10 @@ export const mockInMemoryWallet = { slot: 1 } }), - assetInfo$: of([]) + assetInfo$: of([]), + delegation: { + rewardsHistory$: of([]) + } } as unknown as Wallet.ObservableWallet; export const mockWalletUI = { diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/pending-tx-transformer.test.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/pending-tx-transformer.test.ts index 62a80e0bc..5ca67babd 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/pending-tx-transformer.test.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/__tests__/pending-tx-transformer.test.ts @@ -118,6 +118,7 @@ describe('Testing tx transformers utils', () => { } ], assetsNumber: 2, + date, formattedDate: 'Sending', formattedTimestamp: formatTime({ date, From f36ac675855a759132b13e4ed63c2c2b0ef0c55b Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 15:07:54 +0200 Subject: [PATCH 13/31] fix(all): code review fixes --- ....scss => ActivityDetailHeader.module.scss} | 0 ...erBrowser.tsx => ActivityDetailHeader.tsx} | 8 +- .../ActivityDetail/ActivityTypeIcon.tsx | 2 +- .../ActivityDetail/RewardsDetails.tsx | 6 +- .../ActivityDetail/TransactionDetails.tsx | 6 +- .../src/ui/components/ActivityDetail/index.ts | 4 +- .../src/assert/transactionDetailsAssert.ts | 116 +++++++++--------- .../e2e-tests/src/steps/transactionsSteps.ts | 18 +-- 8 files changed, 81 insertions(+), 79 deletions(-) rename packages/core/src/ui/components/ActivityDetail/{ActivityDetailHeaderBrowser.module.scss => ActivityDetailHeader.module.scss} (100%) rename packages/core/src/ui/components/ActivityDetail/{ActivityDetailHeaderBrowser.tsx => ActivityDetailHeader.tsx} (74%) diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeaderBrowser.module.scss b/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeader.module.scss similarity index 100% rename from packages/core/src/ui/components/ActivityDetail/ActivityDetailHeaderBrowser.module.scss rename to packages/core/src/ui/components/ActivityDetail/ActivityDetailHeader.module.scss diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeaderBrowser.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeader.tsx similarity index 74% rename from packages/core/src/ui/components/ActivityDetail/ActivityDetailHeaderBrowser.tsx rename to packages/core/src/ui/components/ActivityDetail/ActivityDetailHeader.tsx index 7185f8722..4730ac5e2 100644 --- a/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeaderBrowser.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeader.tsx @@ -1,19 +1,19 @@ import React from 'react'; import { ReactComponent as Info } from '../../assets/icons/info.component.svg'; import { Tooltip } from 'antd'; -import styles from './ActivityDetailHeaderBrowser.module.scss'; +import styles from './ActivityDetailHeader.module.scss'; -export interface ActivityDetailHeaderBrowserProps { +export interface ActivityDetailHeaderProps { name: string; description: string; tooltipContent?: string; } -export const ActivityDetailHeaderBrowser = ({ +export const ActivityDetailHeader = ({ name, description, tooltipContent -}: ActivityDetailHeaderBrowserProps): React.ReactElement => ( +}: ActivityDetailHeaderProps): React.ReactElement => (
{name}
diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx index b27a35732..d38e89f86 100644 --- a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { ActivityType } from './ActivityType'; +import { ActivityType } from './activityType'; import { ReactComponent as OutgoingIcon } from '../../assets/icons/outgoing.component.svg'; import { ReactComponent as IncomingIcon } from '../../assets/icons/incoming.component.svg'; import { ReactComponent as SelfIcon } from '../../assets/icons/self-transaction.component.svg'; diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index 589c4a350..cc044fdcc 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -3,9 +3,9 @@ import cn from 'classnames'; import styles from './TransactionDetails.module.scss'; import { useTranslate } from '@src/ui/hooks'; import { ActivityStatus } from '../Activity/AssetActivityItem'; -import type { RewardsInfo } from './RewardsInfo'; +import type { RewardsInfo } from './rewardsInfo'; import { Ellipsis } from '@lace/common'; -import { ActivityDetailHeaderBrowser } from './ActivityDetailHeaderBrowser'; +import { ActivityDetailHeader } from './ActivityDetailHeader'; export interface RewardsDetailsProps { name: string; @@ -34,7 +34,7 @@ export const RewardsDetails = ({ return (
- +
{t('package.core.transactionDetailBrowser.header')}

{t('package.core.transactionDetailBrowser.summary')}

diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index 4a75ec05e..8c308d4e0 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -12,8 +12,8 @@ import { ReactComponent as Info } from '../../assets/icons/info-icon.component.s import { TransactionInputOutput } from './TransactionInputOutput'; import { useTranslate } from '@src/ui/hooks'; import CopyToClipboard from 'react-copy-to-clipboard'; -import type { RewardsInfo } from './RewardsInfo'; -import { ActivityDetailHeaderBrowser } from './ActivityDetailHeaderBrowser'; +import type { RewardsInfo } from './rewardsInfo'; +import { ActivityDetailHeader } from './ActivityDetailHeader'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const displayMetadataMsg = (value: any[]): string => value?.find((val: any) => val.hasOwnProperty('msg'))?.msg || ''; @@ -132,7 +132,7 @@ export const TransactionDetails = ({ return (
- +
{t('package.core.transactionDetailBrowser.header')} diff --git a/packages/core/src/ui/components/ActivityDetail/index.ts b/packages/core/src/ui/components/ActivityDetail/index.ts index f2f069340..d2ea6a99c 100644 --- a/packages/core/src/ui/components/ActivityDetail/index.ts +++ b/packages/core/src/ui/components/ActivityDetail/index.ts @@ -1,7 +1,7 @@ export * from './TransactionDetails'; export * from './RewardsDetails'; -export * from './ActivityType'; +export * from './activityType'; export * from './ActivityTypeIcon'; export * from './TransactionDetailAsset'; export * from './TransactionInputOutput'; -export * from './RewardsInfo'; +export * from './rewardsInfo'; diff --git a/packages/e2e-tests/src/assert/transactionDetailsAssert.ts b/packages/e2e-tests/src/assert/transactionDetailsAssert.ts index 62688bd9e..d606d2b2b 100644 --- a/packages/e2e-tests/src/assert/transactionDetailsAssert.ts +++ b/packages/e2e-tests/src/assert/transactionDetailsAssert.ts @@ -1,5 +1,5 @@ import TransactionsPage from '../elements/transactionsPage'; -import ActivityDetailsPage from '../elements/transactionDetails'; +import TransactionDetailsPage from '../elements/transactionDetails'; import { expect } from 'chai'; import testContext from '../utils/testContext'; import { browser } from '@wdio/globals'; @@ -30,37 +30,39 @@ class TransactionsDetailsAssert { }; async assertSeeActivityDetailsDrawer(shouldBeDisplayed: boolean) { - await ActivityDetailsPage.transactionDetails.waitForDisplayed({ reverse: !shouldBeDisplayed }); - await ActivityDetailsPage.transactionHeader.waitForDisplayed({ reverse: !shouldBeDisplayed }); + await TransactionDetailsPage.transactionDetails.waitForDisplayed({ reverse: !shouldBeDisplayed }); + await TransactionDetailsPage.transactionHeader.waitForDisplayed({ reverse: !shouldBeDisplayed }); if (shouldBeDisplayed) { - expect(await ActivityDetailsPage.transactionHeader.getText()).to.equal( + expect(await TransactionDetailsPage.transactionHeader.getText()).to.equal( await t('package.core.transactionDetailBrowser.header') ); } } async assertSeeActivityDetails(expectedActivityDetails: ExpectedActivityDetails) { - await ActivityDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); + await TransactionDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); - expect(await ActivityDetailsPage.transactionDetailsDescription.getText()).contains( + expect(await TransactionDetailsPage.transactionDetailsDescription.getText()).contains( `${expectedActivityDetails.transactionDescription}` ); if (expectedActivityDetails.hash) { - expect(await ActivityDetailsPage.transactionDetailsHash.getText()).to.equal(String(expectedActivityDetails.hash)); + expect(await TransactionDetailsPage.transactionDetailsHash.getText()).to.equal( + String(expectedActivityDetails.hash) + ); } - expect(await ActivityDetailsPage.transactionDetailsStatus.getText()).to.equal(expectedActivityDetails.status); + expect(await TransactionDetailsPage.transactionDetailsStatus.getText()).to.equal(expectedActivityDetails.status); if (expectedActivityDetails.transactionData) { for (let i = 0; i < expectedActivityDetails.transactionData.length; i++) { if (expectedActivityDetails.transactionData[i].assets) { - const actualAssets = await ActivityDetailsPage.getTransactionSentTokensForBundle(i); + const actualAssets = await TransactionDetailsPage.getTransactionSentTokensForBundle(i); expect(actualAssets.toString()).to.equal(String(expectedActivityDetails.transactionData[i].assets)); } - expect(await ActivityDetailsPage.transactionDetailsSentAda(i).getText()).to.equal( + expect(await TransactionDetailsPage.transactionDetailsSentAda(i).getText()).to.equal( expectedActivityDetails.transactionData[i].ada ); const expectedAddress = expectedActivityDetails.transactionData[i].address; - const actualAddressSplit = (await ActivityDetailsPage.transactionDetailsToAddress(i).getText()).split('...'); + const actualAddressSplit = (await TransactionDetailsPage.transactionDetailsToAddress(i).getText()).split('...'); if (actualAddressSplit.length === 1) { expect(expectedAddress).to.equal(actualAddressSplit[0]); } else { @@ -70,17 +72,17 @@ class TransactionsDetailsAssert { } } if (expectedActivityDetails.poolName) { - expect(await ActivityDetailsPage.transactionDetailsStakepoolName.getText()).to.equal( + expect(await TransactionDetailsPage.transactionDetailsStakepoolName.getText()).to.equal( expectedActivityDetails.poolName ); } if (expectedActivityDetails.poolTicker) { - expect(await ActivityDetailsPage.transactionDetailsStakepoolTicker.getText()).to.equal( + expect(await TransactionDetailsPage.transactionDetailsStakepoolTicker.getText()).to.equal( `(${expectedActivityDetails.poolTicker})` ); } if (expectedActivityDetails.poolID) { - expect(await ActivityDetailsPage.transactionDetailsStakePoolId.getText()).to.equal( + expect(await TransactionDetailsPage.transactionDetailsStakePoolId.getText()).to.equal( expectedActivityDetails.poolID ); } @@ -92,22 +94,22 @@ class TransactionsDetailsAssert { for (let i = 0; i <= rowsNumber && i < 10; i++) { await TransactionsPage.clickOnTransactionRow(i); - await ActivityDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); - await ActivityDetailsPage.transactionDetailsHash.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsStatus.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsTimestamp.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsInputsSection.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsOutputsSection.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsFeeADA.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsFeeFiat.waitForDisplayed(); - const txType = await ActivityDetailsPage.transactionDetailsDescription.getText(); + await TransactionDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); + await TransactionDetailsPage.transactionDetailsHash.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsStatus.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsTimestamp.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsInputsSection.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsOutputsSection.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsFeeADA.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsFeeFiat.waitForDisplayed(); + const txType = await TransactionDetailsPage.transactionDetailsDescription.getText(); if (txType.includes('Delegation')) { - await ActivityDetailsPage.transactionDetailsStakepoolName.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsStakepoolTicker.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsStakePoolId.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsStakepoolName.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsStakepoolTicker.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsStakePoolId.waitForDisplayed(); } - await ActivityDetailsPage.closeActivityDetails(mode); + await TransactionDetailsPage.closeActivityDetails(mode); } } @@ -117,20 +119,20 @@ class TransactionsDetailsAssert { for (let i = 0; i <= rowsNumber && i < 10; i++) { await TransactionsPage.clickOnTransactionRow(i); - await ActivityDetailsPage.transactionDetailsInputsDropdown.click(); - await ActivityDetailsPage.transactionDetailsOutputsDropdown.click(); - await ActivityDetailsPage.transactionDetailsInputAddress.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsInputAdaAmount.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsInputFiatAmount.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsInputsDropdown.click(); + await TransactionDetailsPage.transactionDetailsOutputsDropdown.click(); + await TransactionDetailsPage.transactionDetailsInputAddress.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsInputAdaAmount.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsInputFiatAmount.waitForDisplayed(); // TODO refactor steps below // some transactions (ADA only) don't have this field - // await ActivityDetailsPage.transactionDetailsInputTokens.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsOutputAddress.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsOutputAdaAmount.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsOutputFiatAmount.waitForDisplayed(); - // await ActivityDetailsPage.transactionDetailsOutputTokens.waitForDisplayed(); + // await TransactionDetailsPage.transactionDetailsInputTokens.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsOutputAddress.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsOutputAdaAmount.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsOutputFiatAmount.waitForDisplayed(); + // await TransactionDetailsPage.transactionDetailsOutputTokens.waitForDisplayed(); - await ActivityDetailsPage.closeActivityDetails(mode); + await TransactionDetailsPage.closeActivityDetails(mode); } } @@ -140,25 +142,25 @@ class TransactionsDetailsAssert { for (let i = 0; i <= rowsNumber && i < 10; i++) { await TransactionsPage.clickOnTransactionRow(i); - await ActivityDetailsPage.transactionDetailsInputsDropdown.click(); - await ActivityDetailsPage.transactionDetailsOutputsDropdown.click(); + await TransactionDetailsPage.transactionDetailsInputsDropdown.click(); + await TransactionDetailsPage.transactionDetailsOutputsDropdown.click(); - const txDetailsInputADAValueString = await ActivityDetailsPage.transactionDetailsInputAdaAmount.getText(); + const txDetailsInputADAValueString = await TransactionDetailsPage.transactionDetailsInputAdaAmount.getText(); const txDetailsInputADAValue = Number(txDetailsInputADAValueString.split(' ', 1)); - const txDetailsInputFiatValueString = await ActivityDetailsPage.transactionDetailsInputFiatAmount.getText(); + const txDetailsInputFiatValueString = await TransactionDetailsPage.transactionDetailsInputFiatAmount.getText(); const txDetailsInputFiatValue = Number(txDetailsInputFiatValueString.slice(1).split(' ', 1)); - const txDetailsOutputADAValueString = await ActivityDetailsPage.transactionDetailsOutputAdaAmount.getText(); + const txDetailsOutputADAValueString = await TransactionDetailsPage.transactionDetailsOutputAdaAmount.getText(); const txDetailsOutputADAValue = Number(txDetailsOutputADAValueString.split(' ', 1)); - const txDetailsOutputFiatValueString = await ActivityDetailsPage.transactionDetailsOutputFiatAmount.getText(); + const txDetailsOutputFiatValueString = await TransactionDetailsPage.transactionDetailsOutputFiatAmount.getText(); const txDetailsOutputFiatValue = Number(txDetailsOutputFiatValueString.slice(1).split(' ', 1)); - const txDetailsFeeADAValueString = await ActivityDetailsPage.transactionDetailsFeeADA.getText(); + const txDetailsFeeADAValueString = await TransactionDetailsPage.transactionDetailsFeeADA.getText(); const txDetailsFeeADAValue = Number(txDetailsFeeADAValueString.split(' ', 1)); - const txDetailsFeeFiatValueString = await ActivityDetailsPage.transactionDetailsFeeFiat.getText(); + const txDetailsFeeFiatValueString = await TransactionDetailsPage.transactionDetailsFeeFiat.getText(); const txDetailsFeeFiatValue = Number(txDetailsFeeFiatValueString.slice(1).split(' ', 1)); expect(txDetailsInputADAValue).to.be.greaterThan(0); @@ -168,7 +170,7 @@ class TransactionsDetailsAssert { expect(txDetailsFeeADAValue).to.be.greaterThan(0); expect(txDetailsFeeFiatValue).to.be.greaterThan(0); - await ActivityDetailsPage.closeActivityDetails(mode); + await TransactionDetailsPage.closeActivityDetails(mode); } } @@ -179,17 +181,17 @@ class TransactionsDetailsAssert { for (let i = 0; i <= rowsNumber && i < 10; i++) { const transactionType = await TransactionsPage.transactionsTableItemType(i).getText(); await TransactionsPage.clickOnTransactionRow(i); - await ActivityDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); + await TransactionDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); if ( !['Delegation', 'Stake Key De-Registration', 'Stake Key Registration', 'Self Transaction'].includes( transactionType ) ) { - await ActivityDetailsPage.transactionDetailsSent.waitForDisplayed(); - await ActivityDetailsPage.transactionDetailsToAddress(0).waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsSent.waitForDisplayed(); + await TransactionDetailsPage.transactionDetailsToAddress(0).waitForDisplayed(); } - await ActivityDetailsPage.closeActivityDetails(mode); + await TransactionDetailsPage.closeActivityDetails(mode); } } @@ -201,23 +203,23 @@ class TransactionsDetailsAssert { // TODO Cover self transaction details with automation if ((await TransactionsPage.transactionsTableItemType(i).getText()) !== 'Self Transaction') { await TransactionsPage.clickOnTransactionRow(i); - await ActivityDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); - const txType = await ActivityDetailsPage.transactionDetailsDescription.getText(); + await TransactionDetailsPage.transactionDetailsDescription.waitForClickable({ timeout: 15_000 }); + const txType = await TransactionDetailsPage.transactionDetailsDescription.getText(); if (!txType.includes('Delegation')) { const tokensAmountSummary = - (await ActivityDetailsPage.getTransactionSentTokensWithoutDuplicates()).length + 1; - let tokensDescriptionAmount = await ActivityDetailsPage.transactionDetailsAmountOfTokens.getText(); + (await TransactionDetailsPage.getTransactionSentTokensWithoutDuplicates()).length + 1; + let tokensDescriptionAmount = await TransactionDetailsPage.transactionDetailsAmountOfTokens.getText(); tokensDescriptionAmount = tokensDescriptionAmount.replace('(', '').replace(')', ''); expect(tokensAmountSummary).to.equal(Number(tokensDescriptionAmount)); } - await ActivityDetailsPage.closeActivityDetails(mode); + await TransactionDetailsPage.closeActivityDetails(mode); } } } async assertTxMetadata() { - const currentMetadata = await ActivityDetailsPage.transactionDetailsMetadata.getText(); + const currentMetadata = await TransactionDetailsPage.transactionDetailsMetadata.getText(); expect(currentMetadata).to.equal(testContext.load('metadata')); } } diff --git a/packages/e2e-tests/src/steps/transactionsSteps.ts b/packages/e2e-tests/src/steps/transactionsSteps.ts index e321a45ed..d83f24b10 100644 --- a/packages/e2e-tests/src/steps/transactionsSteps.ts +++ b/packages/e2e-tests/src/steps/transactionsSteps.ts @@ -5,7 +5,7 @@ import mainMenuPageObject from '../pageobject/mainMenuPageObject'; import transactionBundleAssert from '../assert/transaction/transactionBundleAssert'; import NewTransactionExtendedPageObject from '../pageobject/newTransactionExtendedPageObject'; import testContext from '../utils/testContext'; -import ActivityDetailsPage from '../elements/transactionDetails'; +import TransactionDetailsPage from '../elements/transactionDetails'; import simpleTxSideDrawerPageObject from '../pageobject/simpleTxSideDrawerPageObject'; import TransactionsPage from '../elements/transactionsPage'; @@ -53,12 +53,12 @@ When(/^I click on a transaction: (\d)$/, async (rowNumber: number) => { }); When(/^I click on a transaction hash and save hash information$/, async () => { - testContext.save('txHashValue', await ActivityDetailsPage.transactionDetailsHash.getText()); - await ActivityDetailsPage.transactionDetailsHash.click(); + testContext.save('txHashValue', await TransactionDetailsPage.transactionDetailsHash.getText()); + await TransactionDetailsPage.transactionDetailsHash.click(); }); When(/^I click on a transaction hash$/, async () => { - await ActivityDetailsPage.transactionDetailsHash.click(); + await TransactionDetailsPage.transactionDetailsHash.click(); }); Then(/^I see cexplorer url with correct transaction hash$/, async () => { @@ -74,12 +74,12 @@ When( let actualValue; let expectedValue; await TransactionsPage.clickOnTransactionRow(i); - await ActivityDetailsPage.transactionDetailsSkeleton.waitForDisplayed({ timeout: 30_000, reverse: true }); + await TransactionDetailsPage.transactionDetailsSkeleton.waitForDisplayed({ timeout: 30_000, reverse: true }); if (valueForCheck === 'hash') { - actualValue = await ActivityDetailsPage.transactionDetailsHash.getText(); + actualValue = await TransactionDetailsPage.transactionDetailsHash.getText(); expectedValue = String(testContext.load('txHashValue')); } else { - actualValue = await ActivityDetailsPage.transactionDetailsStakePoolId.getText(); + actualValue = await TransactionDetailsPage.transactionDetailsStakePoolId.getText(); expectedValue = String(testContext.load('poolID')); } if (actualValue !== expectedValue) { @@ -108,11 +108,11 @@ When(/^I click on a transaction and click on both dropdowns$/, async () => { }); When(/^I click on inputs dropdowns$/, async () => { - ActivityDetailsPage.clickInputsDropdown(); + TransactionDetailsPage.clickInputsDropdown(); }); When(/^I click on outputs dropdowns$/, async () => { - ActivityDetailsPage.clickOutputsDropdown(); + TransactionDetailsPage.clickOutputsDropdown(); }); Then( From 07392350e9ccdef1f969e5fd0117e0f55e704528 Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 15:09:16 +0200 Subject: [PATCH 14/31] fix(all): make rewards in RewardsDetails component non-optional --- .../src/ui/components/ActivityDetail/RewardsDetails.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index cc044fdcc..fd45fe3d6 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -15,7 +15,7 @@ export interface RewardsDetailsProps { includedTime?: string; amountTransformer: (amount: string) => string; coinSymbol: string; - rewards?: RewardsInfo; + rewards: RewardsInfo; } export const RewardsDetails = ({ @@ -29,7 +29,7 @@ export const RewardsDetails = ({ rewards }: RewardsDetailsProps): React.ReactElement => { const { t } = useTranslate(); - const poolRewards = rewards?.rewards.filter((reward) => !!reward.pool); + const poolRewards = rewards.rewards.filter((reward) => !!reward.pool); const tooltipContent = t('package.core.transactionDetailBrowser.rewardsDescription'); return ( @@ -62,7 +62,7 @@ export const RewardsDetails = ({ {t('package.core.transactionDetailBrowser.pools')}
- {poolRewards?.map(({ pool, amount }) => ( + {poolRewards.map(({ pool, amount }) => (
{pool.name && ( From 701c2846b2f985eb0318ee631bc2776603f063cd Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 16:35:47 +0200 Subject: [PATCH 15/31] refactor(all): remove redundant props from Activity UI components --- .../stores/slices/wallet-activities-slice.ts | 48 ++++++++------- .../activity/helpers/common-tx-transformer.ts | 8 +-- .../helpers/pending-tx-transformer.ts | 5 +- .../helpers/reward-history-transformer.ts | 6 +- .../helpers/tx-history-transformer.ts | 5 +- .../features/activity/helpers/types.ts | 58 ++++++++++++++++++- .../__tests__/AssetDetails.test.tsx | 12 ---- .../components/Activity/AssetActivityItem.tsx | 17 +----- .../__tests__/AssetActivityItem.test.tsx | 3 - .../GroupedAssetActivityList.test.tsx | 2 - .../ActivityDetail/RewardsDetails.tsx | 2 +- .../ActivityDetail/TransactionDetails.tsx | 2 - 12 files changed, 97 insertions(+), 71 deletions(-) diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index 44f480b15..d5199dbf9 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -12,13 +12,14 @@ import { txHistoryTransformer, filterOutputsByTxDirection, isTxWithAssets, - TransformedActivity + TransformedActivity, + TransformedTransactionActivity } from '@src/views/browser-view/features/activity/helpers'; import { - AssetActivityItemProps, - AssetActivityListProps, ActivityAssetProp, ActivityStatus, + AssetActivityItemProps, + AssetActivityListProps, TransactionActivityType } from '@lace/core'; import { CurrencyInfo, TxDirections } from '@src/types'; @@ -57,7 +58,11 @@ interface FetchWalletActivitiesPropsWithSetter extends FetchWalletActivitiesProp set: SetState; } -export type FetchWalletActivitiesReturn = Observable>; +type ExtendedActivityProps = TransformedActivity & AssetActivityItemProps; +type MappedActivityListProps = Omit & { + items: ExtendedActivityProps[]; +}; +export type FetchWalletActivitiesReturn = Observable>; export type DelegationTransactionType = Extract< TransactionActivityType, 'delegation' | 'delegationRegistration' | 'delegationDeregistration' @@ -69,11 +74,11 @@ const delegationTransactionTypes: ReadonlySet = new S 'delegationDeregistration' ]); -type DelegationActivityItemProps = Omit & { +type DelegationActivityItemProps = Omit & { type: DelegationTransactionType; }; -const isDelegationActivity = (activity: AssetActivityItemProps): activity is DelegationActivityItemProps => +const isDelegationActivity = (activity: ExtendedActivityProps): activity is DelegationActivityItemProps => delegationTransactionTypes.has(activity.type as DelegationTransactionType); const getDelegationAmount = (activity: DelegationActivityItemProps) => { @@ -129,7 +134,7 @@ const getWalletActivitiesObservable = async ({ const historicTransactionMapper = ( tx: Wallet.Cardano.HydratedTx, eraSummaries: EraSummary[] - ): Array => { + ): Array => { const slotTimeCalc = Wallet.createSlotTimeCalc(eraSummaries); const date = slotTimeCalc(tx.blockHeader.slot); const transformedTransaction = txHistoryTransformer({ @@ -142,7 +147,7 @@ const getWalletActivitiesObservable = async ({ cardanoCoin }); - const extendWithClickHandler = (transformedTx: TransformedActivity & { type: TransactionActivityType }) => ({ + const extendWithClickHandler = (transformedTx: TransformedTransactionActivity) => ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); @@ -161,7 +166,7 @@ const getWalletActivitiesObservable = async ({ const pendingTransactionMapper = ( tx: Wallet.TxInFlight, eraSummaries: EraSummary[] - ): Array => { + ): Array => { let date; try { const slotTimeCalc = Wallet.createSlotTimeCalc(eraSummaries); @@ -179,7 +184,7 @@ const getWalletActivitiesObservable = async ({ date }); - const extendWithClickHandler = (transformedTx: TransformedActivity & { type: TransactionActivityType }) => ({ + const extendWithClickHandler = (transformedTx: TransformedTransactionActivity) => ({ ...transformedTx, onClick: () => { if (sendAnalytics) sendAnalytics(); @@ -200,7 +205,7 @@ const getWalletActivitiesObservable = async ({ earnedEpoch: EpochNo, rewards: Reward[], eraSummaries: EraSummary[] - ): AssetActivityItemProps => { + ): ExtendedActivityProps => { const REWARD_SPENDABLE_DELAY_EPOCHS = 2; const spendableEpoch = (earnedEpoch + REWARD_SPENDABLE_DELAY_EPOCHS) as EpochNo; const slotTimeCalc = Wallet.createSlotTimeCalc(eraSummaries); @@ -301,7 +306,7 @@ const getWalletActivitiesObservable = async ({ ); return [...filteredPendingTxs, ...confirmedTxs, ...rewards]; }), - map(async (allTransactions: Promise) => + map(async (allTransactions) => (await allTransactions).sort((firstTx, secondTx) => { // ensure pending txs are always first if (firstTx.status === ActivityStatus.PENDING && secondTx.status !== ActivityStatus.PENDING) return 1; @@ -310,14 +315,15 @@ const getWalletActivitiesObservable = async ({ return secondTx.date.getTime() - firstTx.date.getTime(); }) ), - map(async (allTransactions: Promise) => groupBy(await allTransactions, 'formattedDate')), - map(async (lists) => - Object.entries(await lists).map(([listName, transactionsList]) => ({ - title: listName, - items: transactionsList - })) + map(async (allTransactions) => groupBy(await allTransactions, 'formattedDate')), + map( + async (lists): Promise => + Object.entries(await lists).map(([listName, transactionsList]) => ({ + title: listName, + items: transactionsList + })) ), - tap(async (allActivities: Promise) => { + tap(async (allActivities) => { const activities = await allActivities; const flattenedActivities = flattenDeep(activities.map(({ items }: AssetActivityListProps) => items)); const allAssetsIds = uniq( @@ -335,9 +341,9 @@ const getWalletActivitiesObservable = async ({ } }); - const walletActivities = activities.map((activityList: AssetActivityListProps) => ({ + const walletActivities = activities.map((activityList) => ({ ...activityList, - items: activityList.items.map((activity: AssetActivityItemProps) => ({ + items: activityList.items.map((activity) => ({ ...activity, ...(isDelegationActivity(activity) && { amount: `${getDelegationAmount(activity)} ${cardanoCoin.symbol}`, diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts index 53df6bbf4..f2750b670 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts @@ -3,8 +3,8 @@ import { Wallet } from '@lace/cardano'; import { CurrencyInfo, TxDirections } from '@types'; import { inspectTxValues, inspectTxType } from '@src/utils/tx-inspection'; import { formatDate, formatTime } from '@src/utils/format-date'; -import type { TransformedActivity } from './types'; -import { ActivityStatus, TransactionActivityType } from '@lace/core'; +import type { TransformedActivity, TransformedTransactionActivity } from './types'; +import { ActivityStatus } from '@lace/core'; import capitalize from 'lodash/capitalize'; import dayjs from 'dayjs'; import { assertUnreachable } from '@src/utils/assert-unreachable'; @@ -36,7 +36,7 @@ export const getFormattedFiatAmount = ({ return fiatAmount ? `${fiatAmount} ${fiatCurrency.code}` : '-'; }; -const splitDelegationTx = (tx: TransformedActivity): (TransformedActivity & { type: TransactionActivityType })[] => { +const splitDelegationTx = (tx: TransformedActivity): TransformedTransactionActivity[] => { if (tx.deposit) { return [ { @@ -114,7 +114,7 @@ export const txTransformer = ({ date, direction, status -}: TxTransformerInput): (TransformedActivity & { type: TransactionActivityType })[] => { +}: TxTransformerInput): TransformedTransactionActivity[] => { const implicitCoin = Wallet.Cardano.util.computeImplicitCoin(protocolParameters, tx.body); const deposit = implicitCoin.deposit ? Wallet.util.lovelacesToAdaString(implicitCoin.deposit.toString()) : undefined; const depositReclaimValue = Wallet.util.calculateDepositReclaim(implicitCoin); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts index 18e32e820..ba811a87d 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/pending-tx-transformer.ts @@ -1,8 +1,7 @@ import { TxTransformerInput, txTransformer } from './common-tx-transformer'; import { Wallet } from '@lace/cardano'; -import type { TransformedActivity } from './types'; +import type { TransformedTransactionActivity } from './types'; import { TxDirections } from '@types'; -import type { TransactionActivityType } from '@lace/core'; interface TxHistoryTransformerInput extends Omit { tx: Wallet.TxInFlight; @@ -16,7 +15,7 @@ export const pendingTxTransformer = ({ protocolParameters, cardanoCoin, date -}: TxHistoryTransformerInput): (TransformedActivity & { type: TransactionActivityType })[] => +}: TxHistoryTransformerInput): TransformedTransactionActivity[] => txTransformer({ tx, walletAddresses, diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts index 151fef733..a08f6c785 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/reward-history-transformer.ts @@ -1,12 +1,12 @@ import { Wallet } from '@lace/cardano'; import { getFormattedFiatAmount } from './common-tx-transformer'; -import type { TransformedActivity } from './types'; +import type { TransformedRewardsActivity } from './types'; import dayjs from 'dayjs'; import { formatDate, formatTime } from '@src/utils/format-date'; import BigNumber from 'bignumber.js'; import type { CurrencyInfo } from '@src/types'; import type { Reward } from '@cardano-sdk/core'; -import { ActivityStatus, RewardsActivityType } from '@lace/core'; +import { ActivityStatus } from '@lace/core'; interface RewardHistoryTransformerInput { rewards: Reward[]; // TODO this supposes rewards grouped by epoch which is a bit fragile @@ -22,7 +22,7 @@ export const rewardHistoryTransformer = ({ fiatPrice, date, cardanoCoin -}: RewardHistoryTransformerInput): TransformedActivity & { type: RewardsActivityType } => { +}: RewardHistoryTransformerInput): TransformedRewardsActivity => { const formattedTimestamp = formatTime({ date, type: 'local' diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts index fe2d60a98..aa6338004 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/tx-history-transformer.ts @@ -1,8 +1,7 @@ import { Wallet } from '@lace/cardano'; import { getTxDirection, inspectTxType } from '@src/utils/tx-inspection'; import { txTransformer, TxTransformerInput } from './common-tx-transformer'; -import type { TransformedActivity } from './types'; -import type { TransactionActivityType } from '@lace/core'; +import type { TransformedTransactionActivity } from './types'; interface TxHistoryTransformerInput extends Omit { tx: Wallet.Cardano.HydratedTx; @@ -16,7 +15,7 @@ export const txHistoryTransformer = ({ date, protocolParameters, cardanoCoin -}: TxHistoryTransformerInput): (TransformedActivity & { type: TransactionActivityType })[] => { +}: TxHistoryTransformerInput): TransformedTransactionActivity[] => { const type = inspectTxType({ walletAddresses, tx }); const direction = getTxDirection({ type }); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/types.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/types.ts index 5055b9bd2..6a08ada9e 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/types.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/types.ts @@ -1,3 +1,57 @@ -import type { AssetActivityItemProps } from '@lace/core'; +import type { + ActivityAssetProp, + ActivityStatus, + ActivityType, + RewardsActivityType, + TransactionActivityType +} from '@lace/core'; -export type TransformedActivity = Omit; +export type TransformedActivity = { + id?: string; + fee?: string; + deposit?: string; // e.g. stake registrations + depositReclaim?: string; // e.g. stake de-registrations + /** + * Amount formated with symbol (e.g. 50 ADA) + */ + amount: string; + /** + * Date of the activity + */ + date: Date; + /** + * Amount in Fiat currency (e.g. 125$) + */ + fiatAmount: string; + /** + * Activity status: `sending` | `success` | 'error + */ + status?: ActivityStatus; + /** + * Activity or asset custom icon + */ + customIcon?: string; + /** + * Activity type + */ + type?: ActivityType; + /** + * Number of assets (default: 1) + */ + assetsNumber?: number; + formattedDate: string; + formattedTimestamp: string; + /** + * Direction: 'Incoming' | 'Outgoing' | 'Self' + * TODO: Create a separate package for common types across apps/packages + */ + direction?: 'Incoming' | 'Outgoing' | 'Self'; + /** + * assets details + */ + assets?: ActivityAssetProp[]; +}; + +export type TransformedTransactionActivity = TransformedActivity & { type: TransactionActivityType }; + +export type TransformedRewardsActivity = TransformedActivity & { type: RewardsActivityType }; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx index 12a629f03..6ea8a26af 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/assets/components/AssetDetailsDrawer/__tests__/AssetDetails.test.tsx @@ -60,15 +60,11 @@ describe('AssetDetails', () => { { amount: '100', fiatAmount: '450', - date: new Date('2021-01-01'), - formattedDate: 'Date', formattedTimestamp: 'Timestamp' }, { amount: '200', fiatAmount: '400', - date: new Date('2021-01-01'), - formattedDate: 'Date', formattedTimestamp: 'Timestamp' } ]} @@ -90,15 +86,11 @@ describe('AssetDetails', () => { { amount: '100', fiatAmount: '450', - date: new Date('2021-01-01'), - formattedDate: 'Date', formattedTimestamp: 'Timestamp' }, { amount: '200', fiatAmount: '400', - date: new Date('2021-01-01'), - formattedDate: 'Date', formattedTimestamp: 'Timestamp' } ]} @@ -121,15 +113,11 @@ describe('AssetDetails', () => { { amount: '100', fiatAmount: '450', - date: new Date('2021-01-01'), - formattedDate: 'Date', formattedTimestamp: 'Timestamp' }, { amount: '200', fiatAmount: '400', - date: new Date('2021-01-01'), - formattedDate: 'Date', formattedTimestamp: 'Timestamp' } ]} diff --git a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx index 3e6021f6f..c68729016 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx @@ -4,8 +4,8 @@ import debounce from 'lodash/debounce'; import { Image, Tooltip } from 'antd'; import Icon from '@ant-design/icons'; import { getTextWidth } from '@lace/common'; -import { ActivityType } from '@src/ui/components/ActivityDetail/ActivityType'; -import { ActivityTypeIcon } from '@src/ui/components/ActivityDetail/ActivityTypeIcon'; +import { ActivityType } from '@ui/components/ActivityDetail/activityType'; +import { ActivityTypeIcon } from '@ui/components/ActivityDetail/ActivityTypeIcon'; import { ReactComponent as PendingIcon } from '../../assets/icons/pending.component.svg'; import { ReactComponent as ErrorIcon } from '../../assets/icons/error.component.svg'; import styles from './AssetActivityItem.module.scss'; @@ -27,17 +27,10 @@ const DEFAULT_DEBOUNCE = 200; export interface AssetActivityItemProps { id?: string; - fee?: string; - deposit?: string; // e.g. stake registrations - depositReclaim?: string; // e.g. stake de-registrations /** * Amount formated with symbol (e.g. 50 ADA) */ amount: string; - /** - * Date of the activity - */ - date: Date; /** * Amount in Fiat currency (e.g. 125$) */ @@ -62,13 +55,7 @@ export interface AssetActivityItemProps { * Number of assets (default: 1) */ assetsNumber?: number; - formattedDate: string; formattedTimestamp: string; - /** - * Direction: 'Incoming' | 'Outgoing' | 'Self' - * TODO: Create a separate package for common types across apps/packages - */ - direction?: 'Incoming' | 'Outgoing' | 'Self'; /** * assets details */ diff --git a/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx b/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx index 70dc047a3..b42bb1c35 100644 --- a/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx +++ b/packages/core/src/ui/components/Activity/__tests__/AssetActivityItem.test.tsx @@ -9,12 +9,9 @@ const assetsAmountTestId = 'asset-amount'; describe('Testing AssetActivityItem component', () => { const props: AssetActivityItemProps = { id: '1', - fee: '3,40', type: 'outgoing', amount: '100', fiatAmount: '300 $', - date: new Date('2021-01-01'), - formattedDate: 'Date', formattedTimestamp: 'Timestamp', status: ActivityStatus.ERROR, onClick: jest.fn(), diff --git a/packages/core/src/ui/components/Activity/__tests__/GroupedAssetActivityList.test.tsx b/packages/core/src/ui/components/Activity/__tests__/GroupedAssetActivityList.test.tsx index ee6c1ffe3..9d94a228f 100644 --- a/packages/core/src/ui/components/Activity/__tests__/GroupedAssetActivityList.test.tsx +++ b/packages/core/src/ui/components/Activity/__tests__/GroupedAssetActivityList.test.tsx @@ -9,9 +9,7 @@ const activityItem: AssetActivityItemProps = { type: 'outgoing', amount: '100 ADA', fiatAmount: '300 $', - formattedDate: 'FormattedDate', formattedTimestamp: 'FormattedTimestamp', - date: new Date('2021-01-01'), assetsNumber: 1, assets: [{ id: '1', val: '1' }] }; diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index fd45fe3d6..20eaebed9 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -105,7 +105,7 @@ export const RewardsDetails = ({
{t('package.core.transactionDetailBrowser.epoch')}
- {
{`${rewards.spendableEpoch}`}
} +
{`${rewards.spendableEpoch}`}
diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index 8c308d4e0..2c50c89b9 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -12,7 +12,6 @@ import { ReactComponent as Info } from '../../assets/icons/info-icon.component.s import { TransactionInputOutput } from './TransactionInputOutput'; import { useTranslate } from '@src/ui/hooks'; import CopyToClipboard from 'react-copy-to-clipboard'; -import type { RewardsInfo } from './rewardsInfo'; import { ActivityDetailHeader } from './ActivityDetailHeader'; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -65,7 +64,6 @@ export interface TransactionDetailsProps { txSummary?: TxSummary[]; coinSymbol: string; tooltipContent?: string; - rewards?: RewardsInfo; addressToNameMap: Map; isPopupView?: boolean; openExternalLink?: () => void; From 0537051f3c3544a12b4a724c19ff9b09214a8963 Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 16:40:54 +0200 Subject: [PATCH 16/31] refactor(all): rename transaction key for activity details --- .../src/lib/translations/en.json | 2 +- .../activity/components/ActivityDetail.tsx | 14 +++---- .../ActivityDetail/RewardsDetails.tsx | 14 +++---- .../ActivityDetail/TransactionDetails.tsx | 40 +++++++++---------- packages/core/src/ui/lib/translations/en.json | 2 +- .../src/assert/transactionDetailsAssert.ts | 2 +- .../e2e/SendTransactionBundlesE2E.feature | 6 +-- .../e2e/SendTransactionDappE2E.feature | 8 ++-- .../SendTransactionSimpleExtendedE2E.feature | 4 +- .../e2e/SendTransactionSimplePopupE2E.feature | 4 +- .../e2e-tests/src/steps/nftsCommonSteps.ts | 2 +- 11 files changed, 49 insertions(+), 49 deletions(-) diff --git a/apps/browser-extension-wallet/src/lib/translations/en.json b/apps/browser-extension-wallet/src/lib/translations/en.json index 3c9c36a11..ef8c2ebf4 100644 --- a/apps/browser-extension-wallet/src/lib/translations/en.json +++ b/apps/browser-extension-wallet/src/lib/translations/en.json @@ -27,7 +27,7 @@ } } }, - "transactionDetailBrowser": { + "activityDetails": { "address": "Address", "sent": "Sent", "sending": "Sending", diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index fa0c0b9a7..57e16b251 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -83,12 +83,12 @@ interface ActivityDetailProps { } const getTypeLabel = (type: ActivityType, t: ReturnType['t']) => { - if (type === 'rewards') return t('package.core.transactionDetailBrowser.rewards'); - if (type === 'delegation') return t('package.core.transactionDetailBrowser.delegation'); - if (type === 'delegationRegistration') return t('package.core.transactionDetailBrowser.registration'); - if (type === 'delegationDeregistration') return t('package.core.transactionDetailBrowser.deregistration'); - if (type === 'incoming') return t('package.core.transactionDetailBrowser.received'); - return t('package.core.transactionDetailBrowser.sent'); + if (type === 'rewards') return t('package.core.activityDetails.rewards'); + if (type === 'delegation') return t('package.core.activityDetails.delegation'); + if (type === 'delegationRegistration') return t('package.core.activityDetails.registration'); + if (type === 'delegationDeregistration') return t('package.core.activityDetails.deregistration'); + if (type === 'incoming') return t('package.core.activityDetails.received'); + return t('package.core.activityDetails.sent'); }; type TransactionDetailsProxyProps = { @@ -214,7 +214,7 @@ export const ActivityDetail = ({ price }: ActivityDetailProps): ReactElement => const name = activityInfo.status === ActivityStatus.PENDING - ? t('package.core.transactionDetailBrowser.sending') + ? t('package.core.activityDetails.sending') : getTypeLabel(activityInfo.type, t); const amountTransformer = (ada: string) => diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index 20eaebed9..ae6d02e60 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -30,14 +30,14 @@ export const RewardsDetails = ({ }: RewardsDetailsProps): React.ReactElement => { const { t } = useTranslate(); const poolRewards = rewards.rewards.filter((reward) => !!reward.pool); - const tooltipContent = t('package.core.transactionDetailBrowser.rewardsDescription'); + const tooltipContent = t('package.core.activityDetails.rewardsDescription'); return (
-
{t('package.core.transactionDetailBrowser.header')}
-

{t('package.core.transactionDetailBrowser.summary')}

+
{t('package.core.activityDetails.header')}
+

{t('package.core.activityDetails.summary')}

@@ -59,7 +59,7 @@ export const RewardsDetails = ({ {poolRewards.length > 0 && (
- {t('package.core.transactionDetailBrowser.pools')} + {t('package.core.activityDetails.pools')}
{poolRewards.map(({ pool, amount }) => ( @@ -96,7 +96,7 @@ export const RewardsDetails = ({ )}
-
{t('package.core.transactionDetailBrowser.status')}
+
{t('package.core.activityDetails.status')}
{status && (
{`${status.charAt(0).toUpperCase()}${status.slice( 1 @@ -104,12 +104,12 @@ export const RewardsDetails = ({ )}
-
{t('package.core.transactionDetailBrowser.epoch')}
+
{t('package.core.activityDetails.epoch')}
{`${rewards.spendableEpoch}`}
- {t('package.core.transactionDetailBrowser.timestamp')} + {t('package.core.activityDetails.timestamp')}
{includedDate} diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index 2c50c89b9..61592dc05 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -133,12 +133,12 @@ export const TransactionDetails = ({
- {t('package.core.transactionDetailBrowser.header')} + {t('package.core.activityDetails.header')}
-
{t('package.core.transactionDetailBrowser.transactionHash')}
+
{t('package.core.activityDetails.transactionHash')}
{isSending ? ( - + ) : ( hash )} @@ -157,11 +157,11 @@ export const TransactionDetails = ({
-

{t('package.core.transactionDetailBrowser.summary')}

+

{t('package.core.activityDetails.summary')}

{pools?.length > 0 && (
- {t('package.core.transactionDetailBrowser.pools')} + {t('package.core.activityDetails.pools')}
{pools?.map((pool) => ( @@ -218,7 +218,7 @@ export const TransactionDetails = ({
- {t(`package.core.transactionDetailBrowser.${name.toLowerCase() === 'sent' ? 'to' : 'from'}`)} + {t(`package.core.activityDetails.${name.toLowerCase() === 'sent' ? 'to' : 'from'}`)}
{summary.addr.length > 1 && ( @@ -226,7 +226,7 @@ export const TransactionDetails = ({ data-testid="tx-to-detail-multiple-addresses" className={cn(styles.detail, styles.detailTitle)} > - {t('package.core.transactionDetailBrowser.multipleAddresses')} + {t('package.core.activityDetails.multipleAddresses')}
)} {(summary.addr as string[]).map((addr) => { @@ -254,7 +254,7 @@ export const TransactionDetails = ({
))}
-
{t('package.core.transactionDetailBrowser.status')}
+
{t('package.core.activityDetails.status')}
{status && (
{`${status.charAt(0).toUpperCase()}${status.slice( 1 @@ -263,7 +263,7 @@ export const TransactionDetails = ({
- {t('package.core.transactionDetailBrowser.timestamp')} + {t('package.core.activityDetails.timestamp')}
{includedDate} @@ -274,8 +274,8 @@ export const TransactionDetails = ({ {fee && fee !== '-' && (
-
{t('package.core.transactionDetailBrowser.transactionFee')}
- +
{t('package.core.activityDetails.transactionFee')}
+ {Info ? ( ) : ( @@ -296,23 +296,23 @@ export const TransactionDetails = ({ )} {deposit && - renderDepositValueSection({ value: deposit, label: t('package.core.transactionDetailBrowser.deposit') })} + renderDepositValueSection({ value: deposit, label: t('package.core.activityDetails.deposit') })} {depositReclaim && renderDepositValueSection({ value: depositReclaim, - label: t('package.core.transactionDetailBrowser.depositReclaim') + label: t('package.core.activityDetails.depositReclaim') })}
{addrInputs?.length > 0 && ( 0 && ( 0 && (
-
{t('package.core.transactionDetailBrowser.metadata')}
+
{t('package.core.activityDetails.metadata')}
{metadata?.map((item) => (
diff --git a/packages/core/src/ui/lib/translations/en.json b/packages/core/src/ui/lib/translations/en.json index 6dcab838f..c73e862cb 100644 --- a/packages/core/src/ui/lib/translations/en.json +++ b/packages/core/src/ui/lib/translations/en.json @@ -54,7 +54,7 @@ "usedAllAssets": "All gone! You've already selected everything", "noMatchingResult": "No results matching your search" }, - "transactionDetailBrowser": { + "activityDetails": { "address": "Address", "sent": "Sent", "sending": "Sending", diff --git a/packages/e2e-tests/src/assert/transactionDetailsAssert.ts b/packages/e2e-tests/src/assert/transactionDetailsAssert.ts index d606d2b2b..2bf33e7f5 100644 --- a/packages/e2e-tests/src/assert/transactionDetailsAssert.ts +++ b/packages/e2e-tests/src/assert/transactionDetailsAssert.ts @@ -34,7 +34,7 @@ class TransactionsDetailsAssert { await TransactionDetailsPage.transactionHeader.waitForDisplayed({ reverse: !shouldBeDisplayed }); if (shouldBeDisplayed) { expect(await TransactionDetailsPage.transactionHeader.getText()).to.equal( - await t('package.core.transactionDetailBrowser.header') + await t('package.core.activityDetails.header') ); } } diff --git a/packages/e2e-tests/src/features/e2e/SendTransactionBundlesE2E.feature b/packages/e2e-tests/src/features/e2e/SendTransactionBundlesE2E.feature index 74c070c9c..863d332e6 100644 --- a/packages/e2e-tests/src/features/e2e/SendTransactionBundlesE2E.feature +++ b/packages/e2e-tests/src/features/e2e/SendTransactionBundlesE2E.feature @@ -34,7 +34,7 @@ Feature: Send Transaction bundles - E2E When I navigate to Transactions extended page Then the Sent transaction is displayed with value: "4.50 tADA, 0.2333 LaceCoin3, 3 LaceCoin , +1" and tokens count 4 And I click and open recent transactions details until find transaction with correct hash - Then The Tx details are displayed as "package.core.transactionDetailBrowser.sent" for 4 tokens with following details: + Then The Tx details are displayed as "package.core.activityDetails.sent" for 4 tokens with following details: | address | ada | assets | | WalletFirstReceiveBundlesTransactionE2E | 1.34 tADA | 0.2333 LaceCoin3,1 LaceCoin | | WalletSecondReceiveBundlesTransactionE2E | 2.00 tADA | 2 LaceCoin | @@ -45,7 +45,7 @@ Feature: Send Transaction bundles - E2E And I navigate to Transactions extended page Then the Received transaction is displayed with value: "1.34 tADA, 0.2333 LaceCoin3, 1 LaceCoin" and tokens count 3 And I click and open recent transactions details until find transaction with correct hash - Then The Tx details are displayed as "package.core.transactionDetailBrowser.received" for 3 tokens with following details: + Then The Tx details are displayed as "package.core.activityDetails.received" for 3 tokens with following details: | address | ada | assets | | WalletSendBundlesTransactionE2E | 1.34 tADA | 0.2333 LaceCoin3,1 LaceCoin | When I open wallet: "WalletSecondReceiveBundlesTransactionE2E" in: extended mode @@ -53,7 +53,7 @@ Feature: Send Transaction bundles - E2E And I navigate to Transactions extended page Then the Received transaction is displayed with value: "3.16 tADA, 2 LaceCoin, 1 LaceCoin2" and tokens count 3 And I click and open recent transactions details until find transaction with correct hash - Then The Tx details are displayed as "package.core.transactionDetailBrowser.received" for 3 tokens with following details: + Then The Tx details are displayed as "package.core.activityDetails.received" for 3 tokens with following details: | address | ada | assets | | WalletSendBundlesTransactionE2E | 2.00 tADA | 2 LaceCoin | | WalletSendBundlesTransactionE2E | 1.16 tADA | 1 LaceCoin2 | diff --git a/packages/e2e-tests/src/features/e2e/SendTransactionDappE2E.feature b/packages/e2e-tests/src/features/e2e/SendTransactionDappE2E.feature index 717b962a3..da2477a5d 100644 --- a/packages/e2e-tests/src/features/e2e/SendTransactionDappE2E.feature +++ b/packages/e2e-tests/src/features/e2e/SendTransactionDappE2E.feature @@ -24,13 +24,13 @@ Feature: Send Transactions from Dapp - E2E When I navigate to Transactions extended page Then the Sent transaction is displayed with value: "3.00 tADA" and tokens count 1 And I click on a transaction: 1 - Then The Tx details are displayed as "package.core.transactionDetailBrowser.sent" for ADA with value: 3.00 and wallet: "WalletReceiveSimpleTransactionE2E" address + Then The Tx details are displayed as "package.core.activityDetails.sent" for ADA with value: 3.00 and wallet: "WalletReceiveSimpleTransactionE2E" address When I open wallet: "WalletReceiveSimpleTransactionE2E" in: extended mode And Wallet is synced And I navigate to Transactions extended page Then the Received transaction is displayed with value: "3.00 tADA" and tokens count 1 And I click on a transaction: 1 - Then The Tx details are displayed as "package.core.transactionDetailBrowser.received" for ADA with value: 3.00 and wallet: "WalletSendSimpleTransactionE2E" address + Then The Tx details are displayed as "package.core.activityDetails.received" for ADA with value: 3.00 and wallet: "WalletSendSimpleTransactionE2E" address @LW-6797 @Testnet Scenario: Send Token from DApp E2E @@ -53,10 +53,10 @@ Feature: Send Transactions from Dapp - E2E When I navigate to Transactions extended page Then the Sent transaction is displayed with value: "1.38 tADA, 2 LaceCoin2" and tokens count 2 And I click on a transaction: 1 - Then The Tx details are displayed as "package.core.transactionDetailBrowser.sent" for ADA with value: "1.38" and LaceCoin2 with value: "2" and wallet: "WalletReceiveSimpleTransactionE2E" address + Then The Tx details are displayed as "package.core.activityDetails.sent" for ADA with value: "1.38" and LaceCoin2 with value: "2" and wallet: "WalletReceiveSimpleTransactionE2E" address When I open wallet: "WalletReceiveSimpleTransactionE2E" in: extended mode And Wallet is synced And I navigate to Transactions extended page Then the Received transaction is displayed with value: "1.38 tADA" and tokens count 2 And I click on a transaction: 1 - Then The Tx details are displayed as "package.core.transactionDetailBrowser.received" for ADA with value: "1.38" and LaceCoin2 with value: "2" and wallet: "WalletSendSimpleTransactionE2E" address + Then The Tx details are displayed as "package.core.activityDetails.received" for ADA with value: "1.38" and LaceCoin2 with value: "2" and wallet: "WalletSendSimpleTransactionE2E" address diff --git a/packages/e2e-tests/src/features/e2e/SendTransactionSimpleExtendedE2E.feature b/packages/e2e-tests/src/features/e2e/SendTransactionSimpleExtendedE2E.feature index bb7b8d189..988d0df76 100644 --- a/packages/e2e-tests/src/features/e2e/SendTransactionSimpleExtendedE2E.feature +++ b/packages/e2e-tests/src/features/e2e/SendTransactionSimpleExtendedE2E.feature @@ -22,13 +22,13 @@ Feature: Send Simple Transactions - Extended view - E2E When I navigate to Transactions extended page Then the Sent transaction is displayed with value: "1.12 tADA" and tokens count 1 And I click and open recent transactions details until find transaction with correct hash - Then The Tx details are displayed as "package.core.transactionDetailBrowser.sent" for ADA with value: 1.12 and wallet: "WalletReceiveSimpleTransactionE2E" address + Then The Tx details are displayed as "package.core.activityDetails.sent" for ADA with value: 1.12 and wallet: "WalletReceiveSimpleTransactionE2E" address When I open wallet: "WalletReceiveSimpleTransactionE2E" in: extended mode And Wallet is synced And I navigate to Transactions extended page Then the Received transaction is displayed with value: "1.12 tADA" and tokens count 1 And I click and open recent transactions details until find transaction with correct hash - Then The Tx details are displayed as "package.core.transactionDetailBrowser.received" for ADA with value: 1.12 and wallet: "WalletSendSimpleTransactionE2E" address + Then The Tx details are displayed as "package.core.activityDetails.received" for ADA with value: 1.12 and wallet: "WalletSendSimpleTransactionE2E" address @LW-4677 Scenario: Extended-view - Self Transaction E2E diff --git a/packages/e2e-tests/src/features/e2e/SendTransactionSimplePopupE2E.feature b/packages/e2e-tests/src/features/e2e/SendTransactionSimplePopupE2E.feature index 1a2c609b0..a177778dd 100644 --- a/packages/e2e-tests/src/features/e2e/SendTransactionSimplePopupE2E.feature +++ b/packages/e2e-tests/src/features/e2e/SendTransactionSimplePopupE2E.feature @@ -22,13 +22,13 @@ Feature: Send Simple Transactions - Popup view - E2E When I navigate to Transactions popup page Then the Sent transaction is displayed with value: "1.12 tADA" and tokens count 1 And I click and open recent transactions details until find transaction with correct hash - Then The Tx details are displayed as "package.core.transactionDetailBrowser.sent" for ADA with value: 1.12 and wallet: "WalletReceiveSimpleTransactionE2E" address + Then The Tx details are displayed as "package.core.activityDetails.sent" for ADA with value: 1.12 and wallet: "WalletReceiveSimpleTransactionE2E" address When I open wallet: "WalletReceiveSimpleTransactionE2E" in: popup mode And Wallet is synced And I navigate to Transactions popup page Then the Received transaction is displayed with value: "1.12 tADA" and tokens count 1 And I click and open recent transactions details until find transaction with correct hash - Then The Tx details are displayed as "package.core.transactionDetailBrowser.received" for ADA with value: 1.12 and wallet: "WalletSendSimpleTransactionE2E" address + Then The Tx details are displayed as "package.core.activityDetails.received" for ADA with value: 1.12 and wallet: "WalletSendSimpleTransactionE2E" address @LW-4678 Scenario: Popup-view - Self Transaction E2E diff --git a/packages/e2e-tests/src/steps/nftsCommonSteps.ts b/packages/e2e-tests/src/steps/nftsCommonSteps.ts index 788304b26..4385b0cc1 100644 --- a/packages/e2e-tests/src/steps/nftsCommonSteps.ts +++ b/packages/e2e-tests/src/steps/nftsCommonSteps.ts @@ -58,7 +58,7 @@ Then( /^The Tx details are displayed as (sent|received) for NFT with name: "([^"]*)" and wallet: "([^"]*)" address$/, async (type: string, nftName: string, walletName: string) => { const typeTranslationKey = - type === 'sent' ? 'package.core.transactionDetailBrowser.sent' : 'package.core.transactionDetailBrowser.received'; + type === 'sent' ? 'package.core.activityDetails.sent' : 'package.core.activityDetails.received'; const expectedActivityDetails = { transactionDescription: `${await t(typeTranslationKey)}\n(2)`, From e0ae082929fec9567e01e08834e1f996adf95898 Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 16:50:08 +0200 Subject: [PATCH 17/31] refactor(all): change way of importing EpochNo type --- .../src/stores/slices/wallet-activities-slice.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index d5199dbf9..f1466663b 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -37,7 +37,6 @@ import { } from '../types'; import { getAssetsInformation } from '@src/utils/get-assets-information'; import { rewardHistoryTransformer } from '@src/views/browser-view/features/activity/helpers/reward-history-transformer'; -import { EpochNo } from '@cardano-sdk/core/dist/cjs/Cardano'; export interface FetchWalletActivitiesProps { fiatCurrency: CurrencyInfo; @@ -202,12 +201,12 @@ const getWalletActivitiesObservable = async ({ }; const epochRewardsMapper = ( - earnedEpoch: EpochNo, + earnedEpoch: Wallet.Cardano.EpochNo, rewards: Reward[], eraSummaries: EraSummary[] ): ExtendedActivityProps => { const REWARD_SPENDABLE_DELAY_EPOCHS = 2; - const spendableEpoch = (earnedEpoch + REWARD_SPENDABLE_DELAY_EPOCHS) as EpochNo; + const spendableEpoch = (earnedEpoch + REWARD_SPENDABLE_DELAY_EPOCHS) as Wallet.Cardano.EpochNo; const slotTimeCalc = Wallet.createSlotTimeCalc(eraSummaries); const rewardSpendableDate = slotTimeCalc(epochSlotsCalc(spendableEpoch, eraSummaries).firstSlot); @@ -277,7 +276,7 @@ const getWalletActivitiesObservable = async ({ rewardsHistory$.pipe( map((allRewards: Wallet.RewardsHistory) => Object.entries(groupBy(allRewards.all, ({ epoch }) => epoch.toString())) - .map(([epoch, rewards]) => epochRewardsMapper(Number(epoch) as EpochNo, rewards, eraSummaries)) + .map(([epoch, rewards]) => epochRewardsMapper(Number(epoch) as Wallet.Cardano.EpochNo, rewards, eraSummaries)) .filter((reward) => reward.date.getTime() < Date.now()) ) ); From 959aac2369af9f1c7cfc9d9ac5ef5c8bf7dae1dc Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 16:53:24 +0200 Subject: [PATCH 18/31] refactor(all): refactor transformTransactionStatus() --- .../src/utils/assert-unreachable.ts | 4 ---- .../activity/helpers/common-tx-transformer.ts | 21 +++++++------------ 2 files changed, 7 insertions(+), 18 deletions(-) delete mode 100644 apps/browser-extension-wallet/src/utils/assert-unreachable.ts diff --git a/apps/browser-extension-wallet/src/utils/assert-unreachable.ts b/apps/browser-extension-wallet/src/utils/assert-unreachable.ts deleted file mode 100644 index 21997a569..000000000 --- a/apps/browser-extension-wallet/src/utils/assert-unreachable.ts +++ /dev/null @@ -1,4 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export const assertUnreachable = (_x: never): never => { - throw new Error("Didn't expect to get here"); -}; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts index f2750b670..fecd9d0c1 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts @@ -7,7 +7,6 @@ import type { TransformedActivity, TransformedTransactionActivity } from './type import { ActivityStatus } from '@lace/core'; import capitalize from 'lodash/capitalize'; import dayjs from 'dayjs'; -import { assertUnreachable } from '@src/utils/assert-unreachable'; export interface TxTransformerInput { tx: Wallet.TxInFlight | Wallet.Cardano.HydratedTx; @@ -74,20 +73,14 @@ const splitDelegationTx = (tx: TransformedActivity): TransformedTransactionActiv return []; }; -// eslint-disable-next-line consistent-return const transformTransactionStatus = (status: Wallet.TransactionStatus): ActivityStatus => { - switch (status) { - case Wallet.TransactionStatus.PENDING: - return ActivityStatus.PENDING; - case Wallet.TransactionStatus.ERROR: - return ActivityStatus.ERROR; - case Wallet.TransactionStatus.SUCCESS: - return ActivityStatus.SUCCESS; - case Wallet.TransactionStatus.SPENDABLE: - return ActivityStatus.SPENDABLE; - default: - assertUnreachable(status); - } + const statuses = { + [Wallet.TransactionStatus.PENDING]: ActivityStatus.PENDING, + [Wallet.TransactionStatus.ERROR]: ActivityStatus.ERROR, + [Wallet.TransactionStatus.SUCCESS]: ActivityStatus.SUCCESS, + [Wallet.TransactionStatus.SPENDABLE]: ActivityStatus.SPENDABLE + }; + return statuses[status]; }; /** Simplifies the transaction object to be used in the activity list From d6714d305894300e440dd7a5dbf91fa8d9e4bd2f Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 17:00:16 +0200 Subject: [PATCH 19/31] fix(all): lint fixes --- .../features/activity/components/ActivityDetail.tsx | 2 +- packages/core/src/index.ts | 4 ++-- .../components/ActivityDetail/TransactionDetails.tsx | 12 +++--------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index 57e16b251..0722c2f5a 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -98,7 +98,7 @@ type TransactionDetailsProxyProps = { status: ActivityStatus; amountTransformer: (amount: string) => string; }; -const TransactionDetailsProxy = withAddressBookContext( +const TransactionDetailsProxy = withAddressBookContext( ({ name, activityInfo, direction, status, amountTransformer }: TransactionDetailsProxyProps): ReactElement => { const analytics = useAnalyticsContext(); const { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index e17b51a40..4aa7bab6a 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -2,13 +2,13 @@ export * from '@ui/hooks'; export * from '@ui/lib'; export * from '@ui/utils'; -export * from '@src/ui/components/ActivityDetail'; +export * from '@ui/components/ActivityDetail'; export * from '@ui/components/WalletAvatar'; export * from '@ui/components/WalletBasicInfo'; export * from '@ui/components/WalletAddresses'; export * from '@ui/components/WalletUsedAddresses'; export * from '@ui/components/AddressFormBrowserView'; -export * from '@src/ui/components/EditAddressForm'; +export * from '@ui/components/EditAddressForm'; export * from '@ui/components/Activity'; export * from '@ui/components/Nft'; export * from '@ui/components/Token'; diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index 61592dc05..bc03e619f 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -1,5 +1,4 @@ /* eslint-disable no-magic-numbers */ -/* eslint-disable @typescript-eslint/no-explicit-any */ import React from 'react'; import cn from 'classnames'; import { InfoCircleOutlined } from '@ant-design/icons'; @@ -160,9 +159,7 @@ export const TransactionDetails = ({

{t('package.core.activityDetails.summary')}

{pools?.length > 0 && (
-
- {t('package.core.activityDetails.pools')} -
+
{t('package.core.activityDetails.pools')}
{pools?.map((pool) => (
@@ -262,9 +259,7 @@ export const TransactionDetails = ({ )}
-
- {t('package.core.activityDetails.timestamp')} -
+
{t('package.core.activityDetails.timestamp')}
{includedDate}  {includedTime} @@ -295,8 +290,7 @@ export const TransactionDetails = ({
)} - {deposit && - renderDepositValueSection({ value: deposit, label: t('package.core.activityDetails.deposit') })} + {deposit && renderDepositValueSection({ value: deposit, label: t('package.core.activityDetails.deposit') })} {depositReclaim && renderDepositValueSection({ value: depositReclaim, From 28d141499bf4207279399fa2f61b348bb5cbc4ec Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 17:04:52 +0200 Subject: [PATCH 20/31] refactor(all): move TransactionDetailsProxy to separate file --- .../activity/components/ActivityDetail.tsx | 104 +----------------- .../components/TransactionDetailsProxy.tsx | 102 +++++++++++++++++ 2 files changed, 106 insertions(+), 100 deletions(-) create mode 100644 apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetailsProxy.tsx diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index 0722c2f5a..f9c7ee3cc 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -3,7 +3,6 @@ import React, { ReactElement, useCallback, useEffect, useMemo, useState } from ' import uniq from 'lodash/uniq'; import flatMap from 'lodash/flatMap'; import { Skeleton } from 'antd'; -import { config } from '@src/config'; import { Wallet } from '@lace/cardano'; import { AssetActivityListProps, @@ -12,16 +11,13 @@ import { TxSummary, ActivityType, useTranslate, - RewardsDetails, - TransactionDetails + RewardsDetails } from '@lace/core'; import { PriceResult } from '@hooks'; import { useWalletStore } from '@stores'; -import { ActivityDetail as ActivityDetailType, TransactionActivityDetail, TxDirection } from '@src/types'; -import { useAddressBookContext, withAddressBookContext } from '@src/features/address-book/context'; -import { APP_MODE_POPUP } from '@src/utils/constants'; -import { useAnalyticsContext, useCurrencyStore, useExternalLinkOpener } from '@providers'; -import { PostHogAction } from '@providers/AnalyticsProvider/analyticsTracker'; +import { ActivityDetail as ActivityDetailType } from '@src/types'; +import { useCurrencyStore } from '@providers'; +import { TransactionDetailsProxy } from './TransactionDetailsProxy'; const MAX_SUMMARY_ADDRESSES = 5; @@ -91,98 +87,6 @@ const getTypeLabel = (type: ActivityType, t: ReturnType['t' return t('package.core.activityDetails.sent'); }; -type TransactionDetailsProxyProps = { - name: string; - activityInfo: TransactionActivityDetail; - direction: TxDirection; - status: ActivityStatus; - amountTransformer: (amount: string) => string; -}; -const TransactionDetailsProxy = withAddressBookContext( - ({ name, activityInfo, direction, status, amountTransformer }: TransactionDetailsProxyProps): ReactElement => { - const analytics = useAnalyticsContext(); - const { - walletInfo, - environmentName, - walletUI: { cardanoCoin, appMode } - } = useWalletStore(); - const isPopupView = appMode === APP_MODE_POPUP; - const openExternalLink = useExternalLinkOpener(); - const { list: addressList } = useAddressBookContext(); - - const { CEXPLORER_BASE_URL, CEXPLORER_URL_PATHS } = config(); - const explorerBaseUrl = useMemo( - () => `${CEXPLORER_BASE_URL[environmentName]}/${CEXPLORER_URL_PATHS.Tx}`, - [CEXPLORER_BASE_URL, CEXPLORER_URL_PATHS.Tx, environmentName] - ); - const getHeaderDescription = () => { - if (activityInfo.type === 'delegation') return '1 token'; - return ` (${activityInfo?.assetAmount})`; - }; - const isIncomingTransaction = direction === 'Incoming'; - const { - addrOutputs, - addrInputs, - hash, - includedUtcDate, - includedUtcTime, - fee, - pools, - deposit, - depositReclaim, - metadata - } = activityInfo.activity; - const txSummary = useMemo( - () => - getTransactionData({ - addrOutputs, - addrInputs, - walletAddresses: walletInfo.addresses.map((addr) => addr.address.toString()), - isIncomingTransaction - }), - [isIncomingTransaction, addrOutputs, addrInputs, walletInfo.addresses] - ); - - const handleOpenExternalLink = () => { - analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailTransactionHashClick); - const externalLink = `${explorerBaseUrl}/${hash}`; - externalLink && status === 'success' && openExternalLink(externalLink); - }; - - const addressToNameMap = useMemo( - () => new Map(addressList?.map((item: AddressListType) => [item.address, item.name])), - [addressList] - ); - - return ( - // eslint-disable-next-line react/jsx-pascal-case - analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailInputsClick)} - sendAnalyticsOutputs={() => analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailOutputsClick)} - /> - ); - } -); - export const ActivityDetail = ({ price }: ActivityDetailProps): ReactElement => { const { walletUI: { cardanoCoin } diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetailsProxy.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetailsProxy.tsx new file mode 100644 index 000000000..f96efee30 --- /dev/null +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/TransactionDetailsProxy.tsx @@ -0,0 +1,102 @@ +import React, { ReactElement, useMemo } from 'react'; +import { ActivityStatus, TransactionDetails } from '@lace/core'; +import { AddressListType, getTransactionData } from './ActivityDetail'; +import { useWalletStore } from '@src/stores'; +import { useAnalyticsContext, useExternalLinkOpener } from '@providers'; +import { useAddressBookContext, withAddressBookContext } from '@src/features/address-book/context'; +import type { TransactionActivityDetail, TxDirection } from '@src/types'; +import { APP_MODE_POPUP } from '@src/utils/constants'; +import { config } from '@src/config'; +import { PostHogAction } from '@providers/AnalyticsProvider/analyticsTracker'; + +type TransactionDetailsProxyProps = { + name: string; + activityInfo: TransactionActivityDetail; + direction: TxDirection; + status: ActivityStatus; + amountTransformer: (amount: string) => string; +}; +export const TransactionDetailsProxy = withAddressBookContext( + ({ name, activityInfo, direction, status, amountTransformer }: TransactionDetailsProxyProps): ReactElement => { + const analytics = useAnalyticsContext(); + const { + walletInfo, + environmentName, + walletUI: { cardanoCoin, appMode } + } = useWalletStore(); + const isPopupView = appMode === APP_MODE_POPUP; + const openExternalLink = useExternalLinkOpener(); + const { list: addressList } = useAddressBookContext(); + + const { CEXPLORER_BASE_URL, CEXPLORER_URL_PATHS } = config(); + const explorerBaseUrl = useMemo( + () => `${CEXPLORER_BASE_URL[environmentName]}/${CEXPLORER_URL_PATHS.Tx}`, + [CEXPLORER_BASE_URL, CEXPLORER_URL_PATHS.Tx, environmentName] + ); + const getHeaderDescription = () => { + if (activityInfo.type === 'delegation') return '1 token'; + return ` (${activityInfo?.assetAmount})`; + }; + const isIncomingTransaction = direction === 'Incoming'; + const { + addrOutputs, + addrInputs, + hash, + includedUtcDate, + includedUtcTime, + fee, + pools, + deposit, + depositReclaim, + metadata + } = activityInfo.activity; + const txSummary = useMemo( + () => + getTransactionData({ + addrOutputs, + addrInputs, + walletAddresses: walletInfo.addresses.map((addr) => addr.address.toString()), + isIncomingTransaction + }), + [isIncomingTransaction, addrOutputs, addrInputs, walletInfo.addresses] + ); + + const handleOpenExternalLink = () => { + analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailTransactionHashClick); + const externalLink = `${explorerBaseUrl}/${hash}`; + externalLink && status === 'success' && openExternalLink(externalLink); + }; + + const addressToNameMap = useMemo( + () => new Map(addressList?.map((item: AddressListType) => [item.address, item.name])), + [addressList] + ); + + return ( + // eslint-disable-next-line react/jsx-pascal-case + analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailInputsClick)} + sendAnalyticsOutputs={() => analytics.sendEventToPostHog(PostHogAction.ActivityActivityDetailOutputsClick)} + /> + ); + } +); From b2710c8bfe1995d29f9a2d40f73601e46300564c Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 17:21:13 +0200 Subject: [PATCH 21/31] refactor(all): remove redundant ts comment --- .../browser-view/features/activity/components/ActivityDetail.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index f9c7ee3cc..0d1ec3ef5 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ import React, { ReactElement, useCallback, useEffect, useMemo, useState } from 'react'; import uniq from 'lodash/uniq'; import flatMap from 'lodash/flatMap'; From 0ef664ed1c48fb562ba27d253fa910f667a152aa Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 22:18:47 +0200 Subject: [PATCH 22/31] test(all): add reward ui component test --- .../ActivityDetail/RewardsDetails.tsx | 43 +++++++------ .../__tests__/RewardsDetails.test.tsx | 62 +++++++++++++++++++ 2 files changed, 83 insertions(+), 22 deletions(-) create mode 100644 packages/core/src/ui/components/ActivityDetail/__tests__/RewardsDetails.test.tsx diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index ae6d02e60..9fa03d0d0 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -33,22 +33,22 @@ export const RewardsDetails = ({ const tooltipContent = t('package.core.activityDetails.rewardsDescription'); return ( -
+
{t('package.core.activityDetails.header')}

{t('package.core.activityDetails.summary')}

-
+
{name}
-
+
{`${rewards.totalAmount} ${coinSymbol}`} - {`${amountTransformer( + {`${amountTransformer( rewards.totalAmount )}`}
@@ -58,34 +58,35 @@ export const RewardsDetails = ({ {poolRewards.length > 0 && (
-
- {t('package.core.activityDetails.pools')} -
+
{t('package.core.activityDetails.pools')}
{poolRewards.map(({ pool, amount }) => (
{pool.name && ( -
+
{pool.name}
)} {pool.ticker && ( -
+
({pool.ticker})
)}
{pool.id && ( -
+
)}
- + {amount} {coinSymbol} - + {amountTransformer(amount)}
@@ -98,20 +99,18 @@ export const RewardsDetails = ({
{t('package.core.activityDetails.status')}
{status && ( -
{`${status.charAt(0).toUpperCase()}${status.slice( - 1 - )}`}
+
{`${status + .charAt(0) + .toUpperCase()}${status.slice(1)}`}
)}
{t('package.core.activityDetails.epoch')}
-
{`${rewards.spendableEpoch}`}
+
{`${rewards.spendableEpoch}`}
-
-
- {t('package.core.activityDetails.timestamp')} -
-
+
+
{t('package.core.activityDetails.timestamp')}
+
{includedDate}  {includedTime}
diff --git a/packages/core/src/ui/components/ActivityDetail/__tests__/RewardsDetails.test.tsx b/packages/core/src/ui/components/ActivityDetail/__tests__/RewardsDetails.test.tsx new file mode 100644 index 000000000..b00f5723d --- /dev/null +++ b/packages/core/src/ui/components/ActivityDetail/__tests__/RewardsDetails.test.tsx @@ -0,0 +1,62 @@ +/* eslint-disable no-magic-numbers */ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { RewardsDetails, RewardsDetailsProps } from '../RewardsDetails'; +import { ActivityStatus } from '../../Activity/AssetActivityItem'; + +describe('Testing ActivityDetailsBrowser component', () => { + const rewardsDetailsProps: RewardsDetailsProps = { + name: 'Name', + headerDescription: 'Header Description', + status: ActivityStatus.SPENDABLE, + includedDate: 'Date', + includedTime: 'Time', + amountTransformer: (amount) => `${amount} $`, + coinSymbol: 'ADA', + rewards: { + totalAmount: 'Amount', + spendableEpoch: 47, + rewards: [ + { + pool: { name: 'pool1', ticker: 'A', id: '1' }, + amount: '10' + }, + { + pool: { name: 'pool2', ticker: 'B', id: '2' }, + amount: '10' + } + ] + } + }; + + test('should display rewards detail bundle', async () => { + const { findByTestId } = render(); + + const container = await findByTestId('rewards-detail-bundle'); + expect(container).toBeVisible(); + }); + + test('should display rewards pools bundle', async () => { + const { findAllByTestId } = render(); + + const containers = await findAllByTestId('rewards-pool-name'); + + expect(containers).toHaveLength(2); + containers.forEach((c) => expect(c).toBeVisible()); + }); + + test('should display rewards epoch', async () => { + const { findByTestId } = render(); + + const dateContainer = await findByTestId('rewards-epoch'); + expect(dateContainer).toBeVisible(); + }); + + test('should display rewards date and time', async () => { + const { findByTestId } = render(); + + const dateContainer = await findByTestId('rewards-date'); + expect(dateContainer).toBeVisible(); + }); +}); From 5dc12164ddb0cc1bd42a78ac0ecca5487120971c Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 22:30:32 +0200 Subject: [PATCH 23/31] fix(all): fix crashing build --- packages/core/src/ui/components/Activity/AssetActivityItem.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx index c68729016..f24092364 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx @@ -4,14 +4,13 @@ import debounce from 'lodash/debounce'; import { Image, Tooltip } from 'antd'; import Icon from '@ant-design/icons'; import { getTextWidth } from '@lace/common'; -import { ActivityType } from '@ui/components/ActivityDetail/activityType'; -import { ActivityTypeIcon } from '@ui/components/ActivityDetail/ActivityTypeIcon'; import { ReactComponent as PendingIcon } from '../../assets/icons/pending.component.svg'; import { ReactComponent as ErrorIcon } from '../../assets/icons/error.component.svg'; import styles from './AssetActivityItem.module.scss'; import pluralize from 'pluralize'; import { txIconSize } from '@src/ui/utils/icon-size'; import { useTranslate } from '@src/ui/hooks'; +import { ActivityTypeIcon, ActivityType } from '@ui/components/ActivityDetail'; export type ActivityAssetInfo = { ticker: string }; export type ActivityAssetProp = { id: string; val: string; info?: ActivityAssetInfo }; From 734c46e675e88cf3e834727bdc84ca0384ada9c1 Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 22:46:42 +0200 Subject: [PATCH 24/31] fix(all): fix build --- packages/core/src/ui/components/Activity/AssetActivityItem.tsx | 2 +- .../core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx | 2 +- .../src/ui/components/ActivityDetail/TransactionDetails.tsx | 2 +- .../overview/helpers/hasPendingDelegationTransaction.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx index f24092364..0d2afbde5 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx @@ -10,7 +10,7 @@ import styles from './AssetActivityItem.module.scss'; import pluralize from 'pluralize'; import { txIconSize } from '@src/ui/utils/icon-size'; import { useTranslate } from '@src/ui/hooks'; -import { ActivityTypeIcon, ActivityType } from '@ui/components/ActivityDetail'; +import { ActivityTypeIcon, ActivityType } from '../ActivityDetail'; export type ActivityAssetInfo = { ticker: string }; export type ActivityAssetProp = { id: string; val: string; info?: ActivityAssetInfo }; diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx index d38e89f86..735a1e586 100644 --- a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { ActivityType } from './activityType'; +import type { ActivityType } from './activityType'; import { ReactComponent as OutgoingIcon } from '../../assets/icons/outgoing.component.svg'; import { ReactComponent as IncomingIcon } from '../../assets/icons/incoming.component.svg'; import { ReactComponent as SelfIcon } from '../../assets/icons/self-transaction.component.svg'; diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index bc03e619f..e54e20cc1 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -5,7 +5,7 @@ import { InfoCircleOutlined } from '@ant-design/icons'; import { Tooltip } from 'antd'; import styles from './TransactionDetails.module.scss'; import { TransactionDetailAsset, TxOutputInput, TransactionMetadataProps, TxSummary } from './TransactionDetailAsset'; -import { ActivityStatus } from '../Activity'; +import type { ActivityStatus } from '../Activity'; import { Ellipsis, toast } from '@lace/common'; import { ReactComponent as Info } from '../../assets/icons/info-icon.component.svg'; import { TransactionInputOutput } from './TransactionInputOutput'; diff --git a/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts b/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts index b8296022e..509a8073d 100644 --- a/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts +++ b/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts @@ -1,5 +1,5 @@ -import { ActivityType, AssetActivityListProps } from '@lace/core'; import flatMap from 'lodash/flatMap'; +import type { ActivityType, AssetActivityListProps } from '@lace/core'; const DelegationTransactionTypes: Set = new Set([ 'delegation', From edc882f88727987b777d45fad72296c6fb071a13 Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 23:00:43 +0200 Subject: [PATCH 25/31] fix(all): fix type import --- packages/core/src/ui/components/ActivityDetail/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/ui/components/ActivityDetail/index.ts b/packages/core/src/ui/components/ActivityDetail/index.ts index d2ea6a99c..cd2448466 100644 --- a/packages/core/src/ui/components/ActivityDetail/index.ts +++ b/packages/core/src/ui/components/ActivityDetail/index.ts @@ -1,6 +1,6 @@ export * from './TransactionDetails'; export * from './RewardsDetails'; -export * from './activityType'; +export type * from './activityType'; export * from './ActivityTypeIcon'; export * from './TransactionDetailAsset'; export * from './TransactionInputOutput'; From 3accfcc95158850f97bd2ea442e84a159df921e3 Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 23:16:28 +0200 Subject: [PATCH 26/31] fix(all): fix ci build --- packages/core/src/ui/components/Activity/AssetActivityItem.tsx | 3 ++- packages/core/src/ui/components/ActivityDetail/index.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx index 0d2afbde5..eed7073ed 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx @@ -10,7 +10,8 @@ import styles from './AssetActivityItem.module.scss'; import pluralize from 'pluralize'; import { txIconSize } from '@src/ui/utils/icon-size'; import { useTranslate } from '@src/ui/hooks'; -import { ActivityTypeIcon, ActivityType } from '../ActivityDetail'; +import { ActivityTypeIcon } from '../ActivityDetail'; +import type { ActivityType } from '../ActivityDetail/activityType'; export type ActivityAssetInfo = { ticker: string }; export type ActivityAssetProp = { id: string; val: string; info?: ActivityAssetInfo }; diff --git a/packages/core/src/ui/components/ActivityDetail/index.ts b/packages/core/src/ui/components/ActivityDetail/index.ts index cd2448466..d2ea6a99c 100644 --- a/packages/core/src/ui/components/ActivityDetail/index.ts +++ b/packages/core/src/ui/components/ActivityDetail/index.ts @@ -1,6 +1,6 @@ export * from './TransactionDetails'; export * from './RewardsDetails'; -export type * from './activityType'; +export * from './activityType'; export * from './ActivityTypeIcon'; export * from './TransactionDetailAsset'; export * from './TransactionInputOutput'; From 6271c50e367fc8a3208c5108618496633ec46867 Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 23:28:36 +0200 Subject: [PATCH 27/31] fix(all): fix ci build --- packages/core/src/ui/components/Activity/AssetActivityItem.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx index eed7073ed..974e667ac 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx @@ -10,8 +10,7 @@ import styles from './AssetActivityItem.module.scss'; import pluralize from 'pluralize'; import { txIconSize } from '@src/ui/utils/icon-size'; import { useTranslate } from '@src/ui/hooks'; -import { ActivityTypeIcon } from '../ActivityDetail'; -import type { ActivityType } from '../ActivityDetail/activityType'; +import { ActivityTypeIcon, ActivityType } from '@src/ui/components/ActivityDetail'; export type ActivityAssetInfo = { ticker: string }; export type ActivityAssetProp = { id: string; val: string; info?: ActivityAssetInfo }; From 5d6715fcfff364021b8bf59c6c8b1b1ddfa1c935 Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 20 Oct 2023 23:38:06 +0200 Subject: [PATCH 28/31] fix(all): fix ci build --- .../ui/components/Activity/AssetActivityItem.tsx | 2 +- .../ui/components/ActivityDetail/ActivityType.ts | 11 ----------- .../components/ActivityDetail/ActivityTypeIcon.tsx | 13 ++++++++++++- .../ui/components/ActivityDetail/RewardsDetails.tsx | 12 +++++++++++- .../src/ui/components/ActivityDetail/RewardsInfo.ts | 10 ---------- .../core/src/ui/components/ActivityDetail/index.ts | 2 -- 6 files changed, 24 insertions(+), 26 deletions(-) delete mode 100644 packages/core/src/ui/components/ActivityDetail/ActivityType.ts delete mode 100644 packages/core/src/ui/components/ActivityDetail/RewardsInfo.ts diff --git a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx index 974e667ac..0d2afbde5 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx @@ -10,7 +10,7 @@ import styles from './AssetActivityItem.module.scss'; import pluralize from 'pluralize'; import { txIconSize } from '@src/ui/utils/icon-size'; import { useTranslate } from '@src/ui/hooks'; -import { ActivityTypeIcon, ActivityType } from '@src/ui/components/ActivityDetail'; +import { ActivityTypeIcon, ActivityType } from '../ActivityDetail'; export type ActivityAssetInfo = { ticker: string }; export type ActivityAssetProp = { id: string; val: string; info?: ActivityAssetInfo }; diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityType.ts b/packages/core/src/ui/components/ActivityDetail/ActivityType.ts deleted file mode 100644 index dc440c7f4..000000000 --- a/packages/core/src/ui/components/ActivityDetail/ActivityType.ts +++ /dev/null @@ -1,11 +0,0 @@ -export type TransactionActivityType = - | 'outgoing' - | 'incoming' - | 'delegation' - | 'delegationRegistration' - | 'delegationDeregistration' - | 'self'; - -export type RewardsActivityType = 'rewards'; - -export type ActivityType = TransactionActivityType | RewardsActivityType; diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx index 735a1e586..8d69396df 100644 --- a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import type { ActivityType } from './activityType'; import { ReactComponent as OutgoingIcon } from '../../assets/icons/outgoing.component.svg'; import { ReactComponent as IncomingIcon } from '../../assets/icons/incoming.component.svg'; import { ReactComponent as SelfIcon } from '../../assets/icons/self-transaction.component.svg'; @@ -10,6 +9,18 @@ import { ReactComponent as RewardsIcon } from '../../assets/icons/rewards.compon import Icon, { QuestionOutlined } from '@ant-design/icons'; import { txIconSize } from '@src/ui/utils/icon-size'; +export type TransactionActivityType = + | 'outgoing' + | 'incoming' + | 'delegation' + | 'delegationRegistration' + | 'delegationDeregistration' + | 'self'; + +export type RewardsActivityType = 'rewards'; + +export type ActivityType = TransactionActivityType | RewardsActivityType; + export interface ActivityTypeIconProps { type: ActivityType; } diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index 9fa03d0d0..77cd6f480 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -3,10 +3,20 @@ import cn from 'classnames'; import styles from './TransactionDetails.module.scss'; import { useTranslate } from '@src/ui/hooks'; import { ActivityStatus } from '../Activity/AssetActivityItem'; -import type { RewardsInfo } from './rewardsInfo'; import { Ellipsis } from '@lace/common'; import { ActivityDetailHeader } from './ActivityDetailHeader'; +type RewardItem = { + pool?: { name: string; ticker: string; id: string }; + amount: string; +}; + +export type RewardsInfo = { + totalAmount: string; + spendableEpoch: number; + rewards: RewardItem[]; +}; + export interface RewardsDetailsProps { name: string; headerDescription?: string; diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsInfo.ts b/packages/core/src/ui/components/ActivityDetail/RewardsInfo.ts deleted file mode 100644 index 3ef050a8f..000000000 --- a/packages/core/src/ui/components/ActivityDetail/RewardsInfo.ts +++ /dev/null @@ -1,10 +0,0 @@ -type RewardItem = { - pool?: { name: string; ticker: string; id: string }; - amount: string; -}; - -export type RewardsInfo = { - totalAmount: string; - spendableEpoch: number; - rewards: RewardItem[]; -}; diff --git a/packages/core/src/ui/components/ActivityDetail/index.ts b/packages/core/src/ui/components/ActivityDetail/index.ts index d2ea6a99c..26ccb7a4b 100644 --- a/packages/core/src/ui/components/ActivityDetail/index.ts +++ b/packages/core/src/ui/components/ActivityDetail/index.ts @@ -1,7 +1,5 @@ export * from './TransactionDetails'; export * from './RewardsDetails'; -export * from './activityType'; export * from './ActivityTypeIcon'; export * from './TransactionDetailAsset'; export * from './TransactionInputOutput'; -export * from './rewardsInfo'; From f398c32fa000ab15c4609f892650c8278f4290b0 Mon Sep 17 00:00:00 2001 From: refi93 Date: Tue, 24 Oct 2023 23:02:41 +0200 Subject: [PATCH 29/31] fix(all): add forgotten prop to RewardsDetails --- .../features/activity/components/ActivityDetail.tsx | 1 + .../core/src/ui/components/ActivityDetail/RewardsDetails.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index 0d1ec3ef5..cc713a0dc 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -130,6 +130,7 @@ export const ActivityDetail = ({ price }: ActivityDetailProps): ReactElement => name={name} status={activityInfo.status} includedDate={activityInfo.activity.includedUtcDate} + includedTime={activityInfo.activity.includedUtcTime} amountTransformer={amountTransformer} coinSymbol={cardanoCoin.symbol} rewards={activityInfo.activity.rewards} diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index 77cd6f480..774b10796 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -21,8 +21,8 @@ export interface RewardsDetailsProps { name: string; headerDescription?: string; status?: ActivityStatus; - includedDate?: string; - includedTime?: string; + includedDate: string; + includedTime: string; amountTransformer: (amount: string) => string; coinSymbol: string; rewards: RewardsInfo; From 8845a53335ecbc7cdf46b020d9ca90ca6299aa9c Mon Sep 17 00:00:00 2001 From: refi93 Date: Tue, 24 Oct 2023 23:03:38 +0200 Subject: [PATCH 30/31] fix(all): make rewards details time non-optional --- .../core/src/ui/components/ActivityDetail/RewardsDetails.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index 774b10796..6b124a382 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -32,8 +32,8 @@ export const RewardsDetails = ({ name, headerDescription, status, - includedDate = '-', - includedTime = '-', + includedDate, + includedTime, amountTransformer, coinSymbol, rewards From 1a8da57804d22ad2000493119351582e1743bc0b Mon Sep 17 00:00:00 2001 From: refi93 Date: Tue, 24 Oct 2023 23:05:20 +0200 Subject: [PATCH 31/31] refactor(all): enforce spendable status for rewards details component --- .../ui/components/ActivityDetail/RewardsDetails.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx index 6b124a382..497752b27 100644 --- a/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/RewardsDetails.tsx @@ -20,7 +20,7 @@ export type RewardsInfo = { export interface RewardsDetailsProps { name: string; headerDescription?: string; - status?: ActivityStatus; + status: ActivityStatus.SPENDABLE; includedDate: string; includedTime: string; amountTransformer: (amount: string) => string; @@ -108,11 +108,9 @@ export const RewardsDetails = ({
{t('package.core.activityDetails.status')}
- {status && ( -
{`${status - .charAt(0) - .toUpperCase()}${status.slice(1)}`}
- )} +
{`${status + .charAt(0) + .toUpperCase()}${status.slice(1)}`}
{t('package.core.activityDetails.epoch')}