Merge pull request #3982 from nymtech/bug/issue-3981/wallet-delegations-orderby-cp

Wallet: Fix delegation sorting for Cost Params
This commit is contained in:
Tommy Verrall
2023-10-16 16:26:03 +01:00
committed by GitHub
7 changed files with 946 additions and 928 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
- name: Install mdbook plugins
run: |
cargo install --vers "=0.2.2" mdbook-variables && cargo install \
--vers "^1.8.0" mdbook-admonish install && cargo install --vers \
--vers "^1.8.0" mdbook-admonish install --force && cargo install --vers \
"^0.1.2" mdbook-last-changed && cargo install --vers "^0.1.2" mdbook-theme \
&& cargo install --vers "^0.7.7" mdbook-linkcheck
- name: Build all projects in documentation/ & move to ~/dist/docs/
+1 -1
View File
@@ -31,7 +31,7 @@
"@nymproject/mui-theme": "^1.0.0",
"@nymproject/react": "^1.0.0",
"@nymproject/types": "^1.0.0",
"@nymproject/node-tester": ">=1.2.0-rc.10 || ^1",
"@nymproject/node-tester": "^1.0.0",
"@storybook/react": "^6.5.15",
"@tauri-apps/api": "^1.2.0",
"@tauri-apps/tauri-forage": "^1.0.0-beta.2",
@@ -29,7 +29,7 @@ export const items: DelegationWithEverything[] = [
accumulated_by_operator: { amount: '100', denom: 'nym' },
owner: '',
block_height: BigInt(100),
stake_saturation: '0.5',
stake_saturation: '0.25',
avg_uptime_percent: 0.5,
uses_vesting_contract_tokens: false,
pending_events: [],
@@ -38,7 +38,7 @@ export const items: DelegationWithEverything[] = [
{
mix_id: 2,
node_identity: 'DT8S942S8AQs2zKHS9SVo1GyHmuca3pfL2uLhLksJ3D8',
amount: { amount: '100', denom: 'nym' },
amount: { amount: '1010', denom: 'nym' },
delegated_on_iso_datetime: new Date(2021, 1, 2).toDateString(),
unclaimed_rewards: { amount: '0.05', denom: 'nym' },
cost_params: {
@@ -49,11 +49,11 @@ export const items: DelegationWithEverything[] = [
},
},
accumulated_by_delegates: { amount: '50', denom: 'nym' },
accumulated_by_operator: { amount: '100', denom: 'nym' },
accumulated_by_operator: { amount: '200', denom: 'nym' },
owner: '',
block_height: BigInt(4000),
stake_saturation: '0.5',
avg_uptime_percent: 0.1,
stake_saturation: '0.43',
avg_uptime_percent: 0.22,
uses_vesting_contract_tokens: true,
pending_events: [],
mixnode_is_unbonding: true,
@@ -61,18 +61,18 @@ export const items: DelegationWithEverything[] = [
{
mix_id: 3,
node_identity: '',
amount: { amount: '100', denom: 'nym' },
amount: { amount: '300', denom: 'nym' },
delegated_on_iso_datetime: new Date(2021, 1, 2).toDateString(),
unclaimed_rewards: { amount: '0.05', denom: 'nym' },
cost_params: {
profit_margin_percent: '0.1122323949234',
interval_operating_cost: {
amount: '40',
amount: '50',
denom: 'nym',
},
},
accumulated_by_delegates: { amount: '50', denom: 'nym' },
accumulated_by_operator: { amount: '100', denom: 'nym' },
accumulated_by_operator: { amount: '300', denom: 'nym' },
owner: '',
block_height: BigInt(4000),
stake_saturation: '0.5',
@@ -84,18 +84,18 @@ export const items: DelegationWithEverything[] = [
{
mix_id: 4,
node_identity: 'DT8S942S8AQs2zKHS9SVo1GyHmuca3pfL2uLhLksJ3D8',
amount: { amount: '100', denom: 'nym' },
amount: { amount: '201', denom: 'nym' },
delegated_on_iso_datetime: new Date(2021, 1, 2).toDateString(),
unclaimed_rewards: { amount: '0.05', denom: 'nym' },
cost_params: {
profit_margin_percent: '0.1122323949234',
interval_operating_cost: {
amount: '40',
amount: '60',
denom: 'nym',
},
},
accumulated_by_delegates: { amount: '50', denom: 'nym' },
accumulated_by_operator: { amount: '100', denom: 'nym' },
accumulated_by_operator: { amount: '202', denom: 'nym' },
owner: '',
block_height: BigInt(4000),
stake_saturation: '0.5',
@@ -113,7 +113,7 @@ export const items: DelegationWithEverything[] = [
cost_params: {
profit_margin_percent: '0.1122323949234',
interval_operating_cost: {
amount: '40',
amount: '80',
denom: 'nym',
},
},
@@ -130,11 +130,11 @@ export const items: DelegationWithEverything[] = [
{
mix_id: 6,
node_identity: '',
amount: { amount: '100', denom: 'nym' },
amount: { amount: '202', denom: 'nym' },
delegated_on_iso_datetime: new Date(2021, 1, 2).toDateString(),
unclaimed_rewards: { amount: '0.05', denom: 'nym' },
cost_params: {
profit_margin_percent: '0.1122323949234',
profit_margin_percent: '0.8',
interval_operating_cost: {
amount: '40',
denom: 'nym',
@@ -155,9 +155,9 @@ export const items: DelegationWithEverything[] = [
node_identity: 'FiojKW7oY9WQmLCiYAsCA21tpowZHS6zcUoyYm319p6Z',
delegated_on_iso_datetime: new Date(2021, 1, 1).toDateString(),
unclaimed_rewards: { amount: '0.05', denom: 'nym' },
amount: { amount: '10', denom: 'nym' },
amount: { amount: '202', denom: 'nym' },
cost_params: {
profit_margin_percent: '0.1122323949234',
profit_margin_percent: '0.59',
interval_operating_cost: {
amount: '40',
denom: 'nym',
@@ -190,7 +190,7 @@ export const items: DelegationWithEverything[] = [
accumulated_by_operator: { amount: '100', denom: 'nym' },
owner: '',
block_height: BigInt(4000),
stake_saturation: '0.5',
stake_saturation: '0.9',
avg_uptime_percent: 0.1,
uses_vesting_contract_tokens: true,
pending_events: [],
@@ -199,11 +199,11 @@ export const items: DelegationWithEverything[] = [
{
mix_id: 9,
node_identity: '',
amount: { amount: '100', denom: 'nym' },
amount: { amount: '1000', denom: 'nym' },
delegated_on_iso_datetime: new Date(2021, 1, 2).toDateString(),
unclaimed_rewards: { amount: '0.05', denom: 'nym' },
cost_params: {
profit_margin_percent: '0.1122323949234',
profit_margin_percent: '0.4',
interval_operating_cost: {
amount: '40',
denom: 'nym',
@@ -213,7 +213,7 @@ export const items: DelegationWithEverything[] = [
accumulated_by_operator: { amount: '100', denom: 'nym' },
owner: '',
block_height: BigInt(4000),
stake_saturation: '0.5',
stake_saturation: '0.9',
avg_uptime_percent: 0.1,
uses_vesting_contract_tokens: true,
pending_events: [],
@@ -259,8 +259,8 @@ export const items: DelegationWithEverything[] = [
accumulated_by_operator: { amount: '100', denom: 'nym' },
owner: '',
block_height: BigInt(4000),
stake_saturation: '0.5',
avg_uptime_percent: 0.1,
stake_saturation: '0.56',
avg_uptime_percent: 0.9,
uses_vesting_contract_tokens: true,
pending_events: [],
mixnode_is_unbonding: true,
@@ -2,17 +2,17 @@ import React from 'react';
import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TableSortLabel } from '@mui/material';
import { visuallyHidden } from '@mui/utils';
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
import { orderBy as _orderBy } from 'lodash';
import { DelegationWithEverything } from '@nymproject/types';
import { useSortDelegations } from 'src/hooks/useSortDelegations';
import { DelegationListItemActions } from './DelegationActions';
import { isDelegation, isPendingDelegation, TDelegations } from '../../context/delegations';
import { DelegationItem } from './DelegationItem';
import { PendingDelegationItem } from './PendingDelegationItem';
import { LoadingModal } from '../Modals/LoadingModal';
import { isDelegation, isPendingDelegation, TDelegations } from '../../context/delegations';
type Order = 'asc' | 'desc';
export type Order = 'asc' | 'desc';
type AdditionalTypes = { profit_margin_percent: number; operating_cost: number };
type SortingKeys = keyof AdditionalTypes | keyof DelegationWithEverything;
export type SortingKeys = keyof AdditionalTypes | keyof DelegationWithEverything;
interface EnhancedTableProps {
onRequestSort: (event: React.MouseEvent<unknown>, property: string) => void;
@@ -83,10 +83,6 @@ const EnhancedTableHead: FCWithChildren<EnhancedTableProps> = ({ order, orderBy,
};
// Pin delegations on unbonded nodes to the top of the list
const sortByUnbondedMixnodeFirst = (a: any) => {
if (!a.node_identity) return -1;
return 1;
};
export const DelegationList: FCWithChildren<{
isLoading?: boolean;
@@ -98,37 +94,13 @@ export const DelegationList: FCWithChildren<{
const [order, setOrder] = React.useState<Order>('asc');
const [orderBy, setOrderBy] = React.useState<SortingKeys>('delegated_on_iso_datetime');
const handleRequestSort = (event: React.MouseEvent<unknown>, property: any) => {
const handleRequestSort = (_: React.MouseEvent<unknown>, property: any) => {
const isAsc = orderBy === property && order === 'asc';
setOrder(isAsc ? 'desc' : 'asc');
setOrderBy(property);
};
// if sorting by either amount or unclaimed_rewards
// base sorting on their number counterparts
const mapOrderBy = (key: SortingKeys) => {
if (key === 'amount') return 'delegationValue';
if (key === 'unclaimed_rewards') return 'operatorReward';
if (key === 'profit_margin_percent') return 'profitMarginValue';
if (key === 'operating_cost') return 'operatorCostValue';
return key;
};
const mapAndSort = (_items: TDelegations) => {
const map = _items.map((item) =>
isDelegation(item)
? {
...item,
delegationValue: Number(item.amount.amount),
operatorReward: Number(item.unclaimed_rewards?.amount),
profitMarginValue: Number(item.cost_params?.profit_margin_percent),
operatorCostValue: Number(item.cost_params?.interval_operating_cost),
}
: item,
);
return _orderBy(map, mapOrderBy(orderBy), order).sort(sortByUnbondedMixnodeFirst);
};
const sorted = useSortDelegations(items, order, orderBy);
return (
<TableContainer>
@@ -136,8 +108,8 @@ export const DelegationList: FCWithChildren<{
<Table sx={{ width: '100%' }}>
<EnhancedTableHead order={order} orderBy={orderBy} onRequestSort={handleRequestSort} />
<TableBody>
{items?.length
? mapAndSort(items).map((item: any) => {
{sorted?.length
? sorted.map((item: any) => {
if (isPendingDelegation(item)) return <PendingDelegationItem item={item} explorerUrl={explorerUrl} />;
if (isDelegation(item))
return (
+3 -3
View File
@@ -26,11 +26,11 @@ let mockDelegations: DelegationWithEverything[] = [
cost_params: {
profit_margin_percent: '0.04',
interval_operating_cost: {
amount: '40',
amount: '20',
denom: 'nym',
},
},
stake_saturation: '0.5',
stake_saturation: '0.2',
avg_uptime_percent: 0.5,
accumulated_by_delegates: { amount: '0', denom: 'nym' },
accumulated_by_operator: { amount: '0', denom: 'nym' },
@@ -51,7 +51,7 @@ let mockDelegations: DelegationWithEverything[] = [
cost_params: {
profit_margin_percent: '0.04',
interval_operating_cost: {
amount: '40',
amount: '60',
denom: 'nym',
},
},
@@ -0,0 +1,45 @@
import { orderBy as _orderBy } from 'lodash';
import { Order, SortingKeys } from 'src/components/Delegation/DelegationList';
import { TDelegations, isDelegation } from 'src/context/delegations';
type MappedTypes = 'delegationValue' | 'operatorReward' | 'profitMarginValue' | 'operatorCostValue';
export const useSortDelegations = (delegationItems: TDelegations, order: Order, orderBy: SortingKeys) => {
const unbondedDelegations = delegationItems.filter((delegation) => !delegation.node_identity);
const delegations = delegationItems.filter((delegation) => delegation.node_identity);
// example of a mapped type in typescript
const mapOrderBy = (key: SortingKeys): MappedTypes | SortingKeys => {
switch (key) {
case 'amount':
return 'delegationValue';
case 'unclaimed_rewards':
return 'operatorReward';
case 'profit_margin_percent':
return 'profitMarginValue';
case 'operating_cost':
return 'operatorCostValue';
default:
return key;
}
};
const mapAndSort = (_items: TDelegations) => {
const mapToNumberType = _items.map((item) =>
isDelegation(item)
? {
...item,
delegationValue: Number(item.amount.amount),
operatorReward: Number(item.unclaimed_rewards?.amount),
profitMarginValue: Number(item.cost_params?.profit_margin_percent),
operatorCostValue: Number(item.cost_params?.interval_operating_cost.amount),
}
: item,
);
const ordered = _orderBy(mapToNumberType, mapOrderBy(orderBy), order).sort();
return ordered;
};
return [...unbondedDelegations, ...mapAndSort(delegations)];
};
+866 -865
View File
File diff suppressed because it is too large Load Diff