diff --git a/src/pages/TrueSightV2/components/TokenFilter/WatchlistSelect.tsx b/src/pages/TrueSightV2/components/TokenFilter/WatchlistSelect.tsx new file mode 100644 index 0000000000..a4490f332b --- /dev/null +++ b/src/pages/TrueSightV2/components/TokenFilter/WatchlistSelect.tsx @@ -0,0 +1,48 @@ +import { t } from '@lingui/macro' +import { useMemo, useState } from 'react' +import { CSSProperties } from 'styled-components' + +import { SelectOption } from 'components/Select' +import { ActiveSelectItem, StyledSelect } from 'pages/TrueSightV2/components/TokenFilter' +import { ManageListModal } from 'pages/TrueSightV2/components/WatchlistButton' +import { useGetWatchlistInformationQuery } from 'pages/TrueSightV2/hooks/useKyberAIData' + +const WatchlistSelect = ({ + menuStyle, + onChangeFilter, + value, +}: { + menuStyle: CSSProperties + onChangeFilter: (key: string, value: string) => void + value: string +}) => { + const [isOpen, setIsOpen] = useState(false) + const { data: dataWatchList } = useGetWatchlistInformationQuery() + const watchlistesOptions = useMemo(() => { + let total = 0 + const opts: SelectOption[] = + dataWatchList?.watchlists?.map(e => { + total += e.assetNumber + return { value: e.id + '', label: `${e.name} (${e.assetNumber})` } + }) || [] + opts.unshift({ label: t`All Tokens (${total})`, value: '' }) + opts.push({ label: t`Manage Lists`, onSelect: () => setIsOpen(true) }) // todo danh: update like desgin + return opts + }, [dataWatchList]) + + return ( + <> + } + options={watchlistesOptions} + onChange={value => onChangeFilter('watchlist', value)} + optionStyle={{ fontSize: '14px' }} + menuStyle={menuStyle} + /> + + + ) +} +export default WatchlistSelect diff --git a/src/pages/TrueSightV2/components/TokenFilter.tsx b/src/pages/TrueSightV2/components/TokenFilter/index.tsx similarity index 84% rename from src/pages/TrueSightV2/components/TokenFilter.tsx rename to src/pages/TrueSightV2/components/TokenFilter/index.tsx index 8348042842..acd0675db5 100644 --- a/src/pages/TrueSightV2/components/TokenFilter.tsx +++ b/src/pages/TrueSightV2/components/TokenFilter/index.tsx @@ -1,10 +1,9 @@ import { ChainId } from '@kyberswap/ks-sdk-core' -import { t } from '@lingui/macro' import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react' import Skeleton from 'react-loading-skeleton' import { useMedia } from 'react-use' import { Text } from 'rebass' -import styled, { css } from 'styled-components' +import styled, { CSSProperties, css } from 'styled-components' import { ButtonGray } from 'components/Button' import Column from 'components/Column' @@ -14,10 +13,9 @@ import useShowLoadingAtLeastTime from 'hooks/useShowLoadingAtLeastTime' import useTheme from 'hooks/useTheme' import MultipleChainSelect from 'pages/MyEarnings/MultipleChainSelect' import SubscribeButtonKyberAI from 'pages/TrueSightV2/components/SubscireButtonKyberAI' -import WatchlistButton from 'pages/TrueSightV2/components/WatchlistButton' +import WatchlistSelect from 'pages/TrueSightV2/components/TokenFilter/WatchlistSelect' import { NETWORK_TO_CHAINID, SUPPORTED_NETWORK_KYBERAI, Z_INDEX_KYBER_AI } from 'pages/TrueSightV2/constants' import { useGetFilterCategoriesQuery } from 'pages/TrueSightV2/hooks/useKyberAIData' -import { ICustomWatchlists } from 'pages/TrueSightV2/types' import { useSessionInfo } from 'state/authen/hooks' import { MEDIA_WIDTHS } from 'theme' @@ -39,7 +37,7 @@ const StyledSkeleton = styled(Skeleton)` width: 150px; ` -const StyledSelect = styled(Select)` +export const StyledSelect = styled(Select)` ${shareStyle} ` @@ -106,6 +104,18 @@ const SelectGroup = styled.div` const getChainsFromSlugs = (values: string[] | undefined) => (values || []).map(item => NETWORK_TO_CHAINID[item || '']).filter(Boolean) +export const ActiveSelectItem = ({ name, label }: { name: string; label: ReactNode }) => { + const theme = useTheme() + return ( + + {name} + + {label} + + + ) +} + export default function TokenFilter({ handleFilterChange, setShowShare, @@ -158,12 +168,6 @@ export default function TokenFilter({ [chainFilter, onChangeFilter, allChainIds, onTrackingSelectChain], ) - const [watchListInfo, setWatchlistInfo] = useState() - const handleChangeWatchlist = (watchlist: ICustomWatchlists) => { - setWatchlistInfo(watchlist) - onChangeFilter('watchlist', watchlist.id + '') - } - const isInit = useRef(false) useEffect(() => { if (isInit.current || defaultChains.length + allChainIds.length === 0) return @@ -174,15 +178,12 @@ export default function TokenFilter({ // todo loading de len filter const upToSmall = useMedia(`(max-width: ${MEDIA_WIDTHS.upToSmall}px)`) - const activeRender = (name: string, label: ReactNode) => ( - - {name} - - {label} - - - ) - + const menuStyle: CSSProperties = { + zIndex: Z_INDEX_KYBER_AI.FILTER_TOKEN_OPTIONS, + top: upToSmall ? undefined : SELECT_SIZE, + maxHeight: 400, + overflowY: 'scroll', + } return ( @@ -202,33 +203,20 @@ export default function TokenFilter({ handleChangeChains={handleChainChange} chainIds={allChainIds} selectedChainIds={selectedChains} - activeRender={node => activeRender('Chains', node)} + activeRender={node => } /> {listSelects.map(({ queryKey, displayName, values }) => ( activeRender(displayName, item?.label)} + activeRender={item => } options={values} onChange={value => onChangeFilter(queryKey, value)} optionStyle={{ fontSize: '14px' }} - menuStyle={{ - zIndex: Z_INDEX_KYBER_AI.FILTER_TOKEN_OPTIONS, - top: upToSmall ? undefined : SELECT_SIZE, - maxHeight: 400, - overflowY: 'scroll', - }} + menuStyle={menuStyle} /> ))} - activeRender('Watchlist', watchListInfo?.name || t`All Tokens`)} - /> - } - onSelectWatchlist={handleChangeWatchlist} - /> + )} diff --git a/src/pages/TrueSightV2/components/WatchlistButton.tsx b/src/pages/TrueSightV2/components/WatchlistButton.tsx index 7889346b1e..512fe39a4c 100644 --- a/src/pages/TrueSightV2/components/WatchlistButton.tsx +++ b/src/pages/TrueSightV2/components/WatchlistButton.tsx @@ -1,6 +1,6 @@ import { Trans, t } from '@lingui/macro' import { AnimatePresence, Reorder, useDragControls } from 'framer-motion' -import { CSSProperties, ReactNode, memo, useEffect, useRef, useState } from 'react' +import { CSSProperties, memo, useEffect, useRef, useState } from 'react' import { Check, Plus, X } from 'react-feather' import { useDispatch } from 'react-redux' import { Text } from 'rebass' @@ -347,40 +347,83 @@ const debounce = (func: () => void, timeout = 1000) => { const MAX_LIMIT_WATCHED_TOKEN = 50 +export const ManageListModal = ({ isOpen, setIsOpen }: { isOpen: boolean; setIsOpen: (v: boolean) => void }) => { + const { data, refetch: refetchWatchlists } = useGetWatchlistInformationQuery() + const watchlists = data?.watchlists || [] + const numberOfWatchlists = watchlists?.length || 0 + const dispatch = useDispatch() + const [updateWatchlistsPriorities] = useUpdateCustomizedWatchlistsPrioritiesMutation() + const reorderWrapperRef = useRef(null) + const handleReorder = (newOrders: ICustomWatchlists[]) => { + const orderedIds = newOrders.map(item => item.id).join(',') + dispatch( + kyberAIApi.util.updateQueryData('getWatchlistInformation', undefined, draft => { + const order = orderedIds.split(',') + draft.watchlists = draft.watchlists.sort((a, b) => { + return order.indexOf(a.id.toString()) - order.indexOf(b.id.toString()) + }) + return draft + }), + ) + debounce(() => updateWatchlistsPriorities({ orderedIds }), 1000) + } + return ( + + e.stopPropagation()}> + + Manage Watchlists + setIsOpen(false)}> + + + + refetchWatchlists()} /> + + + + {watchlists?.map(item => ( + refetchWatchlists()} + /> + ))} + + + + + + ) +} + function WatchlistButton({ assetId, symbol, size, wrapperStyle, - onSelectWatchlist, - trigger, }: { assetId?: string symbol?: string size?: number wrapperStyle?: CSSProperties - onSelectWatchlist?: (watchListId: ICustomWatchlists) => void - trigger?: ReactNode }) { const theme = useTheme() - const dispatch = useDispatch() + const mixpanelHandler = useMixpanelKyberAI() const [openMenu, setOpenMenu] = useState(false) const [openManageModal, setOpenManageModal] = useState(false) - const { data, refetch: refetchWatchlists } = useGetWatchlistInformationQuery() + const { data } = useGetWatchlistInformationQuery() const watchlists = data?.watchlists || [] - const numberOfWatchlists = watchlists?.length || 0 const isReachMaxLimit = (data?.totalUniqueAssetNumber || 0) >= MAX_LIMIT_WATCHED_TOKEN - const [updateWatchlistsPriorities] = useUpdateCustomizedWatchlistsPrioritiesMutation() - const [addToWatchlist] = useAddToWatchlistMutation() const [removeFromWatchlist] = useRemoveFromWatchlistMutation() const ref = useRef(null) - const reorderWrapperRef = useRef(null) + useOnClickOutside(ref, () => { setOpenMenu(false) }) @@ -405,25 +448,7 @@ function WatchlistButton({ } } - const handleReorder = (newOrders: ICustomWatchlists[]) => { - const orderedIds = newOrders.map(item => item.id).join(',') - dispatch( - kyberAIApi.util.updateQueryData('getWatchlistInformation', undefined, draft => { - const order = orderedIds.split(',') - draft.watchlists = draft.watchlists.sort((a, b) => { - return order.indexOf(a.id.toString()) - order.indexOf(b.id.toString()) - }) - return draft - }), - ) - debounce(() => updateWatchlistsPriorities({ orderedIds }), 1000) - } - const onSelect = (watchlist: ICustomWatchlists, watched: boolean) => { - if (onSelectWatchlist) { - onSelectWatchlist(watchlist) - return - } watched ? handleRemoveFromWatchlist(watchlist.id) : handleAddtoWatchlist(watchlist.id) } @@ -483,45 +508,9 @@ function WatchlistButton({ placement="bottom-start" noArrow={true} > - {trigger ? ( -
{ - e.stopPropagation() - setOpenMenu(v => !v) - }} - > - {trigger} -
- ) : ( - btnStar - )} + {btnStar} - - e.stopPropagation()}> - - Manage Watchlists - setOpenManageModal(false)}> - - - - refetchWatchlists()} /> - - - - {watchlists?.map(item => ( - refetchWatchlists()} - /> - ))} - - - - - + ) }