Skip to content
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
17 changes: 12 additions & 5 deletions govtool/backend/src/VVA/API.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import qualified Data.Text.Lazy.Encoding as TL
import Data.Time (TimeZone, localTimeToUTC)
import Data.Time.LocalTime (TimeZone, getCurrentTimeZone)
import qualified Data.Vector as V
import Data.Hashable (hash, hashWithSalt)

import Numeric.Natural (Natural)

Expand Down Expand Up @@ -64,6 +65,7 @@ type VVAApi =
:> QueryParam "sort" DRepSortMode
:> QueryParam "page" Natural
:> QueryParam "pageSize" Natural
:> QueryParam "seed" Text
:> Get '[JSON] ListDRepsResponse
:<|> "drep" :> "get-voting-power" :> Capture "drepId" HexText :> Get '[JSON] Integer
:<|> "drep" :> "getVotes"
Expand Down Expand Up @@ -175,8 +177,8 @@ delegationToResponse Types.Delegation {..} =
}


drepList :: App m => Maybe Text -> [DRepStatus] -> Maybe DRepSortMode -> Maybe Natural -> Maybe Natural -> m ListDRepsResponse
drepList mSearchQuery statuses mSortMode mPage mPageSize = do
drepList :: App m => Maybe Text -> [DRepStatus] -> Maybe DRepSortMode -> Maybe Natural -> Maybe Natural -> Maybe Text -> m ListDRepsResponse
drepList mSearchQuery statuses mSortMode mPage mPageSize mSeed = do
CacheEnv {dRepListCache} <- asks vvaCache
dreps <- cacheRequest dRepListCache (fromMaybe "" mSearchQuery) (DRep.listDReps mSearchQuery)

Expand All @@ -193,17 +195,22 @@ drepList mSearchQuery statuses mSortMode mPage mPageSize = do
Types.DRep ->
True


let filterDRepsByStatus = case statuses of
[] -> id
_ -> filter $ \Types.DRepRegistration {..} ->
mapDRepStatus dRepRegistrationStatus `elem` statuses

randomizedOrderList <- mapM (\_ -> randomRIO (0, 1 :: Double)) dreps
let seedInt :: Int
seedInt =
maybe 0 (hash . Text.toCaseFold) mSeed

randomKey :: Types.DRepRegistration -> Int
randomKey Types.DRepRegistration{..} =
hashWithSalt seedInt dRepRegistrationDRepHash

let sortDReps = case mSortMode of
Nothing -> id
Just Random -> fmap snd . sortOn fst . Prelude.zip randomizedOrderList
Just Random -> sortOn randomKey
Just VotingPower -> sortOn $ \Types.DRepRegistration {..} ->
Down dRepRegistrationVotingPower
Just Activity -> sortOn $ \Types.DRepRegistration {..} ->
Expand Down
4 changes: 4 additions & 0 deletions govtool/frontend/src/consts/dRepDirectory/sorting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,8 @@ export const DREP_DIRECTORY_SORTING = [
key: "Status",
label: "Status",
},
{
key: "Random",
label: "Random",
},
];
5 changes: 4 additions & 1 deletion govtool/frontend/src/hooks/queries/useGetDRepListQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type Args = GetDRepListArguments & {
};

export function useGetDRepListPaginatedQuery(
{ page, pageSize = 10, filters = [], searchPhrase, sorting, status }: Args,
{ page, pageSize = 10, filters = [], searchPhrase, sorting, status, sortingSeed }: Args,
options?: UseQueryOptions<Infinite<DRepData>>,
): PaginatedResult {
const { pendingTransaction } = useCardano();
Expand All @@ -47,6 +47,7 @@ export function useGetDRepListPaginatedQuery(
searchPhrase ?? "",
sorting ?? "",
status?.length ? status : "",
sortingSeed ?? ""
];

const baselineKey = useMemo(
Expand All @@ -64,6 +65,7 @@ export function useGetDRepListPaginatedQuery(
searchPhrase,
sorting,
status,
sortingSeed,
}),
{
keepPreviousData: true,
Expand All @@ -87,6 +89,7 @@ export function useGetDRepListPaginatedQuery(
searchPhrase: "",
sorting,
status,
sortingSeed
}),
{
initialData: () =>
Expand Down
1 change: 1 addition & 0 deletions govtool/frontend/src/models/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export enum DRepListSort {
VotingPower = "VotingPower",
RegistrationDate = "RegistrationDate",
Status = "Status",
Random = "Random",
}

type Reference = {
Expand Down
22 changes: 22 additions & 0 deletions govtool/frontend/src/pages/DRepDirectoryContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ export const DRepDirectoryContent: FC<DRepDirectoryContentProps> = ({
...dataActionsBarProps
} = useDataActionsBar();

const SEED_STORAGE_KEY = "drep_directory_sorting_seed";

const makeSeed = () =>
(globalThis.crypto?.randomUUID?.() as string | undefined) ??
Math.random().toString(36).slice(2);

const getStoredSeed = () => {
if (typeof window === "undefined") return "";
return sessionStorage.getItem(SEED_STORAGE_KEY) || "";
};

const [sortingSeed, setSortingSeed] = useState<string>(() => getStoredSeed());

useEffect(() => {
if (lastPath && !lastPath.includes("drep_directory")) {
const newSeed = makeSeed();
setSortingSeed(newSeed);
sessionStorage.setItem(SEED_STORAGE_KEY, newSeed);
}
}, [sortingSeed]);

const { page, pageSize, setPage, setPageSize } = usePagination();

const { chosenFilters, chosenSorting, setChosenFilters, setChosenSorting } =
Expand Down Expand Up @@ -108,6 +129,7 @@ export const DRepDirectoryContent: FC<DRepDirectoryContentProps> = ({
searchPhrase: debouncedSearchText,
sorting: chosenSorting as DRepListSort,
status: chosenFilters as DRepStatus[],
sortingSeed
},
{ enabled: !!chosenSorting },
);
Expand Down
3 changes: 3 additions & 0 deletions govtool/frontend/src/services/requests/getDRepList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type GetDRepListArguments = {
sorting?: DRepListSort;
status?: DRepStatus[];
searchPhrase?: string;
sortingSeed?: string;
};

export const getDRepList = async ({
Expand All @@ -23,6 +24,7 @@ export const getDRepList = async ({
pageSize = 10,
searchPhrase: rawSearchPhrase = "",
status = [],
sortingSeed = ""
}: GetDRepListArguments): Promise<Infinite<DRepData>> => {
const searchPhrase = await dRepSearchPhraseProcessor(rawSearchPhrase);

Expand All @@ -34,6 +36,7 @@ export const getDRepList = async ({
...(filters.length && { type: filters }),
...(sorting && { sort: sorting }),
...(status.length && { status }),
...(sortingSeed && { seed: sortingSeed }),
},
});

Expand Down
Loading