diff --git a/src/screens/ActivePickListScreen.test.tsx b/src/screens/ActivePickListScreen.test.tsx index 20a8ee9..c68835c 100644 --- a/src/screens/ActivePickListScreen.test.tsx +++ b/src/screens/ActivePickListScreen.test.tsx @@ -1,5 +1,5 @@ import { MemoryRouter, Route, Routes } from 'react-router-dom'; -import { render, screen, within } from '@testing-library/react'; +import { render, screen, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { describe, expect, it, vi, beforeEach } from 'vitest'; import { ActivePickListScreen } from './ActivePickListScreen'; @@ -327,6 +327,126 @@ describe('ActivePickListScreen product search', () => { expect(itemLabels).toEqual(['Apple Juice', 'Chips', 'Cola', 'Cola']); }); + it('disables packaging filters and selects units when only unit packaging is present', () => { + pickItemsMock.mockReturnValue([ + { + id: 'item-1', + pick_list_id: 'list-1', + product_id: 'prod-1', + quantity: 1, + is_carton: false, + status: 'pending', + created_at: 0, + updated_at: 0, + }, + ]); + + render( + + + } /> + + , + ); + + expect(screen.getByRole('radio', { name: /all/i })).toBeDisabled(); + expect(screen.getByRole('radio', { name: /cartons/i })).toBeDisabled(); + expect(screen.getByRole('radio', { name: /units/i })).toBeDisabled(); + expect(screen.getByRole('radio', { name: /units/i })).toBeChecked(); + }); + + it('disables packaging filters and selects cartons when only carton packaging is present', () => { + pickItemsMock.mockReturnValue([ + { + id: 'item-1', + pick_list_id: 'list-1', + product_id: 'prod-1', + quantity: 1, + is_carton: true, + status: 'pending', + created_at: 0, + updated_at: 0, + }, + ]); + + render( + + + } /> + + , + ); + + expect(screen.getByRole('radio', { name: /all/i })).toBeDisabled(); + expect(screen.getByRole('radio', { name: /cartons/i })).toBeDisabled(); + expect(screen.getByRole('radio', { name: /units/i })).toBeDisabled(); + expect(screen.getByRole('radio', { name: /cartons/i })).toBeChecked(); + }); + + it('resets the filter when the selected packaging type is unavailable', async () => { + const user = userEvent.setup(); + + pickItemsMock.mockReturnValue([ + { + id: 'item-1', + pick_list_id: 'list-1', + product_id: 'prod-1', + quantity: 1, + is_carton: true, + status: 'pending', + created_at: 0, + updated_at: 0, + }, + { + id: 'item-2', + pick_list_id: 'list-1', + product_id: 'prod-2', + quantity: 1, + is_carton: false, + status: 'pending', + created_at: 0, + updated_at: 0, + }, + ]); + + const { rerender } = render( + + + } /> + + , + ); + + await user.click(screen.getByRole('radio', { name: /cartons/i })); + expect(screen.getByRole('radio', { name: /cartons/i })).toBeChecked(); + + pickItemsMock.mockReturnValue([ + { + id: 'item-2', + pick_list_id: 'list-1', + product_id: 'prod-2', + quantity: 1, + is_carton: false, + status: 'pending', + created_at: 0, + updated_at: 0, + }, + ]); + + rerender( + + + } /> + + , + ); + + await waitFor(() => expect(screen.getByRole('radio', { name: /cartons/i })).toBeDisabled()); + expect(screen.getByRole('radio', { name: /all/i })).toBeDisabled(); + expect(screen.getByRole('radio', { name: /units/i })).toBeDisabled(); + expect(screen.getByRole('radio', { name: /units/i })).toBeChecked(); + }); + it('hides picked items when show picked is unchecked', async () => { pickItemsMock.mockReturnValue([ { diff --git a/src/screens/ActivePickListScreen.tsx b/src/screens/ActivePickListScreen.tsx index 3269c41..944f2b4 100644 --- a/src/screens/ActivePickListScreen.tsx +++ b/src/screens/ActivePickListScreen.tsx @@ -98,6 +98,14 @@ export const ActivePickListScreen = () => { ); }, [products]); + const hasCartonItems = useMemo(() => items.some((item) => item.is_carton), [items]); + const hasUnitItems = useMemo(() => items.some((item) => !item.is_carton), [items]); + const packagingTypeCount = useMemo( + () => Number(hasCartonItems) + Number(hasUnitItems), + [hasCartonItems, hasUnitItems], + ); + const disablePackagingSelection = packagingTypeCount === 1; + const filteredProducts = useMemo(() => { const normalizedQuery = query.trim().toLowerCase(); if (!normalizedQuery) return sortedProducts; @@ -121,6 +129,23 @@ export const ActivePickListScreen = () => { } }, [allItemsPicked, showPicked]); + useEffect(() => { + if (packagingTypeCount === 1) { + const singlePackagingFilter = hasCartonItems ? 'cartons' : 'units'; + if (itemFilter !== singlePackagingFilter) { + setItemFilter(singlePackagingFilter); + } + + return; + } + + if (itemFilter === 'cartons' && !hasCartonItems) { + setItemFilter(hasUnitItems ? 'units' : 'all'); + } else if (itemFilter === 'units' && !hasUnitItems) { + setItemFilter(hasCartonItems ? 'cartons' : 'all'); + } + }, [itemFilter, hasCartonItems, hasUnitItems, packagingTypeCount]); + const visibleItems = useMemo(() => { let filteredItems = showPicked ? sortedItems @@ -310,9 +335,24 @@ export const ActivePickListScreen = () => { } sx={{ flexGrow: 1 }} > - } label="All" /> - } label="Cartons" /> - } label="Units" /> + } + label="All" + disabled={disablePackagingSelection} + /> + } + label="Cartons" + disabled={disablePackagingSelection || !hasCartonItems} + /> + } + label="Units" + disabled={disablePackagingSelection || !hasUnitItems} + />