Skip to content

Commit

Permalink
feat: use search query for vault list
Browse files Browse the repository at this point in the history
  • Loading branch information
Majorfi committed Oct 17, 2023
1 parent 99ecf5a commit 4b6534f
Show file tree
Hide file tree
Showing 16 changed files with 90 additions and 31 deletions.
5 changes: 3 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ module.exports = {
}
],
'react-hooks/exhaustive-deps': [
'warn', {
'additionalHooks': '^useAsync$'
'warn',
{
additionalHooks: '^useAsync$'
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion apps/vaults/Wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function Wrapper({children, router}: {children: ReactElement; router: Nex
<StakingRewardsContextApp>
<AnimatePresence mode={'wait'}>
<motion.div
key={router.asPath}
key={router.basePath}
initial={'initial'}
animate={'enter'}
exit={'exit'}
Expand Down
6 changes: 3 additions & 3 deletions apps/vaults/components/ListHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ type TListHero = {
searchValue: string;
set_categories: (categories: string) => void;
set_selectedChains: (chains: string) => void;
set_searchValue: (searchValue: string) => void;
onSearch: (searchValue: string) => void;
};

export function ListHero({categories, set_categories, searchValue, selectedChains, set_searchValue, set_selectedChains}: TListHero): ReactElement {
export function ListHero({categories, set_categories, searchValue, selectedChains, onSearch, set_selectedChains}: TListHero): ReactElement {
const chainsFromJSON = useMemo((): number[] => JSON.parse(selectedChains || '[]') as number[], [selectedChains]);
const categoriesFromJSON = useMemo((): string[] => JSON.parse(categories || '[]') as string[], [categories]);

Expand Down Expand Up @@ -143,7 +143,7 @@ export function ListHero({categories, set_categories, searchValue, selectedChain
className={'md:w-full'}
searchPlaceholder={'YFI Vault'}
searchValue={searchValue}
set_searchValue={set_searchValue}
set_searchValue={onSearch}
/>
</div>
</div>
Expand Down
18 changes: 16 additions & 2 deletions apps/vaults/contexts/useAppSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ const defaultProps: TAppSettingsContext = {

const AppSettingsContext = createContext<TAppSettingsContext>(defaultProps);
export const AppSettingsContextApp = memo(function AppSettingsContextApp({children}: {children: ReactElement}): ReactElement {
const [category, set_category] = useSessionStorage('yearn.fi/[email protected]', ALL_CATEGORIES);
/**
* @deprecated Use use-query-params instead
*/
const [searchValue, set_searchValue] = useSessionStorage('yearn.fi/[email protected]', '');
const [category, set_category] = useSessionStorage('yearn.fi/[email protected]', ALL_CATEGORIES);
const [selectedChains, set_selectedChains] = useSessionStorage('yearn.fi/[email protected]', ALL_CHAINS);
const [shouldHideDust, set_shouldHideDust] = useLocalStorage('yearn.fi/[email protected]', false);
const [shouldHideLowTVLVaults, set_shouldHideLowTVLVaults] = useLocalStorage('yearn.fi/[email protected]', false);
Expand All @@ -56,7 +59,18 @@ export const AppSettingsContextApp = memo(function AppSettingsContextApp({childr
set_searchValue,
set_selectedChains
}),
[shouldHideDust, shouldHideLowTVLVaults, category, searchValue, set_category, set_searchValue, set_shouldHideDust, set_shouldHideLowTVLVaults]
[
shouldHideDust,
shouldHideLowTVLVaults,
category,
selectedChains,
searchValue,
set_category,
set_searchValue,
set_selectedChains,
set_shouldHideDust,
set_shouldHideLowTVLVaults
]
);

return <AppSettingsContext.Provider value={contextValue}>{children}</AppSettingsContext.Provider>;
Expand Down
7 changes: 0 additions & 7 deletions apps/vaults/hooks/useFilteredVaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,6 @@ export function useVaultFilter(): {activeVaults: TYDaemonVault[]; retiredVaults:
//remove duplicates
_vaultList = _vaultList.filter((vault, index, self): boolean => index === self.findIndex((v): boolean => v.address === vault.address));

for (const vault of _vaultList) {
if (vault.apr.forwardAPR.netAPR === 0) {
// console.log(`DebtRatio for vault ${vault.address} - ${vault.name}: 0`);
}
}
// console.log('-------------------')

return _vaultList;
}, [categoriesFromJSON, curveVaults, balancerVaults, velodromeVaults, aerodromeVaults, boostedVaults, stablesVaults, cryptoVaults, holdingsVaults]);

Expand Down
2 changes: 1 addition & 1 deletion apps/vaults/hooks/useSolverChainCoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function useSolverChainCoin(): TSolverContext {
**************************************************************************/
const onRetrieveAllowance = useCallback(
async (shouldForceRefetch?: boolean): Promise<TNormalizedBN> => {
if (!request?.current) {
if (!request?.current || !provider) {
return toNormalizedBN(0);
}

Expand Down
2 changes: 1 addition & 1 deletion apps/vaults/hooks/useSolverCowswap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ export function useSolverCowswap(): TSolverContext {
**************************************************************************/
const onRetrieveAllowance = useCallback(
async (shouldForceRefetch?: boolean): Promise<TNormalizedBN> => {
if (!request?.current || request.current.chainID !== 1) {
if (!request?.current || request.current.chainID !== 1 || !provider) {
return toNormalizedBN(0);
}
assert(request.current, 'Request is not defined');
Expand Down
2 changes: 1 addition & 1 deletion apps/vaults/hooks/useSolverInternalMigration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function useSolverInternalMigration(): TSolverContext {
**************************************************************************/
const onRetrieveAllowance = useCallback(
async (shouldForceRefetch?: boolean): Promise<TNormalizedBN> => {
if (!request?.current) {
if (!request?.current || !provider) {
return toNormalizedBN(0);
}

Expand Down
2 changes: 1 addition & 1 deletion apps/vaults/hooks/useSolverOptimismBooster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function useSolverOptimismBooster(): TSolverContext {
**************************************************************************/
const onRetrieveAllowance = useCallback(
async (shouldForceRefetch?: boolean): Promise<TNormalizedBN> => {
if (!request?.current) {
if (!request?.current || !provider) {
return toNormalizedBN(0);
}

Expand Down
2 changes: 1 addition & 1 deletion apps/vaults/hooks/useSolverPartnerContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function useSolverPartnerContract(): TSolverContext {
**************************************************************************/
const onRetrieveAllowance = useCallback(
async (shouldForceRefetch?: boolean): Promise<TNormalizedBN> => {
if (!request?.current) {
if (!request?.current || !provider) {
return toNormalizedBN(0);
}

Expand Down
2 changes: 1 addition & 1 deletion apps/vaults/hooks/useSolverPortals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ export function useSolverPortals(): TSolverContext {
**************************************************************************/
const onApprove = useCallback(
async (amount = MAX_UINT_256, txStatusSetter: React.Dispatch<React.SetStateAction<TTxStatus>>, onSuccess: () => Promise<void>): Promise<void> => {
if (!request.current || isSolverDisabled(request.current.chainID)[Solver.enum.Portals]) {
if (!request.current || isSolverDisabled(request.current.chainID)[Solver.enum.Portals] || !provider) {
return;
}
assert(request.current, 'Request is not set');
Expand Down
2 changes: 1 addition & 1 deletion apps/vaults/hooks/useSolverVanilla.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function useSolverVanilla(): TSolverContext {
**************************************************************************/
const onRetrieveAllowance = useCallback(
async (shouldForceRefetch?: boolean): Promise<TNormalizedBN> => {
if (!request?.current) {
if (!request?.current || !provider) {
return toNormalizedBN(0);
}

Expand Down
2 changes: 1 addition & 1 deletion apps/vaults/hooks/useSolverWido.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export function useSolverWido(): TSolverContext {
**************************************************************************/
const onRetrieveAllowance = useCallback(
async (shouldForceRefetch?: boolean): Promise<TNormalizedBN> => {
if (!latestQuote?.current || !request?.current || isSolverDisabled(request.current.chainID)[Solver.enum.Wido]) {
if (!latestQuote?.current || !request?.current || isSolverDisabled(request.current.chainID)[Solver.enum.Wido] || !provider) {
return toNormalizedBN(0);
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"tailwindcss": "^3.3.3",
"ts-loader": "^9.4.4",
"typescript": "^5.2.2",
"use-query-params": "^2.2.1",
"vitest": "^0.34.6",
"webpack": "^5.88.2"
},
Expand Down
54 changes: 46 additions & 8 deletions pages/vaults/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Fragment, useCallback, useEffect, useMemo} from 'react';
import {Fragment, useCallback, useEffect, useMemo, useState} from 'react';
import {QueryParamProvider, StringParam, useQueryParams} from 'use-query-params';
import {motion, useSpring, useTransform} from 'framer-motion';
import {VaultListOptions} from '@vaults/components/list/VaultListOptions';
import {VaultsListEmpty} from '@vaults/components/list/VaultsListEmpty';
Expand All @@ -20,6 +21,7 @@ import {isZero} from '@yearn-finance/web-lib/utils/isZero';
import {ListHead} from '@common/components/ListHead';
import {useWallet} from '@common/contexts/useWallet';
import {useYearn} from '@common/contexts/useYearn';
import {NextQueryParamAdapter} from '@common/utils/QueryParamsProvider';

Check failure on line 24 in pages/vaults/index.tsx

View workflow job for this annotation

GitHub Actions / Test Build

Cannot find module '@common/utils/QueryParamsProvider' or its corresponding type declarations.

import type {NextRouter} from 'next/router';
import type {ReactElement, ReactNode} from 'react';
Expand Down Expand Up @@ -95,21 +97,53 @@ function Index(): ReactElement {
sortBy: TPossibleSortBy;
sortDirection: TSortDirection;
}>('yVaultsSorting', {sortBy: 'featuringScore', sortDirection: 'desc'});
const {category, searchValue, selectedChains, set_category, set_searchValue, set_selectedChains} = useAppSettings();
const {category, selectedChains, set_category, set_selectedChains} = useAppSettings();
const chainsFromJSON = useMemo((): number[] => JSON.parse(selectedChains || '[]') as number[], [selectedChains]);
const categoriesFromJSON = useMemo((): string[] => JSON.parse(category || '[]') as string[], [category]);
const {activeVaults, migratableVaults, retiredVaults} = useVaultFilter();
const [searchParam, set_searchParam] = useQueryParams({search: StringParam});
const [search, set_search] = useState(searchParam?.search);

/** 🔵 - Yearn *********************************************************************************
** This useEffect hook is used to synchronize the search state with the query parameter
** It checks if the search state and the search query parameter are the same, if they are,
** it does nothing.
** If the search state is undefined and the search query parameter is not, it sets the search
** state to the value of the search query parameter.
** If the search state is not undefined, it updates the search query parameter to match the
** search state.
** If the search state is undefined, it removes the search query parameter.
*********************************************************************************************/
useEffect((): void => {
// If the search state and the search query parameter are the same, do nothing
if (searchParam.search === search) {
return;
}
// If the search state is undefined and the search query parameter is not, set the search
// state to the value of the search query parameter
if (search === undefined && searchParam.search !== undefined) {
set_search(searchParam.search);
return;
}
// If the search state is not undefined, update the search query parameter to match
// the search state
if (!search) {
set_searchParam({}, 'push');
} else {
set_searchParam({search: search}, 'push');
}
}, [searchParam, search, set_searchParam]);

/* 🔵 - Yearn Finance **************************************************************************
** Then, on the activeVaults list, we apply the search filter. The search filter is
** implemented as a simple string.includes() on the vault name.
**********************************************************************************************/
const searchedVaultsToDisplay = useMemo((): TYDaemonVault[] => {
if (searchValue === '') {
if (!search) {
return activeVaults;
}
return activeVaults.filter((vault: TYDaemonVault): boolean => {
const lowercaseSearch = searchValue.toLowerCase();
const lowercaseSearch = search.toLowerCase();
return (
vault.name.toLowerCase().startsWith(lowercaseSearch) ||
vault.symbol.toLowerCase().startsWith(lowercaseSearch) ||
Expand All @@ -119,7 +153,7 @@ function Index(): ReactElement {
vault.token.address.toLowerCase().startsWith(lowercaseSearch)
);
});
}, [activeVaults, searchValue]);
}, [activeVaults, search]);

/* 🔵 - Yearn Finance **************************************************************************
** Then, once we have reduced the list of vaults to display, we can sort them. The sorting
Expand Down Expand Up @@ -193,10 +227,10 @@ function Index(): ReactElement {
<ListHero
categories={category}
set_categories={set_category}
searchValue={searchValue}
searchValue={search || ''}
selectedChains={selectedChains}
set_selectedChains={set_selectedChains}
set_searchValue={set_searchValue}
onSearch={(value: string): void => set_search(value)}
/>

<Renderable shouldRender={category === 'Holdings' && retiredVaults?.length > 0}>
Expand Down Expand Up @@ -253,7 +287,11 @@ function Index(): ReactElement {
}

Index.getLayout = function getLayout(page: ReactElement, router: NextRouter): ReactElement {
return <Wrapper router={router}>{page}</Wrapper>;
return (
<Wrapper router={router}>
<QueryParamProvider adapter={NextQueryParamAdapter}>{page}</QueryParamProvider>
</Wrapper>
);
};

export default Index;
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8629,6 +8629,11 @@ serialize-javascript@^6.0.1:
dependencies:
randombytes "^2.1.0"

serialize-query-params@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/serialize-query-params/-/serialize-query-params-2.0.2.tgz#598a3fb9e13f4ea1c1992fbd20231aa16b31db81"
integrity sha512-1chMo1dST4pFA9RDXAtF0Rbjaut4is7bzFbI1Z26IuMub68pNCILku85aYmeFhvnY//BXUPUhoRMjYcsT93J/Q==

set-blocking@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
Expand Down Expand Up @@ -9696,6 +9701,13 @@ use-callback-ref@^1.3.0:
dependencies:
tslib "^2.0.0"

use-query-params@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/use-query-params/-/use-query-params-2.2.1.tgz#c558ab70706f319112fbccabf6867b9f904e947d"
integrity sha512-i6alcyLB8w9i3ZK3caNftdb+UnbfBRNPDnc89CNQWkGRmDrm/gfydHvMBfVsQJRq3NoHOM2dt/ceBWG2397v1Q==
dependencies:
serialize-query-params "^2.0.2"

use-sidecar@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2"
Expand Down

0 comments on commit 4b6534f

Please sign in to comment.