Skip to content
Draft
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2af4952
fix: correct typo for website in english translation (#1101)
kennyzlei Dec 18, 2024
a6a1ee8
initial commit
mvadari Mar 31, 2025
1129c90
get something working
mvadari Mar 31, 2025
adbd35c
get sidebar working
mvadari Mar 31, 2025
ed6d9ef
link from metadata
mvadari Mar 31, 2025
7997ddb
basic deleted object support
mvadari Mar 31, 2025
b05c038
get "no entry exists" working
mvadari Mar 31, 2025
6d66b28
clean up translations
mvadari Mar 31, 2025
68af77e
clean up css
mvadari Mar 31, 2025
a774d6b
redirect accounts
mvadari Mar 31, 2025
7e1845b
fix linting issues
mvadari Mar 31, 2025
b4d3eff
add links to all metadata objects
mvadari Mar 31, 2025
12145f6
add more redirects and links
mvadari Mar 31, 2025
c8133d5
redirect AMM
mvadari Apr 1, 2025
d3d6dcc
Merge branch 'staging' into entry-page
mvadari Apr 8, 2025
f2dd700
Merge branch 'staging' into entry-page
mvadari Apr 9, 2025
7fceabb
Merge branch 'staging' into entry-page
mvadari May 6, 2025
20433a2
Merge branch 'staging' into entry-page
mvadari May 13, 2025
e74fcdf
Merge branch 'staging' into entry-page
mvadari May 15, 2025
94ab2f9
Merge branch 'main' into entry-page
mvadari May 20, 2025
61746da
Merge branch 'staging' into entry-page
mvadari May 20, 2025
cca5a1e
Merge branch 'staging' into entry-page
mvadari Oct 21, 2025
ff7e79c
run linter
mvadari Oct 21, 2025
c2abd3f
Merge branch 'staging' into entry-page
mvadari Jan 5, 2026
7b21c84
Merge branch 'staging' into entry-page
mvadari Jan 6, 2026
83b8d66
Merge branch 'staging' into entry-page
mvadari Jan 21, 2026
c5c7342
Merge branch 'staging' into entry-page
mvadari Feb 11, 2026
44dd2bc
Merge branch 'staging' into entry-page
mvadari Feb 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions public/locales/en-US/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
"close_request": "close channel request",
"renew_channel": "renew chanel",
"payment_channel_closed": "payment channel closed",
"paychannel_node_line1": "It <1><0>{{action}}</0></1> a PayChannel node from <3><0>{{account}}</0></3> to <5><0>{{counterAccount}}</0></5>",
"paychannel_node_line1": "It <1><0>{{action}}</0></1> a PayChannel <3><0>{{node}}</0></3> from <5><0>{{account}}</0></5> to <7><0>{{counterAccount}}</0></7>",
"paychannel_amount_changed": "Amount changed by <1><0>{{difference}}</0><1><0>{{currency}}</0></1></1> from <3><0>{{previous}}</0><1><0>{{currency}}</0></1></3> to <5><0>{{final}}</0><1><0>{{currency}}</0></1></5>",
"paychannel_balance_changed": "Balance changed by <1><0>{{difference}}</0><1><0>{{currency}}</0></1></1> from <3><0>{{previous}}</0><1><0>{{currency}}</0></1></3> to <5><0>{{final}}</0><1><0>{{currency}}</0></1></5>",
"setfee_fees_description": "Future transactions will require a minimum fee of <amount />.",
Expand Down Expand Up @@ -257,20 +257,20 @@
"meta": "Meta",
"number_of_affected_node": "It affected {{count}} nodes in the ledger:",
"nodes_type": "{{action}} nodes",
"node_meta_type": "It {{action}} a node with type",
"transaction_balance_line_one": "It <1><0>{{action}}</0></1> a <3><0>{{currency}}</0></3> RippleState node between <5><0>{{account}}</0></5> and <7><0>{{counterAccount}}</0></7>",
"node_meta_type": "It {{action}} a <Link>node</Link> with type",
"transaction_balance_line_one": "It <1><0>{{action}}</0></1> a <3><0>{{currency}}</0></3> RippleState <5><0>{{node}}</0></5> between <7><0>{{account}}</0></7> and <9><0>{{counterAccount}}</0></9>",
"transaction_balance_line_two": "Balance changed by <1><0>{{change}}</0></1> from <3><0>{{previousBalance}}</0></3> to <5><0>{{finalBalance}}</0></5>",
"transaction_outstanding_balance_line_two": "Outstanding balance changed by <1><0>{{change}}</0></1> from <3><0>{{previousBalance}}</0></3> to <5><0>{{finalBalance}}</0></5>",
"transaction_owned_directory": "It {{action}} a DirectoryNode node owned by",
"transaction_unowned_directory": "It {{action}} a DirectoryNode node",
"transaction_owned_directory": "It {{action}} a DirectoryNode <Link>node</Link> owned by",
"transaction_unowned_directory": "It {{action}} a DirectoryNode <Link>node</Link>",
"transaction_mptoken_line_one": "It <1><0>{{action}}</0></1> an MPToken node of <3><0>{{account}}</0></3>",
"transaction_mpt_issuance_line_one": "It <1><0>{{action}}</0></1> an MPTokenIssuance node of <3><0>{{account}}</0></3>",
"transaction_mpt_issuance_line_one": "It <1><0>{{action}}</0></1> an MPTokenIssuance <3><0>node</0></3> of <5><0>{{account}}</0></5>",
"owned_account_root": "It {{action}} the AccountRoot node of",
"unowned_account_root": "It {{action}} the AccountRoot node",
"account_balance_increased": "Balance increased by <1><0>{{difference}}</0><1><0>{{currency}}</0></1></1> from <3><0>{{previous}}</0><1><0>{{currency}}</0></1></3> to <5><0>{{final}}</0><1><0>{{currency}}</0></1></5>",
"account_balance_decreased": "Balance decreased by <1><0>{{difference}}</0><1><0>{{currency}}</0></1></1> from <3><0>{{previous}}</0><1><0>{{currency}}</0></1></3> to <5><0>{{final}}</0><1><0>{{currency}}</0></1></5>",
"decreased_from_to": "decreased by <1><0>{{change}}</0></1> from <3><0>{{previous}}</0></3> to <5><0>{{final}}</0></5>",
"offer_node_meta": "It <1><0>{{action}}</0></1> a <3><0>{{pair}}</0></3> offer node owned by <5><0>{{account}}</0></5> with sequence # <7><0>{{sequence}}</0></7>",
"offer_node_meta": "It <1><0>{{action}}</0></1> a <3><0>{{pair}}</0></3> offer <5><0>{{node}}</0></5> owned by <7><0>{{account}}</0></7> with sequence # <9><0>{{sequence}}</0></9>",
"offer_replaces": "This offer replaces the existing offer #",
"offer_partially_filled": "The offer was partially filled",
"offer_filled": "The offer was filled",
Expand Down Expand Up @@ -576,5 +576,15 @@
"load_fee_description": "Current reference transaction cost (base fee) for this ledger version",
"nUnl_description": "No. of validators in NegativeUNL (nUNL)",
"computation_allowance": "Computation Allowance",
"gas": "Gas"
"gas": "Gas",
"prev_ledger_index": "Previous Ledger Index",
"prev_tx_id": "Previous Modifying Transaction",
"entry_not_found": "Entry not found",
"entry_empty_title": "No entry hash supplied",
"entry_empty_hint": "Enter a entry hash in the search box",
"check_entry_id": "Please check your entry ID.",
"entry_short": "Entry",
"entry": "Entry",
"invalid_entry_id": "The entry ID is invalid",
"id": "ID"
}
2 changes: 1 addition & 1 deletion src/containers/Accounts/AMM/AMMAccounts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const AMMAccounts = () => {
*/
return getAccountInfo(rippledSocket, accountId)
.then((accountInfo) =>
getLedgerEntry(rippledSocket, { index: accountInfo.AMMID })
getLedgerEntry(rippledSocket, accountInfo.AMMID)
.then((ammLedgerEntry) => {
asset1 = formatAsset(ammLedgerEntry.node.Asset)
asset2 = formatAsset(ammLedgerEntry.node.Asset2)
Expand Down
3 changes: 3 additions & 0 deletions src/containers/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
AMENDMENTS_ROUTE,
AMENDMENT_ROUTE,
MPT_ROUTE,
ENTRY_ROUTE,
NODES_ROUTE,
VALIDATORS_ROUTE,
UPGRADE_STATUS_ROUTE,
Expand All @@ -38,6 +39,7 @@ import { NFT } from '../NFT/NFT'
import { legacyRedirect } from './legacyRedirects'
import { useCustomNetworks } from '../shared/hooks'
import { Amendments } from '../Amendments'
import { Entry } from '../Entry'
import { Amendment } from '../Amendment'
import { MPT } from '../MPT/MPT'
import { Nodes } from '../Network/Nodes'
Expand Down Expand Up @@ -68,6 +70,7 @@ export const AppWrapper = () => {
[LEDGERS_ROUTE, Ledgers],
[LEDGER_ROUTE, Ledger],
[ACCOUNT_ROUTE, AccountsRouter],
[ENTRY_ROUTE, Entry],
[TRANSACTION_ROUTE, Transaction],
[NODES_ROUTE, Nodes],
[VALIDATORS_ROUTE, Validators],
Expand Down
11 changes: 9 additions & 2 deletions src/containers/App/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const ACCOUNT_ROUTE: RouteDefinition<{
tab?: 'assets' | 'transactions'
assetType?: 'issued' | 'nfts' | 'mpts'
}> = {
path: '/accounts/:id?/:tab?/:assetType?',
path: '/accounts/:id/:tab?/:assetType?',
}

export const LEDGERS_ROUTE: RouteDefinition = {
Expand Down Expand Up @@ -49,7 +49,14 @@ export const TRANSACTION_ROUTE: RouteDefinition<{
identifier: string
tab?: 'simple' | 'detailed' | 'raw'
}> = {
path: `/transactions/:identifier?/:tab?`,
path: `/transactions/:identifier/:tab?`,
}

export const ENTRY_ROUTE: RouteDefinition<{
id: string
tab?: 'simple' | 'raw'
}> = {
path: `/entry/:id/:tab?`,
}

export const VALIDATOR_ROUTE: RouteDefinition<{
Expand Down
195 changes: 195 additions & 0 deletions src/containers/Entry/Simple/DefaultSimple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import { isValidClassicAddress } from 'ripple-address-codec'
import { formatAmount } from '../../../rippled/lib/txSummary/formatAmount'
import { Account } from '../../shared/components/Account'
import { Amount } from '../../shared/components/Amount'
import Currency from '../../shared/components/Currency'
import { SimpleGroup } from '../../shared/components/Transaction/SimpleGroup'
import { SimpleRow } from '../../shared/components/Transaction/SimpleRow'

const DEFAULT_ENTRY_ELEMENTS = [
'Account',
'Owner',
'index',
'LedgerEntryType',
'PreviousTxnID',
'PreviousTxnLgrSeq',
'Flags',
'LedgerIndex',
'OwnerNode',
]

const displayKey = (key: string) => key.replace(/([a-z])([A-Z])/g, '$1 $2')

const isCurrency = (value: any) =>
typeof value === 'object' &&
Object.keys(value).length <= 2 &&
(value.issuer == null || typeof value.issuer === 'string') &&
typeof value.currency === 'string'

const isAmount = (amount: any, key: any = null) =>
key === 'Amount' ||
(typeof amount === 'object' &&
Object.keys(amount).length === 3 &&
typeof amount.issuer === 'string' &&
typeof amount.currency === 'string' &&
typeof amount.value === 'string')

const processValue = (value: any) => {
if (typeof value === 'string') {
if (isValidClassicAddress(value)) {
return <Account account={value} />
}
if (value.length > 300) {
return `${value.substring(0, 300)}...`
}
if (value === '') {
return <em>{'<empty>'}</em>
}
if (typeof value === 'object') {
return JSON.stringify(value)
}
return value
}

if (Array.isArray(value)) {
return value.map((childValue) => {
if (
typeof childValue === 'object' &&
Object.keys(childValue).length === 1
) {
const childKey = Object.keys(childValue)[0]
const processed = processValue(childValue[childKey])
return <div key={JSON.stringify(childValue)}>{processed}</div>
}
const processed = processValue(childValue)
return <div key={JSON.stringify(processed)}>{processed}</div>
})
}

if (typeof value === 'object') {
return (
<div className="subgroup">
{Object.entries(value).map(([childKey, childValue]) => (
<div key={childKey} data-test={childKey}>
{`${childKey}: `}
{processValue(childValue)}
</div>
))}
</div>
)
}

return JSON.stringify(value)
}

const getRowNested = (key: any, value: any, uniqueKey: string = '') => {
if (key === 'Amount') {
return (
<SimpleRow
key={`${key}${uniqueKey}`}
label={displayKey(key)}
data-test={key}
>
<Amount value={formatAmount(value)} />
</SimpleRow>
)
}

if (isCurrency(value)) {
return (
<SimpleRow
key={`${key}${uniqueKey}`}
label={displayKey(key)}
data-test={key}
>
<Currency currency={value.currency} issuer={value.issuer} />
</SimpleRow>
)
}

if (isAmount(value, key)) {
return (
<SimpleRow
key={`${key}${uniqueKey}`}
label={displayKey(key)}
data-test={key}
>
<Amount value={formatAmount(value)} />
</SimpleRow>
)
}
return (
<SimpleRow
key={`${key}${uniqueKey}`}
label={displayKey(key)}
data-test={key}
>
{processValue(value)}
</SimpleRow>
)
}

const getRow = (key: any, value: any) => {
if (Array.isArray(value)) {
return (
<div key={key}>
{value.map((innerValue, index) => {
if (
typeof innerValue === 'object' &&
Object.keys(innerValue).length === 1
) {
const innerKey = Object.keys(innerValue)[0]
return (
<SimpleGroup
// eslint-disable-next-line react/no-array-index-key -- okay here
key={`group_${innerKey}_${index}`}
title={displayKey(innerKey)}
data-test={key}
>
{Object.entries(innerValue[innerKey]).map(
([childKey, childValue], index2) =>
getRowNested(childKey, childValue, index2.toString()),
)}
</SimpleGroup>
)
}
return getRowNested(index.toString(), innerValue, index.toString())
})}
</div>
)
}

if (
typeof value === 'object' &&
!isCurrency(value) &&
!isAmount(value, key)
) {
return (
<SimpleGroup key={key} title={displayKey(key)} data-test={key}>
{Object.entries(value).map(([childKey, childValue], index) =>
getRowNested(childKey, childValue, index.toString()),
)}
</SimpleGroup>
)
}

return getRowNested(key, value)
}

export interface EntrySimpleProps<I = any> {
data: {
node: I
}
}

export const DefaultSimple = ({ data }: EntrySimpleProps) => {
const uniqueData = Object.fromEntries(
Object.entries(data.node).filter(
([key, value]) => !DEFAULT_ENTRY_ELEMENTS.includes(key) && value != null,
),
)

return (
<>{Object.entries(uniqueData).map(([key, value]) => getRow(key, value))}</>
)
}
29 changes: 29 additions & 0 deletions src/containers/Entry/Simple/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FC } from 'react'
import { ErrorBoundary } from 'react-error-boundary'
import { useTranslation } from 'react-i18next'
import { transactionTypes } from '../../shared/components/Transaction'
import { DefaultSimple } from './DefaultSimple'

export const Simple: FC<{
data: any
type: string
}> = ({ data, type }) => {
// Locate the component for the left side of the simple tab that is unique per TransactionType.
const { t } = useTranslation()
const SimpleComponent = transactionTypes[type]?.Simple
if (SimpleComponent) {
return (
<ErrorBoundary
fallback={
<div className="error">
<div>{t('component_error')}</div>
<div>{t('try_detailed_raw')}</div>
</div>
}
>
<SimpleComponent data={data} />
</ErrorBoundary>
)
}
return <DefaultSimple data={data} />
}
57 changes: 57 additions & 0 deletions src/containers/Entry/SimpleTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { Account } from '../shared/components/Account'
import { Simple } from './Simple'

import { RouteLink } from '../shared/routing'
import { SimpleRow } from '../shared/components/Transaction/SimpleRow'
import '../shared/css/simpleTab.scss'
import './simpleTab.scss'
import { LEDGER_ROUTE, TRANSACTION_ROUTE } from '../App/routes'
import { BREAKPOINTS } from '../shared/utils'

export const SimpleTab: FC<{ data: any; width: number }> = ({
data,
width,
}) => {
const { t } = useTranslation()

const renderRowIndex = (owner, prevLedgerIndex, prevTx) => (
<>
{owner && (
<SimpleRow label={t('owner')} data-test="owner">
<Account account={owner} />
</SimpleRow>
)}
<SimpleRow label={t('prev_ledger_index')} data-test="prev-ledger-index">
<RouteLink to={LEDGER_ROUTE} params={{ identifier: prevLedgerIndex }}>
{prevLedgerIndex}
</RouteLink>
</SimpleRow>
<SimpleRow label={t('prev_tx_id')} data-test="prev-tx">
<RouteLink to={TRANSACTION_ROUTE} params={{ identifier: prevTx }}>
{prevTx}
</RouteLink>
</SimpleRow>
</>
)

const rowIndex = renderRowIndex(
data?.node?.Owner ?? data?.node?.Account,
data?.node?.PreviousTxnLgrSeq,
data?.node?.PreviousTxnID,
)

return (
<div className="simple-body simple-body-tx">
<div className="rows">
<Simple type={data?.node.LedgerEntryType} data={data} />
{width < BREAKPOINTS.landscape && rowIndex}
</div>
{width >= BREAKPOINTS.landscape && (
<div className="index">{rowIndex}</div>
)}
<div className="clear" />
</div>
)
}
Loading
Loading