From 7ffa73d0b508ec7038cc8c13dbf1da589fd1f950 Mon Sep 17 00:00:00 2001 From: Tyler Date: Fri, 4 Oct 2024 15:45:32 -0400 Subject: [PATCH] vault fixes --- package.json | 2 +- pnpm-lock.yaml | 8 ++--- src/components/Output.tsx | 33 +++++++++---------- src/components/ToggleGroup.tsx | 2 ++ src/lib/do.ts | 2 +- .../portfolio/AccountOverviewSection.tsx | 8 ++--- src/pages/portfolio/History.tsx | 2 +- src/pages/portfolio/PortfolioNavMobile.tsx | 2 +- src/pages/vaults/VaultDepositWithdrawForm.tsx | 30 ++++++++++++++--- src/pages/vaults/VaultInfoSections.tsx | 2 +- src/pages/vaults/VaultLockedSharesTable.tsx | 4 +-- src/pages/vaults/VaultPnlChart.tsx | 14 +++++--- src/pages/vaults/VaultPositionsTable.tsx | 2 +- src/views/ExportHistoryDropdown.tsx | 2 +- 14 files changed, 70 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 9128e380f..0a27f0333 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "@datadog/browser-logs": "^5.23.3", "@dydxprotocol/v4-abacus": "1.12.18", "@dydxprotocol/v4-client-js": "1.10.0", - "@dydxprotocol/v4-localization": "^1.1.215", + "@dydxprotocol/v4-localization": "^1.1.216", "@dydxprotocol/v4-proto": "^7.0.0-dev.0", "@emotion/is-prop-valid": "^1.3.0", "@ethersproject/providers": "^5.7.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ee2b05992..8d5ab56f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ dependencies: specifier: 1.10.0 version: 1.10.0 '@dydxprotocol/v4-localization': - specifier: ^1.1.215 - version: 1.1.215 + specifier: ^1.1.216 + version: 1.1.216 '@dydxprotocol/v4-proto': specifier: ^7.0.0-dev.0 version: 7.0.0-dev.0 @@ -3061,8 +3061,8 @@ packages: - utf-8-validate dev: false - /@dydxprotocol/v4-localization@1.1.215: - resolution: {integrity: sha512-cJystgZn7noJCvE4kF/WRbZdLWI/8SDbVDU0tBwuWlPWWcgeh7WI9ECCaQF81Y5mrrDxWaij3o7fstgOrRGSQQ==} + /@dydxprotocol/v4-localization@1.1.216: + resolution: {integrity: sha512-Fy9GCfQwffwl9xaGTFM8+gzQln1Ye95amkRgS/0/Kjjd4ciyaS2+lgSiO2Tb0MTHAF3fxm/Z9Hmi3TS4rlf36g==} dev: false /@dydxprotocol/v4-proto@7.0.0-dev.0: diff --git a/src/components/Output.tsx b/src/components/Output.tsx index cb301d024..b9cec4da2 100644 --- a/src/components/Output.tsx +++ b/src/components/Output.tsx @@ -404,9 +404,23 @@ export const Output = ({ case OutputType.Percent: case OutputType.SmallPercent: case OutputType.Multiple: { + const formattedNumber = formatNumberOutput(value, type, { + decimalSeparator, + groupSeparator, + selectedLocale, + useGrouping, + fractionDigits, + minimumFractionDigits, + roundingMode, + showSign: ShowSign.None, + }); + + const renderedNumber = ; + const hasValue = value !== null && value !== undefined; - const isNegative = MustBigNumber(value).isNegative(); - const isPositive = MustBigNumber(value).isPositive() && !MustBigNumber(value).isZero(); + const containsNonZeroNumber = /[1-9]/.test(formattedNumber); + const isNegative = MustBigNumber(value).isNegative() && containsNonZeroNumber; + const isPositive = MustBigNumber(value).isPositive() && containsNonZeroNumber; const sign: string | undefined = { [ShowSign.Both]: isNegative ? UNICODE.MINUS : isPositive ? UNICODE.PLUS : undefined, @@ -414,21 +428,6 @@ export const Output = ({ [ShowSign.None]: undefined, }[showSign]; - const renderedNumber = ( - - ); return ( <$Number key={value?.toString()} diff --git a/src/components/ToggleGroup.tsx b/src/components/ToggleGroup.tsx index fa49a74b1..783e437b2 100644 --- a/src/components/ToggleGroup.tsx +++ b/src/components/ToggleGroup.tsx @@ -98,4 +98,6 @@ const $Root = styled(Root)<{ overflow: 'scroll' | 'wrap' }>` const $Label = styled.div` ${layoutMixins.textTruncate} + // don't truncate 2 characters + min-width: 1rem; `; diff --git a/src/lib/do.ts b/src/lib/do.ts index 4b8d69dd2..16375f8c6 100644 --- a/src/lib/do.ts +++ b/src/lib/do.ts @@ -6,7 +6,7 @@ type NonNullableArray = { [K in keyof T]: NonNullable; }; -export function runIf( +export function mapIfPresent( ...args: [...Args, (...args: NonNullableArray) => T] ): T | undefined { if ([...args].some((f) => f == null)) { diff --git a/src/pages/portfolio/AccountOverviewSection.tsx b/src/pages/portfolio/AccountOverviewSection.tsx index 68936bfc7..075e9364d 100644 --- a/src/pages/portfolio/AccountOverviewSection.tsx +++ b/src/pages/portfolio/AccountOverviewSection.tsx @@ -23,7 +23,7 @@ import { getSubaccount } from '@/state/accountSelectors'; import { useAppSelector } from '@/state/appTypes'; import { track } from '@/lib/analytics/analytics'; -import { runIf } from '@/lib/do'; +import { mapIfPresent } from '@/lib/do'; import { isTruthy } from '@/lib/isTruthy'; import { testFlags } from '@/lib/testFlags'; import { orEmptyObj } from '@/lib/typeUtils'; @@ -60,7 +60,7 @@ export const AccountOverviewSection = () => { const { equity, freeCollateral } = orEmptyObj(useAppSelector(getSubaccount, shallowEqual)); const { balanceUsdc: vaultBalance } = orEmptyObj(useLoadedVaultAccount().data); - const totalValue = runIf(equity?.current, (e) => e + (vaultBalance ?? 0)); + const totalValue = mapIfPresent(equity?.current, (e) => e + (vaultBalance ?? 0)); const handleViewVault = useCallback(() => { track(AnalyticsEvents.ClickViewVaultFromOverview()); @@ -81,8 +81,8 @@ export const AccountOverviewSection = () => { }, { id: 'open-positions', - label: stringGetter({ key: STRING_KEYS.OPEN_POSITIONS }), - amount: runIf(equity?.current, freeCollateral?.current, (e, f) => e - f), + label: stringGetter({ key: STRING_KEYS.POSITION_MARGIN }), + amount: mapIfPresent(equity?.current, freeCollateral?.current, (e, f) => e - f), color: ColorToken.Green2, }, (showVaults || (vaultBalance ?? 0) > 0.01) && { diff --git a/src/pages/portfolio/History.tsx b/src/pages/portfolio/History.tsx index 505ca1942..1d631e626 100644 --- a/src/pages/portfolio/History.tsx +++ b/src/pages/portfolio/History.tsx @@ -44,7 +44,7 @@ export const History = () => { }, enableVaults && { value: HistoryRoute.VaultTransfers, - label:

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

