Skip to content

Commit

Permalink
[#536] add BE search for governance actions
Browse files Browse the repository at this point in the history
  • Loading branch information
j-dyczka committed Mar 26, 2024
1 parent d398f1c commit 7f9e84c
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 173 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useState, useCallback, useEffect } from "react";
import { useState, useEffect } from "react";
import { Box, CircularProgress, Tab, Tabs, styled } from "@mui/material";
import { useLocation } from "react-router-dom";

import { GOVERNANCE_ACTIONS_FILTERS } from "@consts";
import { useCardano } from "@context";
import {
useDataActionsBar,
useGetProposalsQuery,
useGetVoterInfo,
useScreenDimension,
Expand Down Expand Up @@ -64,11 +65,8 @@ const StyledTab = styled((props: StyledTabProps) => (
}));

export const DashboardGovernanceActions = () => {
const [searchText, setSearchText] = useState<string>("");
const [filtersOpen, setFiltersOpen] = useState(false);
const [chosenFilters, setChosenFilters] = useState<string[]>([]);
const [sortOpen, setSortOpen] = useState(false);
const [chosenSorting, setChosenSorting] = useState<string>("");
const { debouncedSearchText, ...dataActionsBarProps } = useDataActionsBar();
const { chosenFilters, chosenSorting } = dataActionsBarProps;
const { voter } = useGetVoterInfo();
const { isMobile } = useScreenDimension();
const { t } = useTranslation();
Expand All @@ -80,7 +78,7 @@ export const DashboardGovernanceActions = () => {
const { proposals, isProposalsLoading } = useGetProposalsQuery({
filters: queryFilters,
sorting: chosenSorting,
searchPhrase: searchText,
searchPhrase: debouncedSearchText,
});

const { state } = useLocation();
Expand All @@ -92,14 +90,6 @@ export const DashboardGovernanceActions = () => {
setContent(newValue);
};

const closeFilters = useCallback(() => {
setFiltersOpen(false);
}, [setFiltersOpen]);

const closeSorts = useCallback(() => {
setSortOpen(false);
}, [setSortOpen]);

useEffect(() => {
window.history.replaceState({}, document.title);
}, []);
Expand All @@ -113,22 +103,7 @@ export const DashboardGovernanceActions = () => {
flexDirection="column"
>
<>
<DataActionsBar
chosenFilters={chosenFilters}
chosenFiltersLength={chosenFilters.length}
chosenSorting={chosenSorting}
closeFilters={closeFilters}
closeSorts={closeSorts}
filtersOpen={filtersOpen}
searchText={searchText}
setChosenFilters={setChosenFilters}
setChosenSorting={setChosenSorting}
setFiltersOpen={setFiltersOpen}
setSearchText={setSearchText}
setSortOpen={setSortOpen}
sortingActive={Boolean(chosenSorting)}
sortOpen={sortOpen}
/>
<DataActionsBar {...dataActionsBarProps} />
{!proposals || !voter || isEnableLoading || isProposalsLoading ? (
<Box
alignItems="center"
Expand Down Expand Up @@ -177,15 +152,15 @@ export const DashboardGovernanceActions = () => {
<GovernanceActionsToVote
filters={chosenFilters}
onDashboard
searchPhrase={searchText}
searchPhrase={debouncedSearchText}
sorting={chosenSorting}
proposals={proposals}
/>
</CustomTabPanel>
<CustomTabPanel value={content} index={1}>
<DashboardGovernanceActionsVotedOn
filters={chosenFilters}
searchPhrase={searchText}
searchPhrase={debouncedSearchText}
sorting={chosenSorting}
/>
</CustomTabPanel>
Expand Down
3 changes: 3 additions & 0 deletions govtool/frontend/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export { useTranslation } from "react-i18next";

export * from "./useDataActionsBar";
export * from "./useDebounce";
export * from "./useFetchNextPageDetector";
export * from "./useOutsideClick";
export * from "./useSaveScrollPosition";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { useInfiniteQuery } from "react-query";

import { QUERY_KEYS } from "@consts";
import { useCardano } from "@context";
import { getProposals, getProposalsArguments } from "@services";
import { getProposals, GetProposalsArguments } from "@services";

export const useGetProposalsInfiniteQuery = ({
filters = [],
pageSize = 10,
searchPhrase,
sorting = "",
}: getProposalsArguments) => {
}: GetProposalsArguments) => {
const { dRepID, isEnabled, pendingTransaction } = useCardano();

const fetchProposals = ({ pageParam = 0 }) =>
Expand All @@ -17,6 +18,7 @@ export const useGetProposalsInfiniteQuery = ({
filters,
page: pageParam,
pageSize,
searchPhrase,
sorting,
});

Expand All @@ -34,6 +36,7 @@ export const useGetProposalsInfiniteQuery = ({
filters,
isEnabled,
pendingTransaction.vote?.transactionHash,
searchPhrase,
sorting,
],
fetchProposals,
Expand Down
51 changes: 20 additions & 31 deletions govtool/frontend/src/hooks/queries/useGetProposalsQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@ import { useQuery } from "react-query";

import { QUERY_KEYS } from "@consts";
import { useCardano } from "@context";
import { getProposals, getProposalsArguments } from "@services";
import { getFullGovActionId } from "@utils";
import { getProposals, GetProposalsArguments } from "@services";

export const useGetProposalsQuery = ({
filters = [],
sorting,
searchPhrase,
}: getProposalsArguments) => {
sorting,
}: GetProposalsArguments) => {
const { dRepID, pendingTransaction } = useCardano();

const fetchProposals = async (): Promise<ActionType[]> => {
const allProposals = await Promise.all(
filters.map((filter) =>
getProposals({ dRepID, filters: [filter], sorting }),
getProposals({ dRepID, filters: [filter], searchPhrase, sorting }),
),
);

Expand All @@ -26,45 +25,35 @@ export const useGetProposalsQuery = ({
[
QUERY_KEYS.useGetProposalsKey,
filters,
searchPhrase,
sorting,
dRepID,
pendingTransaction.vote?.transactionHash,
],
fetchProposals,
);

const mappedData = Object.values(
(groupedByType(
data?.filter((i) =>
getFullGovActionId(i.txHash, i.index)
.toLowerCase()
.includes(searchPhrase.toLowerCase()))
) ?? []) as ToVoteDataType
const proposals = Object.values(
(groupByType(data) ?? [])
);

return {
isProposalsLoading: isLoading,
proposals: mappedData,
proposals,
};
};

const groupedByType = (data?: ActionType[]) => data?.reduce((groups, item) => {
const itemType = item.type;
const groupByType = (data?: ActionType[]) =>
data?.reduce<Record<string, ArrayElement<ToVoteDataType>>>((groups, item) => {
const itemType = item.type;

// TODO: Provide better typing for groups
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
if (!groups[itemType]) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
groups[itemType] = {
title: itemType,
actions: [],
};
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
groups[itemType].actions.push(item);
if (!groups[itemType]) {
groups[itemType] = {
title: itemType,
actions: [],
};
}
groups[itemType].actions.push(item);

return groups;
}, {});
return groups;
}, {});
58 changes: 58 additions & 0 deletions govtool/frontend/src/hooks/useDataActionsBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useState, useCallback, Dispatch, SetStateAction } from "react";

import {
useDebounce,
} from "@hooks";

type UseDataActionsBarReturnType = {
chosenFilters: string[];
chosenFiltersLength: number;
chosenSorting: string;
closeFilters: () => void;
closeSorts: () => void;
debouncedSearchText: string;
filtersOpen: boolean;
searchText: string;
setChosenFilters: Dispatch<SetStateAction<string[]>>;
setChosenSorting: Dispatch<SetStateAction<string>>;
setFiltersOpen: Dispatch<SetStateAction<boolean>>;
setSearchText: Dispatch<SetStateAction<string>>;
setSortOpen: Dispatch<SetStateAction<boolean>>;
sortingActive: boolean;
sortOpen: boolean;
};

export const useDataActionsBar = (): UseDataActionsBarReturnType => {
const [searchText, setSearchText] = useState<string>("");
const debouncedSearchText = useDebounce(searchText, 300);
const [filtersOpen, setFiltersOpen] = useState(false);
const [chosenFilters, setChosenFilters] = useState<string[]>([]);
const [sortOpen, setSortOpen] = useState(false);
const [chosenSorting, setChosenSorting] = useState<string>("");

const closeFilters = useCallback(() => {
setFiltersOpen(false);
}, [setFiltersOpen]);

const closeSorts = useCallback(() => {
setSortOpen(false);
}, [setSortOpen]);

return {
chosenFilters,
chosenFiltersLength: chosenFilters.length,
chosenSorting,
closeFilters,
closeSorts,
debouncedSearchText,
filtersOpen,
searchText,
setChosenFilters,
setChosenSorting,
setFiltersOpen,
setSearchText,
setSortOpen,
sortingActive: Boolean(chosenSorting),
sortOpen,
};
};
17 changes: 17 additions & 0 deletions govtool/frontend/src/hooks/useDebounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useEffect, useState } from 'react';

export function useDebounce<T>(value: T, delay: number) {
const [debouncedValue, setDebouncedValue] = useState(value);

useEffect(() => {
const timerID = setTimeout(() => {
setDebouncedValue(value);
}, delay);

return () => {
clearTimeout(timerID);
};
}, [value, delay]);

return debouncedValue;
}
34 changes: 7 additions & 27 deletions govtool/frontend/src/pages/DashboardGovernanceActionsCategory.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useMemo, useRef, useState } from "react";
import { useMemo, useRef } from "react";
import { generatePath, useNavigate, useParams } from "react-router-dom";
import { Box, CircularProgress, Link } from "@mui/material";

Expand All @@ -7,6 +7,7 @@ import { ICONS, PATHS } from "@consts";
import { useCardano } from "@context";
import { DataActionsBar, GovernanceActionCard } from "@molecules";
import {
useDataActionsBar,
useFetchNextPageDetector,
useGetProposalsInfiniteQuery,
useGetVoterInfo,
Expand All @@ -23,9 +24,8 @@ import {

export const DashboardGovernanceActionsCategory = () => {
const { category } = useParams();
const [searchText, setSearchText] = useState<string>("");
const [sortOpen, setSortOpen] = useState(false);
const [chosenSorting, setChosenSorting] = useState<string>("");
const { debouncedSearchText, ...dataActionsBarProps } = useDataActionsBar();
const { chosenSorting } = dataActionsBarProps;
const { isMobile, screenWidth } = useScreenDimension();
const navigate = useNavigate();
const { pendingTransaction, isEnableLoading } = useCardano();
Expand All @@ -42,7 +42,7 @@ export const DashboardGovernanceActionsCategory = () => {
} = useGetProposalsInfiniteQuery({
filters: [category?.replace(/ /g, "") ?? ""],
sorting: chosenSorting,
searchPhrase: searchText,
searchPhrase: debouncedSearchText,
});
const loadNextPageRef = useRef(null);

Expand All @@ -57,25 +57,12 @@ export const DashboardGovernanceActionsCategory = () => {
isProposalsFetching,
);

const mappedData = useMemo(() => {
const uniqueProposals = removeDuplicatedProposals(proposals);

return uniqueProposals?.filter((i) =>
getFullGovActionId(i.txHash, i.index)
.toLowerCase()
.includes(searchText.toLowerCase()),
);
}, [
const mappedData = useMemo(() => removeDuplicatedProposals(proposals), [
proposals,
voter?.isRegisteredAsDRep,
searchText,
isProposalsFetchingNextPage,
]);

const closeSorts = useCallback(() => {
setSortOpen(false);
}, [setSortOpen]);

return (
<Background>
<Box
Expand Down Expand Up @@ -106,15 +93,8 @@ export const DashboardGovernanceActionsCategory = () => {
</Typography>
</Link>
<DataActionsBar
chosenSorting={chosenSorting}
closeSorts={closeSorts}
{...dataActionsBarProps}
isFiltering={false}
searchText={searchText}
setChosenSorting={setChosenSorting}
setSearchText={setSearchText}
setSortOpen={setSortOpen}
sortingActive={Boolean(chosenSorting)}
sortOpen={sortOpen}
/>
<Typography
variant="title2"
Expand Down
Loading

0 comments on commit 7f9e84c

Please sign in to comment.