feat(WEB): 공정 관리 UI 개선
- ProcessDetail: 공정 상세 정보 표시 개선 - ProcessForm: 공정 등록/수정 폼 유효성 검사 강화 - RuleModal: 공정 규칙 설정 모달 리팩토링
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useState, useMemo } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { List, Edit, Wrench } from 'lucide-react';
|
||||
import { List, Edit, Wrench, Package } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { PageLayout } from '@/components/organisms/PageLayout';
|
||||
import { ProcessWorkLogPreviewModal } from './ProcessWorkLogPreviewModal';
|
||||
import type { Process } from '@/types/process';
|
||||
import { MATCHING_TYPE_OPTIONS } from '@/types/process';
|
||||
|
||||
interface ProcessDetailProps {
|
||||
process: Process;
|
||||
@@ -18,6 +19,23 @@ export function ProcessDetail({ process }: ProcessDetailProps) {
|
||||
const router = useRouter();
|
||||
const [workLogModalOpen, setWorkLogModalOpen] = useState(false);
|
||||
|
||||
// 패턴 규칙과 개별 품목 분리
|
||||
const { patternRules, individualItems } = useMemo(() => {
|
||||
const patterns = process.classificationRules.filter(
|
||||
(rule) => rule.registrationType === 'pattern'
|
||||
);
|
||||
const individuals = process.classificationRules.filter(
|
||||
(rule) => rule.registrationType === 'individual'
|
||||
);
|
||||
return { patternRules: patterns, individualItems: individuals };
|
||||
}, [process.classificationRules]);
|
||||
|
||||
// 매칭 타입 라벨
|
||||
const getMatchingTypeLabel = (type: string) => {
|
||||
const option = MATCHING_TYPE_OPTIONS.find((opt) => opt.value === type);
|
||||
return option?.label || type;
|
||||
};
|
||||
|
||||
const handleEdit = () => {
|
||||
router.push(`/ko/master-data/process-management/${process.id}/edit`);
|
||||
};
|
||||
@@ -110,20 +128,23 @@ export function ProcessDetail({ process }: ProcessDetailProps) {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 자동 분류 규칙 */}
|
||||
{/* 자동 분류 규칙 (패턴 기반) */}
|
||||
<Card>
|
||||
<CardHeader className="bg-muted/50">
|
||||
<CardTitle className="text-base">자동 분류 규칙</CardTitle>
|
||||
<CardTitle className="text-base flex items-center gap-2">
|
||||
<Wrench className="h-4 w-4" />
|
||||
자동 분류 규칙
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-6">
|
||||
{process.classificationRules.length === 0 ? (
|
||||
<div className="text-center py-12 text-muted-foreground">
|
||||
<Wrench className="h-12 w-12 mx-auto mb-4 opacity-30" />
|
||||
<p>등록된 자동 분류 규칙이 없습니다</p>
|
||||
{patternRules.length === 0 ? (
|
||||
<div className="text-center py-8 text-muted-foreground">
|
||||
<Wrench className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||
<p className="text-sm">등록된 자동 분류 규칙이 없습니다</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{process.classificationRules.map((rule) => (
|
||||
{patternRules.map((rule) => (
|
||||
<div
|
||||
key={rule.id}
|
||||
className="flex items-center justify-between p-4 border rounded-lg"
|
||||
@@ -134,7 +155,51 @@ export function ProcessDetail({ process }: ProcessDetailProps) {
|
||||
</Badge>
|
||||
<div>
|
||||
<div className="font-medium">
|
||||
{rule.ruleType} - "{rule.conditionValue}"
|
||||
{rule.ruleType} · {getMatchingTypeLabel(rule.matchingType)} · "{rule.conditionValue}"
|
||||
</div>
|
||||
{rule.description && (
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{rule.description}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<Badge variant="outline">우선순위: {rule.priority}</Badge>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 개별 품목 */}
|
||||
<Card>
|
||||
<CardHeader className="bg-muted/50">
|
||||
<CardTitle className="text-base flex items-center gap-2">
|
||||
<Package className="h-4 w-4" />
|
||||
개별 품목
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-6">
|
||||
{individualItems.length === 0 ? (
|
||||
<div className="text-center py-8 text-muted-foreground">
|
||||
<Package className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||
<p className="text-sm">등록된 개별 품목이 없습니다</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{individualItems.map((rule) => (
|
||||
<div
|
||||
key={rule.id}
|
||||
className="flex items-center justify-between p-4 border rounded-lg"
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<Badge variant={rule.isActive ? 'default' : 'secondary'}>
|
||||
{rule.isActive ? '활성' : '비활성'}
|
||||
</Badge>
|
||||
<div>
|
||||
<div className="font-medium">
|
||||
{rule.conditionValue}
|
||||
</div>
|
||||
{rule.description && (
|
||||
<div className="text-sm text-muted-foreground">
|
||||
|
||||
Reference in New Issue
Block a user