diff --git a/crates/cli/src/commands/order/list.rs b/crates/cli/src/commands/order/list.rs index 4048c780e..0333508ea 100644 --- a/crates/cli/src/commands/order/list.rs +++ b/crates/cli/src/commands/order/list.rs @@ -120,6 +120,7 @@ mod tests { }, filter_args: CliFilterArgs { owners: vec!["addr1".to_string()], + active: Some(true), }, }; @@ -146,6 +147,7 @@ mod tests { }, filter_args: CliFilterArgs { owners: vec!["addr1".to_string()], + active: Some(true), }, }; @@ -172,6 +174,7 @@ mod tests { }, filter_args: CliFilterArgs { owners: vec!["addr1".to_string()], + active: Some(true), }, }; diff --git a/crates/cli/src/commands/vault/list.rs b/crates/cli/src/commands/vault/list.rs index b582c8afc..70a63ec97 100644 --- a/crates/cli/src/commands/vault/list.rs +++ b/crates/cli/src/commands/vault/list.rs @@ -119,6 +119,7 @@ mod tests { }, filter_args: CliFilterArgs { owners: vec!["addr1".to_string()], + active: Some(true), }, }; @@ -145,6 +146,7 @@ mod tests { }, filter_args: CliFilterArgs { owners: vec!["addr1".to_string()], + active: Some(true), }, }; @@ -165,6 +167,7 @@ mod tests { }, filter_args: CliFilterArgs { owners: vec!["addr1".to_string()], + active: Some(true), }, }; diff --git a/crates/cli/src/subgraph.rs b/crates/cli/src/subgraph.rs index c3040e2fc..905a4822b 100644 --- a/crates/cli/src/subgraph.rs +++ b/crates/cli/src/subgraph.rs @@ -69,12 +69,16 @@ pub struct CliFilterArgs { value_delimiter = ',' )] pub owners: Vec, + + #[arg(long, help = "Filter orders by active status", default_value = "true")] + pub active: Option, } impl From for OrdersListFilterArgs { fn from(val: CliFilterArgs) -> Self { Self { owners: val.owners.into_iter().map(Bytes).collect(), + active: val.active, } } } diff --git a/crates/subgraph/src/orderbook_client.rs b/crates/subgraph/src/orderbook_client.rs index d9861a4c4..cc8a18a97 100644 --- a/crates/subgraph/src/orderbook_client.rs +++ b/crates/subgraph/src/orderbook_client.rs @@ -74,16 +74,19 @@ impl OrderbookSubgraphClient { ) -> Result, OrderbookSubgraphClientError> { let pagination_variables = Self::parse_pagination_args(pagination_args); + let filters = if !filter_args.owners.is_empty() || filter_args.active.is_some() { + Some(OrdersListQueryFilters { + owner_in: filter_args.owners, + active: filter_args.active, + }) + } else { + None + }; + let variables = OrdersListQueryVariables { first: pagination_variables.first, skip: pagination_variables.skip, - filters: if filter_args.owners.is_empty() { - None - } else { - Some(OrdersListQueryFilters { - owner_in: filter_args.owners, - }) - }, + filters, }; let data = self @@ -100,7 +103,10 @@ impl OrderbookSubgraphClient { loop { let page_data = self .orders_list( - OrdersListFilterArgs { owners: vec![] }, + OrdersListFilterArgs { + owners: vec![], + active: None, + }, PaginationArgs { page, page_size: ALL_PAGES_QUERY_PAGE_SIZE, diff --git a/crates/subgraph/src/types/common.rs b/crates/subgraph/src/types/common.rs index 3c036a7a5..8aa75ee79 100644 --- a/crates/subgraph/src/types/common.rs +++ b/crates/subgraph/src/types/common.rs @@ -11,6 +11,7 @@ pub struct IdQueryVariables<'a> { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct OrdersListFilterArgs { pub owners: Vec, + pub active: Option, } #[derive(cynic::QueryVariables, Debug, Clone)] @@ -24,8 +25,10 @@ pub struct PaginationQueryVariables { #[cynic(graphql_type = "Order_filter")] #[typeshare] pub struct OrdersListQueryFilters { - #[cynic(rename = "owner_in")] + #[cynic(rename = "owner_in", skip_serializing_if = "Vec::is_empty")] pub owner_in: Vec, + #[cynic(rename = "active", skip_serializing_if = "Option::is_none")] + pub active: Option, } #[derive(cynic::QueryVariables, Debug, Clone)] diff --git a/tauri-app/src/lib/components/ListViewOrderbookSelector.svelte b/tauri-app/src/lib/components/ListViewOrderbookSelector.svelte index 19569ce03..193f5b421 100644 --- a/tauri-app/src/lib/components/ListViewOrderbookSelector.svelte +++ b/tauri-app/src/lib/components/ListViewOrderbookSelector.svelte @@ -3,6 +3,7 @@ import DropdownActiveNetwork from './DropdownActiveNetwork.svelte'; import DropdownActiveOrderbook from './DropdownActiveOrderbook.svelte'; import DropdownOrderListWatchlist from './dropdown/DropdownOrderListWatchlist.svelte'; + import DropdownOrderStatus from './dropdown/DropdownOrderStatus.svelte'; import { settings } from '$lib/stores/settings'; import { Alert } from 'flowbite-svelte'; @@ -13,6 +14,7 @@ >No networks added to settings {:else} + diff --git a/tauri-app/src/lib/components/dropdown/DropdownCheckbox.svelte b/tauri-app/src/lib/components/dropdown/DropdownCheckbox.svelte index c39e2be93..a9c6fa79b 100644 --- a/tauri-app/src/lib/components/dropdown/DropdownCheckbox.svelte +++ b/tauri-app/src/lib/components/dropdown/DropdownCheckbox.svelte @@ -10,7 +10,9 @@ export let value: Record = {}; export let label: string = 'Select items'; export let allLabel: string = 'All items'; + export let showAllLabel: boolean = true; export let emptyMessage: string = 'No items available'; + export let onlyTitle: boolean = false; $: selectedCount = Object.keys(value).length; $: allSelected = selectedCount === Object.keys(options).length; @@ -57,7 +59,7 @@ {#if isEmpty(options)}
{emptyMessage}
- {:else if Object.keys(options).length > 1} + {:else if Object.keys(options).length > 1 && showAllLabel}
{key}
-
{optionValue}
+ {#if !onlyTitle} +
{optionValue}
+ {/if}
{/each} diff --git a/tauri-app/src/lib/components/dropdown/DropdownOrderStatus.svelte b/tauri-app/src/lib/components/dropdown/DropdownOrderStatus.svelte new file mode 100644 index 000000000..fa6551ac5 --- /dev/null +++ b/tauri-app/src/lib/components/dropdown/DropdownOrderStatus.svelte @@ -0,0 +1,32 @@ + + + diff --git a/tauri-app/src/lib/components/tables/OrdersListTable.svelte b/tauri-app/src/lib/components/tables/OrdersListTable.svelte index 8f2e7e5cf..da6e7f180 100644 --- a/tauri-app/src/lib/components/tables/OrdersListTable.svelte +++ b/tauri-app/src/lib/components/tables/OrdersListTable.svelte @@ -21,13 +21,18 @@ import { subgraphUrl } from '$lib/stores/settings'; import { formatTimestampSecondsAsLocal } from '$lib/utils/time'; import { handleOrderRemoveModal } from '$lib/services/modal'; - import { activeWatchlist } from '$lib/stores/settings'; + import { activeWatchlist, activeOrderStatus } from '$lib/stores/settings'; import { get } from 'svelte/store'; $: query = createInfiniteQuery({ - queryKey: [QKEY_ORDERS, $activeWatchlist], + queryKey: [QKEY_ORDERS, $activeWatchlist, $activeOrderStatus], queryFn: ({ pageParam }) => { - return ordersList($subgraphUrl, Object.values(get(activeWatchlist)), pageParam); + return ordersList( + $subgraphUrl, + Object.values(get(activeWatchlist)), + $activeOrderStatus, + pageParam, + ); }, initialPageParam: 0, getNextPageParam(lastPage, _allPages, lastPageParam) { diff --git a/tauri-app/src/lib/queries/ordersList.ts b/tauri-app/src/lib/queries/ordersList.ts index dc86c1aae..01b1974da 100644 --- a/tauri-app/src/lib/queries/ordersList.ts +++ b/tauri-app/src/lib/queries/ordersList.ts @@ -16,6 +16,7 @@ export type OrdersListArgs = { export const ordersList = async ( url: string | undefined, owners: string[] = [], + active: boolean | undefined = undefined, pageParam: number, pageSize: number = DEFAULT_PAGE_SIZE, ) => { @@ -26,6 +27,7 @@ export const ordersList = async ( subgraphArgs: { url }, filterArgs: { owners, + active, }, paginationArgs: { page: pageParam + 1, page_size: pageSize }, } as OrdersListArgs); @@ -54,10 +56,10 @@ if (import.meta.vitest) { }); // check for a result with no URL - expect(await ordersList(undefined, [], 0)).toEqual([]); + expect(await ordersList(undefined, [], undefined, 0)).toEqual([]); // check for a result with a URL - expect(await ordersList('http://localhost:8000', [], 0)).toEqual([ + expect(await ordersList('http://localhost:8000', [], undefined, 0)).toEqual([ { id: '1', order_bytes: '0x123', diff --git a/tauri-app/src/lib/stores/settings.ts b/tauri-app/src/lib/stores/settings.ts index 51d34dfc9..162ab532f 100644 --- a/tauri-app/src/lib/stores/settings.ts +++ b/tauri-app/src/lib/stores/settings.ts @@ -198,3 +198,17 @@ export async function resetActiveNetworkRef() { activeNetworkRef.set(undefined); } } + +export const activeOrderStatus = cachedWritableStore( + 'settings.activeOrderStatus', + undefined, + (value) => JSON.stringify(value), + (str) => { + try { + const parsed = JSON.parse(str); + return typeof parsed === 'boolean' ? parsed : undefined; + } catch { + return undefined; + } + }, +);