diff --git a/src/automats/index.js b/src/automats/index.js index 516afe8..b590ea1 100644 --- a/src/automats/index.js +++ b/src/automats/index.js @@ -69,6 +69,7 @@ export { default as orderAutomat, selectOrders, selectOrderTotal, + selectOrderUnfilteredTotal, selectOrderPagination, selectOnlyUnpaid, selectOnlyUndelivered, diff --git a/src/automats/orderAutomat.js b/src/automats/orderAutomat.js index 7a88368..068139f 100644 --- a/src/automats/orderAutomat.js +++ b/src/automats/orderAutomat.js @@ -65,6 +65,7 @@ const CHUNK_DEBOUNCE_MS = 130; const initialState = { items: null, total: 0, + unfilteredTotal: 0, filter: '', onlyUnpaid: false, onlyUndelivered: false, @@ -181,6 +182,7 @@ function getOrCreateFilterCache(filterKey, filterState = automat?.state || initi label: formatFilterLabel(params), params, total: 0, + unfilteredTotal: automat?.state?.unfilteredTotal || 0, items: null, loadedChunks: new Set(), status: 'idle', @@ -508,7 +510,8 @@ async function fetchOrdersPageFor(filterParams, offset = 0, limit = CHUNK_SIZE) const res = await orderApi.list(params); const orders = Array.isArray(res?.orders) ? res.orders : []; const total = Number(res?.total ?? orders.length); - return { orders, total }; + const unfilteredTotal = res?.unfilteredTotal != null ? Number(res.unfilteredTotal) : total; + return { orders, total, unfilteredTotal }; } function onFilterChange(immediate = false) { @@ -544,6 +547,7 @@ function applyFilterReload() { automat.setState({ items: cached.items, total: cached.total, + unfilteredTotal: cached.unfilteredTotal ?? automat.state.unfilteredTotal ?? 0, status: cached.status || 'ready', error: cached.error || null, }); @@ -568,6 +572,7 @@ function applyFilterReload() { automat.setState({ items: null, total: 0, + unfilteredTotal: automat.state.unfilteredTotal ?? 0, status: 'loading', error: null, }); @@ -757,9 +762,10 @@ const actions = { const filterParams = entry.params || getFilterParams(automat.state); const promise = fetchOrdersPageFor(filterParams, offset, limit) - .then(({ orders, total }) => { + .then(({ orders, total, unfilteredTotal }) => { const currentTotal = total > 0 ? total : 0; entry.total = currentTotal; + entry.unfilteredTotal = unfilteredTotal; if (entry.items === null || entry.items.length !== currentTotal) { entry.items = new Array(currentTotal).fill(null); @@ -788,6 +794,7 @@ const actions = { automat.setState({ items: entry.items, total: currentTotal, + unfilteredTotal, status: 'ready', error: null, }); @@ -1157,6 +1164,11 @@ export function selectOrderTotal(state = automat.state) { return state.total; } +/** Selects unfiltered total count */ +export function selectOrderUnfilteredTotal(state = automat.state) { + return state.unfilteredTotal ?? 0; +} + /** Selects unpaid filter */ export function selectOnlyUnpaid(state = automat.state) { return state.onlyUnpaid; diff --git a/src/components/manifest/OrderList.jsx b/src/components/manifest/OrderList.jsx index 71cc723..b534d62 100644 --- a/src/components/manifest/OrderList.jsx +++ b/src/components/manifest/OrderList.jsx @@ -474,6 +474,7 @@ export class OrderList extends PureComponent { // getItems() returns current items or null and triggers loading of the first chunk this.state = { items: orderAutomat.getItems(), + unfilteredTotal: orderAutomat.state.unfilteredTotal ?? 0, partiesById: {}, busyId: null, }; @@ -490,9 +491,9 @@ export class OrderList extends PureComponent { componentDidMount() { this._cancelled = false; - // Subscribe to items only this.unsub = orderAutomat.subscribe(this, (state) => ({ items: state.items, + unfilteredTotal: state.unfilteredTotal ?? 0, })); void this.loadParties(); } @@ -582,7 +583,7 @@ export class OrderList extends PureComponent { } render() { - const { items, partiesById, busyId } = this.state; + const { items, unfilteredTotal, partiesById, busyId } = this.state; rowContext.partiesById = partiesById; rowContext.busyId = busyId; @@ -616,6 +617,7 @@ export class OrderList extends PureComponent { minHeight={0} items={items || []} totalCount={items ? items.length : 0} + unfilteredTotal={unfilteredTotal} renderItem={OrderRow} virtualScrollbar header={