Skip to content

Commit

Permalink
Merge pull request #860 from alleslabs/feature/cfe-vote-search-filter
Browse files Browse the repository at this point in the history
[CFE-42, 43] Feat(pages): add search to voted proposals
  • Loading branch information
Poafs1 committed Apr 2, 2024
2 parents 9129462 + fe6e1a7 commit 9121f86
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 87 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- [#860](https://github.com/alleslabs/celatone-frontend/pull/860) Add voted proposals in voted tab
- [#862](https://github.com/alleslabs/celatone-frontend/pull/862) View failed reason
- [#853](https://github.com/alleslabs/celatone-frontend/pull/853) Add voted proposals in overview
- [#847](https://github.com/alleslabs/celatone-frontend/pull/847) Add amp proposal details page
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { EmptyState, ErrorFetching } from "lib/components/state";
import { useDebounce } from "lib/hooks";
import type { ProposalAnswerCountsResponse } from "lib/services/proposal";
import { useProposalValidatorVotes } from "lib/services/proposalService";
import { ProposalValidatorVoteType } from "lib/types";
import { ProposalVoteType } from "lib/types";
import type { Option, ProposalValidatorVote } from "lib/types";

import { ValidatorVotesTableHeader } from "./ValidatorVotesTableHeader";
Expand Down Expand Up @@ -112,8 +112,8 @@ export const ValidatorVotesTable = ({
isProposalResolved,
onViewMore,
}: ValidatorVotesTableProps) => {
const [answerFilter, setAnswerFilter] = useState<ProposalValidatorVoteType>(
ProposalValidatorVoteType.ALL
const [answerFilter, setAnswerFilter] = useState<ProposalVoteType>(
ProposalVoteType.ALL
);
const [search, setSearch] = useState("");
const debouncedSearch = useDebounce(search);
Expand Down Expand Up @@ -148,45 +148,45 @@ export const ValidatorVotesTable = ({
}, [data, setTotalData]);

const isSearching =
debouncedSearch !== "" || answerFilter !== ProposalValidatorVoteType.ALL;
debouncedSearch !== "" || answerFilter !== ProposalVoteType.ALL;

const totalValidators = answers?.totalValidators ?? 0;

const answerOptions = useMemo(
() => [
{
label: `All votes (${totalValidators})`,
value: ProposalValidatorVoteType.ALL,
value: ProposalVoteType.ALL,
disabled: false,
},
{
label: `Yes (${answers?.yes ?? 0})`,
value: ProposalValidatorVoteType.YES,
value: ProposalVoteType.YES,
disabled: false,
},
{
label: `No (${answers?.no ?? 0})`,
value: ProposalValidatorVoteType.NO,
value: ProposalVoteType.NO,
disabled: false,
},
{
label: `No with veto (${answers?.noWithVeto ?? 0})`,
value: ProposalValidatorVoteType.NO_WITH_VETO,
value: ProposalVoteType.NO_WITH_VETO,
disabled: false,
},
{
label: `Abstain (${answers?.abstain ?? 0})`,
value: ProposalValidatorVoteType.ABSTAIN,
value: ProposalVoteType.ABSTAIN,
disabled: false,
},
{
label: `Weighted (${answers?.weighted ?? 0})`,
value: ProposalValidatorVoteType.WEIGHTED,
value: ProposalVoteType.WEIGHTED,
disabled: false,
},
{
label: `Did not vote (${answers?.didNotVote ?? 0})`,
value: ProposalValidatorVoteType.DID_NOT_VOTE,
value: ProposalVoteType.DID_NOT_VOTE,
disabled: false,
},
],
Expand All @@ -199,27 +199,17 @@ export const ValidatorVotesTable = ({
setSearch(e.target.value);
};

const handleOnAnswerFilterChange = (newAnswer: ProposalValidatorVoteType) => {
const handleOnAnswerFilterChange = (newAnswer: ProposalVoteType) => {
setCurrentPage(1);
setAnswerFilter(newAnswer);
};

const onPageChange = (nextPage: number) => {
setCurrentPage(nextPage);
};

const onPageSizeChange = (e: ChangeEvent<HTMLSelectElement>) => {
const size = Number(e.target.value);
setPageSize(size);
setCurrentPage(1);
};

return (
<Box id={tableHeaderId}>
{fullVersion && (
<Grid gap={4} templateColumns={{ base: "1fr", md: "240px auto" }}>
<GridItem>
<SelectInput<ProposalValidatorVoteType>
<SelectInput<ProposalVoteType>
formLabel="Filter by Answer"
options={answerOptions}
onChange={handleOnAnswerFilterChange}
Expand Down Expand Up @@ -254,8 +244,12 @@ export const ValidatorVotesTable = ({
offset={offset}
totalData={data?.total ?? 0}
pageSize={pageSize}
onPageChange={onPageChange}
onPageSizeChange={onPageSizeChange}
onPageChange={setCurrentPage}
onPageSizeChange={(e) => {
const size = Number(e.target.value);
setPageSize(size);
setCurrentPage(1);
}}
/>
)}
{onViewMore && !!totalValidators && totalValidators > 10 && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { EmptyState, ErrorFetching } from "lib/components/state";
import { useDebounce } from "lib/hooks";
import type { ProposalAnswerCountsResponse } from "lib/services/proposal";
import { useProposalVotes } from "lib/services/proposalService";
import { ProposalVoteType } from "lib/types";
import type { Option, ProposalVote } from "lib/types";

import { ProposalVotesTableHeader } from "./ProposalVotesTableHeader";
Expand Down Expand Up @@ -87,16 +88,6 @@ interface ProposalVotesTableProps {
onViewMore?: () => void;
}

// pass it to api
enum AnswerType {
ALL = "all",
YES = "yes",
NO = "no",
NO_WITH_VETO = "no_with_veto",
ABSTAIN = "abstain",
WEIGHTED = "weighted",
}

const tableHeaderId = "proposalVotesTable";

export const ProposalVotesTable = ({
Expand All @@ -105,7 +96,9 @@ export const ProposalVotesTable = ({
fullVersion,
onViewMore,
}: ProposalVotesTableProps) => {
const [answerFilter, setAnswerFilter] = useState<AnswerType>(AnswerType.ALL);
const [answerFilter, setAnswerFilter] = useState<ProposalVoteType>(
ProposalVoteType.ALL
);
const [search, setSearch] = useState("");
const debouncedSearch = useDebounce(search);

Expand Down Expand Up @@ -134,40 +127,41 @@ export const ProposalVotesTable = ({
{ onSuccess: ({ total }) => setTotalData(total) }
);

const isSearching = debouncedSearch !== "" || answerFilter !== AnswerType.ALL;
const isSearching =
debouncedSearch !== "" || answerFilter !== ProposalVoteType.ALL;

const total = answers?.total ?? 0;

const answerOptions = useMemo(
() => [
{
label: `All votes (${total})`,
value: AnswerType.ALL,
value: ProposalVoteType.ALL,
disabled: false,
},
{
label: `Yes (${answers?.yes ?? 0})`,
value: AnswerType.YES,
value: ProposalVoteType.YES,
disabled: false,
},
{
label: `No (${answers?.no ?? 0})`,
value: AnswerType.NO,
value: ProposalVoteType.NO,
disabled: false,
},
{
label: `No with veto (${answers?.noWithVeto ?? 0})`,
value: AnswerType.NO_WITH_VETO,
value: ProposalVoteType.NO_WITH_VETO,
disabled: false,
},
{
label: `Abstain (${answers?.abstain ?? 0})`,
value: AnswerType.ABSTAIN,
value: ProposalVoteType.ABSTAIN,
disabled: false,
},
{
label: `Weighted (${answers?.weighted ?? 0})`,
value: AnswerType.WEIGHTED,
value: ProposalVoteType.WEIGHTED,
disabled: false,
},
],
Expand All @@ -180,27 +174,17 @@ export const ProposalVotesTable = ({
setSearch(e.target.value);
};

const handleOnAnswerFilterChange = (newAnswer: AnswerType) => {
const handleOnAnswerFilterChange = (newAnswer: ProposalVoteType) => {
setCurrentPage(1);
setAnswerFilter(newAnswer);
};

const onPageChange = (nextPage: number) => {
setCurrentPage(nextPage);
};

const onPageSizeChange = (e: ChangeEvent<HTMLSelectElement>) => {
const size = Number(e.target.value);
setPageSize(size);
setCurrentPage(1);
};

return (
<Box id={tableHeaderId}>
{fullVersion && (
<Grid gap={4} templateColumns={{ base: "1fr", md: "240px auto" }}>
<GridItem>
<SelectInput<AnswerType>
<SelectInput<ProposalVoteType>
formLabel="Filter by Answer"
options={answerOptions}
onChange={handleOnAnswerFilterChange}
Expand Down Expand Up @@ -234,8 +218,12 @@ export const ProposalVotesTable = ({
offset={offset}
totalData={data?.total ?? 0}
pageSize={pageSize}
onPageChange={onPageChange}
onPageSizeChange={onPageSizeChange}
onPageChange={setCurrentPage}
onPageSizeChange={(e) => {
const size = Number(e.target.value);
setPageSize(size);
setCurrentPage(1);
}}
/>
)}
{onViewMore && !!total && total > 10 && (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { Alert, Flex, Text } from "@chakra-ui/react";
import { Alert, Flex, Grid, GridItem, Text } from "@chakra-ui/react";
import type { ChangeEvent } from "react";
import { useMemo, useState } from "react";

import { useMobile } from "lib/app-provider";
import { SelectInput } from "lib/components/forms";
import { CustomIcon } from "lib/components/icon";
import InputWithIcon from "lib/components/InputWithIcon";
import { Pagination } from "lib/components/pagination";
import { usePaginator } from "lib/components/pagination/usePaginator";
import { TableTitle, ViewMore } from "lib/components/table";
import { useDebounce } from "lib/hooks";
import { useValidatorVotedProposals } from "lib/services/validatorService";
import { ProposalVoteType } from "lib/types";
import type { ValidatorAddr } from "lib/types";

import { VotedProposalsTableBody } from "./VotedProposalsTableBody";
Expand All @@ -23,6 +29,11 @@ export const VotedProposalsTable = ({
}: VotedProposalsTableProps) => {
const isMobile = useMobile();
const isMobileOverview = isMobile && !!onViewMore;
const [answerFilter, setAnswerFilter] = useState<ProposalVoteType>(
ProposalVoteType.ALL
);
const [search, setSearch] = useState("");
const debouncedSearch = useDebounce(search);

const {
pagesQuantity,
Expand All @@ -44,11 +55,62 @@ export const VotedProposalsTable = ({
validatorAddress,
onViewMore ? 5 : pageSize,
offset,
{
onSuccess: ({ total }) => setTotalData(total),
}
answerFilter,
debouncedSearch,
{ onSuccess: ({ total }) => setTotalData(total) }
);

const answerOptions = useMemo(
() => [
{
label: `All votes`,
value: ProposalVoteType.ALL,
disabled: false,
},
{
label: `Yes`,
value: ProposalVoteType.YES,
disabled: false,
},
{
label: `No`,
value: ProposalVoteType.NO,
disabled: false,
},
{
label: `No with veto`,
value: ProposalVoteType.NO_WITH_VETO,
disabled: false,
},
{
label: `Abstain`,
value: ProposalVoteType.ABSTAIN,
disabled: false,
},
{
label: `Weighted`,
value: ProposalVoteType.WEIGHTED,
disabled: false,
},
{
label: `Did not vote`,
value: ProposalVoteType.DID_NOT_VOTE,
disabled: false,
},
],
[]
);

const handleOnSearchChange = (e: ChangeEvent<HTMLInputElement>) => {
setCurrentPage(1);
setSearch(e.target.value);
};

const handleOnAnswerFilterChange = (newAnswer: ProposalVoteType) => {
setCurrentPage(1);
setAnswerFilter(newAnswer);
};

return isMobileOverview ? (
<Flex
backgroundColor="gray.900"
Expand All @@ -66,13 +128,36 @@ export const VotedProposalsTable = ({
<Flex direction="column" gap={6}>
<TableTitle title="Voted Proposals" count={data?.total ?? 0} mb={0} />
{!onViewMore && (
<Alert variant="info" gap={4} display={{ base: "none", md: "flex" }}>
<CustomIcon boxSize={4} name="info-circle-solid" />
<Text variant="body2" color="text.dark">
Kindly note that the validator may not have voted on the proposal
due to ineligibility, such as being recently added to the network.
</Text>
</Alert>
<>
<Alert variant="info" gap={4} display={{ base: "none", md: "flex" }}>
<CustomIcon boxSize={4} name="info-circle-solid" />
<Text variant="body2" color="text.dark">
Kindly note that the validator may not have voted on the proposal
due to ineligibility, such as being recently added to the network.
</Text>
</Alert>
<Grid gap={4} templateColumns={{ base: "1fr", md: "240px auto" }}>
<GridItem>
<SelectInput<ProposalVoteType>
formLabel="Filter by vote answer"
options={answerOptions}
onChange={handleOnAnswerFilterChange}
labelBgColor="background.main"
initialSelected={answerFilter}
popoverBgColor="gray.800"
disableMaxH
/>
</GridItem>
<GridItem>
<InputWithIcon
placeholder="Search with proposal ID or proposal title..."
value={search}
onChange={handleOnSearchChange}
size="lg"
/>
</GridItem>
</Grid>
</>
)}
<VotedProposalsTableBody
data={data}
Expand Down
Loading

0 comments on commit 9121f86

Please sign in to comment.