fix: 품목기준관리 실시간 동기화 수정
- BOM 항목 추가/수정/삭제 시 섹션탭 즉시 반영 - 섹션 복제 시 UI 즉시 업데이트 (null vs undefined 이슈 해결) - 항목 수정 기능 추가 (useTemplateManagement) - 실시간 동기화 문서 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -100,8 +100,13 @@ export function useTabManagement(): UseTabManagementReturn {
|
||||
]);
|
||||
const [activeTab, setActiveTab] = useState('hierarchy');
|
||||
|
||||
// 속성 하위 탭 상태
|
||||
const [attributeSubTabs, setAttributeSubTabs] = useState<AttributeSubTab[]>([]);
|
||||
// 속성 하위 탭 상태 (기본 탭: 단위, 재질, 표면처리)
|
||||
// TODO: 나중에 백엔드에서 기준값 로드로 대체 예정
|
||||
const [attributeSubTabs, setAttributeSubTabs] = useState<AttributeSubTab[]>([
|
||||
{ id: 'units', label: '단위', key: 'units', isDefault: true, order: 0 },
|
||||
{ id: 'materials', label: '재질', key: 'materials', isDefault: true, order: 1 },
|
||||
{ id: 'surface', label: '표면처리', key: 'surface', isDefault: true, order: 2 },
|
||||
]);
|
||||
const [activeAttributeTab, setActiveAttributeTab] = useState('units');
|
||||
|
||||
// 메인 탭 다이얼로그 상태
|
||||
@@ -123,7 +128,7 @@ export function useTabManagement(): UseTabManagementReturn {
|
||||
// 이전 필드 상태 추적용 ref (무한 루프 방지)
|
||||
const prevFieldsRef = useRef<string>('');
|
||||
|
||||
// 마스터 항목이 추가/수정될 때 속성 탭 자동 생성
|
||||
// 마스터 항목이 추가/수정/삭제될 때 속성 탭 자동 동기화
|
||||
useEffect(() => {
|
||||
// 현재 필드 상태를 문자열로 직렬화
|
||||
const currentFieldsState = JSON.stringify(
|
||||
@@ -136,15 +141,30 @@ export function useTabManagement(): UseTabManagementReturn {
|
||||
}
|
||||
prevFieldsRef.current = currentFieldsState;
|
||||
|
||||
// 현재 마스터 필드 ID 목록
|
||||
const currentFieldIds = new Set(itemMasterFields.map(f => f.id.toString()));
|
||||
|
||||
setAttributeSubTabs(prev => {
|
||||
const newTabs: AttributeSubTab[] = [];
|
||||
const updates: { key: string; label: string }[] = [];
|
||||
|
||||
// 삭제된 마스터 항목에 해당하는 탭 제거 (숫자 key만 체크 - 마스터 항목 ID)
|
||||
const filteredTabs = prev.filter(tab => {
|
||||
// 숫자로만 이루어진 key는 마스터 항목 ID
|
||||
const isNumericKey = /^\d+$/.test(tab.key);
|
||||
if (isNumericKey && !currentFieldIds.has(tab.key)) {
|
||||
// 삭제된 마스터 항목의 탭
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// 새로운 마스터 항목 추가 또는 기존 항목 라벨 업데이트
|
||||
itemMasterFields.forEach(field => {
|
||||
const existingTab = prev.find(tab => tab.key === field.id.toString());
|
||||
const existingTab = filteredTabs.find(tab => tab.key === field.id.toString());
|
||||
|
||||
if (!existingTab) {
|
||||
const maxOrder = Math.max(...prev.map(t => t.order), ...newTabs.map(t => t.order), -1);
|
||||
const maxOrder = Math.max(...filteredTabs.map(t => t.order), ...newTabs.map(t => t.order), -1);
|
||||
newTabs.push({
|
||||
id: `attr-${field.id.toString()}`,
|
||||
label: field.field_name,
|
||||
@@ -157,12 +177,17 @@ export function useTabManagement(): UseTabManagementReturn {
|
||||
}
|
||||
});
|
||||
|
||||
// 탭 삭제, 추가, 업데이트 여부 확인
|
||||
const hasRemovals = filteredTabs.length !== prev.length;
|
||||
const hasAdditions = newTabs.length > 0;
|
||||
const hasUpdates = updates.length > 0;
|
||||
|
||||
// 변경사항 없으면 이전 상태 그대로 반환
|
||||
if (newTabs.length === 0 && updates.length === 0) {
|
||||
if (!hasRemovals && !hasAdditions && !hasUpdates) {
|
||||
return prev;
|
||||
}
|
||||
|
||||
let result = prev.map(tab => {
|
||||
let result = filteredTabs.map(tab => {
|
||||
const update = updates.find(u => u.key === tab.key);
|
||||
return update ? { ...tab, label: update.label } : tab;
|
||||
});
|
||||
@@ -173,6 +198,12 @@ export function useTabManagement(): UseTabManagementReturn {
|
||||
index === self.findIndex(t => t.key === tab.key)
|
||||
);
|
||||
});
|
||||
|
||||
// 현재 활성 탭이 삭제된 마스터 항목인 경우 기본 탭으로 전환
|
||||
const isNumericKey = /^\d+$/.test(activeAttributeTab);
|
||||
if (isNumericKey && !currentFieldIds.has(activeAttributeTab)) {
|
||||
setActiveAttributeTab('units');
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [itemMasterFields]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user