Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/validator list bug #849

Merged
merged 9 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Bug fixes

- [#849](https://github.com/alleslabs/celatone-frontend/pull/849) Fix validator list empty state and voting percent dividers
- [#846](https://github.com/alleslabs/celatone-frontend/pull/846) Fix voting period status badge
- [#838](https://github.com/alleslabs/celatone-frontend/pull/838) Fix validator list sorting on priority
- [#839](https://github.com/alleslabs/celatone-frontend/pull/839) Disable contract delegations on non-gov chains
Expand Down
2 changes: 1 addition & 1 deletion src/config/chain/initia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const INITIA_CHAIN_CONFIGS: ChainConfigs = {
enabled: true,
moduleMaxFileSize: 1_048_576,
decodeApi: INITIA_DECODER,
verify: "https://compiler.mahalo-1.initia.xyz/contracts/verify",
verify: "https://compiler.mahalo-2.initia.xyz/contracts/verify",
},
pool: {
enabled: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
useValidatorStakingProvisions,
} from "lib/services/validatorService";
import type { Option, ValidatorAddr } from "lib/types";
import { formatPrettyPercent } from "lib/utils";
import { divWithDefault, formatPrettyPercent } from "lib/utils";

const StatWithLabel = ({
label,
Expand Down Expand Up @@ -49,15 +49,17 @@ export const ValidatorStats = ({
singleStakingDenom,
}: ValidatorStatsProps) => {
const { data: stakingProvisions, isLoading: isStakingProvisionsLoading } =
useValidatorStakingProvisions();
useValidatorStakingProvisions(!!singleStakingDenom);
const { data: delegations, isLoading: isDelegationsLoading } =
useValidatorDelegators(validatorAddress);

const estimatedApr = stakingProvisions
? formatPrettyPercent(
stakingProvisions.stakingProvisions
.div(totalVotingPower.mul(1 - commissionRate))
.toNumber(),
divWithDefault(
stakingProvisions.stakingProvisions,
totalVotingPower.mul(1 - commissionRate),
0
).toNumber(),
2,
true
)
Expand Down
5 changes: 3 additions & 2 deletions src/lib/pages/validators/components/ActiveFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Flex, Text } from "@chakra-ui/react";
import { Select } from "chakra-react-select";
import { isUndefined } from "lodash";
import { useMemo } from "react";

import type { Option } from "lib/types";
Expand All @@ -12,7 +13,7 @@ interface ActiveFilterProps {
}

const getOptionLabel = (label: string, count: Option<number>) =>
label + (count ? ` (${count})` : "");
label + (!isUndefined(count) ? ` (${count})` : "");

export const ActiveFilter = ({
isActive,
Expand All @@ -32,7 +33,7 @@ export const ActiveFilter = ({
);

return (
<Flex direction="column" gap={1} minW={{ base: "full", md: "240px" }}>
<Flex direction="column" gap={1} minW={{ base: "full", md: "280px" }}>
<Text variant="body3" color="text.dark" pl={{ base: 1, md: 3 }}>
Show only
</Text>
Expand Down

This file was deleted.

86 changes: 67 additions & 19 deletions src/lib/pages/validators/components/validators-table/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { TableContainer } from "@chakra-ui/react";
import { Fragment } from "react";

import type { ValidatorOrder } from "../../types";
import { useMobile } from "lib/app-provider";
import { ValidatorOrder } from "../../types";
import { useCelatoneApp, useMobile } from "lib/app-provider";
import { Loading } from "lib/components/Loading";
import { EmptyState, ErrorFetching } from "lib/components/state";
import { MobileTableContainer } from "lib/components/table";
import { useAssetInfos } from "lib/services/assetService";
import type { ValidatorsResponse } from "lib/services/validator";
import type { Option } from "lib/types";
import { coinToTokenWithValue } from "lib/utils";

import { ValidatorsTableBody } from "./ValidatorsTableBody";
import { ValidatorsPercentDivider } from "./ValidatorsPercentDivider";
import { ValidatorsTableHeader } from "./ValidatorsTableHeader";
import { ValidatorsTableMobileCard } from "./ValidatorsTableMobileCard";
import { ValidatorsTableRow } from "./ValidatorsTableRow";

interface ValidatorsTableProps {
data: Option<ValidatorsResponse>;
Expand All @@ -31,19 +38,44 @@ export const ValidatorsTable = ({
scrollComponentId,
}: ValidatorsTableProps) => {
const isMobile = useMobile();
const {
chainConfig: {
extra: { singleStakingDenom },
},
} = useCelatoneApp();
const { data: assetInfos } = useAssetInfos({ withPrices: false });

if (isLoading) return <Loading />;
if (!data) return <ErrorFetching dataName="validators" />;
if (!data.total)
return (
<EmptyState
imageVariant="empty"
message={`This network does not have any ${isActive ? "active" : "inactive"} validators.`}
withBorder
/>
);

const displayDividers = order === ValidatorOrder.VotingPower && isDesc;
const denomToken = singleStakingDenom
? coinToTokenWithValue(singleStakingDenom, "0", assetInfos)
: undefined;

const templateColumns = `${isActive ? "64px " : ""}3fr 2fr 110px 110px`;
return (
<>
{isMobile ? (
<MobileTableContainer>
<ValidatorsTableBody
templateColumns={templateColumns}
data={data}
isLoading={isLoading}
isActive={isActive}
order={order}
isDesc={isDesc}
/>
{data.items.map((validator) => (
<ValidatorsTableMobileCard
key={validator.validatorAddress}
isActive={isActive}
validator={validator}
totalVotingPower={data.metadata.totalVotingPower}
minCommissionRate={data.metadata.minCommissionRate}
denomToken={denomToken}
/>
))}
</MobileTableContainer>
) : (
<TableContainer>
Expand All @@ -56,14 +88,30 @@ export const ValidatorsTable = ({
isDesc={isDesc}
setIsDesc={setIsDesc}
/>
<ValidatorsTableBody
templateColumns={templateColumns}
data={data}
isLoading={isLoading}
isActive={isActive}
order={order}
isDesc={isDesc}
/>
{data.items.map((validator) => (
<Fragment key={validator.validatorAddress}>
<ValidatorsTableRow
templateColumns={templateColumns}
isActive={isActive}
validator={validator}
totalVotingPower={data.metadata.totalVotingPower}
minCommissionRate={data.metadata.minCommissionRate}
denomToken={denomToken}
/>
{displayDividers &&
(validator.rank === data.metadata.percent33Rank ||
validator.rank === data.metadata.percent66Rank) && (
<ValidatorsPercentDivider
rank={validator.rank}
label={
validator.rank === data.metadata.percent66Rank
? "66%"
: "33%"
}
/>
)}
</Fragment>
))}
</TableContainer>
)}
</>
Expand Down
3 changes: 2 additions & 1 deletion src/lib/services/validatorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,14 @@ export const useValidators = (
);
};

export const useValidatorStakingProvisions = () => {
export const useValidatorStakingProvisions = (enabled: boolean) => {
const endpoint = useBaseApiRoute("validators");

return useQuery<StakingProvisionsResponse>(
[CELATONE_QUERY_KEYS.VALIDATOR_STAKING_PROVISIONS, endpoint],
async () => getValidatorStakingProvisions(endpoint),
{
enabled,
retry: 1,
}
);
Expand Down
Loading