, + label:

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

, href: HistoryRoute.VaultTransfers, tag: 'USDC', }, diff --git a/src/pages/portfolio/PortfolioNavMobile.tsx b/src/pages/portfolio/PortfolioNavMobile.tsx index 9aa12241d..52f0b1661 100644 --- a/src/pages/portfolio/PortfolioNavMobile.tsx +++ b/src/pages/portfolio/PortfolioNavMobile.tsx @@ -57,7 +57,7 @@ export const PortfolioNavMobile = () => { }, enableVaults && { value: `${AppRoute.Portfolio}/${PortfolioRoute.History}/${HistoryRoute.VaultTransfers}`, - label: stringGetter({ key: STRING_KEYS.MEGAVAULT_TRANSFERS }), + label: stringGetter({ key: STRING_KEYS.VAULT_TRANSFERS }), description: stringGetter({ key: STRING_KEYS.MEGAVAULT_TRANSFERS_DESCRIPTION }), }, // TODO: TRCL-1693 - re-enable when Payments are ready diff --git a/src/pages/vaults/VaultDepositWithdrawForm.tsx b/src/pages/vaults/VaultDepositWithdrawForm.tsx index c2b88bdb7..cfb5f1516 100644 --- a/src/pages/vaults/VaultDepositWithdrawForm.tsx +++ b/src/pages/vaults/VaultDepositWithdrawForm.tsx @@ -56,9 +56,10 @@ import { import { track } from '@/lib/analytics/analytics'; import { dd } from '@/lib/analytics/datadog'; import { assertNever } from '@/lib/assertNever'; -import { runFn } from '@/lib/do'; -import { MustBigNumber } from '@/lib/numbers'; +import { mapIfPresent, runFn } from '@/lib/do'; +import { MustBigNumber, getNumberSign } from '@/lib/numbers'; import { safeAssign } from '@/lib/objectHelpers'; +import { sleep } from '@/lib/timeUtils'; import { orEmptyObj } from '@/lib/typeUtils'; // errors we don't want to show aggressive visual cues about, just disable submit @@ -69,7 +70,7 @@ type VaultDepositWithdrawFormProps = { onSuccess?: () => void; }; -const INDEXER_LAG_ALLOWANCE = timeUnits.second * 2; +const INDEXER_LAG_ALLOWANCE = timeUnits.second * 2.5; const $SmallIcon = styled(Icon)<{ $hasError?: boolean }>` ${({ $hasError }) => ($hasError ? 'color: var(--color-error);' : 'color: var(--color-success);')} @@ -206,6 +207,7 @@ export const VaultDepositWithdrawForm = ({ } await depositToMegavault(cachedAmount); + await sleep(INDEXER_LAG_ALLOWANCE); track( AnalyticsEvents.SuccessfulVaultOperation({ @@ -261,6 +263,7 @@ export const VaultDepositWithdrawForm = ({ submissionData?.withdraw?.shares, submissionData?.withdraw?.minAmount ); + await sleep(INDEXER_LAG_ALLOWANCE); const events = (result as IndexedTx)?.events; const actualAmount = events @@ -328,7 +331,6 @@ export const VaultDepositWithdrawForm = ({ console.error('Error submitting megavault transaction', e); } finally { forceRefreshVaultAccount(); - setTimeout(() => forceRefreshVaultAccount(), INDEXER_LAG_ALLOWANCE); forceRefreshVault(); setIsSubmitting(false); } @@ -347,6 +349,13 @@ export const VaultDepositWithdrawForm = ({ type={OutputType.Fiat} value={freeCollateral?.current} newValue={freeCollateralUpdated} + sign={getNumberSign( + mapIfPresent( + freeCollateralUpdated, + freeCollateral?.current, + (updated, cur) => updated - cur + ) + )} withDiff={ MustBigNumber(amount).gt(0) && freeCollateralUpdated != null && @@ -359,6 +368,9 @@ export const VaultDepositWithdrawForm = ({ type={OutputType.Fiat} value={userBalance} newValue={userBalanceUpdated} + sign={getNumberSign( + mapIfPresent(userBalanceUpdated, userBalance ?? 0.0, (updated, cur) => updated - cur) + )} withDiff={ MustBigNumber(amount).gt(0) && userBalanceUpdated != null && @@ -371,6 +383,13 @@ export const VaultDepositWithdrawForm = ({ type={OutputType.Fiat} value={userAvailableBalance} newValue={userAvailableUpdated} + sign={getNumberSign( + mapIfPresent( + userAvailableUpdated, + userAvailableBalance ?? 0.0, + (updated, cur) => updated - cur + ) + )} withDiff={ MustBigNumber(amount).gt(0) && userAvailableUpdated != null && @@ -383,6 +402,9 @@ export const VaultDepositWithdrawForm = ({ type={OutputType.Percent} value={marginUsage?.current} newValue={marginUsageUpdated} + sign={getNumberSign( + mapIfPresent(marginUsage?.current, marginUsageUpdated, (updated, cur) => updated - cur) + )} withDiff={ MustBigNumber(amount).gt(0) && marginUsageUpdated != null && diff --git a/src/pages/vaults/VaultInfoSections.tsx b/src/pages/vaults/VaultInfoSections.tsx index 666b29a72..db8f8c92c 100644 --- a/src/pages/vaults/VaultInfoSections.tsx +++ b/src/pages/vaults/VaultInfoSections.tsx @@ -109,7 +109,7 @@ export const VaultPositionsSection = ({ className }: { className?: string }) => return (
- {stringGetter({ key: STRING_KEYS.OPEN_POSITIONS })}{' '} + {stringGetter({ key: STRING_KEYS.POSITIONS })}{' '} {numPositions} diff --git a/src/pages/vaults/VaultLockedSharesTable.tsx b/src/pages/vaults/VaultLockedSharesTable.tsx index b5a0e86d1..efdae70d0 100644 --- a/src/pages/vaults/VaultLockedSharesTable.tsx +++ b/src/pages/vaults/VaultLockedSharesTable.tsx @@ -17,7 +17,7 @@ import { Button } from '@/components/Button'; import { Output, OutputType } from '@/components/Output'; import { ColumnDef, Table } from '@/components/Table'; -import { runIf } from '@/lib/do'; +import { mapIfPresent } from '@/lib/do'; export const VaultLockedSharesCard = ({ className }: { className?: string }) => { const stringGetter = useStringGetter(); @@ -75,7 +75,7 @@ const VaultLockedSharesTable = ({ getCellValue: (row) => row.unlockBlockHeight, label: stringGetter({ key: STRING_KEYS.AVAILABLE }), renderCell: ({ unlockBlockHeight }) => { - const estimatedUnlockMs = runIf( + const estimatedUnlockMs = mapIfPresent( unlockBlockHeight, height, (unblock, actual) => new Date().valueOf() + (unblock - actual) * 1000 diff --git a/src/pages/vaults/VaultPnlChart.tsx b/src/pages/vaults/VaultPnlChart.tsx index e32fe158b..2fc12b804 100644 --- a/src/pages/vaults/VaultPnlChart.tsx +++ b/src/pages/vaults/VaultPnlChart.tsx @@ -162,7 +162,7 @@ export const VaultPnlChart = ({ className }: VaultPnlChartProps) => { }, []); const chartDotsBackground = useAppSelector(getChartDotBackground); - const { isMobile } = useBreakpoints(); + const { isMobile, isDesktopSmall } = useBreakpoints(); const onVisibleDataChange = useCallback((inRangeData: VaultPnlDatum[]) => { setVisibleTimeRange( @@ -201,7 +201,11 @@ export const VaultPnlChart = ({ className }: VaultPnlChartProps) => {
{hoveredTime != null ? ( - + ) : ( )} @@ -232,7 +236,7 @@ export const VaultPnlChart = ({ className }: VaultPnlChartProps) => { series={series} yAxisOrientation="right" margin={{ - left: 0, + left: isDesktopSmall ? 20 : 0, right: isMobile ? 20 : 60, top: 24, bottom: 32, @@ -240,8 +244,8 @@ export const VaultPnlChart = ({ className }: VaultPnlChartProps) => { padding={{ left: 0.01, right: 0.01, - top: 0.05, - bottom: 0, + top: 0.1, + bottom: 0.1, }} tickFormatY={tickFormatY} onVisibleDataChange={onVisibleDataChange} diff --git a/src/pages/vaults/VaultPositionsTable.tsx b/src/pages/vaults/VaultPositionsTable.tsx index 047cb0a6a..6c2edf011 100644 --- a/src/pages/vaults/VaultPositionsTable.tsx +++ b/src/pages/vaults/VaultPositionsTable.tsx @@ -29,7 +29,7 @@ import { orEmptyRecord } from '@/lib/typeUtils'; type VaultTableRow = VaultPosition; -const VAULT_PAGE_SIZE = 50 as const; +const VAULT_PAGE_SIZE = 20 as const; export const VaultPositionsTable = ({ className }: { className?: string }) => { const stringGetter = useStringGetter(); const navigate = useNavigate(); diff --git a/src/views/ExportHistoryDropdown.tsx b/src/views/ExportHistoryDropdown.tsx index 9887c3bbc..452ed1726 100644 --- a/src/views/ExportHistoryDropdown.tsx +++ b/src/views/ExportHistoryDropdown.tsx @@ -358,7 +358,7 @@ export const ExportHistoryDropdown = (props: ExportHistoryDropdownProps) => { testFlags.enableVaults && { label: ( {