Skip to content

Commit

Permalink
chore: add delegation details sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
icfor committed Mar 6, 2024
1 parent 96776e6 commit 93e539e
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 25 deletions.
21 changes: 21 additions & 0 deletions src/features/core/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export const sortUtil = (a: unknown, b: unknown, sorting: "asc" | "desc") => {
if (typeof a !== typeof b) {
return 0;
}

if (typeof a === "string") {
return sorting === "asc"
? a.localeCompare(b as string)
: (b as string).localeCompare(a);
}

if (typeof a === "number") {
if (Number.isNaN(a) || Number.isNaN(b as number)) {
return 0;
}

return sorting === "asc" ? a - (b as number) : (b as number) - a;
}

return 0;
};
135 changes: 110 additions & 25 deletions src/features/staking/components/delegation-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { HeaderTitleBase } from "@/features/core/components/table";
import { useCore } from "@/features/core/context/hooks";
import { setIsLoadingBlocking } from "@/features/core/context/reducer";
import type { CoreContextType } from "@/features/core/context/state";
import { sortUtil } from "@/features/core/utils";

import {
claimRewardsAction,
Expand Down Expand Up @@ -253,9 +254,24 @@ const UnbondingRow = ({ disabled, staking, unbonding }: UnbondingRowProps) => {
);
};

type SortMethod = "bar" | "foo" | "none";

const HeaderTitle = HeaderTitleBase<SortMethod>;
type DelegationSortMethod =
| "commission-asc"
| "commission-desc"
| "none"
| "rewards-asc"
| "rewards-desc"
| "staked-asc"
| "staked-desc";

type SortMethod =
| "amount-asc"
| "amount-desc"
| "completion-asc"
| "completion-desc"
| "none";

const DelegationHeaderTitle = HeaderTitleBase<DelegationSortMethod>;
const UnbondingHeaderTitle = HeaderTitleBase<SortMethod>;

const headerStyle =
"grid w-full items-center justify-between gap-2 p-4 uppercase";
Expand All @@ -267,7 +283,7 @@ const DelegationDetails = () => {
const { client, staking } = stakingRef;

const [delegationsSortMethod, setDelegationsSortMethod] =
useState<SortMethod>("none");
useState<DelegationSortMethod>("none");

const [unbondingsSortMethod, setUnbondingsSortMethod] =
useState<SortMethod>("none");
Expand All @@ -285,34 +301,80 @@ const DelegationDetails = () => {
<div className="flex h-full flex-1 flex-col items-end gap-[16px]">
{hasDelegations &&
(() => {
const sortedDelegations = delegations.items.slice();
const validatorIdToValidator =
staking.state.validators?.items.reduce(
(acc, v) => {
acc[v.operatorAddress] = v;

return acc;
},
{ ...staking.state.extraValidators },
) || {};

const sortedDelegations = delegations.items.slice().sort((a, b) => {
switch (delegationsSortMethod) {
case "staked-asc":
case "staked-desc":
return sortUtil(
a.balance.amount,
b.balance.amount,
delegationsSortMethod === "staked-asc" ? "asc" : "desc",
);

case "rewards-asc":
case "rewards-desc":
return sortUtil(
a.rewards.amount,
b.rewards.amount,
delegationsSortMethod === "rewards-asc" ? "asc" : "desc",
);

case "commission-asc":

case "commission-desc": {
const validatorA = validatorIdToValidator[a.validatorAddress];
const validatorB = validatorIdToValidator[b.validatorAddress];

return sortUtil(
Number(validatorA?.commission.commissionRates.rate),
Number(validatorB?.commission.commissionRates.rate),
delegationsSortMethod === "commission-asc" ? "asc" : "desc",
);
}

default:
delegationsSortMethod satisfies "none";

return 0;
}
});

return (
<div className={wrapperStyle}>
<div className={headerStyle} style={gridStyle}>
<div />
<HeaderTitle>Delegations</HeaderTitle>
<HeaderTitle
onSort={setUnbondingsSortMethod}
<DelegationHeaderTitle>Delegations</DelegationHeaderTitle>
<DelegationHeaderTitle
onSort={setDelegationsSortMethod}
sort={delegationsSortMethod}
sorting={["staked-asc", "staked-desc"]}
>
<div className="text-right">Staked Amount</div>
</HeaderTitle>
<HeaderTitle
onSort={setUnbondingsSortMethod}
</DelegationHeaderTitle>
<DelegationHeaderTitle
onSort={setDelegationsSortMethod}
sort={delegationsSortMethod}
sorting={["commission-asc", "commission-desc"]}
>
<div className="text-right">Commission</div>
</HeaderTitle>
<HeaderTitle
onSort={setUnbondingsSortMethod}
</DelegationHeaderTitle>
<DelegationHeaderTitle
onSort={setDelegationsSortMethod}
sort={delegationsSortMethod}
sorting={["rewards-asc", "rewards-desc"]}
>
<div className="text-right">Rewards</div>
</HeaderTitle>
</DelegationHeaderTitle>
</div>
{sortedDelegations.map((delegation, index) => (
<DelegationRow
Expand All @@ -330,30 +392,53 @@ const DelegationDetails = () => {
})()}
{hasUnbondings &&
(() => {
const sortedUnbondings = unbondings.items.slice();
const sortedUnbondings = unbondings.items.slice().sort((a, b) => {
switch (unbondingsSortMethod) {
case "amount-asc":
case "amount-desc":
return sortUtil(
Number(a.balance.amount),
Number(b.balance.amount),
unbondingsSortMethod === "amount-asc" ? "asc" : "desc",
);

case "completion-asc":
case "completion-desc":
return sortUtil(
a.completionTime,
b.completionTime,
unbondingsSortMethod === "completion-asc" ? "asc" : "desc",
);

default:
unbondingsSortMethod satisfies "none";

return 0;
}
});

return (
<div className={wrapperStyle}>
<div className={headerStyle} style={gridStyle}>
<div />
<HeaderTitle>Delegations</HeaderTitle>
<HeaderTitle
onSort={setDelegationsSortMethod}
<UnbondingHeaderTitle>Unstakings</UnbondingHeaderTitle>
<UnbondingHeaderTitle
onSort={setUnbondingsSortMethod}
sort={unbondingsSortMethod}
sorting={["staked-asc", "staked-desc"]}
>
<div className="text-right">Staked Amount</div>
</HeaderTitle>
<HeaderTitle>
</UnbondingHeaderTitle>
<UnbondingHeaderTitle>
<div className="text-right">Status</div>
</HeaderTitle>
<HeaderTitle
onSort={setDelegationsSortMethod}
</UnbondingHeaderTitle>
<UnbondingHeaderTitle
onSort={setUnbondingsSortMethod}
sort={unbondingsSortMethod}
sorting={["date-asc", "date-desc"]}
>
<div className="text-right">Completion Time</div>
</HeaderTitle>
</UnbondingHeaderTitle>
</div>
{sortedUnbondings.map((unbonding, index) => (
<UnbondingRow
Expand Down

0 comments on commit 93e539e

Please sign in to comment.