feat: NumberingRuleDesigner에서 파트 업데이트 및 삭제 로직 개선
- 파트 업데이트 및 삭제 시 id 대신 order를 사용하여 로직을 개선하였습니다. - savedRules 상태 업데이트 시 깊은 복사를 통해 객체 참조를 분리하여 클로저 문제를 방지하였습니다. - 규칙 선택 시 깊은 복사를 통해 좌측 목록과 편집 영역의 객체가 공유되지 않도록 하여 데이터 무결성을 강화하였습니다. - 관련 로깅을 추가하여 상태 변경 시 디버깅을 용이하게 하였습니다.
This commit is contained in:
parent
d28e703cd2
commit
34202be843
|
|
@ -260,22 +260,24 @@ export const NumberingRuleDesigner: React.FC<NumberingRuleDesignerProps> = ({
|
|||
toast.success(`규칙 ${newPart.order}가 추가되었습니다`);
|
||||
}, [currentRule, maxRules]);
|
||||
|
||||
const handleUpdatePart = useCallback((partId: string, updates: Partial<NumberingRulePart>) => {
|
||||
// partOrder 기반으로 파트 업데이트 (id가 null일 수 있으므로 order 사용)
|
||||
const handleUpdatePart = useCallback((partOrder: number, updates: Partial<NumberingRulePart>) => {
|
||||
setCurrentRule((prev) => {
|
||||
if (!prev) return null;
|
||||
return {
|
||||
...prev,
|
||||
parts: prev.parts.map((part) => (part.id === partId ? { ...part, ...updates } : part)),
|
||||
parts: prev.parts.map((part) => (part.order === partOrder ? { ...part, ...updates } : part)),
|
||||
};
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleDeletePart = useCallback((partId: string) => {
|
||||
// partOrder 기반으로 파트 삭제 (id가 null일 수 있으므로 order 사용)
|
||||
const handleDeletePart = useCallback((partOrder: number) => {
|
||||
setCurrentRule((prev) => {
|
||||
if (!prev) return null;
|
||||
return {
|
||||
...prev,
|
||||
parts: prev.parts.filter((part) => part.id !== partId).map((part, index) => ({ ...part, order: index + 1 })),
|
||||
parts: prev.parts.filter((part) => part.order !== partOrder).map((part, index) => ({ ...part, order: index + 1 })),
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -295,8 +297,6 @@ export const NumberingRuleDesigner: React.FC<NumberingRuleDesignerProps> = ({
|
|||
|
||||
setLoading(true);
|
||||
try {
|
||||
const existing = savedRules.find((r) => r.ruleId === currentRule.ruleId);
|
||||
|
||||
// 파트별 기본 autoConfig 정의
|
||||
const defaultAutoConfigs: Record<string, any> = {
|
||||
sequence: { sequenceLength: 3, startFrom: 1 },
|
||||
|
|
@ -345,15 +345,30 @@ export const NumberingRuleDesigner: React.FC<NumberingRuleDesignerProps> = ({
|
|||
const response = await saveNumberingRuleToTest(ruleToSave);
|
||||
|
||||
if (response.success && response.data) {
|
||||
// 깊은 복사하여 savedRules와 currentRule이 다른 객체를 참조하도록 함
|
||||
const currentData = JSON.parse(JSON.stringify(response.data)) as NumberingRuleConfig;
|
||||
|
||||
// setSavedRules 내부에서 prev를 사용해서 existing 확인 (클로저 문제 방지)
|
||||
setSavedRules((prev) => {
|
||||
if (existing) {
|
||||
return prev.map((r) => (r.ruleId === ruleToSave.ruleId ? response.data! : r));
|
||||
const savedData = JSON.parse(JSON.stringify(response.data)) as NumberingRuleConfig;
|
||||
const existsInPrev = prev.some((r) => r.ruleId === ruleToSave.ruleId);
|
||||
|
||||
console.log("🔍 [handleSave] setSavedRules:", {
|
||||
ruleId: ruleToSave.ruleId,
|
||||
existsInPrev,
|
||||
prevCount: prev.length,
|
||||
});
|
||||
|
||||
if (existsInPrev) {
|
||||
// 기존 규칙 업데이트
|
||||
return prev.map((r) => (r.ruleId === ruleToSave.ruleId ? savedData : r));
|
||||
} else {
|
||||
return [...prev, response.data!];
|
||||
// 새 규칙 추가
|
||||
return [...prev, savedData];
|
||||
}
|
||||
});
|
||||
|
||||
setCurrentRule(response.data);
|
||||
setCurrentRule(currentData);
|
||||
setSelectedRuleId(response.data.ruleId);
|
||||
|
||||
await onSave?.(response.data);
|
||||
|
|
@ -366,11 +381,27 @@ export const NumberingRuleDesigner: React.FC<NumberingRuleDesignerProps> = ({
|
|||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [currentRule, savedRules, onSave, currentTableName]);
|
||||
}, [currentRule, onSave, currentTableName, menuObjid]);
|
||||
|
||||
const handleSelectRule = useCallback((rule: NumberingRuleConfig) => {
|
||||
console.log("🔍 [handleSelectRule] 규칙 선택:", {
|
||||
ruleId: rule.ruleId,
|
||||
ruleName: rule.ruleName,
|
||||
partsCount: rule.parts?.length || 0,
|
||||
parts: rule.parts?.map(p => ({ id: p.id, order: p.order, partType: p.partType })),
|
||||
});
|
||||
|
||||
setSelectedRuleId(rule.ruleId);
|
||||
setCurrentRule(rule);
|
||||
// 깊은 복사하여 객체 참조 분리 (좌측 목록과 편집 영역의 객체가 공유되지 않도록)
|
||||
const ruleCopy = JSON.parse(JSON.stringify(rule)) as NumberingRuleConfig;
|
||||
|
||||
console.log("🔍 [handleSelectRule] 깊은 복사 후:", {
|
||||
ruleId: ruleCopy.ruleId,
|
||||
partsCount: ruleCopy.parts?.length || 0,
|
||||
parts: ruleCopy.parts?.map(p => ({ id: p.id, order: p.order, partType: p.partType })),
|
||||
});
|
||||
|
||||
setCurrentRule(ruleCopy);
|
||||
toast.info(`"${rule.ruleName}" 규칙을 불러왔습니다`);
|
||||
}, []);
|
||||
|
||||
|
|
@ -595,12 +626,12 @@ export const NumberingRuleDesigner: React.FC<NumberingRuleDesignerProps> = ({
|
|||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
|
||||
{currentRule.parts.map((part) => (
|
||||
{currentRule.parts.map((part, index) => (
|
||||
<NumberingRuleCard
|
||||
key={part.id}
|
||||
key={`part-${part.order}-${index}`}
|
||||
part={part}
|
||||
onUpdate={(updates) => handleUpdatePart(part.id, updates)}
|
||||
onDelete={() => handleDeletePart(part.id)}
|
||||
onUpdate={(updates) => handleUpdatePart(part.order, updates)}
|
||||
onDelete={() => handleDeletePart(part.order)}
|
||||
isPreview={isPreview}
|
||||
/>
|
||||
))}
|
||||
|
|
|
|||
Loading…
Reference in New Issue