diff --git a/libs/deal-ticket/src/order-dialog.tsx b/libs/deal-ticket/src/order-dialog.tsx
index 30c123666..2cc5c0c3e 100644
--- a/libs/deal-ticket/src/order-dialog.tsx
+++ b/libs/deal-ticket/src/order-dialog.tsx
@@ -37,7 +37,7 @@ export const OrderDialog = ({
return (
}
+ icon={}
>
{transaction.hash && (
diff --git a/libs/order-list/package.json b/libs/order-list/package.json
new file mode 100644
index 000000000..e11fcc705
--- /dev/null
+++ b/libs/order-list/package.json
@@ -0,0 +1,4 @@
+{
+ "name": "@vegaprotocol/order-list",
+ "version": "0.0.1"
+}
diff --git a/libs/order-list/project.json b/libs/order-list/project.json
index a85b132a6..66b7ea639 100644
--- a/libs/order-list/project.json
+++ b/libs/order-list/project.json
@@ -4,6 +4,26 @@
"projectType": "library",
"tags": [],
"targets": {
+ "build": {
+ "executor": "@nrwl/web:rollup",
+ "outputs": ["{options.outputPath}"],
+ "options": {
+ "outputPath": "dist/libs/order-list",
+ "tsConfig": "libs/order-list/tsconfig.lib.json",
+ "project": "libs/order-list/package.json",
+ "entryFile": "libs/order-list/src/index.ts",
+ "external": ["react/jsx-runtime"],
+ "rollupConfig": "@nrwl/react/plugins/bundle-rollup",
+ "compiler": "babel",
+ "assets": [
+ {
+ "glob": "libs/order-list/README.md",
+ "input": ".",
+ "output": "."
+ }
+ ]
+ }
+ },
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
diff --git a/libs/order-list/src/index.ts b/libs/order-list/src/index.ts
index 3d3fcc27c..5e75f9108 100644
--- a/libs/order-list/src/index.ts
+++ b/libs/order-list/src/index.ts
@@ -1,2 +1,2 @@
-export * from './order-list';
-export * from './order-list-container';
+export * from './lib/order-list';
+export * from './lib/order-list-container';
diff --git a/libs/order-list/src/__generated__/OrderFields.ts b/libs/order-list/src/lib/__generated__/OrderFields.ts
similarity index 100%
rename from libs/order-list/src/__generated__/OrderFields.ts
rename to libs/order-list/src/lib/__generated__/OrderFields.ts
diff --git a/libs/order-list/src/__generated__/OrderSub.ts b/libs/order-list/src/lib/__generated__/OrderSub.ts
similarity index 100%
rename from libs/order-list/src/__generated__/OrderSub.ts
rename to libs/order-list/src/lib/__generated__/OrderSub.ts
diff --git a/libs/order-list/src/__generated__/Orders.ts b/libs/order-list/src/lib/__generated__/Orders.ts
similarity index 100%
rename from libs/order-list/src/__generated__/Orders.ts
rename to libs/order-list/src/lib/__generated__/Orders.ts
diff --git a/libs/order-list/src/order-list-container.tsx b/libs/order-list/src/lib/order-list-container.tsx
similarity index 100%
rename from libs/order-list/src/order-list-container.tsx
rename to libs/order-list/src/lib/order-list-container.tsx
diff --git a/libs/order-list/src/order-list-manager.spec.tsx b/libs/order-list/src/lib/order-list-manager.spec.tsx
similarity index 55%
rename from libs/order-list/src/order-list-manager.spec.tsx
rename to libs/order-list/src/lib/order-list-manager.spec.tsx
index 70bd19a7b..a49c1dd02 100644
--- a/libs/order-list/src/order-list-manager.spec.tsx
+++ b/libs/order-list/src/lib/order-list-manager.spec.tsx
@@ -1,17 +1,17 @@
import { render, screen } from '@testing-library/react';
import { OrderListManager } from './order-list-manager';
-import * as useOrdersHook from './use-orders';
+import * as useDataProviderHook from '@vegaprotocol/react-helpers';
import type { Orders_party_orders } from './__generated__/Orders';
+import * as orderListMock from './order-list';
+import { forwardRef } from 'react';
-jest.mock('./order-list', () => ({
- OrderList: () =>
OrderList
,
-}));
+jest.mock('./order-list');
test('Renders a loading state while awaiting orders', () => {
- jest.spyOn(useOrdersHook, 'useOrders').mockReturnValue({
- orders: [],
+ jest.spyOn(useDataProviderHook, 'useDataProvider').mockReturnValue({
+ data: [],
loading: true,
- error: null,
+ error: undefined,
});
render();
expect(screen.getByText('Loading...')).toBeInTheDocument();
@@ -19,8 +19,8 @@ test('Renders a loading state while awaiting orders', () => {
test('Renders an error state', () => {
const errorMsg = 'Oops! An Error';
- jest.spyOn(useOrdersHook, 'useOrders').mockReturnValue({
- orders: [],
+ jest.spyOn(useDataProviderHook, 'useDataProvider').mockReturnValue({
+ data: [],
loading: false,
error: new Error(errorMsg),
});
@@ -31,10 +31,13 @@ test('Renders an error state', () => {
});
test('Renders the order list if orders provided', async () => {
- jest.spyOn(useOrdersHook, 'useOrders').mockReturnValue({
- orders: [{ id: '1' } as Orders_party_orders],
+ // @ts-ignore Orderlist is read only but we need to override with the forwardref to
+ // avoid warnings about padding refs
+ orderListMock.OrderList = forwardRef(() => OrderList
);
+ jest.spyOn(useDataProviderHook, 'useDataProvider').mockReturnValue({
+ data: [{ id: '1' } as Orders_party_orders],
loading: false,
- error: null,
+ error: undefined,
});
render();
expect(await screen.findByText('OrderList')).toBeInTheDocument();
diff --git a/libs/order-list/src/lib/order-list-manager.tsx b/libs/order-list/src/lib/order-list-manager.tsx
new file mode 100644
index 000000000..fd0321270
--- /dev/null
+++ b/libs/order-list/src/lib/order-list-manager.tsx
@@ -0,0 +1,79 @@
+import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
+import { OrderList } from './order-list';
+import type { OrderFields } from './__generated__/OrderFields';
+import { useDataProvider } from '@vegaprotocol/react-helpers';
+import {
+ ordersDataProvider,
+ prepareIncomingOrders,
+ sortOrders,
+} from './orders-data-provider';
+import { useCallback, useMemo, useRef } from 'react';
+import type { AgGridReact } from 'ag-grid-react';
+import type { OrderSub_orders } from './__generated__/OrderSub';
+import isEqual from 'lodash/isEqual';
+
+interface OrderListManagerProps {
+ partyId: string;
+}
+
+export const OrderListManager = ({ partyId }: OrderListManagerProps) => {
+ const gridRef = useRef(null);
+ const variables = useMemo(() => ({ partyId }), [partyId]);
+
+ // Apply updates to the table
+ const update = useCallback((delta: OrderSub_orders[]) => {
+ if (!gridRef.current) {
+ return false;
+ }
+
+ const incoming = prepareIncomingOrders(delta);
+
+ const update: OrderFields[] = [];
+ const add: OrderFields[] = [];
+
+ incoming.forEach((d) => {
+ if (!gridRef.current) {
+ return;
+ }
+
+ const rowNode = gridRef.current.api.getRowNode(d.id);
+
+ if (rowNode) {
+ if (!isEqual) {
+ update.push(d);
+ }
+ } else {
+ add.push(d);
+ }
+ });
+
+ if (update.length || add.length) {
+ gridRef.current.api.applyTransactionAsync({
+ update,
+ add,
+ addIndex: 0,
+ });
+ }
+
+ return true;
+ }, []);
+
+ const { data, error, loading } = useDataProvider(
+ ordersDataProvider,
+ update,
+ variables
+ );
+
+ const orders = useMemo(() => {
+ if (!data) {
+ return null;
+ }
+ return sortOrders(data);
+ }, [data]);
+
+ return (
+
+ {(data) => }
+
+ );
+};
diff --git a/libs/order-list/src/order-list.spec.tsx b/libs/order-list/src/lib/order-list.spec.tsx
similarity index 93%
rename from libs/order-list/src/order-list.spec.tsx
rename to libs/order-list/src/lib/order-list.spec.tsx
index eb9b5bb4a..2cbc332ce 100644
--- a/libs/order-list/src/order-list.spec.tsx
+++ b/libs/order-list/src/lib/order-list.spec.tsx
@@ -12,7 +12,7 @@ import { OrderList } from './order-list';
test('No orders message shown', async () => {
await act(async () => {
- render();
+ render();
});
expect(screen.getByText('No orders')).toBeInTheDocument();
});
@@ -77,7 +77,7 @@ const limitOrder: Orders_party_orders = {
test('Correct columns are rendered', async () => {
await act(async () => {
- render();
+ render();
});
const headers = screen.getAllByRole('columnheader');
@@ -87,7 +87,7 @@ test('Correct columns are rendered', async () => {
'Amount',
'Type',
'Status',
- 'Remaining',
+ 'Filled',
'Price',
'Time In Force',
'Created At',
@@ -96,7 +96,7 @@ test('Correct columns are rendered', async () => {
test('Correct formatting applied for market order', async () => {
await act(async () => {
- render();
+ render();
});
const cells = screen.getAllByRole('gridcell');
@@ -117,7 +117,7 @@ test('Correct formatting applied for market order', async () => {
test('Correct formatting applied for GTT limit order', async () => {
await act(async () => {
- render();
+ render();
});
const cells = screen.getAllByRole('gridcell');
const expectedValues = [
@@ -144,7 +144,7 @@ test('Correct formatting applied for a rejected order', async () => {
rejectionReason: OrderRejectionReason.InsufficientAssetBalance,
};
await act(async () => {
- render();
+ render();
});
const cells = screen.getAllByRole('gridcell');
expect(cells[3]).toHaveTextContent(
diff --git a/libs/order-list/src/lib/order-list.tsx b/libs/order-list/src/lib/order-list.tsx
new file mode 100644
index 000000000..42ea5e8fd
--- /dev/null
+++ b/libs/order-list/src/lib/order-list.tsx
@@ -0,0 +1,89 @@
+import { OrderTimeInForce, OrderStatus, Side } from '@vegaprotocol/types';
+import type { Orders_party_orders } from './__generated__/Orders';
+import { formatNumber, getDateTimeFormat } from '@vegaprotocol/react-helpers';
+import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
+import type { ValueFormatterParams } from 'ag-grid-community';
+import type { AgGridReact } from 'ag-grid-react';
+import { AgGridColumn } from 'ag-grid-react';
+import { forwardRef } from 'react';
+
+interface OrderListProps {
+ data: Orders_party_orders[] | null;
+}
+
+export const OrderList = forwardRef(
+ ({ data }, ref) => {
+ return (
+ data.id}
+ >
+
+ {
+ const prefix = data.side === Side.Buy ? '+' : '-';
+ return prefix + value;
+ }}
+ />
+
+ {
+ if (value === OrderStatus.Rejected) {
+ return `${value}: ${data.rejectionReason}`;
+ }
+
+ return value;
+ }}
+ />
+ {
+ return `${Number(data.size) - Number(data.remaining)}/${data.size}`;
+ }}
+ />
+ {
+ if (data.type === 'Market') {
+ return '-';
+ }
+ return formatNumber(value, data.market.decimalPlaces);
+ }}
+ />
+ {
+ if (value === OrderTimeInForce.GTT && data.expiresAt) {
+ const expiry = getDateTimeFormat().format(
+ new Date(data.expiresAt)
+ );
+ return `${value}: ${expiry}`;
+ }
+
+ return value;
+ }}
+ />
+ {
+ return getDateTimeFormat().format(new Date(value));
+ }}
+ />
+
+ );
+ }
+);
diff --git a/libs/order-list/src/lib/orders-data-provider.ts b/libs/order-list/src/lib/orders-data-provider.ts
new file mode 100644
index 000000000..8f8492f79
--- /dev/null
+++ b/libs/order-list/src/lib/orders-data-provider.ts
@@ -0,0 +1,104 @@
+import { gql } from '@apollo/client';
+import { makeDataProvider } from '@vegaprotocol/react-helpers';
+import type { OrderFields } from './__generated__/OrderFields';
+import type { Orders, Orders_party_orders } from './__generated__/Orders';
+import type { OrderSub } from './__generated__/OrderSub';
+import orderBy from 'lodash/orderBy';
+import uniqBy from 'lodash/uniqBy';
+
+const ORDER_FRAGMENT = gql`
+ fragment OrderFields on Order {
+ id
+ market {
+ id
+ name
+ decimalPlaces
+ tradableInstrument {
+ instrument {
+ code
+ }
+ }
+ }
+ type
+ side
+ size
+ status
+ rejectionReason
+ price
+ timeInForce
+ remaining
+ expiresAt
+ createdAt
+ updatedAt
+ }
+`;
+
+export const ORDERS_QUERY = gql`
+ ${ORDER_FRAGMENT}
+ query Orders($partyId: ID!) {
+ party(id: $partyId) {
+ id
+ orders {
+ ...OrderFields
+ }
+ }
+ }
+`;
+
+export const ORDERS_SUB = gql`
+ ${ORDER_FRAGMENT}
+ subscription OrderSub($partyId: ID!) {
+ orders(partyId: $partyId) {
+ ...OrderFields
+ }
+ }
+`;
+
+// A single update can contain the same order with multiple updates, so we need to find
+// the latest version of the order and only update using that
+export const sortOrders = (orders: OrderFields[]) => {
+ return orderBy(
+ orders,
+ (o) => {
+ if (!o.updatedAt) return new Date(o.createdAt).getTime();
+ return new Date(o.updatedAt).getTime();
+ },
+ 'desc'
+ );
+};
+
+export const uniqOrders = (orders: OrderFields[]) => {
+ return uniqBy(orders, 'id');
+};
+
+export const prepareIncomingOrders = (delta: OrderFields[]) => {
+ const sortedOrders = sortOrders(delta);
+ const incoming = uniqOrders(sortedOrders);
+ return incoming;
+};
+
+const update = (draft: OrderFields[], delta: OrderFields[]) => {
+ const incoming = prepareIncomingOrders(delta);
+
+ // Add or update incoming orders
+ incoming.forEach((order) => {
+ const index = draft.findIndex((o) => o.id === order.id);
+ if (index === -1) {
+ draft.unshift(order);
+ } else {
+ draft[index] = order;
+ }
+ });
+};
+
+const getData = (responseData: Orders): Orders_party_orders[] | null =>
+ responseData?.party?.orders || null;
+const getDelta = (subscriptionData: OrderSub) => subscriptionData.orders || [];
+
+export const ordersDataProvider = makeDataProvider(
+ ORDERS_QUERY,
+ ORDERS_SUB,
+ update,
+ getData,
+ getDelta
+);
diff --git a/libs/order-list/src/order-list-manager.tsx b/libs/order-list/src/order-list-manager.tsx
deleted file mode 100644
index 7a2b13915..000000000
--- a/libs/order-list/src/order-list-manager.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
-import { useOrders } from './use-orders';
-import { OrderList } from './order-list';
-import type { OrderFields } from './__generated__/OrderFields';
-
-interface OrderListManagerProps {
- partyId: string;
-}
-
-export const OrderListManager = ({ partyId }: OrderListManagerProps) => {
- const { orders, loading, error } = useOrders(partyId);
-
- return (
- loading={loading} error={error} data={orders}>
- {(data) => }
-
- );
-};
diff --git a/libs/order-list/src/order-list.tsx b/libs/order-list/src/order-list.tsx
deleted file mode 100644
index c48f10cd8..000000000
--- a/libs/order-list/src/order-list.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import { OrderTimeInForce, OrderStatus, Side } from '@vegaprotocol/types';
-import type { Orders_party_orders } from './__generated__/Orders';
-import {
- formatNumber,
- getDateTimeFormat,
- t,
- useApplyGridTransaction,
-} from '@vegaprotocol/react-helpers';
-import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
-import type { GridApi, ValueFormatterParams } from 'ag-grid-community';
-import { AgGridColumn } from 'ag-grid-react';
-import { useRef, useState } from 'react';
-
-interface OrderListProps {
- orders: Orders_party_orders[];
-}
-
-export const OrderList = ({ orders }: OrderListProps) => {
- // Store initial orders for initial table data set, further updates
- // are handled by the effect below
- const [initialOrders] = useState(orders);
- const gridApi = useRef(null);
- useApplyGridTransaction(orders, gridApi.current);
-
- return (
- {
- gridApi.current = params.api;
- }}
- getRowNodeId={(data) => data.id}
- >
-
- {
- const prefix = data.side === Side.Buy ? '+' : '-';
- return prefix + value;
- }}
- />
-
- {
- if (value === OrderStatus.Rejected) {
- return `${value}: ${data.rejectionReason}`;
- }
-
- return value;
- }}
- />
- {
- return `${Number(data.size) - Number(data.remaining)}/${data.size}`;
- }}
- />
- {
- if (data.type === 'Market') {
- return '-';
- }
- return formatNumber(value, data.market.decimalPlaces);
- }}
- />
- {
- if (value === OrderTimeInForce.GTT && data.expiresAt) {
- const expiry = getDateTimeFormat().format(new Date(data.expiresAt));
- return `${value}: ${expiry}`;
- }
-
- return value;
- }}
- />
- {
- return getDateTimeFormat().format(new Date(value));
- }}
- />
-
- );
-};
diff --git a/libs/order-list/src/use-orders.spec.tsx b/libs/order-list/src/use-orders.spec.tsx
deleted file mode 100644
index bce747a0c..000000000
--- a/libs/order-list/src/use-orders.spec.tsx
+++ /dev/null
@@ -1,138 +0,0 @@
-import type { MockedResponse } from '@apollo/client/testing';
-import { MockedProvider } from '@apollo/client/testing';
-import { renderHook } from '@testing-library/react-hooks';
-import type { OrderFields } from './__generated__/OrderFields';
-import type { Orders } from './__generated__/Orders';
-import type { OrderSub } from './__generated__/OrderSub';
-import {
- OrderStatus,
- Side,
- OrderType,
- OrderTimeInForce,
-} from '@vegaprotocol/types';
-import type { ReactNode } from 'react';
-import { ORDERS_QUERY, ORDERS_SUB, useOrders } from './use-orders';
-
-const partyId = '0x123';
-
-function generateOrder(order?: Partial): OrderFields {
- return {
- __typename: 'Order',
- id: '1',
- market: {
- __typename: 'Market',
- id: 'market-id',
- name: 'market-name',
- decimalPlaces: 0,
- tradableInstrument: {
- __typename: 'TradableInstrument',
- instrument: {
- __typename: 'Instrument',
- code: 'instrument-code',
- },
- },
- },
- type: OrderType.Market,
- side: Side.Buy,
- size: '10',
- status: OrderStatus.Active,
- rejectionReason: null,
- price: '',
- timeInForce: OrderTimeInForce.GTC,
- remaining: '10',
- createdAt: '2022-01-01T00:00:00',
- updatedAt: null,
- expiresAt: null,
- ...order,
- };
-}
-
-function setup(mocks: MockedResponse[] = [], id: string | null) {
- const wrapper = ({ children }: { children: ReactNode }) => (
- {children}
- );
- return renderHook(() => useOrders(id as string), { wrapper });
-}
-
-test('Fetches and subscribes to orders and merges appropriately', async () => {
- const order = generateOrder();
- const mockOrderQuery: MockedResponse = {
- request: {
- query: ORDERS_QUERY,
- variables: { partyId },
- },
- result: {
- data: {
- party: {
- __typename: 'Party',
- id: partyId,
- orders: [order],
- },
- },
- },
- };
-
- const updatedOrder = generateOrder({
- id: '1',
- remaining: '5',
- updatedAt: '2022-01-01T00:01:00',
- });
- const newOrder = generateOrder({
- id: '2',
- createdAt: '2022-01-01T01:00:00',
- });
- const mockOrderSub: MockedResponse = {
- request: {
- query: ORDERS_SUB,
- variables: { partyId },
- },
- result: {
- data: {
- orders: [updatedOrder, newOrder],
- },
- },
- delay: 100,
- };
- const { result, waitForNextUpdate } = setup(
- [mockOrderQuery, mockOrderSub],
- partyId
- );
- expect(result.current.loading).toBe(true);
- expect(result.current.error).toBe(null);
- await waitForNextUpdate();
- expect(result.current.orders).toEqual([order]);
- expect(result.current.loading).toBe(false);
- await waitForNextUpdate();
- expect(result.current.orders).toEqual([newOrder, updatedOrder]);
-});
-
-test('Returns an error if fetch fails', async () => {
- const error = new Error('Something failed');
- const mockFailedOrderQuery: MockedResponse = {
- request: {
- query: ORDERS_QUERY,
- variables: { partyId },
- },
- error,
- };
- const { result, waitForNextUpdate } = setup([mockFailedOrderQuery], partyId);
- expect(result.current.loading).toBe(true);
- expect(result.current.error).toBe(null);
- await waitForNextUpdate();
- expect(result.current.error).toEqual(error);
- expect(result.current.loading).toBe(false);
-});
-
-test('No queries are made if no pubkey provided', () => {
- const mockQuery: MockedResponse = {
- request: {
- query: ORDERS_QUERY,
- variables: { partyId },
- },
- newData: jest.fn(),
- };
- const { result } = setup([mockQuery], null);
- expect(mockQuery.newData).not.toBeCalled();
- expect(result.current.loading).toBe(false);
- expect(result.current.error).toBe(null);
-});
diff --git a/libs/order-list/src/use-orders.ts b/libs/order-list/src/use-orders.ts
deleted file mode 100644
index 9bae2ad90..000000000
--- a/libs/order-list/src/use-orders.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-import { useCallback, useEffect, useState } from 'react';
-import { gql, useApolloClient } from '@apollo/client';
-import uniqBy from 'lodash/uniqBy';
-import orderBy from 'lodash/orderBy';
-import type { Orders, OrdersVariables } from './__generated__/Orders';
-import type { OrderSub, OrderSubVariables } from './__generated__/OrderSub';
-import type { OrderFields } from './__generated__/OrderFields';
-
-const ORDER_FRAGMENT = gql`
- fragment OrderFields on Order {
- id
- market {
- id
- name
- decimalPlaces
- tradableInstrument {
- instrument {
- code
- }
- }
- }
- type
- side
- size
- status
- rejectionReason
- price
- timeInForce
- remaining
- expiresAt
- createdAt
- updatedAt
- }
-`;
-
-export const ORDERS_QUERY = gql`
- ${ORDER_FRAGMENT}
- query Orders($partyId: ID!) {
- party(id: $partyId) {
- id
- orders {
- ...OrderFields
- }
- }
- }
-`;
-
-export const ORDERS_SUB = gql`
- ${ORDER_FRAGMENT}
- subscription OrderSub($partyId: ID!) {
- orders(partyId: $partyId) {
- ...OrderFields
- }
- }
-`;
-
-interface UseOrders {
- orders: OrderFields[];
- error: Error | null;
- loading: boolean;
-}
-
-export const useOrders = (partyId: string): UseOrders => {
- const client = useApolloClient();
- const [orders, setOrders] = useState([]);
- const [error, setError] = useState(null);
- const [loading, setLoading] = useState(false);
-
- const mergeOrders = useCallback((update: OrderFields[]) => {
- // A subscription payload can contain multiple updates for a single order so we need to first
- // sort them by updatedAt (or createdAt if the order hasn't been updated) with the newest first,
- // then use uniqBy, which selects the first occuring order for an id to ensure we only get the latest order
- setOrders((curr) => {
- const sorted = orderBy(
- [...curr, ...update],
- (o) => {
- if (!o.updatedAt) return new Date(o.createdAt).getTime();
- return new Date(o.updatedAt).getTime();
- },
- 'desc'
- );
- return uniqBy(sorted, 'id');
- });
- }, []);
-
- // Make initial fetch
- useEffect(() => {
- const fetchOrders = async () => {
- if (!partyId) return;
-
- setLoading(true);
-
- try {
- const res = await client.query({
- query: ORDERS_QUERY,
- variables: { partyId },
- });
-
- if (!res.data.party?.orders?.length) return;
-
- mergeOrders(res.data.party.orders);
- } catch (err) {
- setError(
- err instanceof Error ? err : new Error('Something went wrong')
- );
- } finally {
- setLoading(false);
- }
- };
-
- fetchOrders();
- }, [mergeOrders, partyId, client]);
-
- // Start subscription
- useEffect(() => {
- if (!partyId) return;
-
- const sub = client
- .subscribe({
- query: ORDERS_SUB,
- variables: { partyId },
- })
- .subscribe(({ data }) => {
- if (!data?.orders) {
- return;
- }
- mergeOrders(data.orders);
- });
-
- return () => {
- if (sub) {
- sub.unsubscribe();
- }
- };
- }, [client, partyId, mergeOrders]);
-
- return { orders, error, loading };
-};
diff --git a/libs/ui-toolkit/src/components/async-renderer/async-renderer.tsx b/libs/ui-toolkit/src/components/async-renderer/async-renderer.tsx
index 451b25354..6fe2e9925 100644
--- a/libs/ui-toolkit/src/components/async-renderer/async-renderer.tsx
+++ b/libs/ui-toolkit/src/components/async-renderer/async-renderer.tsx
@@ -8,8 +8,7 @@ interface AsyncRendererProps {
children: (data: T) => ReactNode;
}
-// eslint-disable-next-line
-export function AsyncRenderer({
+export function AsyncRenderer({
loading,
error,
data,
diff --git a/libs/ui-toolkit/src/components/loader/loader.tsx b/libs/ui-toolkit/src/components/loader/loader.tsx
index 9d7a46935..fdedc65aa 100644
--- a/libs/ui-toolkit/src/components/loader/loader.tsx
+++ b/libs/ui-toolkit/src/components/loader/loader.tsx
@@ -1,6 +1,10 @@
import { useEffect, useState } from 'react';
-export const Loader = () => {
+interface LoaderProps {
+ size?: 'small' | 'large';
+}
+
+export const Loader = ({ size = 'large' }: LoaderProps) => {
const [, forceRender] = useState(false);
useEffect(() => {
@@ -11,13 +15,17 @@ export const Loader = () => {
return () => clearInterval(interval);
}, []);
+ const wrapperClasses = size === 'small' ? 'w-[15px] h-[15px]' : 'w-64 h-64';
+ const gridItemClasses = size === 'small' ? 'w-[5px] h-[5px]' : 'w-16 h-16';
+ const items = size === 'small' ? 9 : 16;
+
return (
-
- {new Array(16).fill(null).map((_, i) => {
+
+ {new Array(items).fill(null).map((_, i) => {
return (
0.75 ? 1 : 0,
diff --git a/netlify.toml b/netlify.toml
index d31ba46ec..7abf75d68 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -1,2 +1,5 @@
[build]
- ignore = "node ignore-netlify-build.js"
\ No newline at end of file
+ ignore = "node ignore-netlify-build.js"
+
+[functions]
+ included_files = ["!node_modules/@sentry/cli/sentry-cli"]
\ No newline at end of file