fix(WEB): 자재투입 모달 UX 개선 - 선택 유지/중복투입 차단/버튼 UI
- 자재 투입 후 전체 새로고침 제거, 로컬 오버라이드로 현재 수주 선택 유지 - 자동선택 useEffect에 현재 선택 유효 가드 추가 - API remainingRequiredQty 활용하여 이미 충족된 품목 추가 선택 차단 - 기투입 수량 표시 및 '투입 완료' 뱃지 표시 - 체크박스 → 버튼 형태(선택/선택됨)로 변경 - 수량 소수점 불필요 자릿수 제거 (parseFloat 래핑)
This commit is contained in:
@@ -11,10 +11,13 @@
|
||||
* - 양식 미매핑 시 processType 폴백
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { Loader2, Save } from 'lucide-react';
|
||||
import { DocumentViewer } from '@/components/document-system';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { toast } from 'sonner';
|
||||
import { getWorkOrderById, getMaterialInputLots } from '../WorkOrders/actions';
|
||||
import { saveWorkLog } from './actions';
|
||||
import type { MaterialInputLot } from '../WorkOrders/actions';
|
||||
import type { WorkOrder, ProcessType } from '../WorkOrders/types';
|
||||
import { WorkLogContent } from './WorkLogContent';
|
||||
@@ -58,6 +61,7 @@ export function WorkLogModal({
|
||||
const [order, setOrder] = useState<WorkOrder | null>(null);
|
||||
const [materialLots, setMaterialLots] = useState<MaterialInputLot[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// 목업 WorkOrder 생성
|
||||
@@ -136,6 +140,38 @@ export function WorkLogModal({
|
||||
}
|
||||
}, [open, workOrderId, processType]);
|
||||
|
||||
// 저장 핸들러
|
||||
const handleSave = useCallback(async () => {
|
||||
if (!workOrderId || !order) return;
|
||||
|
||||
setIsSaving(true);
|
||||
try {
|
||||
// 현재 아이템 데이터를 table_data로 변환
|
||||
const tableData = (order.items || []).map((item) => ({
|
||||
id: item.id,
|
||||
item_name: item.productName,
|
||||
specification: item.specification || item.floorCode,
|
||||
quantity: item.quantity,
|
||||
unit: item.unit || 'EA',
|
||||
}));
|
||||
|
||||
const result = await saveWorkLog(workOrderId, {
|
||||
table_data: tableData,
|
||||
title: workLogTemplateName || '작업일지',
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
toast.success('작업일지가 저장되었습니다.');
|
||||
} else {
|
||||
toast.error(result.error || '저장에 실패했습니다.');
|
||||
}
|
||||
} catch {
|
||||
toast.error('저장 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
}, [workOrderId, order, workLogTemplateName]);
|
||||
|
||||
if (!workOrderId) return null;
|
||||
|
||||
// 로딩/에러 상태는 DocumentViewer 내부에서 처리
|
||||
@@ -183,6 +219,17 @@ export function WorkLogModal({
|
||||
// 양식명으로 문서 제목 결정
|
||||
const documentTitle = workLogTemplateName || '작업일지';
|
||||
|
||||
const toolbarExtra = (
|
||||
<Button onClick={handleSave} disabled={isSaving} size="sm">
|
||||
{isSaving ? (
|
||||
<Loader2 className="w-4 h-4 mr-1.5 animate-spin" />
|
||||
) : (
|
||||
<Save className="w-4 h-4 mr-1.5" />
|
||||
)}
|
||||
{isSaving ? '저장 중...' : '저장'}
|
||||
</Button>
|
||||
);
|
||||
|
||||
return (
|
||||
<DocumentViewer
|
||||
title={documentTitle}
|
||||
@@ -190,6 +237,7 @@ export function WorkLogModal({
|
||||
preset="inspection"
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
toolbarExtra={toolbarExtra}
|
||||
>
|
||||
{isLoading ? (
|
||||
<div className="flex items-center justify-center h-64 bg-white">
|
||||
|
||||
Reference in New Issue
Block a user