Skip to content

Commit 9908426

Browse files
authored
Merge pull request #4043 from IntersectMBO/issue-4030
More DRep search improvements #4030
2 parents bcf9ac1 + 0cca71c commit 9908426

File tree

16 files changed

+297
-109
lines changed

16 files changed

+297
-109
lines changed

govtool/backend/sql/list-dreps.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ LatestVoteEpoch AS (
3232
JOIN tx ON tx.id = lvp.tx_id
3333
JOIN block ON block.id = tx.block_id
3434
),
35+
VotesLastYear AS (
36+
SELECT
37+
vp.drep_voter AS drep_id,
38+
COUNT(DISTINCT vp.gov_action_proposal_id) AS votes_last_year
39+
FROM voting_procedure vp
40+
JOIN tx ON tx.id = vp.tx_id
41+
JOIN block ON block.id = tx.block_id
42+
WHERE block.time >= now() - INTERVAL '1 year'
43+
GROUP BY vp.drep_voter
44+
),
3545
RankedDRepRegistration AS (
3646
SELECT DISTINCT ON (dr.drep_hash_id)
3747
dr.id,
@@ -127,6 +137,7 @@ DRepData AS (
127137
off_chain_vote_drep_data.qualifications,
128138
off_chain_vote_drep_data.image_url,
129139
off_chain_vote_drep_data.image_hash,
140+
COALESCE(vly.votes_last_year, 0) AS votes_last_year,
130141
COALESCE(
131142
(
132143
SELECT jsonb_agg(
@@ -239,6 +250,7 @@ DRepData AS (
239250
LEFT JOIN tx AS tx_first_register ON tx_first_register.id = dr_first_register.tx_id
240251
LEFT JOIN block AS block_first_register ON block_first_register.id = tx_first_register.block_id
241252
LEFT JOIN LatestVoteEpoch lve ON lve.drep_id = dh.id
253+
LEFT JOIN VotesLastYear vly ON vly.drep_id = dh.id
242254
CROSS JOIN DRepActivity
243255
GROUP BY
244256
dh.raw,
@@ -265,6 +277,7 @@ DRepData AS (
265277
off_chain_vote_drep_data.qualifications,
266278
off_chain_vote_drep_data.image_url,
267279
off_chain_vote_drep_data.image_hash,
280+
vly.votes_last_year,
268281
(
269282
SELECT jsonb_agg(
270283
jsonb_build_object(

govtool/backend/src/VVA/API.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ drepRegistrationToDrep Types.DRepRegistration {..} =
160160
dRepQualifications = dRepRegistrationQualifications,
161161
dRepImageUrl = dRepRegistrationImageUrl,
162162
dRepImageHash = HexText <$> dRepRegistrationImageHash,
163+
dRepVotesLastYear = dRepRegistrationVotesLastYear,
163164
dRepIdentityReferences = DRepReferences <$> dRepRegistrationIdentityReferences,
164165
dRepLinkReferences = DRepReferences <$> dRepRegistrationLinkReferences
165166
}
@@ -205,6 +206,8 @@ drepList mSearchQuery statuses mSortMode mPage mPageSize = do
205206
Just Random -> fmap snd . sortOn fst . Prelude.zip randomizedOrderList
206207
Just VotingPower -> sortOn $ \Types.DRepRegistration {..} ->
207208
Down dRepRegistrationVotingPower
209+
Just Activity -> sortOn $ \Types.DRepRegistration {..} ->
210+
Down dRepRegistrationVotesLastYear
208211
Just RegistrationDate -> sortOn $ \Types.DRepRegistration {..} ->
209212
Down dRepRegistrationLatestRegistrationDate
210213
Just Status -> sortOn $ \Types.DRepRegistration {..} ->

govtool/backend/src/VVA/API/Types.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ instance ToParamSchema GovernanceActionType where
205205
& enum_ ?~ map toJSON (enumFromTo minBound maxBound :: [GovernanceActionType])
206206

207207

208-
data DRepSortMode = Random | VotingPower | RegistrationDate | Status deriving
208+
data DRepSortMode = Random | VotingPower | Activity | RegistrationDate | Status deriving
209209
( Bounded
210210
, Enum
211211
, Eq
@@ -917,6 +917,7 @@ data DRep
917917
, dRepQualifications :: Maybe Text
918918
, dRepImageUrl :: Maybe Text
919919
, dRepImageHash :: Maybe HexText
920+
, dRepVotesLastYear :: Maybe Integer
920921
, dRepIdentityReferences :: Maybe DRepReferences
921922
, dRepLinkReferences :: Maybe DRepReferences
922923
}
@@ -944,6 +945,7 @@ exampleDrep =
944945
<> "\"qualifications\": \"Some Qualifications\","
945946
<> "\"qualifications\": \"Some Qualifications\","
946947
<> "\"imageUrl\": \"https://image.url\","
948+
<> "\"votesLastYear\": 15,"
947949
<> "\"imageHash\": \"9198b1b204273ba5c67a13310b5a806034160f6a063768297e161d9b759cad61\"}"
948950

949951
-- ToSchema instance for DRep

govtool/backend/src/VVA/DRep.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ data DRepQueryResult
5959
, queryQualifications :: Maybe Text
6060
, queryImageUrl :: Maybe Text
6161
, queryImageHash :: Maybe Text
62+
, queryVotesLastYear :: Maybe Integer
6263
, queryIdentityReferences :: Maybe Value
6364
, queryLinkReferences :: Maybe Value
6465
}
@@ -69,7 +70,7 @@ instance FromRow DRepQueryResult where
6970
<$> field <*> field <*> field <*> field <*> field <*> field
7071
<*> field <*> field <*> field <*> field <*> field <*> field
7172
<*> field <*> field <*> field <*> field <*> field <*> field
72-
<*> field <*> field <*> field <*> field
73+
<*> field <*> field <*> field <*> field <*> field
7374

7475
sqlFrom :: ByteString -> SQL.Query
7576
sqlFrom bs = fromString $ unpack $ Text.decodeUtf8 bs
@@ -113,6 +114,7 @@ listDReps mSearchQuery = withPool $ \conn -> do
113114
(queryQualifications result)
114115
(queryImageUrl result)
115116
(queryImageHash result)
117+
(queryVotesLastYear result)
116118
(queryIdentityReferences result)
117119
(queryLinkReferences result)
118120
| result <- results

govtool/backend/src/VVA/Types.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ data DRepRegistration
160160
, dRepRegistrationQualifications :: Maybe Text
161161
, dRepRegistrationImageUrl :: Maybe Text
162162
, dRepRegistrationImageHash :: Maybe Text
163+
, dRepRegistrationVotesLastYear :: Maybe Integer
163164
, dRepRegistrationIdentityReferences :: Maybe Value
164165
, dRepRegistrationLinkReferences :: Maybe Value
165166
}
@@ -187,6 +188,7 @@ instance FromRow DRepRegistration where
187188
<*> field -- dRepRegistrationQualifications
188189
<*> field -- dRepRegistrationImageUrl
189190
<*> field -- dRepRegistrationImageHash
191+
<*> field -- dRepRegistrationVotesLastYear
190192
<*> field -- dRepRegistrationIdentityReferences
191193
<*> field -- dRepRegistrationLinkReferences
192194

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import {
2+
Box,
3+
Typography,
4+
IconButton,
5+
Select,
6+
MenuItem,
7+
SelectChangeEvent,
8+
} from "@mui/material";
9+
import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft";
10+
import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight";
11+
import { FC } from "react";
12+
13+
type Props = {
14+
page: number;
15+
total: number;
16+
pageSize: number;
17+
onPageChange: (nextPage: number) => void;
18+
onPageSizeChange: (nextRpp: number) => void;
19+
pageSizeOptions?: number[];
20+
};
21+
22+
export const PaginationFooter: FC<Props> = ({
23+
page,
24+
total,
25+
pageSize,
26+
onPageChange,
27+
onPageSizeChange,
28+
pageSizeOptions = [5, 10, 25, 50],
29+
}) => {
30+
const pageCount = Math.max(1, Math.ceil((total || 0) / (pageSize || 1)));
31+
const clampedPage = Math.min(Math.max(page, 1), pageCount);
32+
33+
const start = total === 0 ? 0 : (clampedPage - 1) * pageSize + 1;
34+
const end = total === 0 ? 0 : Math.min(clampedPage * pageSize, total);
35+
36+
const handlePrev = () => onPageChange(Math.max(clampedPage - 1, 1));
37+
const handleNext = () => onPageChange(Math.min(clampedPage + 1, pageCount));
38+
39+
const handlePageSizeChange = (e: SelectChangeEvent<number>) => {
40+
const next = Number(e.target.value);
41+
onPageSizeChange(next);
42+
43+
const nextPageCount = Math.max(1, Math.ceil((total || 0) / next));
44+
if (clampedPage > nextPageCount) {
45+
onPageChange(nextPageCount);
46+
}
47+
};
48+
49+
return (
50+
<Box
51+
sx={{
52+
display: "flex",
53+
alignItems: "center",
54+
justifyContent: "flex-end",
55+
gap: 2,
56+
px: 2,
57+
py: 1,
58+
color: "#3B485C",
59+
}}
60+
>
61+
<Box sx={{ display: "inline-flex", alignItems: "baseline", gap: 1.25 }}>
62+
<Typography variant="body2" sx={{ fontWeight: 500, color: "#3B485C" }}>
63+
Rows&nbsp;per&nbsp;page:
64+
</Typography>
65+
66+
<Select
67+
value={pageSize}
68+
onChange={handlePageSizeChange}
69+
variant="standard"
70+
disableUnderline
71+
sx={{
72+
verticalAlign: "baseline",
73+
"& .MuiSelect-select": {
74+
py: 0,
75+
lineHeight: 1.5,
76+
display: "inline-flex",
77+
alignItems: "center",
78+
},
79+
"& .MuiSelect-icon": {
80+
top: "calc(50% - 12px)",
81+
},
82+
}}
83+
renderValue={(val) => (
84+
<Box
85+
component="span"
86+
sx={{ fontWeight: 500, color: "#3B485C", fontSize: 15 }}
87+
>
88+
{val as number}
89+
</Box>
90+
)}
91+
MenuProps={{
92+
PaperProps: { sx: { mt: 1, borderRadius: 1.5 } },
93+
MenuListProps: { dense: true },
94+
}}
95+
>
96+
{pageSizeOptions.map((n) => (
97+
<MenuItem key={n} value={n}>
98+
{n}
99+
</MenuItem>
100+
))}
101+
</Select>
102+
</Box>
103+
104+
<Typography variant="body2" sx={{ minWidth: 110, textAlign: "center" }}>
105+
{start}-{end} of {total}
106+
</Typography>
107+
108+
<Box sx={{ display: "flex", alignItems: "center", gap: 0.5 }}>
109+
<IconButton
110+
size="small"
111+
onClick={handlePrev}
112+
disabled={clampedPage <= 1 || total === 0}
113+
aria-label="Previous page"
114+
>
115+
<KeyboardArrowLeft />
116+
</IconButton>
117+
118+
<Typography
119+
variant="body2"
120+
sx={{ width: 24, textAlign: "center" }}
121+
aria-label="Current page"
122+
>
123+
{clampedPage}
124+
</Typography>
125+
126+
<IconButton
127+
size="small"
128+
onClick={handleNext}
129+
disabled={clampedPage >= pageCount || total === 0}
130+
aria-label="Next page"
131+
>
132+
<KeyboardArrowRight />
133+
</IconButton>
134+
</Box>
135+
</Box>
136+
);
137+
};

govtool/frontend/src/consts/dRepDirectory/sorting.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export const DREP_DIRECTORY_SORTING = [
22
{
3-
key: "Random",
4-
label: "Random",
3+
key: "Activity",
4+
label: "Activity",
55
},
66
{
77
key: "RegistrationDate",

govtool/frontend/src/context/contextProviders.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { CardanoProvider, useCardano } from "./wallet";
33
import { ModalProvider, useModal } from "./modal";
44
import { SnackbarProvider, useSnackbar } from "./snackbar";
55
import { DataActionsBarProvider } from "./dataActionsBar";
6+
import { PaginationProvider } from "./pagination";
67
import { FeatureFlagProvider } from "./featureFlag";
78
import { GovernanceActionProvider } from "./governanceAction";
89
import { AdaHandleProvider } from "./adaHandle";
@@ -23,11 +24,13 @@ const ContextProviders = ({ children }: Props) => (
2324
<ModalProvider>
2425
<SnackbarProvider>
2526
<DataActionsBarProvider>
26-
<CardanoProvider>
27-
<MaintenanceEndingBannerProvider>
28-
{children}
29-
</MaintenanceEndingBannerProvider>
30-
</CardanoProvider>
27+
<PaginationProvider>
28+
<CardanoProvider>
29+
<MaintenanceEndingBannerProvider>
30+
{children}
31+
</MaintenanceEndingBannerProvider>
32+
</CardanoProvider>
33+
</PaginationProvider>
3134
</DataActionsBarProvider>
3235
</SnackbarProvider>
3336
</ModalProvider>

govtool/frontend/src/context/dataActionsBar.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ interface DataActionsBarContextType {
2424
debouncedSearchText: string;
2525
filtersOpen: boolean;
2626
searchText: string;
27+
lastPath: string;
2728
setChosenFilters: Dispatch<SetStateAction<string[]>>;
2829
setChosenSorting: Dispatch<SetStateAction<string>>;
2930
setFiltersOpen: Dispatch<SetStateAction<boolean>>;
@@ -120,6 +121,7 @@ const DataActionsBarProvider: FC<ProviderProps> = ({ children }) => {
120121
debouncedSearchText,
121122
filtersOpen,
122123
searchText,
124+
lastPath,
123125
setChosenFilters,
124126
setChosenSorting,
125127
setFiltersOpen,

govtool/frontend/src/context/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from "./appContext";
22
export * from "./contextProviders";
33
export * from "./dataActionsBar";
4+
export * from "./pagination";
45
export * from "./modal";
56
export * from "./pendingTransaction";
67
export * from "./snackbar";

0 commit comments

Comments
 (0)