From 9d7722ef167b62d5619aea7c81812fb23bc1fa9d Mon Sep 17 00:00:00 2001 From: Dawid Sowa Date: Wed, 19 Jun 2024 22:53:40 +0200 Subject: [PATCH] fix: go to dashboard on account address click --- src/components/account/account.tsx | 26 ++++++++- .../linked-wallet/shared-accounts.tsx | 21 +++++++- src/utils/parse-address.test.ts | 53 +++++++++++++++++++ src/utils/parse-address.ts | 19 +++++++ 4 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 src/utils/parse-address.test.ts create mode 100644 src/utils/parse-address.ts diff --git a/src/components/account/account.tsx b/src/components/account/account.tsx index c1da4a25..a4e6a639 100644 --- a/src/components/account/account.tsx +++ b/src/components/account/account.tsx @@ -1,9 +1,11 @@ import { Account as AccountType } from '@radixdlt/radix-dapp-toolkit' +import { RefObject, createRef, useEffect } from 'react' declare global { namespace JSX { interface IntrinsicElements { 'radix-account': { + ref: RefObject label: string address: string appearanceId: number @@ -12,9 +14,31 @@ declare global { } } -export const Account = ({ account }: { account: AccountType }) => { +export const Account = ({ + account, + onLinkClick, +}: { + account: AccountType + onLinkClick?: (ev: CustomEvent) => void +}) => { + const ref = createRef() + + useEffect(() => { + if (!ref.current || !onLinkClick) return + + ref.current.addEventListener('onLinkClick', onLinkClick as EventListener) + + return () => { + if (!ref.current || !onLinkClick) return + ref.current.removeEventListener( + 'onLinkClick', + onLinkClick as EventListener, + ) + } + }, []) return ( { const [isCollapsed, setIsCollapsed] = useState(!props.isJustLinked) + const onLinkClick = async (e: CustomEvent) => { + if (e.detail.type === 'account' && e.detail.data) { + const { networkId } = parseAddress(e.detail.data) + const dashboardUrl = RadixNetworkConfigById[networkId].dashboardUrl + + window.open([dashboardUrl, 'account', e.detail.data].join('/'), '_blank') + } + } + return ( {props.accounts?.map((account) => ( - + ))} diff --git a/src/utils/parse-address.test.ts b/src/utils/parse-address.test.ts new file mode 100644 index 00000000..32245f5a --- /dev/null +++ b/src/utils/parse-address.test.ts @@ -0,0 +1,53 @@ +import { parseAddress } from './parse-address' + +describe('parse address', () => { + const tests: [string, { networkId: number; type: string }][] = [ + [ + 'account_tdx_2_129449mktvws4ww6wyww0dt85fn7md383cdq58307ayfz7g0n9vznfa', + { networkId: 2, type: 'account' }, + ], + [ + 'account_tdx_2_128ex28rgvj4nqsqs7vtha0upknrpspzanfr95t6j6nss225dc47nu4', + { networkId: 2, type: 'account' }, + ], + [ + 'resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd', + { + networkId: 1, + type: 'resource', + }, + ], + [ + 'account_rdx12xezaw0gn9yhld6kplkk3ah7h6y48qgrmjr5e76krxq9hgws4junpr', + { + networkId: 1, + type: 'account', + }, + ], + [ + 'account_tdx_21_128wkep7c2mtdv5d0vvj23kp0rreud09384gru64w992pkmqga0nr87', + { + type: 'account', + networkId: 21, + }, + ], + [ + 'account_sim1cyyavav59dl55jur4eyxqz9wqyjycp2aua9dzduflfeefrfl623wgc', + { + networkId: 242, + type: 'account', + }, + ], + ] + it('should parse address', () => { + tests.forEach(([address, expected]) => { + expect(parseAddress(address)).toEqual(expected) + }) + }) + + it('should throw error on invalid address', () => { + expect(() => parseAddress('invalid')).toThrowError( + 'Invalid address invalid', + ) + }) +}) diff --git a/src/utils/parse-address.ts b/src/utils/parse-address.ts new file mode 100644 index 00000000..da2d026e --- /dev/null +++ b/src/utils/parse-address.ts @@ -0,0 +1,19 @@ +export const parseAddress = ( + address: string, +): { networkId: number; type: string } => { + const match = address.match(/^([a-z]+)_(rdx|sim|tdx_[\d]+_)1(?:[a-z0-9]+)$/) + + if (!match) { + throw new Error(`Invalid address ${address}`) + } + + const [, type, network] = match + + const networkId = + network === 'rdx' ? 1 : network === 'sim' ? 242 : network.split('_')[1] + + return { + networkId: Number(networkId), + type, + } +}