feat: [receiving] 수입검사 모달에 테스트입력/초기화 토글 버튼 추가
- 테스트입력: 전체 항목에 합격값 자동 채움 (tolerance/criteria 기반) - 초기화: 입력값 전체 리셋 - 수입검사 타이틀 옆 눈에 띄는 색상 버튼
This commit is contained in:
@@ -233,6 +233,9 @@ export function ImportInspectionInputModal({
|
||||
const [overallResult, setOverallResult] = useState<'pass' | 'fail' | null>(null);
|
||||
const [remark, setRemark] = useState('');
|
||||
|
||||
// Test fill toggle
|
||||
const [isTestFilled, setIsTestFilled] = useState(false);
|
||||
|
||||
// Photos
|
||||
const [newPhotos, setNewPhotos] = useState<File[]>([]);
|
||||
const [existingPhotos, setExistingPhotos] = useState<ExistingFile[]>([]);
|
||||
@@ -453,6 +456,78 @@ export function ImportInspectionInputModal({
|
||||
setCurrentTab(0);
|
||||
}, []);
|
||||
|
||||
// ===== 테스트 데이터 채우기 (전체 합격값) =====
|
||||
const generatePassingValue = useCallback(
|
||||
(item: InspectionItem): string => {
|
||||
const raw = rawDataMap.get(item.id);
|
||||
const base = baseValueMap.get(item.id);
|
||||
|
||||
// 1. 기준값이 있으면 그대로 사용 (공차 범위 중앙)
|
||||
if (base != null) return String(base);
|
||||
|
||||
// 2. Tolerance 기반
|
||||
if (raw?.tolerance) {
|
||||
switch (raw.tolerance.type) {
|
||||
case 'range': {
|
||||
const min = parseFloat(String(raw.tolerance.min || 0));
|
||||
const max = parseFloat(String(raw.tolerance.max || 0));
|
||||
return String(Math.round(((min + max) / 2) * 100) / 100);
|
||||
}
|
||||
case 'limit': {
|
||||
const lv = parseFloat(String(raw.tolerance.value || 0));
|
||||
if (raw.tolerance.op === 'gte') return String(lv);
|
||||
if (raw.tolerance.op === 'gt') return String(Math.round((lv + 1) * 100) / 100);
|
||||
if (raw.tolerance.op === 'lte') return String(lv);
|
||||
if (raw.tolerance.op === 'lt') return String(Math.round((lv - 1) * 100) / 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Criteria 기반
|
||||
if (raw?.criteria) {
|
||||
const { min, max } = raw.criteria;
|
||||
if (min != null && max != null) return String(Math.round(((min + max) / 2) * 100) / 100);
|
||||
if (min != null) return String(min);
|
||||
if (max != null) return String(max);
|
||||
}
|
||||
|
||||
return '100';
|
||||
},
|
||||
[rawDataMap, baseValueMap]
|
||||
);
|
||||
|
||||
const fillTestData = useCallback(() => {
|
||||
if (!template) return;
|
||||
const targetItems = template.inspectionItems.filter(i => i.isFirstInItem !== false);
|
||||
const newMeas: Record<string, Record<number, string>> = {};
|
||||
const newOkng: Record<string, Record<number, 'ok' | 'ng' | null>> = {};
|
||||
|
||||
for (const item of targetItems) {
|
||||
for (let n = 0; n < item.measurementCount; n++) {
|
||||
if (item.measurementType === 'okng') {
|
||||
if (!newOkng[item.id]) newOkng[item.id] = {};
|
||||
newOkng[item.id][n] = 'ok';
|
||||
} else if (item.measurementType === 'substitute') {
|
||||
if (!newMeas[item.id]) newMeas[item.id] = {};
|
||||
newMeas[item.id][n] = '정상';
|
||||
} else {
|
||||
if (!newMeas[item.id]) newMeas[item.id] = {};
|
||||
newMeas[item.id][n] = generatePassingValue(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setMeasurements(newMeas);
|
||||
setOkngValues(newOkng);
|
||||
setIsTestFilled(true);
|
||||
}, [template, generatePassingValue]);
|
||||
|
||||
const clearTestData = useCallback(() => {
|
||||
resetForm();
|
||||
setIsTestFilled(false);
|
||||
}, [resetForm]);
|
||||
|
||||
// ===== 단일 측정값의 자동 판정 =====
|
||||
const getMeasurementResult = useCallback(
|
||||
(itemId: string, nIndex: number): 'ok' | 'ng' | null => {
|
||||
@@ -760,7 +835,23 @@ export function ImportInspectionInputModal({
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="w-[95vw] max-w-[500px] sm:max-w-[500px] max-h-[90vh] flex flex-col p-0">
|
||||
<DialogHeader className="px-6 pt-6 pb-0 shrink-0">
|
||||
<DialogTitle className="text-lg font-bold">수입검사</DialogTitle>
|
||||
<div className="flex items-center gap-2">
|
||||
<DialogTitle className="text-lg font-bold">수입검사</DialogTitle>
|
||||
{template && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={isTestFilled ? clearTestData : fillTestData}
|
||||
className={cn(
|
||||
'px-3 py-1 text-xs font-bold rounded-full transition-colors',
|
||||
isTestFilled
|
||||
? 'bg-red-500 hover:bg-red-600 text-white'
|
||||
: 'bg-amber-500 hover:bg-amber-600 text-white'
|
||||
)}
|
||||
>
|
||||
{isTestFilled ? '초기화' : '테스트입력'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<VisuallyHidden><DialogDescription>수입검사 항목 입력</DialogDescription></VisuallyHidden>
|
||||
</DialogHeader>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user