Skip to content

Commit edb2b55

Browse files
authored
Account application (#59)
* feat: account created applications tab * feat: account opted application tab
1 parent fbbec2a commit edb2b55

File tree

9 files changed

+267
-201
lines changed

9 files changed

+267
-201
lines changed

src/features/accounts/components/account-activity-tabs.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
} from './labels'
2525
import { AccountAssetsCreated } from './account-assets-created'
2626
import { AccountAssetsOpted } from './account-assets-opted'
27+
import { AccountApplications } from './account-applications'
2728

2829
type Props = {
2930
account: Account
@@ -60,15 +61,22 @@ export function AccountActivityTabs({ account }: Props) {
6061
{
6162
id: accountCreatedApplicationsTabId,
6263
label: accountCreatedApplicationsTabLabel,
63-
children: '',
64+
children: <AccountApplications applications={account.applicationsCreated} />,
6465
},
6566
{
6667
id: accountOptedApplicationsTabId,
6768
label: accountOptedApplicationsTabLabel,
68-
children: '',
69+
children: <AccountApplications applications={account.applicationsOpted} />,
6970
},
7071
],
71-
[account.address, account.assetsCreated, account.assetsHeld, account.assetsOpted]
72+
[
73+
account.address,
74+
account.applicationsCreated,
75+
account.applicationsOpted,
76+
account.assetsCreated,
77+
account.assetsHeld,
78+
account.assetsOpted,
79+
]
7280
)
7381
return (
7482
<Tabs defaultValue={accountLiveTransactionsTabId}>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { DataTable } from '@/features/common/components/data-table'
2+
import { AccountApplicationSummary } from '../models'
3+
import { ColumnDef } from '@tanstack/react-table'
4+
import { ApplicationLink } from '@/features/applications/components/application-link'
5+
import { ApplicationSummary } from '@/features/applications/models'
6+
7+
type Props = {
8+
applications: AccountApplicationSummary[]
9+
}
10+
11+
const applicationsTableColumns: ColumnDef<ApplicationSummary>[] = [
12+
{
13+
header: 'ID',
14+
accessorFn: (item) => item.id,
15+
cell: (c) => <ApplicationLink applicationId={c.getValue<number>()} />,
16+
},
17+
]
18+
19+
export function AccountApplications({ applications }: Props) {
20+
return <DataTable columns={applicationsTableColumns} data={applications} />
21+
}

src/features/accounts/components/account-info.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export function AccountInfo({ account }: { account: Account }) {
2222
const totalAssetsHeld = account.assetsHeld.length
2323
const totalAssetsCreated = account.assetsCreated.length
2424
const totalAssetsOptedIn = account.assetsHeld.length + account.assetsOpted.length
25+
const totalApplicationsCreated = account.applicationsCreated.length
26+
const totalApplicationsOptedIn = account.applicationsOpted.length
2527

2628
const accountInfoItems = useMemo(() => {
2729
const items = [
@@ -51,11 +53,11 @@ export function AccountInfo({ account }: { account: Account }) {
5153
},
5254
{
5355
dt: accountApplicationsCreatedLabel,
54-
dd: account.totalApplicationsCreated ? account.totalApplicationsCreated : 0,
56+
dd: totalApplicationsCreated,
5557
},
5658
{
5759
dt: accountApplicationsOptedInLabel,
58-
dd: account.totalApplicationsOptedIn ? account.totalApplicationsOptedIn : 0,
60+
dd: totalApplicationsOptedIn,
5961
},
6062
...(account.rekeyedTo
6163
? [
@@ -71,12 +73,12 @@ export function AccountInfo({ account }: { account: Account }) {
7173
account.address,
7274
account.balance,
7375
account.minBalance,
74-
account.totalApplicationsCreated,
75-
account.totalApplicationsOptedIn,
7676
account.rekeyedTo,
7777
totalAssetsHeld,
7878
totalAssetsCreated,
7979
totalAssetsOptedIn,
80+
totalApplicationsCreated,
81+
totalApplicationsOptedIn,
8082
])
8183
return (
8284
<Card aria-label={accountInformationLabel} className={cn('p-4')}>

src/features/accounts/data/account-result.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { AccountResult, Address } from './types'
33
import { algod } from '@/features/common/data'
44
import { atomsInAtom } from '@/features/common/data/atoms-in-atom'
55
import { assetResultsAtom } from '@/features/assets/data'
6+
import { applicationResultsAtom } from '@/features/applications/data'
67

78
const getAccountResult = (address: Address) =>
89
algod
@@ -15,6 +16,7 @@ const getAccountResult = (address: Address) =>
1516
const syncAssociatedDataAndReturnAccountResultAtom = atom(null, async (get, set, address: Address) => {
1617
const accountResult = await getAccountResult(address)
1718
const assetResults = get(assetResultsAtom)
19+
const applicationResults = get(applicationResultsAtom)
1820

1921
const assetsToAdd = (accountResult['created-assets'] ?? []).filter((a) => !assetResults.has(a.index))
2022
if (assetsToAdd.length > 0) {
@@ -28,7 +30,18 @@ const syncAssociatedDataAndReturnAccountResultAtom = atom(null, async (get, set,
2830
return next
2931
})
3032
}
31-
33+
const applicationsToAdd = (accountResult['created-apps'] ?? []).filter((a) => !applicationResults.has(a.id))
34+
if (applicationsToAdd.length > 0) {
35+
set(applicationResultsAtom, (prev) => {
36+
const next = new Map(prev)
37+
applicationsToAdd.forEach((application) => {
38+
if (!next.has(application.id)) {
39+
next.set(application.id, atom(application))
40+
}
41+
})
42+
return next
43+
})
44+
}
3245
return accountResult
3346
})
3447

src/features/accounts/mappers/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ export const asAccount = async (
2727
address: accountResult.address,
2828
balance: microAlgos(accountResult.amount),
2929
minBalance: microAlgos(accountResult['min-balance']),
30-
totalApplicationsCreated: accountResult['total-created-apps'],
31-
totalApplicationsOptedIn: accountResult['total-apps-opted-in'],
30+
applicationsCreated: (accountResult['created-apps'] ?? []).map((app) => ({ id: app.id })),
31+
applicationsOpted: (accountResult['apps-local-state'] ?? []).map((app) => ({ id: app.id })),
3232
assetsHeld,
3333
assetsCreated: await asAccountAssetSummaries(accountResult['created-assets'] ?? [], asAccountAssetSummary),
3434
assetsOpted,

src/features/accounts/models/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount'
22
import { Address } from '../data/types'
33
import { AssetSummary } from '@/features/assets/models'
4+
import { ApplicationId } from '@/features/applications/data/types'
45

56
export type AccountAssetSummary = Omit<AssetSummary, 'clawback'>
67

@@ -9,13 +10,16 @@ export type AssetHolding = {
910
amount: number | bigint
1011
isFrozen: boolean
1112
}
13+
export type AccountApplicationSummary = {
14+
id: ApplicationId
15+
}
1216

1317
export type Account = {
1418
address: Address
1519
balance: AlgoAmount
1620
minBalance: AlgoAmount
17-
totalApplicationsCreated: number
18-
totalApplicationsOptedIn: number
21+
applicationsCreated: AccountApplicationSummary[]
22+
applicationsOpted: AccountApplicationSummary[]
1923
assetsHeld: AssetHolding[]
2024
assetsCreated: AccountAssetSummary[]
2125
assetsOpted: AssetHolding[]

src/features/accounts/pages/account-page.test.tsx

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ describe('account-page', () => {
5353
})
5454
})
5555

56-
describe('when rendering an account with applications', () => {
56+
describe('when rendering an account', () => {
5757
const accountResult = accountResultMother['mainnet-BIQXAK67KSCKN3EJXT4S3RVXUBFOLZ45IQOBTSOQWOSR4LLULBTD54S5IA']().build()
5858
const assetResults = new Map([
5959
[924268058, atom(assetResultMother['mainnet-924268058']().build())],
@@ -95,18 +95,15 @@ describe('account-page', () => {
9595
})
9696
})
9797

98-
describe('when rendering an account with assets', () => {
99-
const accountResult = accountResultMother['mainnet-JY2FRXQP7Q6SYH7QE2HF2XWNE644V6KUH3PYC4SYWPUSEATTDJSNUHMHR4']().build()
98+
describe('when rendering an account with assets and applications', () => {
99+
const accountResult = accountResultMother['mainnet-ORANGESCU7XMR2TFXSFTOHCUHNP6OYEPIKZW3JZANTCDHVQYMGQFYFIDDA']().build()
100100
const assetResults = new Map([
101-
[1205372113, atom(accountResult['created-assets']![0])],
102-
[1205372555, atom(accountResult['created-assets']![1])],
103-
[1205372814, atom(accountResult['created-assets']![2])],
104-
[2254146, atom(assetResultMother['mainnet-2254146']().build())],
105-
[2254149, atom(assetResultMother['mainnet-2254149']().build())],
106-
[2254150, atom(assetResultMother['mainnet-2254150']().build())],
107-
[127745593, atom(assetResultMother['mainnet-127745593']().build())],
108-
[127746157, atom(assetResultMother['mainnet-127746157']().build())],
109-
[127746786, atom(assetResultMother['mainnet-127746786']().build())],
101+
[1336655079, atom(accountResult['created-assets']![0])],
102+
[1284444444, atom(assetResultMother['mainnet-1284444444']().build())],
103+
[1162292622, atom(assetResultMother['mainnet-1162292622']().build())],
104+
[1294765516, atom(assetResultMother['mainnet-1294765516']().build())],
105+
[1355858325, atom(assetResultMother['mainnet-1355858325']().build())],
106+
[1355898842, atom(assetResultMother['mainnet-1355898842']().build())],
110107
])
111108

112109
it('should be rendered with the correct data', () => {
@@ -124,14 +121,14 @@ describe('account-page', () => {
124121
descriptionListAssertion({
125122
container: informationCard,
126123
items: [
127-
{ term: accountAddressLabel, description: 'JY2FRXQP7Q6SYH7QE2HF2XWNE644V6KUH3PYC4SYWPUSEATTDJSNUHMHR4' },
128-
{ term: accountBalanceLabel, description: '12016.438084' },
129-
{ term: accountMinBalanceLabel, description: '1' },
130-
{ term: accountAssetsHeldLabel, description: '3' },
131-
{ term: accountAssetsCreatedLabel, description: '3' },
132-
{ term: accountAssetsOptedInLabel, description: '9' },
133-
{ term: accountApplicationsCreatedLabel, description: '0' },
134-
{ term: accountApplicationsOptedInLabel, description: '0' },
124+
{ term: accountAddressLabel, description: 'ORANGESCU7XMR2TFXSFTOHCUHNP6OYEPIKZW3JZANTCDHVQYMGQFYFIDDA' },
125+
{ term: accountBalanceLabel, description: '123.714752' },
126+
{ term: accountMinBalanceLabel, description: '5.281' },
127+
{ term: accountAssetsHeldLabel, description: '5' },
128+
{ term: accountAssetsCreatedLabel, description: '1' },
129+
{ term: accountAssetsOptedInLabel, description: '6' },
130+
{ term: accountApplicationsCreatedLabel, description: '4' },
131+
{ term: accountApplicationsOptedInLabel, description: '1' },
135132
],
136133
})
137134
const activityTabList = component.getByRole('tablist', { name: accountActivityLabel })

0 commit comments

Comments
 (0)