From f4efb12cb73fae603a0f2b3947f38b6b44156aaa Mon Sep 17 00:00:00 2001 From: Tyler Date: Thu, 26 Sep 2024 17:21:58 -0400 Subject: [PATCH 1/6] vault history page --- src/constants/routes.ts | 1 + src/pages/portfolio/History.tsx | 6 ++++++ src/pages/portfolio/Portfolio.tsx | 5 +++++ src/pages/portfolio/PortfolioNavMobile.tsx | 5 +++++ src/pages/vaults/VaultTransactions.tsx | 10 ++++++++-- 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/constants/routes.ts b/src/constants/routes.ts index d1c8abdaa..585308516 100644 --- a/src/constants/routes.ts +++ b/src/constants/routes.ts @@ -29,6 +29,7 @@ export enum PortfolioRoute { export enum HistoryRoute { Trades = 'trades', Transfers = 'transfers', + VaultTransfers = 'vault-transfers', Payments = 'payments', } diff --git a/src/pages/portfolio/History.tsx b/src/pages/portfolio/History.tsx index 248a4cb5c..9fd6f36ba 100644 --- a/src/pages/portfolio/History.tsx +++ b/src/pages/portfolio/History.tsx @@ -38,6 +38,12 @@ export const History = () => { href: HistoryRoute.Transfers, tag: 'USDC', }, + { + value: HistoryRoute.VaultTransfers, + label:

MegaVault Transfers

, + href: HistoryRoute.VaultTransfers, + tag: 'USDC', + }, // TODO - TRCL-1693 - // { // value: HistoryRoute.Payments, diff --git a/src/pages/portfolio/Portfolio.tsx b/src/pages/portfolio/Portfolio.tsx index a03af9305..069a5f444 100644 --- a/src/pages/portfolio/Portfolio.tsx +++ b/src/pages/portfolio/Portfolio.tsx @@ -34,6 +34,7 @@ import { openDialog } from '@/state/dialogs'; import { shortenNumberForDisplay } from '@/lib/numbers'; +import { VaultTransactionsTable } from '../vaults/VaultTransactions'; import { PortfolioNavMobile } from './PortfolioNavMobile'; const Overview = lazy(() => import('./Overview').then((module) => ({ default: module.Overview }))); @@ -114,6 +115,10 @@ const PortfolioPage = () => { /> } /> + } + /> {/* TODO - TRCL-1693 { label: stringGetter({ key: STRING_KEYS.TRANSFERS }), description: stringGetter({ key: STRING_KEYS.TRANSFERS_DESCRIPTION }), }, + { + value: `${AppRoute.Portfolio}/${PortfolioRoute.History}/${HistoryRoute.VaultTransfers}`, + label: 'Vault Transfers', + description: 'Transfers to and from the MegaVault', + }, // TODO: TRCL-1693 - re-enable when Payments are ready // { // value: `${AppRoute.Portfolio}/${PortfolioRoute.History}/${HistoryRoute.Payments}`, diff --git a/src/pages/vaults/VaultTransactions.tsx b/src/pages/vaults/VaultTransactions.tsx index 18e920d75..24954988d 100644 --- a/src/pages/vaults/VaultTransactions.tsx +++ b/src/pages/vaults/VaultTransactions.tsx @@ -55,7 +55,13 @@ export const VaultTransactionsCard = ({ className }: { className?: string }) => ); }; const $ShowHideHistoryButton = styled(Button)``; -const VaultTransactionsTable = ({ className }: { className?: string }) => { +export const VaultTransactionsTable = ({ + className, + withOuterBorders, +}: { + className?: string; + withOuterBorders?: boolean; +}) => { const stringGetter = useStringGetter(); const transactions = useLoadedVaultAccountTransfers() ?? EMPTY_ARR; @@ -117,7 +123,7 @@ const VaultTransactionsTable = ({ className }: { className?: string }) => { }} columns={columns} className={className} - withOuterBorder={transactions.length === 0} + withOuterBorder={transactions.length === 0 || withOuterBorders} /> ); }; From 528e4524de5e0e407c9b6ddb19eb1bbf04f4c41d Mon Sep 17 00:00:00 2001 From: Tyler Date: Thu, 26 Sep 2024 18:26:49 -0400 Subject: [PATCH 2/6] Fix and string get --- package.json | 2 +- pnpm-lock.yaml | 8 +- src/constants/analytics.ts | 3 + src/pages/portfolio/History.tsx | 2 +- src/pages/portfolio/PortfolioNavMobile.tsx | 4 +- src/views/ExportHistoryDropdown.tsx | 104 ++++++++++++++++++++- 6 files changed, 112 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 45815a1ef..9579c6f00 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "@datadog/browser-logs": "^5.23.3", "@dydxprotocol/v4-abacus": "1.12.2", "@dydxprotocol/v4-client-js": "1.6.1", - "@dydxprotocol/v4-localization": "^1.1.203", + "@dydxprotocol/v4-localization": "^1.1.205", "@dydxprotocol/v4-proto": "^6.0.1", "@emotion/is-prop-valid": "^1.3.0", "@ethersproject/providers": "^5.7.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db19dece4..e37f00376 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ dependencies: specifier: 1.6.1 version: 1.6.1 '@dydxprotocol/v4-localization': - specifier: ^1.1.203 - version: 1.1.203 + specifier: ^1.1.205 + version: 1.1.205 '@dydxprotocol/v4-proto': specifier: ^6.0.1 version: 6.0.1 @@ -3061,8 +3061,8 @@ packages: - utf-8-validate dev: false - /@dydxprotocol/v4-localization@1.1.203: - resolution: {integrity: sha512-U9l0gzM9A/MvzSVh0iy7yjqzdzuO+VVDakoPltgqTU6/b/0wDrjIJpuoxn8Tr2AKVx/ZkJdChGM8EiJwueaicA==} + /@dydxprotocol/v4-localization@1.1.205: + resolution: {integrity: sha512-5AVTWYt2tvOuHAhpXYQ9uvH1cFm+lVCHepHZcZRnLFV5M25lgDlQDPSCWDuFtZGm0X59BbPgwi8l4zQS+VJKzw==} dev: false /@dydxprotocol/v4-proto@6.0.1: diff --git a/src/constants/analytics.ts b/src/constants/analytics.ts index 66e1715a0..b4a474675 100644 --- a/src/constants/analytics.ts +++ b/src/constants/analytics.ts @@ -128,6 +128,9 @@ export const AnalyticsEvents = unionize( ExportTransfersCheckboxClick: ofType<{ value: boolean; }>(), + ExportVaultTransfersCheckboxClick: ofType<{ + value: boolean; + }>(), // Navigation NavigatePage: ofType<{ diff --git a/src/pages/portfolio/History.tsx b/src/pages/portfolio/History.tsx index 9fd6f36ba..131879671 100644 --- a/src/pages/portfolio/History.tsx +++ b/src/pages/portfolio/History.tsx @@ -40,7 +40,7 @@ export const History = () => { }, { value: HistoryRoute.VaultTransfers, - label:

MegaVault Transfers

, + label:

{stringGetter({ key: STRING_KEYS.MEGAVAULT_TRANSFERS })}

, href: HistoryRoute.VaultTransfers, tag: 'USDC', }, diff --git a/src/pages/portfolio/PortfolioNavMobile.tsx b/src/pages/portfolio/PortfolioNavMobile.tsx index 54f3a1cf9..ac025bc7c 100644 --- a/src/pages/portfolio/PortfolioNavMobile.tsx +++ b/src/pages/portfolio/PortfolioNavMobile.tsx @@ -53,8 +53,8 @@ export const PortfolioNavMobile = () => { }, { value: `${AppRoute.Portfolio}/${PortfolioRoute.History}/${HistoryRoute.VaultTransfers}`, - label: 'Vault Transfers', - description: 'Transfers to and from the MegaVault', + label: stringGetter({ key: STRING_KEYS.MEGAVAULT_TRANSFERS }), + description: stringGetter({ key: STRING_KEYS.MEGAVAULT_TRANSFERS_DESCRIPTION }), }, // TODO: TRCL-1693 - re-enable when Payments are ready // { diff --git a/src/views/ExportHistoryDropdown.tsx b/src/views/ExportHistoryDropdown.tsx index a11bea0d4..cc23136a5 100644 --- a/src/views/ExportHistoryDropdown.tsx +++ b/src/views/ExportHistoryDropdown.tsx @@ -11,6 +11,7 @@ import { useAccounts } from '@/hooks/useAccounts'; import { useDydxClient } from '@/hooks/useDydxClient'; import { useLocaleSeparators } from '@/hooks/useLocaleSeparators'; import { useStringGetter } from '@/hooks/useStringGetter'; +import { useLoadedVaultAccountTransfers } from '@/hooks/vaultsHooks'; import { Button } from '@/components/Button'; import { Checkbox } from '@/components/Checkbox'; @@ -39,6 +40,7 @@ export const ExportHistoryDropdown = (props: ExportHistoryDropdownProps) => { const { requestAllAccountFills, requestAllAccountTransfers } = useDydxClient(); const [checkedTrades, setCheckedTrades] = useState(true); const [checkedTransfers, setCheckedTransfers] = useState(true); + const [checkedVaultTransfers, setCheckedVaultTransfers] = useState(false); const { decimal: LOCALE_DECIMAL_SEPARATOR, group: LOCALE_GROUP_SEPARATOR } = useLocaleSeparators(); @@ -210,6 +212,63 @@ export const ExportHistoryDropdown = (props: ExportHistoryDropdownProps) => { selectedLocale, ]); + const allVaultTransfers = useLoadedVaultAccountTransfers(); + const exportVaultTransfers = useCallback(async () => { + if (dydxAddress && subaccountNumber !== undefined && allVaultTransfers != null) { + const transfers = allVaultTransfers; + const csvTransfers = transfers.map((transfer) => { + const amount = formatNumberOutput(transfer.amountUsdc, OutputType.Fiat, { + decimalSeparator: LOCALE_DECIMAL_SEPARATOR, + groupSeparator: LOCALE_GROUP_SEPARATOR, + selectedLocale, + }); + + return { + time: + transfer.timestampMs == null + ? '' + : new Date(transfer.timestampMs).toLocaleString(selectedLocale, { + dateStyle: 'short', + timeStyle: 'short', + }), + action: transfer.type?.name ?? '', + amount, + id: transfer.id, + }; + }); + + exportCSV(csvTransfers, { + filename: 'vault-transfers', + columnHeaders: [ + { + key: 'time', + displayLabel: stringGetter({ key: STRING_KEYS.TIME }), + }, + { + key: 'action', + displayLabel: stringGetter({ key: STRING_KEYS.ACTION }), + }, + { + key: 'amount', + displayLabel: stringGetter({ key: STRING_KEYS.AMOUNT }), + }, + { + key: 'id', + displayLabel: stringGetter({ key: STRING_KEYS.TRANSACTION }), + }, + ], + }); + } + }, [ + dydxAddress, + subaccountNumber, + allVaultTransfers, + stringGetter, + LOCALE_DECIMAL_SEPARATOR, + LOCALE_GROUP_SEPARATOR, + selectedLocale, + ]); + const { mutate: mutateExportTrades, isPending: isPendingExportTrades } = useMutation({ mutationFn: exportTrades, }); @@ -218,6 +277,11 @@ export const ExportHistoryDropdown = (props: ExportHistoryDropdownProps) => { mutationFn: exportTransfers, }); + const { mutate: mutateExportVaultTransfers, isPending: isPendingExportVaultTransfers } = + useMutation({ + mutationFn: exportVaultTransfers, + }); + const exportData = useCallback( (e: Event) => { e.preventDefault(); @@ -230,6 +294,10 @@ export const ExportHistoryDropdown = (props: ExportHistoryDropdownProps) => { mutateExportTransfers(); } + if (checkedVaultTransfers) { + mutateExportVaultTransfers(); + } + track( AnalyticsEvents.ExportDownloadClick({ trades: checkedTrades, @@ -237,7 +305,14 @@ export const ExportHistoryDropdown = (props: ExportHistoryDropdownProps) => { }) ); }, - [checkedTrades, checkedTransfers, mutateExportTrades, mutateExportTransfers] + [ + checkedTrades, + checkedTransfers, + checkedVaultTransfers, + mutateExportTrades, + mutateExportTransfers, + mutateExportVaultTransfers, + ] ); return ( @@ -278,12 +353,35 @@ export const ExportHistoryDropdown = (props: ExportHistoryDropdownProps) => { value: 'transfers', onSelect: (e) => e.preventDefault(), }, + { + label: ( + { + setCheckedVaultTransfers(!checkedVaultTransfers); + + track( + AnalyticsEvents.ExportVaultTransfersCheckboxClick({ + value: !checkedVaultTransfers, + }) + ); + }} + /> + ), + value: 'vault-transfers', + onSelect: (e) => e.preventDefault(), + }, { label: (