From 39682c38c207e79e8ac631ba27c4ebb8efca8d84 Mon Sep 17 00:00:00 2001 From: adambalcerzak Date: Wed, 12 Aug 2026 12:15:50 +0200 Subject: [PATCH 1/3] OBLS-935 Pick queue does not lock/refresh fast enough switch to show assigned tasks --- src/apis/picking.ts | 12 ++++++++---- src/redux/actions/picking.ts | 2 ++ src/redux/sagas/picking.ts | 2 +- .../Picking/DiscretePickingListScreen.tsx | 17 ++++++++++++----- src/screens/Picking/discretePickingStyles.ts | 3 +++ 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/apis/picking.ts b/src/apis/picking.ts index e726a1ea..314e1375 100644 --- a/src/apis/picking.ts +++ b/src/apis/picking.ts @@ -50,12 +50,16 @@ export function getPickTasksApi(facilityId: string, params?: Partial `status=${encodeURIComponent(status)}`); - return ApiClient.get( - `/facilities/${facilityId}/pick-tasks?${statuses.map((status) => `status=${encodeURIComponent(status)}`).join('&')}` - ); + if (showAssigned !== undefined) { + query.push(`showAssigned=${showAssigned}`); + } + + return ApiClient.get(`/facilities/${facilityId}/pick-tasks?${query.join('&')}`); } export function getPickTaskCountsApi(facilityId: string) { diff --git a/src/redux/actions/picking.ts b/src/redux/actions/picking.ts index e80fb8b3..c943877a 100644 --- a/src/redux/actions/picking.ts +++ b/src/redux/actions/picking.ts @@ -71,6 +71,7 @@ export function getPickTasksAction( } export function getOpenPickTasksAction( + showAssigned: boolean, callback: (response: { response?: { data: PickTask[]; @@ -85,6 +86,7 @@ export function getOpenPickTasksAction( ) { return { type: GET_OPEN_PICK_TASKS_REQUEST, + payload: { showAssigned }, callback }; } diff --git a/src/redux/sagas/picking.ts b/src/redux/sagas/picking.ts index 3c636642..9ec6beed 100644 --- a/src/redux/sagas/picking.ts +++ b/src/redux/sagas/picking.ts @@ -75,7 +75,7 @@ function* getOpenPickTasksAction(action: any) { // No full-screen loading indicator here on purpose: the list screen renders its own // inline skeleton / pull-to-refresh state so the screen never blocks on the fetch. // @ts-ignore - const response = yield call(api.getOpenPickTasksApi, currentLocation.id); + const response = yield call(api.getOpenPickTasksApi, currentLocation.id, action.payload?.showAssigned); yield action.callback({ response }); yield put({ type: GET_OPEN_PICK_TASKS_REQUEST_SUCCESS, payload: response.data }); } catch (error) { diff --git a/src/screens/Picking/DiscretePickingListScreen.tsx b/src/screens/Picking/DiscretePickingListScreen.tsx index 5f46eb53..b071aebe 100644 --- a/src/screens/Picking/DiscretePickingListScreen.tsx +++ b/src/screens/Picking/DiscretePickingListScreen.tsx @@ -11,6 +11,7 @@ import { navigate } from '../../NavigationService'; import { getOpenPickTasksAction } from '../../redux/actions/picking'; import { DiscretePickingOrder, PickTask } from '../../types/picking'; import { emptyStateMessage } from '../../utils/emptyStateMessage'; +import { ToggleRow } from '../Dashboard/ToggleRow'; import { DELIVERY_TYPES } from './constants'; import DiscretePickingCardSkeleton from './DiscretePickingCardSkeleton'; import DiscretePickingFilterSkeleton from './DiscretePickingFilterSkeleton'; @@ -33,18 +34,19 @@ export default function DiscretePickingListScreen() { const [tasks, setTasks] = useState([]); const [searchTerm, setSearchTerm] = useState(''); const [selectedQueueType, setSelectedQueueType] = useState(ALL_QUEUE_TYPES); + const [showAssigned, setShowAssigned] = useState(false); const [isRefreshing, setIsRefreshing] = useState(false); const [isPullRefreshing, setIsPullRefreshing] = useState(false); const [hasLoaded, setHasLoaded] = useState(false); const fetchOrders = useCallback( - (fromPull = false) => { + (showAssignedParam: boolean, fromPull = false) => { setIsRefreshing(true); if (fromPull) { setIsPullRefreshing(true); } dispatch( - getOpenPickTasksAction(({ response, errorMessage }) => { + getOpenPickTasksAction(showAssignedParam, ({ response, errorMessage }) => { if (!errorMessage && response?.data) { setTasks(response.data); } @@ -59,8 +61,8 @@ export default function DiscretePickingListScreen() { useFocusEffect( useCallback(() => { - fetchOrders(); - }, [fetchOrders]) + fetchOrders(showAssigned); + }, [fetchOrders, showAssigned]) ); const sortedOrders = useMemo(() => sortOrders(groupTasksIntoOrders(tasks)), [tasks]); @@ -129,6 +131,11 @@ export default function DiscretePickingListScreen() { })} )} + {!isLoadingList && ( + + + + )} {isLoadingList ? ( @@ -150,7 +157,7 @@ export default function DiscretePickingListScreen() { description={emptyStateMessage('orders', searchTerm, 'No open orders ready for picking')} /> } - onRefresh={() => fetchOrders(true)} + onRefresh={() => fetchOrders(showAssigned, true)} /> )} diff --git a/src/screens/Picking/discretePickingStyles.ts b/src/screens/Picking/discretePickingStyles.ts index 1f765672..1f6c0ea7 100644 --- a/src/screens/Picking/discretePickingStyles.ts +++ b/src/screens/Picking/discretePickingStyles.ts @@ -45,6 +45,9 @@ export default StyleSheet.create({ flexDirection: 'row', overflow: 'hidden' }, + showAssignedToggle: { + paddingHorizontal: Theme.spacing.medium + }, filterChipSkeleton: { height: 32, borderRadius: 12, From ee8a0866713c865298421702894925a2b2589519 Mon Sep 17 00:00:00 2001 From: adambalcerzak Date: Wed, 12 Aug 2026 14:51:05 +0200 Subject: [PATCH 2/3] OBLS-935 Pick queue does not lock/refresh fast enough show assigned person --- src/screens/Picking/DiscretePickingListScreen.tsx | 4 +++- src/screens/Picking/DiscretePickingOrderCard.tsx | 11 ++++++++++- src/screens/Picking/discretePickingLib.ts | 1 + src/types/picking.ts | 1 + 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/screens/Picking/DiscretePickingListScreen.tsx b/src/screens/Picking/DiscretePickingListScreen.tsx index b071aebe..87f84f1e 100644 --- a/src/screens/Picking/DiscretePickingListScreen.tsx +++ b/src/screens/Picking/DiscretePickingListScreen.tsx @@ -144,7 +144,9 @@ export default function DiscretePickingListScreen() { order.requisitionId} - renderItem={({ item }) => } + renderItem={({ item }) => ( + + )} keyboardShouldPersistTaps="handled" keyboardDismissMode="on-drag" contentContainerStyle={styles.listContent} diff --git a/src/screens/Picking/DiscretePickingOrderCard.tsx b/src/screens/Picking/DiscretePickingOrderCard.tsx index 993d0186..85914d75 100644 --- a/src/screens/Picking/DiscretePickingOrderCard.tsx +++ b/src/screens/Picking/DiscretePickingOrderCard.tsx @@ -17,13 +17,15 @@ const DELIVERY_TYPE_LABELS: Record = DELIVERY_TYPES.reduce void; + showAssignee?: boolean; }; -export default function DiscretePickingOrderCard({ order, onPress }: Props) { +export default function DiscretePickingOrderCard({ order, onPress, showAssignee = false }: Props) { const deliveryTypeLabel = order.deliveryTypeCode ? DELIVERY_TYPE_LABELS[order.deliveryTypeCode] ?? order.deliveryTypeCode : null; const lineCountLabel = order.taskCount === 1 ? 'Line' : 'Lines'; + const assigneeName = order.assignee ? `${order.assignee.firstName} ${order.assignee.lastName}`.trim() : null; return ( onPress(order)}> @@ -75,6 +77,13 @@ export default function DiscretePickingOrderCard({ order, onPress }: Props) { {lineCountLabel}: {order.taskCount} + {showAssignee && assigneeName ? ( + + + Assigned to: {assigneeName} + + + ) : null} diff --git a/src/screens/Picking/discretePickingLib.ts b/src/screens/Picking/discretePickingLib.ts index 2383e7fb..70816d6c 100644 --- a/src/screens/Picking/discretePickingLib.ts +++ b/src/screens/Picking/discretePickingLib.ts @@ -39,6 +39,7 @@ export function groupTasksIntoOrders(tasks: PickTask[]): DiscretePickingOrder[] destination: task.destination, destinationLocationType: task.destinationLocationType, deliveryTypeCode: task.deliveryTypeCode, + assignee: task.assignee, priority: task.priority, taskCount: 0, inProgress: false, diff --git a/src/types/picking.ts b/src/types/picking.ts index c7b7fda2..c1117ea2 100644 --- a/src/types/picking.ts +++ b/src/types/picking.ts @@ -83,6 +83,7 @@ export type DiscretePickingOrder = { destination?: string; destinationLocationType?: string; deliveryTypeCode?: DeliveryTypeCode; + assignee?: Person | null; /** requisition.priority (lower = higher priority) */ priority?: number; /** number of open pick tasks (line items) in this order */ From 0f853746fd453b5ab0d966eb663b4badad23457c Mon Sep 17 00:00:00 2001 From: adambalcerzak Date: Thu, 13 Aug 2026 13:36:57 +0200 Subject: [PATCH 3/3] OBLS-935 Pick queue does not lock/refresh fast enough rename --- src/apis/picking.ts | 10 +++++----- src/redux/actions/picking.ts | 4 ++-- src/redux/sagas/picking.ts | 6 +++++- .../Picking/DiscretePickingListScreen.tsx | 20 +++++++++++-------- .../Picking/DiscretePickingOrderCard.tsx | 5 ++--- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/apis/picking.ts b/src/apis/picking.ts index 314e1375..c6d97191 100644 --- a/src/apis/picking.ts +++ b/src/apis/picking.ts @@ -50,20 +50,20 @@ export function getPickTasksApi(facilityId: string, params?: Partial `status=${encodeURIComponent(status)}`); - if (showAssigned !== undefined) { - query.push(`showAssigned=${showAssigned}`); + if (excludeAssignedRequisitions !== undefined) { + query.push(`excludeAssignedRequisitions=${excludeAssignedRequisitions}`); } return ApiClient.get(`/facilities/${facilityId}/pick-tasks?${query.join('&')}`); } export function getPickTaskCountsApi(facilityId: string) { - return ApiClient.get(`/facilities/${facilityId}/pick-tasks/counts`); + return ApiClient.get(`/facilities/${facilityId}/pick-tasks/counts?excludeAssignedRequisitions=true`); } export function patchPickTaskApi(facilityId: string, taskId: string, params: PickTaskActionParams) { diff --git a/src/redux/actions/picking.ts b/src/redux/actions/picking.ts index c943877a..90a79972 100644 --- a/src/redux/actions/picking.ts +++ b/src/redux/actions/picking.ts @@ -71,7 +71,7 @@ export function getPickTasksAction( } export function getOpenPickTasksAction( - showAssigned: boolean, + excludeAssignedRequisitions: boolean, callback: (response: { response?: { data: PickTask[]; @@ -86,7 +86,7 @@ export function getOpenPickTasksAction( ) { return { type: GET_OPEN_PICK_TASKS_REQUEST, - payload: { showAssigned }, + payload: { excludeAssignedRequisitions }, callback }; } diff --git a/src/redux/sagas/picking.ts b/src/redux/sagas/picking.ts index 9ec6beed..c32785de 100644 --- a/src/redux/sagas/picking.ts +++ b/src/redux/sagas/picking.ts @@ -75,7 +75,11 @@ function* getOpenPickTasksAction(action: any) { // No full-screen loading indicator here on purpose: the list screen renders its own // inline skeleton / pull-to-refresh state so the screen never blocks on the fetch. // @ts-ignore - const response = yield call(api.getOpenPickTasksApi, currentLocation.id, action.payload?.showAssigned); + const response = yield call( + api.getOpenPickTasksApi, + currentLocation.id, + action.payload?.excludeAssignedRequisitions + ); yield action.callback({ response }); yield put({ type: GET_OPEN_PICK_TASKS_REQUEST_SUCCESS, payload: response.data }); } catch (error) { diff --git a/src/screens/Picking/DiscretePickingListScreen.tsx b/src/screens/Picking/DiscretePickingListScreen.tsx index 87f84f1e..8d037117 100644 --- a/src/screens/Picking/DiscretePickingListScreen.tsx +++ b/src/screens/Picking/DiscretePickingListScreen.tsx @@ -34,19 +34,19 @@ export default function DiscretePickingListScreen() { const [tasks, setTasks] = useState([]); const [searchTerm, setSearchTerm] = useState(''); const [selectedQueueType, setSelectedQueueType] = useState(ALL_QUEUE_TYPES); - const [showAssigned, setShowAssigned] = useState(false); + const [excludeAssignedRequisitions, setExcludeAssignedRequisitions] = useState(true); const [isRefreshing, setIsRefreshing] = useState(false); const [isPullRefreshing, setIsPullRefreshing] = useState(false); const [hasLoaded, setHasLoaded] = useState(false); const fetchOrders = useCallback( - (showAssignedParam: boolean, fromPull = false) => { + (excludeAssignedRequisitionsParam: boolean, fromPull = false) => { setIsRefreshing(true); if (fromPull) { setIsPullRefreshing(true); } dispatch( - getOpenPickTasksAction(showAssignedParam, ({ response, errorMessage }) => { + getOpenPickTasksAction(excludeAssignedRequisitionsParam, ({ response, errorMessage }) => { if (!errorMessage && response?.data) { setTasks(response.data); } @@ -61,8 +61,8 @@ export default function DiscretePickingListScreen() { useFocusEffect( useCallback(() => { - fetchOrders(showAssigned); - }, [fetchOrders, showAssigned]) + fetchOrders(excludeAssignedRequisitions); + }, [fetchOrders, excludeAssignedRequisitions]) ); const sortedOrders = useMemo(() => sortOrders(groupTasksIntoOrders(tasks)), [tasks]); @@ -133,7 +133,11 @@ export default function DiscretePickingListScreen() { )} {!isLoadingList && ( - + setExcludeAssignedRequisitions(!value)} + /> )} @@ -145,7 +149,7 @@ export default function DiscretePickingListScreen() { data={visibleOrders} keyExtractor={(order) => order.requisitionId} renderItem={({ item }) => ( - + )} keyboardShouldPersistTaps="handled" keyboardDismissMode="on-drag" @@ -159,7 +163,7 @@ export default function DiscretePickingListScreen() { description={emptyStateMessage('orders', searchTerm, 'No open orders ready for picking')} /> } - onRefresh={() => fetchOrders(showAssigned, true)} + onRefresh={() => fetchOrders(excludeAssignedRequisitions, true)} /> )} diff --git a/src/screens/Picking/DiscretePickingOrderCard.tsx b/src/screens/Picking/DiscretePickingOrderCard.tsx index 85914d75..3eb2c4e2 100644 --- a/src/screens/Picking/DiscretePickingOrderCard.tsx +++ b/src/screens/Picking/DiscretePickingOrderCard.tsx @@ -17,10 +17,9 @@ const DELIVERY_TYPE_LABELS: Record = DELIVERY_TYPES.reduce void; - showAssignee?: boolean; }; -export default function DiscretePickingOrderCard({ order, onPress, showAssignee = false }: Props) { +export default function DiscretePickingOrderCard({ order, onPress }: Props) { const deliveryTypeLabel = order.deliveryTypeCode ? DELIVERY_TYPE_LABELS[order.deliveryTypeCode] ?? order.deliveryTypeCode : null; @@ -77,7 +76,7 @@ export default function DiscretePickingOrderCard({ order, onPress, showAssignee {lineCountLabel}: {order.taskCount} - {showAssignee && assigneeName ? ( + {assigneeName ? ( Assigned to: {assigneeName}