diff --git a/src/components/dashboard/Recovery/index.tsx b/src/components/dashboard/Recovery/index.tsx index 2213e74acc..00c1fa9a1f 100644 --- a/src/components/dashboard/Recovery/index.tsx +++ b/src/components/dashboard/Recovery/index.tsx @@ -6,18 +6,31 @@ import RecoveryLogo from '@/public/images/common/recovery.svg' import { WidgetBody, WidgetContainer } from '@/components/dashboard/styled' import { Chip } from '@/components/common/Chip' import { TxModalContext } from '@/components/tx-flow' -import { EnableRecoveryFlow } from '@/components/tx-flow/flows/EnableRecovery' -import { useIsRecoveryEnabled } from '@/hooks/useIsRecoveryEnabled' +import { UpsertRecoveryFlow } from '@/components/tx-flow/flows/UpsertRecovery' +import { useRecovery } from '@/components/recovery/RecoveryContext' +import { useRouter } from 'next/router' +import { AppRoutes } from '@/config/routes' import CheckWallet from '@/components/common/CheckWallet' +import { useHasFeature } from '@/hooks/useChains' +import { FEATURES } from '@/utils/chains' import css from './styles.module.css' export function Recovery(): ReactElement { - const isRecoveryEnabled = useIsRecoveryEnabled() + const router = useRouter() const { setTxFlow } = useContext(TxModalContext) + const [recovery] = useRecovery() + const supportsRecovery = useHasFeature(FEATURES.RECOVERY) - const onClick = () => { - setTxFlow() + const onEnable = () => { + setTxFlow() + } + + const onEdit = () => { + router.push({ + pathname: AppRoutes.settings.recovery, + query: router.query, + }) } return ( @@ -42,14 +55,23 @@ export function Recovery(): ReactElement { Ensure that you never lose access to your funds by choosing a guardian to recover your account. - - {isRecoveryEnabled && ( + {supportsRecovery && ( - {(isOk) => ( - - )} + {(isOk) => { + if (!recovery || recovery.length === 0) { + return ( + + ) + } + + return ( + + ) + }} )} diff --git a/src/components/dashboard/RecoveryHeader/index.test.tsx b/src/components/dashboard/RecoveryHeader/index.test.tsx index c1dc830935..5e82d231f9 100644 --- a/src/components/dashboard/RecoveryHeader/index.test.tsx +++ b/src/components/dashboard/RecoveryHeader/index.test.tsx @@ -2,56 +2,65 @@ import { BigNumber } from 'ethers' import { _RecoveryHeader } from '.' import { render } from '@/tests/test-utils' -import type { RecoveryQueueItem } from '@/components/recovery/RecoveryContext' +import { RecoveryContext } from '@/components/recovery/RecoveryContext' describe('RecoveryHeader', () => { it('should not render a widget if the chain does not support recovery', () => { + const queue = [{ validFrom: BigNumber.from(0) }] as any + const { container } = render( - <_RecoveryHeader - isOwner - isGuardian - queue={[{ validFrom: BigNumber.from(0) } as RecoveryQueueItem]} - supportsRecovery={false} - />, + + <_RecoveryHeader isOwner isGuardian queue={queue} supportsRecovery={false} /> + , ) expect(container).toBeEmptyDOMElement() }) it('should render the in-progress widget if there is a queue for guardians', () => { + const queue = [{ validFrom: BigNumber.from(0) }] as any + const { queryByText } = render( - <_RecoveryHeader - isOwner={false} - isGuardian - queue={[{ validFrom: BigNumber.from(0) } as RecoveryQueueItem]} - supportsRecovery - />, + + <_RecoveryHeader isOwner={false} isGuardian queue={queue} supportsRecovery /> + , ) expect(queryByText('Account recovery in progress')).toBeTruthy() }) it('should render the in-progress widget if there is a queue for owners', () => { + const queue = [{ validFrom: BigNumber.from(0) }] as any + const { queryByText } = render( - <_RecoveryHeader - isOwner - isGuardian={false} - queue={[{ validFrom: BigNumber.from(0) } as RecoveryQueueItem]} - supportsRecovery - />, + + <_RecoveryHeader isOwner isGuardian={false} queue={queue} supportsRecovery /> + , ) expect(queryByText('Account recovery in progress')).toBeTruthy() }) it('should render the proposal widget when there is no queue for guardians', () => { - const { queryByText } = render(<_RecoveryHeader isOwner={false} isGuardian queue={[]} supportsRecovery />) + const queue = [] as any + + const { queryByText } = render( + + <_RecoveryHeader isOwner={false} isGuardian queue={queue} supportsRecovery /> + , + ) expect(queryByText('Recover this Account')).toBeTruthy() }) it('should not render the proposal widget when there is no queue for owners', () => { - const { container } = render(<_RecoveryHeader isOwner isGuardian={false} queue={[]} supportsRecovery />) + const queue = [] as any + + const { container } = render( + + <_RecoveryHeader isOwner isGuardian={false} queue={queue} supportsRecovery /> + , + ) expect(container).toBeEmptyDOMElement() }) diff --git a/src/components/recovery/RecoveryModal/index.test.tsx b/src/components/recovery/RecoveryModal/index.test.tsx index c17a10f27d..5e82d54aad 100644 --- a/src/components/recovery/RecoveryModal/index.test.tsx +++ b/src/components/recovery/RecoveryModal/index.test.tsx @@ -8,6 +8,7 @@ import { safeInfoBuilder } from '@/tests/builders/safe' import { connectedWalletBuilder } from '@/tests/builders/wallet' import * as safeInfo from '@/hooks/useSafeInfo' import { _useDidDismissProposal } from './index' +import { RecoveryContext } from '@/components/recovery/RecoveryContext' import type { RecoveryQueueItem } from '@/components/recovery/RecoveryContext' describe('RecoveryModal', () => { @@ -27,9 +28,11 @@ describe('RecoveryModal', () => { const queue = [{ validFrom: BigNumber.from(0) } as RecoveryQueueItem] const { queryByText } = render( - <_RecoveryModal wallet={wallet} isOwner={false} isGuardian={false} queue={queue}> - Test - , + + <_RecoveryModal wallet={wallet} isOwner={false} isGuardian={false} queue={queue}> + Test + + , ) expect(queryByText('Test')).toBeTruthy() @@ -41,9 +44,11 @@ describe('RecoveryModal', () => { const queue = [] as Array const { queryByText } = render( - <_RecoveryModal wallet={wallet} isOwner={false} isGuardian queue={queue}> - Test - , + + <_RecoveryModal wallet={wallet} isOwner={false} isGuardian queue={queue}> + Test + + , ) expect(queryByText('Test')).toBeTruthy() @@ -55,9 +60,11 @@ describe('RecoveryModal', () => { const queue = [] as Array const { queryByText } = render( - <_RecoveryModal wallet={wallet} isOwner isGuardian={false} queue={queue}> - Test - , + + <_RecoveryModal wallet={wallet} isOwner isGuardian={false} queue={queue}> + Test + + , ) expect(queryByText('Test')).toBeTruthy() @@ -69,9 +76,11 @@ describe('RecoveryModal', () => { const queue = [{ validFrom: BigNumber.from(0) } as RecoveryQueueItem] const { queryByText } = render( - <_RecoveryModal wallet={wallet} isOwner={false} isGuardian queue={queue}> - Test - , + + <_RecoveryModal wallet={wallet} isOwner={false} isGuardian queue={queue}> + Test + + , ) expect(queryByText('Test')).toBeTruthy() @@ -83,9 +92,11 @@ describe('RecoveryModal', () => { const queue = [{ validFrom: BigNumber.from(0) } as RecoveryQueueItem] const { queryByText } = render( - <_RecoveryModal wallet={wallet} isOwner isGuardian={false} queue={queue}> - Test - , + + <_RecoveryModal wallet={wallet} isOwner isGuardian={false} queue={queue}> + Test + + , ) expect(queryByText('Test')).toBeTruthy() @@ -97,9 +108,11 @@ describe('RecoveryModal', () => { const queue = [] as Array const { queryByText } = render( - <_RecoveryModal wallet={wallet} isOwner={false} isGuardian queue={queue}> - Test - , + + <_RecoveryModal wallet={wallet} isOwner={false} isGuardian queue={queue}> + Test + + , ) expect(queryByText('Test')).toBeTruthy() @@ -111,9 +124,11 @@ describe('RecoveryModal', () => { const queue = [] as Array const { queryByText } = render( - <_RecoveryModal wallet={wallet} isOwner isGuardian={false} queue={queue}> - Test - , + + <_RecoveryModal wallet={wallet} isOwner isGuardian={false} queue={queue}> + Test + + , ) expect(queryByText('Test')).toBeTruthy() @@ -136,9 +151,11 @@ describe('RecoveryModal', () => { const queue = [{ validFrom: BigNumber.from(0), transactionHash: faker.string.hexadecimal() } as RecoveryQueueItem] const { queryByText } = render( - <_RecoveryModal wallet={wallet} isOwner isGuardian={false} queue={queue}> - Test - , + + <_RecoveryModal wallet={wallet} isOwner isGuardian={false} queue={queue}> + Test + + , ) expect(queryByText('Test')).toBeTruthy() diff --git a/src/components/settings/Recovery/DelayModifierRow.tsx b/src/components/settings/Recovery/DelayModifierRow.tsx index 44a7c205ed..9a0e77c98d 100644 --- a/src/components/settings/Recovery/DelayModifierRow.tsx +++ b/src/components/settings/Recovery/DelayModifierRow.tsx @@ -8,6 +8,7 @@ import DeleteIcon from '@/public/images/common/delete.svg' import EditIcon from '@/public/images/common/edit.svg' import CheckWallet from '@/components/common/CheckWallet' import { ConfirmRemoveRecoveryModal } from './ConfirmRemoveRecoveryModal' +import { UpsertRecoveryFlow } from '@/components/tx-flow/flows/UpsertRecovery' import type { RecoveryStateItem } from '@/components/recovery/RecoveryContext' export function DelayModifierRow({ delayModifier }: { delayModifier: RecoveryStateItem }): ReactElement | null { @@ -20,8 +21,7 @@ export function DelayModifierRow({ delayModifier }: { delayModifier: RecoverySta } const onEdit = () => { - // TODO: Display flow - setTxFlow(undefined) + setTxFlow() } const onDelete = () => { diff --git a/src/components/settings/Recovery/index.tsx b/src/components/settings/Recovery/index.tsx index 76811a9fc5..e26432a0be 100644 --- a/src/components/settings/Recovery/index.tsx +++ b/src/components/settings/Recovery/index.tsx @@ -2,7 +2,7 @@ import { Alert, Box, Button, Grid, Paper, SvgIcon, Tooltip, Typography } from '@ import { useContext, useMemo } from 'react' import type { ReactElement } from 'react' -import { EnableRecoveryFlow } from '@/components/tx-flow/flows/EnableRecovery' +import { UpsertRecoveryFlow } from '@/components/tx-flow/flows/UpsertRecovery' import { TxModalContext } from '@/components/tx-flow' import { Chip } from '@/components/common/Chip' import ExternalLink from '@/components/common/ExternalLink' @@ -65,6 +65,7 @@ const headCells = [ { id: HeadCells.Actions, label: '', sticky: true }, ] +// TODO: Combine section with spending limits under "Security & Login" as per design export function Recovery(): ReactElement { const { setTxFlow } = useContext(TxModalContext) const [recovery] = useRecovery() @@ -148,7 +149,7 @@ export function Recovery(): ReactElement {