feat(collection-pool): gate assign UI on ready_for_collection
Both the per-row Assign Driver button and the bulk-assign button in each supplier section header now disable when the target row(s) have not been marked ready for collection. Tooltips explain the reason. This enforces the rule that a stop must be ready before it can be assigned to a driver — same gate for single-row and bulk flows.
This commit is contained in:
parent
c88a52cf2d
commit
ed9503706d
1 changed files with 24 additions and 3 deletions
|
|
@ -177,7 +177,13 @@ export function PoolRow({
|
|||
</div>
|
||||
|
||||
<div className="flex flex-col items-stretch gap-2 lg:min-w-[11rem]">
|
||||
<Button size="sm" variant={isAssigned ? "outline" : "default"} onClick={() => onOpenAssign(row)} disabled={busy}>
|
||||
<Button
|
||||
size="sm"
|
||||
variant={isAssigned ? "outline" : "default"}
|
||||
onClick={() => onOpenAssign(row)}
|
||||
disabled={busy || !row.ready_for_collection}
|
||||
title={!row.ready_for_collection ? "Mark this stop as ready before assigning" : undefined}
|
||||
>
|
||||
{isAssigned ? "Reschedule" : "Assign Driver"}
|
||||
</Button>
|
||||
<Button
|
||||
|
|
@ -243,6 +249,15 @@ export function SupplierGroup({
|
|||
(r) => getAssignmentState(r, todayYmd) !== "unassigned",
|
||||
);
|
||||
|
||||
// Compute which rows WOULD be assigned if the user clicked the bulk
|
||||
// assign button. The same gating rule from PoolRow applies here: a
|
||||
// row can only be assigned once it's marked ready.
|
||||
const targetRows = allSelected || selectedCount === 0
|
||||
? group.rows
|
||||
: group.rows.filter((r) => selectedIds.has(r.id));
|
||||
const unreadyTargetCount = targetRows.filter((r) => !r.ready_for_collection).length;
|
||||
const allTargetsReady = unreadyTargetCount === 0;
|
||||
|
||||
const eyebrowText = (() => {
|
||||
if (group.topPoNumbers.length === 0) return null;
|
||||
const head = group.topPoNumbers.map((p) => `PO ${p}`).join(", ");
|
||||
|
|
@ -257,6 +272,12 @@ export function SupplierGroup({
|
|||
? `Assign ${selectedCount} selected`
|
||||
: `Assign all ${rowIds.length}`;
|
||||
|
||||
const assignDisabledReason = allAssigned
|
||||
? "Every stop at this supplier is already assigned"
|
||||
: !allTargetsReady
|
||||
? `${unreadyTargetCount} ${unreadyTargetCount === 1 ? "stop" : "stops"} not marked ready — mark ready before assigning`
|
||||
: undefined;
|
||||
|
||||
const onAssignClick = () => {
|
||||
const ids = allSelected || selectedCount === 0 ? rowIds : rowIds.filter((id) => selectedIds.has(id));
|
||||
onOpenBulkAssign(group.supplierId, group.supplierName, ids);
|
||||
|
|
@ -301,8 +322,8 @@ export function SupplierGroup({
|
|||
<Button
|
||||
size="sm"
|
||||
onClick={onAssignClick}
|
||||
disabled={busy || allAssigned}
|
||||
title={allAssigned ? "Every stop at this supplier is already assigned" : undefined}
|
||||
disabled={busy || allAssigned || !allTargetsReady}
|
||||
title={assignDisabledReason}
|
||||
>
|
||||
<Truck className="mr-1.5 size-3.5" />
|
||||
{assignLabel}
|
||||
|
|
|
|||
Loading…
Reference in a new issue