Skip to content

Commit

Permalink
feat: order history modal first pass
Browse files Browse the repository at this point in the history
  • Loading branch information
crnbarr93 committed Aug 11, 2024
1 parent 80b4f1a commit ebe5174
Show file tree
Hide file tree
Showing 3 changed files with 478 additions and 55 deletions.
71 changes: 45 additions & 26 deletions packages/trpc/src/orderbook-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,34 +69,53 @@ export const orderbookRouter = createTRPCRouter({
const { contractAddresses, userOsmoAddress } = input;
if (contractAddresses.length === 0 || userOsmoAddress.length === 0)
return [];
const promises = contractAddresses.map(
async (contractOsmoAddress: string) => {
const { quoteAsset, baseAsset } = await getOrderbookDenoms({
orderbookAddress: contractOsmoAddress,
chainList: ctx.chainList,
assetLists: ctx.assetLists,
});
const orders = await getOrderbookActiveOrders({
orderbookAddress: contractOsmoAddress,
userOsmoAddress: userOsmoAddress,
chainList: ctx.chainList,
baseAsset,
quoteAsset,
});
return orders;

const chunk = (arr: any[], size: number) => {
const result = [];
for (let i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}
);
promises.push(
getOrderbookHistoricalOrders({
userOsmoAddress: input.userOsmoAddress,
assetLists: ctx.assetLists,
chainList: ctx.chainList,
})
);
return result;
};

const chunkedAddresses = chunk(contractAddresses, 8);

const ordersByContracts: MappedLimitOrder[] = [];
for (let i = 0; i < chunkedAddresses.length; i++) {
const contractOsmoAddresses = chunkedAddresses[i];
const orderPromises = contractOsmoAddresses.map(
async (contractOsmoAddress: string) => {
const { quoteAsset, baseAsset } = await getOrderbookDenoms({
orderbookAddress: contractOsmoAddress,
chainList: ctx.chainList,
assetLists: ctx.assetLists,
});
const orders = await getOrderbookActiveOrders({
orderbookAddress: contractOsmoAddress,
userOsmoAddress: userOsmoAddress,
chainList: ctx.chainList,
baseAsset,
quoteAsset,
});
return orders;
}
);
if (i === chunkedAddresses.length - 1) {
orderPromises.push(
getOrderbookHistoricalOrders({
userOsmoAddress: input.userOsmoAddress,
assetLists: ctx.assetLists,
chainList: ctx.chainList,
})
);
}
const newOrders = await Promise.all(orderPromises);
ordersByContracts.push(...newOrders.flat().flat());
}

// const ordersByContracts = await Promise.all(promises);

const ordersByContracts = await Promise.all(promises);
const allOrders = ordersByContracts.flat();
return allOrders.sort(defaultSortOrders);
return ordersByContracts.sort(defaultSortOrders);
},
cacheKey: `all-active-orders-${input.contractAddresses.join(",")}-${
input.userOsmoAddress
Expand Down
103 changes: 74 additions & 29 deletions packages/web/components/complex/orders-history/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@ import React, { memo, useCallback, useMemo, useRef, useState } from "react";
import { Icon } from "~/components/assets";
import { ActionsCell } from "~/components/complex/orders-history/cells/actions";
import { OrderProgressBar } from "~/components/complex/orders-history/cells/filled-progress";
import { OrderModal } from "~/components/complex/orders-history/order-modal";
import { Intersection } from "~/components/intersection";
import { Spinner } from "~/components/loaders";
import { GenericDisclaimer } from "~/components/tooltip/generic-disclaimer";
import { Button } from "~/components/ui/button";
import { EventName } from "~/config";
import {
Breakpoint,
useAmplitudeAnalytics,
useFeatureFlags,
useTranslation,
useWalletSelect,
useWindowSize,
} from "~/hooks";
import {
useOrderbookAllActiveOrders,
Expand Down Expand Up @@ -50,6 +53,10 @@ function groupOrdersByStatus(orders: MappedLimitOrder[]) {
}

const headers = ["order", "amount", "price", "orderPlaced", "status"];
const mdHeaders = ["order", "status"];

const gridClasses =
"grid grid-cols-[80px_4fr_2fr_2fr_2fr_150px] md:grid-cols-[2fr_1fr]";

export const OrderHistory = observer(() => {
const { logEvent } = useAmplitudeAnalytics({
Expand All @@ -61,6 +68,8 @@ export const OrderHistory = observer(() => {
const wallet = accountStore.getWallet(accountStore.osmosisChainId);
const listRef = useRef<HTMLTableElement>(null);
const { onOpenWalletSelect, isLoading: isWalletLoading } = useWalletSelect();
const { isMobile } = useWindowSize(Breakpoint.md);
const [selectedOrder, setSelectedOrder] = useState<MappedLimitOrder>();

const {
orders,
Expand Down Expand Up @@ -98,7 +107,7 @@ export const OrderHistory = observer(() => {

const rowVirtualizer = useWindowVirtualizer({
count: rows.length,
estimateSize: () => 84,
estimateSize: () => (isMobile ? 60 : 84),
paddingStart: -220,
paddingEnd: 110,
overscan: 10,
Expand Down Expand Up @@ -132,6 +141,14 @@ export const OrderHistory = observer(() => {

const showConnectWallet = !wallet?.isWalletConnected && !isWalletLoading;

const onOrderSelect = useCallback(
(order: MappedLimitOrder) => {
if (!isMobile) return;
setSelectedOrder(order);
},
[isMobile]
);

if (showConnectWallet) {
return (
<div className="mx-auto my-6 flex flex-col justify-center gap-6 px-4 text-center">
Expand Down Expand Up @@ -191,27 +208,35 @@ export const OrderHistory = observer(() => {

return (
<div className="mt-3 flex flex-col overflow-y-clip overflow-x-scroll">
<table className="relative min-w-[900px] table-auto" ref={listRef}>
<table
className="relative min-w-[900px] table-auto md:min-w-[100vw]"
ref={listRef}
>
{!isLoading && (
<thead className="border-b border-osmoverse-700 bg-osmoverse-1000">
<thead className="border-b border-osmoverse-700 bg-osmoverse-1000">
<tr
className={classNames(
"grid grid-cols-[80px_4fr_2fr_2fr_2fr_150px]",
{
"!bg-osmoverse-1000": featureFlags.limitOrders,
}
},
gridClasses
)}
>
{headers.map((header) => (
<th key={header} className="!px-0">
<th
key={header}
className={classNames("!px-0", {
"md:hidden": !mdHeaders.includes(header),
})}
>
{header !== "amount" && (
<small className="body2">
<small className="body2 sm:caption">
{t(`limitOrders.historyTable.columns.${header}`)}
</small>
)}
</th>
))}
<th />
{!isMobile && <th />}
</tr>
</thead>
)}
Expand Down Expand Up @@ -258,6 +283,7 @@ export const OrderHistory = observer(() => {
order={order}
style={style}
refetch={refetch}
onOrderSelect={onOrderSelect}
/>
);
})
Expand All @@ -271,6 +297,12 @@ export const OrderHistory = observer(() => {
}
}}
/>
{isMobile && (
<OrderModal
order={selectedOrder}
onRequestClose={() => setSelectedOrder(undefined)}
/>
)}
</div>
);
});
Expand All @@ -297,14 +329,18 @@ const TableGroupHeader = ({

if (group === "filled") {
return (
<tr className="h-[84px]">
<tr style={style} className="md:flex md:items-end">
<td colSpan={5} className="!p-0">
<div className="flex w-full items-end justify-between pr-4">
<div className="relative flex items-end gap-3 pt-5">
<div className="flex items-center gap-2 pb-3">
<h6>{t("limitOrders.orderHistoryHeaders.filled")}</h6>
<span className="text-h6 font-h6">
{t("limitOrders.orderHistoryHeaders.filled")}
</span>
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-[#A51399]">
<span className="caption">{filledOrdersCount}</span>
<span className="md:body2 pb-4 pt-8 text-h6 font-h6 md:flex md:items-end md:pb-2 md:pt-4">
{filledOrdersCount}
</span>
</div>
</div>
<GenericDisclaimer
Expand Down Expand Up @@ -336,12 +372,12 @@ const TableGroupHeader = ({
}

return (
<tr style={style}>
<h6 className="pb-4 pt-8">
<tr style={style} className="md:flex md:items-end">
<span className="md:body2 pb-4 pt-8 text-h6 font-h6 md:pb-2 md:pt-4">
{group === "pending"
? t("limitOrders.orderHistoryHeaders.pending")
: t("limitOrders.orderHistoryHeaders.past")}
</h6>
</span>
</tr>
);
};
Expand All @@ -351,10 +387,12 @@ const TableOrderRow = memo(
order,
style,
refetch,
onOrderSelect,
}: {
order: MappedLimitOrder;
style: Object;
refetch: () => Promise<any>;
onOrderSelect: (order: MappedLimitOrder) => void;
}) => {
const { t } = useTranslation();

Expand Down Expand Up @@ -401,7 +439,7 @@ const TableOrderRow = memo(
const hourDiff = dayjs(new Date()).diff(dayjs(placed_at), "h");

return (
<span className="body2 text-osmoverse-300">
<span className="body2 md:caption text-osmoverse-300">
{dayDiff > 0
? t("limitOrders.daysAgo", {
days: dayDiff.toString(),
Expand All @@ -418,8 +456,12 @@ const TableOrderRow = memo(
}
})();
return (
<tr style={style} className="grid grid-cols-[80px_4fr_2fr_2fr_2fr_150px]">
<td className="flex items-center justify-center !px-0 !text-left">
<tr
style={style}
className={gridClasses}
onClick={() => onOrderSelect(order)}
>
<td className="flex items-center justify-center !px-0 !text-left md:hidden">
<div className="subtitle1 rounded-full bg-osmoverse-alpha-850 p-3">
<Icon
id="coins"
Expand All @@ -437,7 +479,7 @@ const TableOrderRow = memo(
<div className="flex flex-col gap-1">
<p
className={classNames(
"body2 inline-flex w-fit items-center gap-1 text-osmoverse-300",
"body2 md:caption inline-flex w-fit items-center gap-1 text-osmoverse-300",
{ "flex-row-reverse": order_direction === "bid" }
)}
>
Expand Down Expand Up @@ -472,7 +514,7 @@ const TableOrderRow = memo(
)}
</span>
</p>
<div className="inline-flex items-center gap-2">
<div className="md:caption inline-flex items-center gap-2">
<span>
{formatFiatPrice(
new PricePretty(
Expand Down Expand Up @@ -504,7 +546,7 @@ const TableOrderRow = memo(
</div>
</div>
</td>
<td className="!px-0 !text-left">
<td className="!px-0 !text-left md:hidden">
<div className="flex flex-col gap-1">
<p className="body2 text-osmoverse-300">
{baseAsset?.symbol} · {t("limitOrders.limit")}
Expand All @@ -516,7 +558,7 @@ const TableOrderRow = memo(
</p>
</div>
</td>
<td className="!px-0 !text-left">
<td className="!px-0 !text-left md:hidden">
<div className="flex flex-col gap-1">
<p className="body2 text-osmoverse-300">{formattedTime}</p>
<p>{formattedDate}</p>
Expand All @@ -526,19 +568,22 @@ const TableOrderRow = memo(
<div className="flex flex-col gap-1">
{statusComponent}
<span
className={classNames({
"text-bullish-400":
status === "filled" || status === "fullyClaimed",
"text-osmoverse-300":
status === "open" || status === "partiallyFilled",
"text-osmoverse-500": status === "cancelled",
})}
className={classNames(
{
"text-bullish-400":
status === "filled" || status === "fullyClaimed",
"text-osmoverse-300":
status === "open" || status === "partiallyFilled",
"text-osmoverse-500": status === "cancelled",
},
"md:caption"
)}
>
{statusString}
</span>
</div>
</td>
<td className="flex w-[150px] items-center justify-end !px-0 !text-left">
<td className="flex w-[150px] items-center justify-end !px-0 !text-left md:hidden">
<ActionsCell order={order} refetch={refetch} />
</td>
</tr>
Expand Down
Loading

0 comments on commit ebe5174

Please sign in to comment.