리비전 페이지 제거 및 트랜잭션 오류 임시 수정
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
- frontend/src/pages/revision/ 폴더 완전 삭제 - EnhancedRevisionPage.css 제거 - support_details 저장 시 트랜잭션 오류로 인해 임시로 상세 정보 저장 비활성화 - 리비전 기능 재설계 예정
This commit is contained in:
@@ -34,6 +34,12 @@ const BOMManagementPage = ({
|
||||
const [userRequirements, setUserRequirements] = useState({});
|
||||
const [purchasedMaterials, setPurchasedMaterials] = useState(new Set());
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
// 리비전 관련 상태
|
||||
const [isRevisionMode, setIsRevisionMode] = useState(false);
|
||||
const [revisionData, setRevisionData] = useState(null);
|
||||
const [previousFileId, setPreviousFileId] = useState(null);
|
||||
const [changedMaterials, setChangedMaterials] = useState({});
|
||||
|
||||
// 자재 업데이트 함수 (브랜드, 사용자 요구사항 등)
|
||||
const updateMaterial = (materialId, updates) => {
|
||||
@@ -155,12 +161,58 @@ const BOMManagementPage = ({
|
||||
}
|
||||
};
|
||||
|
||||
// 리비전 모드 감지 및 변경된 자재 로드
|
||||
const checkAndLoadRevisionData = async () => {
|
||||
try {
|
||||
// 현재 job_no의 모든 파일 목록 확인
|
||||
const filesResponse = await api.get(`/files/list?job_no=${jobNo}`);
|
||||
const files = filesResponse.data.files || [];
|
||||
|
||||
if (files.length > 1) {
|
||||
// 파일이 여러 개 있으면 리비전 모드 활성화
|
||||
setIsRevisionMode(true);
|
||||
|
||||
// 파일들을 업로드 날짜순으로 정렬
|
||||
const sortedFiles = files.sort((a, b) => new Date(a.upload_date) - new Date(b.upload_date));
|
||||
|
||||
// 이전 파일 ID 찾기 (현재 파일 이전 버전)
|
||||
const currentIndex = sortedFiles.findIndex(file => file.id === parseInt(fileId));
|
||||
if (currentIndex > 0) {
|
||||
const previousFile = sortedFiles[currentIndex - 1];
|
||||
setPreviousFileId(previousFile.id);
|
||||
|
||||
// 변경된 자재 로드
|
||||
await loadChangedMaterials(fileId, previousFile.id);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('리비전 데이터 로드 실패:', error);
|
||||
// API 오류 시 리비전 모드 비활성화
|
||||
setIsRevisionMode(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 변경된 자재 로드
|
||||
const loadChangedMaterials = async (currentFileId, previousFileId) => {
|
||||
try {
|
||||
const response = await api.get(`/simple-revision/changed-materials/${currentFileId}/${previousFileId}`);
|
||||
if (response.data.success) {
|
||||
setChangedMaterials(response.data.data.changes_by_category || {});
|
||||
setRevisionData(response.data.data);
|
||||
console.log('✅ 변경된 자재 로드 완료:', response.data.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('변경된 자재 로드 실패:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 초기 로드
|
||||
useEffect(() => {
|
||||
if (fileId) {
|
||||
loadMaterials(fileId);
|
||||
loadAvailableRevisions();
|
||||
loadUserRequirements(fileId);
|
||||
checkAndLoadRevisionData(); // 리비전 데이터 확인
|
||||
}
|
||||
}, [fileId]);
|
||||
|
||||
@@ -180,12 +232,30 @@ const BOMManagementPage = ({
|
||||
}
|
||||
}, [materials, selectedCategory]);
|
||||
|
||||
// 카테고리별 자재 필터링
|
||||
// 카테고리별 자재 필터링 (리비전 모드 지원)
|
||||
const getCategoryMaterials = (category) => {
|
||||
return materials.filter(material =>
|
||||
material.classified_category === category ||
|
||||
material.category === category
|
||||
);
|
||||
if (isRevisionMode && changedMaterials[category]) {
|
||||
// 리비전 모드: 변경된 자재만 표시
|
||||
const changedMaterialIds = changedMaterials[category].changes.map(change => change.material_id);
|
||||
return materials.filter(material =>
|
||||
(material.classified_category === category || material.category === category) &&
|
||||
changedMaterialIds.includes(material.id)
|
||||
);
|
||||
} else {
|
||||
// 일반 모드: 모든 자재 표시
|
||||
return materials.filter(material =>
|
||||
material.classified_category === category ||
|
||||
material.category === category
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// 리비전 액션 정보 가져오기
|
||||
const getRevisionAction = (materialId, category) => {
|
||||
if (!isRevisionMode || !changedMaterials[category]) return null;
|
||||
|
||||
const change = changedMaterials[category].changes.find(c => c.material_id === materialId);
|
||||
return change || null;
|
||||
};
|
||||
|
||||
// 카테고리별 컴포넌트 렌더링
|
||||
@@ -210,7 +280,11 @@ const BOMManagementPage = ({
|
||||
fileId,
|
||||
jobNo,
|
||||
user,
|
||||
onNavigate
|
||||
onNavigate,
|
||||
// 리비전 관련 props 추가
|
||||
isRevisionMode,
|
||||
getRevisionAction: (materialId) => getRevisionAction(materialId, selectedCategory),
|
||||
revisionData
|
||||
};
|
||||
|
||||
switch (selectedCategory) {
|
||||
@@ -282,15 +356,32 @@ const BOMManagementPage = ({
|
||||
}}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '28px' }}>
|
||||
<div>
|
||||
<h2 style={{
|
||||
fontSize: '28px',
|
||||
fontWeight: '700',
|
||||
color: '#0f172a',
|
||||
margin: '0 0 8px 0',
|
||||
letterSpacing: '-0.025em'
|
||||
}}>
|
||||
BOM Materials Management
|
||||
</h2>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '8px' }}>
|
||||
<h2 style={{
|
||||
fontSize: '28px',
|
||||
fontWeight: '700',
|
||||
color: '#0f172a',
|
||||
margin: 0,
|
||||
letterSpacing: '-0.025em'
|
||||
}}>
|
||||
BOM Materials Management
|
||||
</h2>
|
||||
{isRevisionMode && (
|
||||
<div style={{
|
||||
background: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)',
|
||||
color: 'white',
|
||||
padding: '6px 12px',
|
||||
borderRadius: '8px',
|
||||
fontSize: '12px',
|
||||
fontWeight: '600',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.05em',
|
||||
boxShadow: '0 4px 6px -1px rgba(245, 158, 11, 0.3)'
|
||||
}}>
|
||||
📊 Revision Mode
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<p style={{
|
||||
fontSize: '16px',
|
||||
color: '#64748b',
|
||||
@@ -298,6 +389,15 @@ const BOMManagementPage = ({
|
||||
fontWeight: '400'
|
||||
}}>
|
||||
{bomName} - {currentRevision} | Project: {selectedProject?.job_name || jobNo}
|
||||
{isRevisionMode && revisionData && (
|
||||
<span style={{
|
||||
marginLeft: '16px',
|
||||
color: '#f59e0b',
|
||||
fontWeight: '600'
|
||||
}}>
|
||||
• {revisionData.total_changed_materials} materials changed
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
@@ -415,6 +515,7 @@ const BOMManagementPage = ({
|
||||
.map((category) => {
|
||||
const isActive = selectedCategory === category.key;
|
||||
const count = getCategoryMaterials(category.key).length;
|
||||
const hasChanges = isRevisionMode && changedMaterials[category.key];
|
||||
|
||||
return (
|
||||
<button
|
||||
@@ -423,9 +524,11 @@ const BOMManagementPage = ({
|
||||
style={{
|
||||
background: isActive
|
||||
? `linear-gradient(135deg, ${category.color} 0%, ${category.color}dd 100%)`
|
||||
: 'white',
|
||||
color: isActive ? 'white' : '#64748b',
|
||||
border: isActive ? 'none' : '1px solid #e2e8f0',
|
||||
: hasChanges
|
||||
? 'linear-gradient(135deg, #fef3c7 0%, #fde68a 100%)'
|
||||
: 'white',
|
||||
color: isActive ? 'white' : hasChanges ? '#92400e' : '#64748b',
|
||||
border: isActive ? 'none' : hasChanges ? '2px solid #f59e0b' : '1px solid #e2e8f0',
|
||||
borderRadius: '12px',
|
||||
padding: '16px 12px',
|
||||
cursor: 'pointer',
|
||||
@@ -433,7 +536,8 @@ const BOMManagementPage = ({
|
||||
fontWeight: '600',
|
||||
transition: 'all 0.2s ease',
|
||||
textAlign: 'center',
|
||||
boxShadow: isActive ? `0 4px 14px 0 ${category.color}39` : '0 2px 8px rgba(0,0,0,0.05)'
|
||||
boxShadow: isActive ? `0 4px 14px 0 ${category.color}39` : hasChanges ? '0 4px 14px 0 rgba(245, 158, 11, 0.3)' : '0 2px 8px rgba(0,0,0,0.05)',
|
||||
position: 'relative'
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
if (!isActive) {
|
||||
@@ -448,8 +552,16 @@ const BOMManagementPage = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div style={{ marginBottom: '4px' }}>
|
||||
<div style={{ marginBottom: '4px', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '4px' }}>
|
||||
{category.label}
|
||||
{hasChanges && (
|
||||
<div style={{
|
||||
width: '8px',
|
||||
height: '8px',
|
||||
borderRadius: '50%',
|
||||
background: isActive ? 'rgba(255,255,255,0.8)' : '#f59e0b'
|
||||
}}></div>
|
||||
)}
|
||||
</div>
|
||||
<div style={{
|
||||
fontSize: '12px',
|
||||
@@ -457,6 +569,11 @@ const BOMManagementPage = ({
|
||||
fontWeight: '500'
|
||||
}}>
|
||||
{count} items
|
||||
{hasChanges && (
|
||||
<span style={{ marginLeft: '4px', fontSize: '10px' }}>
|
||||
({changedMaterials[category.key].changed_count} changed)
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user