From 4a4a9036d6d64d495d7d23be2d7c1c5fa1bc3286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B8b=C4=97rt=C3=B8?= <106074508+EchoDex@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:03:13 +0400 Subject: [PATCH 1/2] feat: added layout for filters --- src/assets/icons/tableSettings.svg | 5 + src/assets/icons/tablesSize.svg | 1 - src/assets/icons/tablesSizeSelector.svg | 1 + .../SpotScreen/BottomTables/BaseTable.tsx | 77 +------- .../BottomTables/TableActionButtons.tsx | 172 ++++++++++++++++++ 5 files changed, 182 insertions(+), 74 deletions(-) create mode 100644 src/assets/icons/tableSettings.svg delete mode 100644 src/assets/icons/tablesSize.svg create mode 100644 src/assets/icons/tablesSizeSelector.svg create mode 100644 src/screens/SpotScreen/BottomTables/TableActionButtons.tsx diff --git a/src/assets/icons/tableSettings.svg b/src/assets/icons/tableSettings.svg new file mode 100644 index 00000000..1549614d --- /dev/null +++ b/src/assets/icons/tableSettings.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/icons/tablesSize.svg b/src/assets/icons/tablesSize.svg deleted file mode 100644 index 7f6d8134..00000000 --- a/src/assets/icons/tablesSize.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/icons/tablesSizeSelector.svg b/src/assets/icons/tablesSizeSelector.svg new file mode 100644 index 00000000..4ac190cc --- /dev/null +++ b/src/assets/icons/tablesSizeSelector.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/screens/SpotScreen/BottomTables/BaseTable.tsx b/src/screens/SpotScreen/BottomTables/BaseTable.tsx index 2a5b5a93..b7a5ffc7 100644 --- a/src/screens/SpotScreen/BottomTables/BaseTable.tsx +++ b/src/screens/SpotScreen/BottomTables/BaseTable.tsx @@ -1,22 +1,18 @@ -import React, { useState } from "react"; -import { Config } from "react-popper-tooltip"; +import React from "react"; import styled from "@emotion/styled"; import { observer } from "mobx-react-lite"; import { Row } from "@components/Flex"; -import SizedBox from "@components/SizedBox"; import { SmartFlex } from "@components/SmartFlex"; import Tab from "@components/Tab"; import Text, { TEXT_TYPES } from "@components/Text"; -import Tooltip from "@components/Tooltip"; import { media } from "@themes/breakpoints"; -import tableSizeSelector from "@assets/icons/tablesSize.svg"; - import { useStores } from "@stores"; import { TRADE_TABLE_SIZE } from "@stores/SettingsStore"; -import { MAX_TABLE_HEIGHT, RESIZE_TOOLTIP_CONFIG, TABLE_SIZES_CONFIG } from "./constants"; +import { MAX_TABLE_HEIGHT } from "./constants"; +import { TableActionButtons } from "./TableActionButtons"; interface Props { tabs: { title: string; disabled: boolean; rowCount: number }[]; @@ -28,19 +24,6 @@ interface Props { export const BaseTable: React.FC = observer(({ tabs, activeTab, onTabClick, children }) => { const { settingsStore } = useStores(); - const [isTooltipVisible, setIsTooltipVisible] = useState(false); - - const tooltipConfig: Config = { - ...RESIZE_TOOLTIP_CONFIG, - visible: isTooltipVisible, - onVisibleChange: setIsTooltipVisible, - }; - - const handleTableSize = (size: TRADE_TABLE_SIZE) => { - settingsStore.setTradeTableSize(size); - setIsTooltipVisible(false); - }; - return ( @@ -63,35 +46,7 @@ export const BaseTable: React.FC = observer(({ tabs, activeTab, onTabClic )} ))} - - - {TABLE_SIZES_CONFIG.map(({ size, icon, title }) => ( - handleTableSize(size)} - > - - - - {title.toUpperCase()} - - - ))} - - } - > - setIsTooltipVisible(true)} - /> - - + {children} @@ -135,36 +90,12 @@ const TabContainer = styled(Row)` } `; -const TableSizeSelector = styled.div` - position: absolute; - right: 12px; - top: 4px; - - ${media.mobile} { - display: none; - } -`; - const TableContainer = styled(SmartFlex)` width: 100%; height: 100%; overflow-y: scroll; `; -const TableSize = styled.div<{ active?: boolean }>` - display: flex; - align-items: center; - padding: 4px 12px; - width: 100%; - cursor: pointer; - - ${({ active, theme }) => active && `background: ${theme.colors.borderPrimary}`}; - - :hover { - background: ${({ theme }) => theme.colors.borderSecondary}; - } -`; - const Badge = styled.div` margin-left: 4px; background: ${({ theme }) => theme.colors.borderSecondary}; diff --git a/src/screens/SpotScreen/BottomTables/TableActionButtons.tsx b/src/screens/SpotScreen/BottomTables/TableActionButtons.tsx new file mode 100644 index 00000000..feed9763 --- /dev/null +++ b/src/screens/SpotScreen/BottomTables/TableActionButtons.tsx @@ -0,0 +1,172 @@ +import React, { useState } from "react"; +import { Config } from "react-popper-tooltip"; +import styled from "@emotion/styled"; +import { observer } from "mobx-react-lite"; + +import SizedBox from "@components/SizedBox"; +import { SmartFlex } from "@components/SmartFlex"; +import Text, { TEXT_TYPES } from "@components/Text"; +import Tooltip from "@components/Tooltip"; +import { media } from "@themes/breakpoints"; + +import TableSettingsIcon from "@assets/icons/tableSettings.svg?react"; +import TableSizeSelectorIcon from "@assets/icons/tablesSizeSelector.svg?react"; + +import { useStores } from "@stores"; +import { TRADE_TABLE_SIZE } from "@stores/SettingsStore"; + +import { Checkbox } from "@src/components/Checkbox"; + +import { RESIZE_TOOLTIP_CONFIG, TABLE_SIZES_CONFIG } from "./constants"; + +const useTooltipConfig = (isVisible: boolean, setIsVisible: React.Dispatch>): Config => ({ + ...RESIZE_TOOLTIP_CONFIG, + visible: isVisible, + onVisibleChange: setIsVisible, +}); + +export const TableActionButtons: React.FC = observer(() => { + const { settingsStore } = useStores(); + + const [isResizeTooltipVisible, setIsResizeTooltipVisible] = useState(false); + const [isSettingsTooltipVisible, setIsSettingsTooltipVisible] = useState(false); + + const resizeTooltipConfig = useTooltipConfig(isResizeTooltipVisible, setIsResizeTooltipVisible); + const settingsTooltipConfig = useTooltipConfig(isSettingsTooltipVisible, setIsSettingsTooltipVisible); + + const handleTableSize = (size: TRADE_TABLE_SIZE) => { + settingsStore.setTradeTableSize(size); + setIsResizeTooltipVisible(false); + }; + + const isAnySettingsChanged = false; + + const renderResizeTooltipContent = () => { + return ( + + {TABLE_SIZES_CONFIG.map(({ size, icon, title }) => ( + handleTableSize(size)}> + + + + {title.toUpperCase()} + + + ))} + + ); + }; + + const renderSettingsTooltipContent = () => { + return ( + + + + Type + + + + MARKET + + + + + LIMIT + + + + + + Side + + + + BUY + + + + + SELL + + + + + ); + }; + + const renderResizeButton = () => { + return ( + + + setIsResizeTooltipVisible(true)} /> + + + ); + }; + + const renderSettingsButton = () => { + return ( + + {isAnySettingsChanged && } + + setIsSettingsTooltipVisible(true)} /> + + + ); + }; + + return ( + + {renderResizeButton()} + {renderSettingsButton()} + + ); +}); + +const ActionContainer = styled(SmartFlex)` + gap: 12px; + position: absolute; + right: 12px; + top: 4px; + + ${media.mobile} { + display: none; + } +`; + +const TableSize = styled.div<{ active?: boolean }>` + display: flex; + align-items: center; + padding: 4px 12px; + width: 100%; + cursor: pointer; + + ${({ active, theme }) => active && `background: ${theme.colors.borderPrimary}`}; + + :hover { + background: ${({ theme }) => theme.colors.borderSecondary}; + } +`; + +const SettingsTooltipContainer = styled(SmartFlex)` + gap: 16px; + padding: 0 16px 16px; + position: relative; +`; + +const GreenDot = styled.div` + position: absolute; + right: -3px; + top: -3px; + width: 8px; + height: 8px; + background-color: ${({ theme }) => theme.colors.greenLight}; + border-radius: 8px; +`; + +const Icon = styled(SmartFlex)<{ isActive: boolean }>` + cursor: pointer; + + transition: color 250ms; + color: ${({ theme, isActive }) => (isActive ? theme.colors.textPrimary : theme.colors.textDisabled)}; +`; From 10f4ec494544189bc5d18ffbd74b0baf2e6739b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B8b=C4=97rt=C3=B8?= <106074508+EchoDex@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:28:36 +0400 Subject: [PATCH 2/2] feat: update filter logic --- src/components/Header/MenuNav.tsx | 1 - .../BottomTables/SpotTable/SpotTableVM.tsx | 47 +++++++++++++++++-- .../BottomTables/TableActionButtons.tsx | 12 +++-- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/components/Header/MenuNav.tsx b/src/components/Header/MenuNav.tsx index 60807fe0..73488919 100644 --- a/src/components/Header/MenuNav.tsx +++ b/src/components/Header/MenuNav.tsx @@ -149,7 +149,6 @@ export const MenuNav: React.FC = observer(({ isMobile, onMenuClick }) => setOpenDropdown(openDropdown === title ? null : title); }; - console.log("isGradient", isGradient); const titleComponent = isGradient ? {title} : title; if (children) { diff --git a/src/screens/SpotScreen/BottomTables/SpotTable/SpotTableVM.tsx b/src/screens/SpotScreen/BottomTables/SpotTable/SpotTableVM.tsx index b4b8c477..86b812e4 100644 --- a/src/screens/SpotScreen/BottomTables/SpotTable/SpotTableVM.tsx +++ b/src/screens/SpotScreen/BottomTables/SpotTable/SpotTableVM.tsx @@ -2,6 +2,8 @@ import React, { PropsWithChildren, useMemo } from "react"; import { makeAutoObservable, reaction } from "mobx"; import { Nullable } from "tsdef"; +import { OrderType } from "@compolabs/spark-orderbook-ts-sdk"; + import useVM from "@hooks/useVM"; import { RootStore, useStores } from "@stores"; @@ -42,9 +44,33 @@ class SpotTableVM { isOpenOrdersLoaded = false; isHistoryOrdersLoaded = false; + + // filters offset = 0; limit = 10; + filterIsSellOrderTypeEnabled = true; + filterIsBuyOrderTypeEnabled = true; + toggleFilterOrderType = (orderType: OrderType) => { + if (orderType === OrderType.Sell) { + if (this.filterIsSellOrderTypeEnabled && !this.filterIsBuyOrderTypeEnabled) { + this.filterIsSellOrderTypeEnabled = false; + this.filterIsBuyOrderTypeEnabled = true; + return; + } + this.filterIsSellOrderTypeEnabled = !this.filterIsSellOrderTypeEnabled; + return; + } + + if (this.filterIsBuyOrderTypeEnabled && !this.filterIsSellOrderTypeEnabled) { + // Cannot uncheck 'buy' because 'sell' is already unchecked + this.filterIsBuyOrderTypeEnabled = false; + this.filterIsSellOrderTypeEnabled = true; + return; + } + this.filterIsBuyOrderTypeEnabled = !this.filterIsBuyOrderTypeEnabled; + }; + constructor(rootStore: RootStore) { makeAutoObservable(this); this.rootStore = rootStore; @@ -68,6 +94,21 @@ class SpotTableVM { return this.isOpenOrdersLoaded && this.isHistoryOrdersLoaded; } + get tableFilters() { + const orderType = + this.filterIsSellOrderTypeEnabled && this.filterIsBuyOrderTypeEnabled + ? undefined + : this.filterIsSellOrderTypeEnabled + ? OrderType.Sell + : OrderType.Buy; + + return { + limit: this.limit, + offset: this.offset, + orderType, + }; + } + cancelOrder = async (order: SpotMarketOrder) => { const { notificationStore } = this.rootStore; const bcNetwork = FuelNetwork.getInstance(); @@ -117,8 +158,7 @@ class SpotTableVM { this.subscriptionToOpenOrders = bcNetwork .subscribeSpotOrders({ - limit: this.limit, - offset: this.offset, + ...this.tableFilters, asset: tradeStore.market!.baseToken.assetId, user: accountStore.address!, status: ["Active"], @@ -146,8 +186,7 @@ class SpotTableVM { } this.subscriptionToHistoryOrders = bcNetwork .subscribeSpotOrders({ - limit: this.limit, - offset: this.offset, + ...this.tableFilters, asset: tradeStore.market!.baseToken.assetId, user: accountStore.address!, status: ["Closed", "Canceled"], diff --git a/src/screens/SpotScreen/BottomTables/TableActionButtons.tsx b/src/screens/SpotScreen/BottomTables/TableActionButtons.tsx index feed9763..f7095b2b 100644 --- a/src/screens/SpotScreen/BottomTables/TableActionButtons.tsx +++ b/src/screens/SpotScreen/BottomTables/TableActionButtons.tsx @@ -3,6 +3,8 @@ import { Config } from "react-popper-tooltip"; import styled from "@emotion/styled"; import { observer } from "mobx-react-lite"; +import { OrderType } from "@compolabs/spark-orderbook-ts-sdk"; + import SizedBox from "@components/SizedBox"; import { SmartFlex } from "@components/SmartFlex"; import Text, { TEXT_TYPES } from "@components/Text"; @@ -17,6 +19,7 @@ import { TRADE_TABLE_SIZE } from "@stores/SettingsStore"; import { Checkbox } from "@src/components/Checkbox"; +import { useSpotTableVMProvider } from "./SpotTable/SpotTableVM"; import { RESIZE_TOOLTIP_CONFIG, TABLE_SIZES_CONFIG } from "./constants"; const useTooltipConfig = (isVisible: boolean, setIsVisible: React.Dispatch>): Config => ({ @@ -26,6 +29,7 @@ const useTooltipConfig = (isVisible: boolean, setIsVisible: React.Dispatch { + const vm = useSpotTableVMProvider(); const { settingsStore } = useStores(); const [isResizeTooltipVisible, setIsResizeTooltipVisible] = useState(false); @@ -60,7 +64,7 @@ export const TableActionButtons: React.FC = observer(() => { const renderSettingsTooltipContent = () => { return ( - + {/* Type @@ -74,17 +78,17 @@ export const TableActionButtons: React.FC = observer(() => { LIMIT - + */} Side - + vm.toggleFilterOrderType(OrderType.Buy)}> BUY - + vm.toggleFilterOrderType(OrderType.Sell)}> SELL