1
0
Fork 0

fix(grid): prevent split collision by including source in overlap check

Server action: remove 'other.id === entryId' exclusion from the
split overlap scan so the source item's own footprint is treated
as occupied, forcing the split to find a different position.

UI: disable the split button via findEmptySpot check when no room
exists for the split stack, preventing a failed action.
This commit is contained in:
Jason Fraley 2026-07-28 14:51:56 -04:00
parent 256e5bd68a
commit d88fe04b56
3 changed files with 7 additions and 3 deletions

View file

@ -737,7 +737,7 @@ export async function splitGridStack(
let overlaps = false;
for (const other of existing) {
if (other.id === entryId || other.id == null) continue;
if (other.id == null) continue;
const otherRes = other.resource as Resource;
if (!otherRes || typeof otherRes === "number") continue;
const otherRotated = other.rotated ?? false;

View file

@ -9,7 +9,7 @@ import {
LayoutGridIcon,
ListIcon,
} from "lucide-react";
import { GridItem, getItemFootprint, getGridOccupancy } from "@/lib/logistics";
import { GridItem, getItemFootprint, getGridOccupancy, findEmptySpot } from "@/lib/logistics";
import { Resource } from "@/payload-types";
import { cn, pluralize } from "@/lib/utils";
@ -41,6 +41,9 @@ export function GridToolbar({
const occupancy = getGridOccupancy(storedResources, gridWidth, gridHeight);
const res = selectedItem ? (selectedItem.resource as Resource) : null;
const fp = res ? getItemFootprint(res, selectedItem!.rotated) : null;
const canSplit = selectedItem && res && fp
? findEmptySpot(storedResources, fp.width, fp.height, gridWidth, gridHeight) !== null
: false;
return (
<div className="flex flex-col gap-3">
@ -94,6 +97,7 @@ export function GridToolbar({
<Button
variant="outline"
size="sm"
disabled={!canSplit}
onClick={() => onSplit(selectedItem.id, Math.floor(selectedItem.amount / 2))}
>
<ScissorsIcon className="size-3.5" />

View file

@ -46,7 +46,7 @@ export function StructureCard({ structure }: StructureCardProps) {
return (
<Link href={`/logistics/structures/${structure.id}`}>
<Item variant="outline" className="cursor-pointer group transition-all duration-200 hover:scale-[1.01] hover:[box-shadow:inset_0_2px_8px_rgba(255,255,255,0.12)]">
<Item variant="outline" className="cursor-pointer group transition-all duration-200 hover:scale-[1.01] hover:[box-shadow:inset_0_2px_8px_rgba(255,255,255,0.33)]">
<ItemHeader>
<div className="flex items-center gap-2">
<ItemMedia variant="icon">