Last fixes
- Pending Delegate events with registry-miss identity keep explorer navigation; unbonded label limited to pending Undelegate rows (`isPendingUndelegateWithRegistryMiss`, `formatPendingDelegationLinkLabel`). - Tests in `delegationIdentity.test.ts`.
This commit is contained in:
@@ -319,28 +319,9 @@ export const DelegationList: FCWithChildren<{
|
|||||||
Pending
|
Pending
|
||||||
</Typography>
|
</Typography>
|
||||||
<Stack spacing={2}>
|
<Stack spacing={2}>
|
||||||
{pendingItems.map((item: any, index: number) => {
|
{pendingItems.map((item: any, index: number) => (
|
||||||
if (
|
<PendingDelegationCard key={pendingKey(item, `p-${index}`)} item={item} explorerUrl={explorerUrl} />
|
||||||
item.event &&
|
))}
|
||||||
item.event.kind === 'Delegate' &&
|
|
||||||
(!item.node_identity || item.node_identity === '')
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<PendingDelegationCard
|
|
||||||
key={pendingKey(item, `d-${index}`)}
|
|
||||||
item={{
|
|
||||||
...item,
|
|
||||||
node_identity: `Mix Identity Key ${item.event.mix_id}`,
|
|
||||||
}}
|
|
||||||
explorerUrl={explorerUrl}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PendingDelegationCard key={pendingKey(item, `p-${index}`)} item={item} explorerUrl={explorerUrl} />
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -2,11 +2,16 @@ import React from 'react';
|
|||||||
import { Box, Chip, Paper, Stack, Tooltip, Typography } from '@mui/material';
|
import { Box, Chip, Paper, Stack, Tooltip, Typography } from '@mui/material';
|
||||||
import { WrappedDelegationEvent } from '@nymproject/types';
|
import { WrappedDelegationEvent } from '@nymproject/types';
|
||||||
import { TauriLink as Link } from 'src/components/TauriLinkWrapper';
|
import { TauriLink as Link } from 'src/components/TauriLinkWrapper';
|
||||||
import { formatDelegationNodeIdentityForDisplay, isUnbondedNodeIdentity } from 'src/utils/delegationIdentity';
|
import {
|
||||||
|
formatDelegationNodeIdentityForDisplay,
|
||||||
|
formatPendingDelegationLinkLabel,
|
||||||
|
isPendingUndelegateWithRegistryMiss,
|
||||||
|
} from 'src/utils/delegationIdentity';
|
||||||
|
|
||||||
export const PendingDelegationCard = ({ item, explorerUrl }: { item: WrappedDelegationEvent; explorerUrl: string }) => {
|
export const PendingDelegationCard = ({ item, explorerUrl }: { item: WrappedDelegationEvent; explorerUrl: string }) => {
|
||||||
|
const pendingUndelegateRegistryMiss = isPendingUndelegateWithRegistryMiss(item);
|
||||||
const displayIdentity = formatDelegationNodeIdentityForDisplay(item.node_identity, item.event.mix_id);
|
const displayIdentity = formatDelegationNodeIdentityForDisplay(item.node_identity, item.event.mix_id);
|
||||||
const nodeIsUnbonded = isUnbondedNodeIdentity(item.node_identity);
|
const linkLabel = formatPendingDelegationLinkLabel(item.node_identity, item.event.mix_id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper
|
<Paper
|
||||||
@@ -20,7 +25,7 @@ export const PendingDelegationCard = ({ item, explorerUrl }: { item: WrappedDele
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack spacing={1.5} direction={{ xs: 'column', sm: 'row' }} alignItems={{ sm: 'center' }} flexWrap="wrap">
|
<Stack spacing={1.5} direction={{ xs: 'column', sm: 'row' }} alignItems={{ sm: 'center' }} flexWrap="wrap">
|
||||||
{nodeIsUnbonded ? (
|
{pendingUndelegateRegistryMiss ? (
|
||||||
<Typography variant="body2" color="text.secondary">
|
<Typography variant="body2" color="text.secondary">
|
||||||
{displayIdentity}
|
{displayIdentity}
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -28,7 +33,7 @@ export const PendingDelegationCard = ({ item, explorerUrl }: { item: WrappedDele
|
|||||||
<Link
|
<Link
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href={`${explorerUrl}/nodes/${item.event.mix_id}`}
|
href={`${explorerUrl}/nodes/${item.event.mix_id}`}
|
||||||
text={`${item.node_identity.slice(0, 6)}...${item.node_identity.slice(-6)}`}
|
text={linkLabel}
|
||||||
color="text.primary"
|
color="text.primary"
|
||||||
noIcon
|
noIcon
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ import {
|
|||||||
UNBONDED_NODE_IDENTITY_PREFIX,
|
UNBONDED_NODE_IDENTITY_PREFIX,
|
||||||
formatUnbondedNodeLabel,
|
formatUnbondedNodeLabel,
|
||||||
formatDelegationNodeIdentityForDisplay,
|
formatDelegationNodeIdentityForDisplay,
|
||||||
|
formatPendingDelegationLinkLabel,
|
||||||
isFullyUnbondedDelegation,
|
isFullyUnbondedDelegation,
|
||||||
|
isPendingUndelegateWithRegistryMiss,
|
||||||
isUnbondedNodeIdentity,
|
isUnbondedNodeIdentity,
|
||||||
} from './delegationIdentity';
|
} from './delegationIdentity';
|
||||||
|
import { buildPendingDelegateEvent, buildPendingUndelegateEvent } from './unbondedDelegation.fixture';
|
||||||
|
|
||||||
describe('delegationIdentity', () => {
|
describe('delegationIdentity', () => {
|
||||||
it('treats empty identity as unbonded', () => {
|
it('treats empty identity as unbonded', () => {
|
||||||
@@ -35,4 +38,20 @@ describe('delegationIdentity', () => {
|
|||||||
'2Abcdefghijklmnopqrstuvwxyz1234567890',
|
'2Abcdefghijklmnopqrstuvwxyz1234567890',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('uses unbonded label only for pending undelegate registry misses', () => {
|
||||||
|
const pendingDelegate = buildPendingDelegateEvent(`unbonded:${42}`);
|
||||||
|
const pendingUndelegate = buildPendingUndelegateEvent(`unbonded:${42}`);
|
||||||
|
|
||||||
|
expect(isPendingUndelegateWithRegistryMiss(pendingDelegate)).toBe(false);
|
||||||
|
expect(isPendingUndelegateWithRegistryMiss(pendingUndelegate)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats pending delegate explorer link label by mix id when identity lookup missed', () => {
|
||||||
|
expect(formatPendingDelegationLinkLabel('', 788)).toBe('Mix 788');
|
||||||
|
expect(formatPendingDelegationLinkLabel('unbonded:788', 788)).toBe('Mix 788');
|
||||||
|
expect(formatPendingDelegationLinkLabel('2Abcdefghijklmnopqrstuvwxyz1234567890', 788)).toBe(
|
||||||
|
'2Abcde...567890',
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { DelegationWithEverything } from '@nymproject/types';
|
import type { DelegationWithEverything, WrappedDelegationEvent } from '@nymproject/types';
|
||||||
|
|
||||||
export const UNBONDED_NODE_IDENTITY_PREFIX = 'unbonded:';
|
export const UNBONDED_NODE_IDENTITY_PREFIX = 'unbonded:';
|
||||||
|
|
||||||
@@ -25,3 +25,16 @@ export function formatDelegationNodeIdentityForDisplay(nodeIdentity: string, mix
|
|||||||
}
|
}
|
||||||
return nodeIdentity;
|
return nodeIdentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isPendingUndelegateWithRegistryMiss(
|
||||||
|
item: Pick<WrappedDelegationEvent, 'node_identity' | 'event'>,
|
||||||
|
): boolean {
|
||||||
|
return item.event.kind === 'Undelegate' && isUnbondedNodeIdentity(item.node_identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatPendingDelegationLinkLabel(nodeIdentity: string, mixId: number): string {
|
||||||
|
if (!nodeIdentity || isUnbondedNodeIdentity(nodeIdentity)) {
|
||||||
|
return `Mix ${mixId}`;
|
||||||
|
}
|
||||||
|
return `${nodeIdentity.slice(0, 6)}...${nodeIdentity.slice(-6)}`;
|
||||||
|
}
|
||||||
|
|||||||
@@ -69,3 +69,19 @@ export function buildPendingUndelegateEvent(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildPendingDelegateEvent(
|
||||||
|
nodeIdentity: string,
|
||||||
|
mixId: number = EXAMPLE_UNBONDED_MIX_ID,
|
||||||
|
): WrappedDelegationEvent {
|
||||||
|
return {
|
||||||
|
node_identity: nodeIdentity,
|
||||||
|
event: {
|
||||||
|
kind: 'Delegate',
|
||||||
|
mix_id: mixId,
|
||||||
|
address: EXAMPLE_DELEGATOR_ADDRESS,
|
||||||
|
amount: { amount: '1000000', denom: 'nym' },
|
||||||
|
proxy: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user