Skip to content

Commit 4367bc1

Browse files
committed
react-app: Handle sorting proposal vote table
refs oursky#128
1 parent 67e3b04 commit 4367bc1

File tree

2 files changed

+77
-10
lines changed

2 files changed

+77
-10
lines changed

react-app/src/components/ProposalDetailScreen/ProposalDetailScreenAPI.ts

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
ProposalDetailDepositsPanelQueryQuery,
1414
ProposalDetailDepositsPanelQueryQueryVariables,
1515
ProposalDepositSort,
16+
Sort,
1617
} from "../../generated/graphql";
1718
import { useLazyGraphQLQuery } from "../../hooks/graphql";
1819
import { mapRequestData, RequestState } from "../../models/RequestState";
@@ -60,13 +61,44 @@ const getVoterOrDepositorAddress = (
6061
return null;
6162
};
6263

64+
export enum ProposalVoteSortableColumn {
65+
Voter = "voter",
66+
Option = "option",
67+
}
68+
69+
function getProposalVoteSortOrderVariable(
70+
order: {
71+
id: ProposalVoteSortableColumn;
72+
direction: "asc" | "desc";
73+
} | null
74+
): ProposalVoteSort {
75+
if (!order) {
76+
return {};
77+
}
78+
switch (order.id) {
79+
case ProposalVoteSortableColumn.Voter:
80+
return {
81+
voter: order.direction === "asc" ? Sort.Asc : Sort.Desc,
82+
};
83+
case ProposalVoteSortableColumn.Option:
84+
return {
85+
option: order.direction === "asc" ? Sort.Asc : Sort.Desc,
86+
};
87+
default:
88+
return {};
89+
}
90+
}
91+
6392
interface UseProposalVotesQuery {
6493
(proposalId: string, initialOffset: number, pageSize: number): {
6594
requestState: RequestState<PaginatedProposalVotes>;
6695
fetch: (variables: {
6796
first: number;
6897
after: number;
69-
order: ProposalVoteSort;
98+
order: {
99+
id: ProposalVoteSortableColumn;
100+
direction: "asc" | "desc";
101+
} | null;
70102
}) => Promise<void>;
71103
};
72104
}
@@ -105,7 +137,10 @@ export const useProposalVotesQuery: UseProposalVotesQuery = (
105137
}: {
106138
first: number;
107139
after: number;
108-
order: ProposalVoteSort;
140+
order: {
141+
id: ProposalVoteSortableColumn;
142+
direction: "asc" | "desc";
143+
} | null;
109144
}) => {
110145
let delegatedValidators: string[] = [];
111146

@@ -130,8 +165,8 @@ export const useProposalVotesQuery: UseProposalVotesQuery = (
130165
input: {
131166
first,
132167
after,
133-
order,
134168
pinnedValidators: delegatedValidators,
169+
order: getProposalVoteSortOrderVariable(order),
135170
},
136171
},
137172
});

react-app/src/components/ProposalDetailScreen/ProposalVotesPanel.tsx

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ import {
1717
ProposalVote,
1818
ProposalVoteVoter,
1919
} from "./ProposalDetailScreenModel";
20-
import { useProposalVotesQuery } from "./ProposalDetailScreenAPI";
20+
import {
21+
ProposalVoteSortableColumn,
22+
useProposalVotesQuery,
23+
} from "./ProposalDetailScreenAPI";
2124

2225
const PROPOSAL_VOTE_PAGE_SIZE = 5;
2326

@@ -149,10 +152,22 @@ const ProposalVotesPanel: React.FC = () => {
149152
const { translate } = useLocale();
150153
const [searchParams, setSearchParams] = useSearchParams();
151154

152-
const currentOffset = useMemo(() => {
155+
const [currentOffset, sortOrder] = useMemo(() => {
153156
const page = searchParams.get("page") ?? "1";
157+
const sortBy = searchParams.get("sortBy");
158+
const sortDirection = searchParams.get("sortDirection");
159+
160+
const sortOrder =
161+
sortBy && sortDirection
162+
? {
163+
id: sortBy as ProposalVoteSortableColumn,
164+
direction: sortDirection as SectionedTable.ColumnOrder["direction"],
165+
}
166+
: undefined;
167+
168+
const offset = (parseInt(page, 10) - 1) * PROPOSAL_VOTE_PAGE_SIZE;
154169

155-
return (parseInt(page, 10) - 1) * PROPOSAL_VOTE_PAGE_SIZE;
170+
return [offset, sortOrder];
156171
}, [searchParams]);
157172

158173
const { fetch, requestState } = useProposalVotesQuery(
@@ -170,6 +185,16 @@ const ProposalVotesPanel: React.FC = () => {
170185
[setSearchParams]
171186
);
172187

188+
const setSortOrder = useCallback(
189+
(order: SectionedTable.ColumnOrder) => {
190+
setSearchParams({
191+
sortBy: order.id,
192+
sortDirection: order.direction,
193+
});
194+
},
195+
[setSearchParams]
196+
);
197+
173198
const tableSections =
174199
useMemo((): SectionedTable.SectionItem<ProposalVote>[] => {
175200
if (!isRequestStateLoaded(requestState)) {
@@ -202,9 +227,14 @@ const ProposalVotesPanel: React.FC = () => {
202227
fetch({
203228
first: PROPOSAL_VOTE_PAGE_SIZE,
204229
after: currentOffset,
205-
order: {},
230+
order: sortOrder
231+
? {
232+
id: sortOrder.id,
233+
direction: sortOrder.direction,
234+
}
235+
: null,
206236
});
207-
}, [fetch, currentOffset]);
237+
}, [fetch, currentOffset, sortOrder]);
208238

209239
useEffect(() => {
210240
if (isRequestStateError(requestState)) {
@@ -219,16 +249,18 @@ const ProposalVotesPanel: React.FC = () => {
219249
sections={tableSections}
220250
isLoading={!isRequestStateLoaded(requestState)}
221251
emptyMessageID="ProposalDetail.votes.empty"
252+
sortOrder={sortOrder}
253+
onSort={setSortOrder}
222254
>
223255
<SectionedTable.Column<ProposalVote>
224-
id="voter"
256+
id={ProposalVoteSortableColumn.Voter}
225257
titleId="ProposalDetail.votes.voter"
226258
sortable={true}
227259
>
228260
{(item) => <ProposalVoter voter={item.voter} />}
229261
</SectionedTable.Column>
230262
<SectionedTable.Column<ProposalVote>
231-
id="option"
263+
id={ProposalVoteSortableColumn.Option}
232264
titleId="ProposalDetail.votes.option"
233265
sortable={true}
234266
>

0 commit comments

Comments
 (0)