영역의 자재를 “해당 영역”에만 배치가 가능하게 구현
This commit is contained in:
parent
90b7c2b0f0
commit
b80d6cb85e
|
|
@ -778,9 +778,32 @@ export default function DigitalTwinEditor({ layoutId, layoutName, onBack }: Digi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 부모 ID 설정
|
// 부모 ID 설정 및 논리적 유효성 검사
|
||||||
if (validation.parent) {
|
if (validation.parent) {
|
||||||
|
// 1. 부모 객체 찾기
|
||||||
|
const parentObj = placedObjects.find((obj) => obj.id === validation.parent!.id);
|
||||||
|
|
||||||
|
// 2. 논리적 키 검사 (DB에서 가져온 데이터인 경우)
|
||||||
|
if (parentObj && parentObj.externalKey && newObject.parentKey) {
|
||||||
|
if (parentObj.externalKey !== newObject.parentKey) {
|
||||||
|
toast({
|
||||||
|
variant: "destructive",
|
||||||
|
title: "배치 오류",
|
||||||
|
description: `이 Location은 '${newObject.parentKey}' Area에만 배치할 수 있습니다. (현재 선택된 Area: ${parentObj.externalKey})`,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newObject.parentId = validation.parent.id;
|
newObject.parentId = validation.parent.id;
|
||||||
|
} else if (newObject.parentKey) {
|
||||||
|
// DB 데이터인데 부모 영역 위에 놓이지 않은 경우
|
||||||
|
toast({
|
||||||
|
variant: "destructive",
|
||||||
|
title: "배치 오류",
|
||||||
|
description: `이 Location은 '${newObject.parentKey}' Area 내부에 배치해야 합니다.`,
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -964,7 +987,59 @@ export default function DigitalTwinEditor({ layoutId, layoutName, onBack }: Digi
|
||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2. 그룹 이동: 자식 객체들도 함께 이동
|
// 2. 하위 계층 객체 이동 시 논리적 키 검증
|
||||||
|
if (hierarchyConfig && targetObj.hierarchyLevel && targetObj.hierarchyLevel > 1) {
|
||||||
|
const spatialObjects = updatedObjects.map((obj) => ({
|
||||||
|
id: obj.id,
|
||||||
|
position: obj.position,
|
||||||
|
size: obj.size,
|
||||||
|
hierarchyLevel: obj.hierarchyLevel || 1,
|
||||||
|
parentId: obj.parentId,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const targetSpatialObj = spatialObjects.find((obj) => obj.id === objectId);
|
||||||
|
if (targetSpatialObj) {
|
||||||
|
const validation = validateSpatialContainment(
|
||||||
|
targetSpatialObj,
|
||||||
|
spatialObjects.filter((obj) => obj.id !== objectId),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 새로운 부모 영역 찾기
|
||||||
|
if (validation.parent) {
|
||||||
|
const newParentObj = prev.find((obj) => obj.id === validation.parent!.id);
|
||||||
|
|
||||||
|
// DB에서 가져온 데이터인 경우 논리적 키 검증
|
||||||
|
if (newParentObj && newParentObj.externalKey && targetObj.parentKey) {
|
||||||
|
if (newParentObj.externalKey !== targetObj.parentKey) {
|
||||||
|
toast({
|
||||||
|
variant: "destructive",
|
||||||
|
title: "이동 불가",
|
||||||
|
description: `이 Location은 '${targetObj.parentKey}' Area에만 배치할 수 있습니다. (현재 선택된 Area: ${newParentObj.externalKey})`,
|
||||||
|
});
|
||||||
|
return prev; // 이동 취소
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 부모 ID 업데이트
|
||||||
|
updatedObjects = updatedObjects.map((obj) => {
|
||||||
|
if (obj.id === objectId) {
|
||||||
|
return { ...obj, parentId: validation.parent!.id };
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
});
|
||||||
|
} else if (targetObj.parentKey) {
|
||||||
|
// DB 데이터인데 부모 영역 밖으로 이동하려는 경우
|
||||||
|
toast({
|
||||||
|
variant: "destructive",
|
||||||
|
title: "이동 불가",
|
||||||
|
description: `이 Location은 '${targetObj.parentKey}' Area 내부에 있어야 합니다.`,
|
||||||
|
});
|
||||||
|
return prev; // 이동 취소
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 그룹 이동: 자식 객체들도 함께 이동
|
||||||
const spatialObjects = updatedObjects.map((obj) => ({
|
const spatialObjects = updatedObjects.map((obj) => ({
|
||||||
id: obj.id,
|
id: obj.id,
|
||||||
position: obj.position,
|
position: obj.position,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue