feat(WEB): 작업일지/검사성적서 버튼 공정 레벨 설정 연동
- Process 타입에 documentTemplateId, needsWorkLog 필드 추가 (ProcessStep에서 이동) - ProcessForm에 중간검사 양식/작업일지 설정 UI 추가 - StepForm에서 해당 UI 제거 - WorkerScreen 하단 버튼 조건부 렌더링: needsWorkLog/documentTemplateId 기반
This commit is contained in:
@@ -37,7 +37,9 @@ import {
|
||||
updateProcess,
|
||||
getDepartmentOptions,
|
||||
getProcessSteps,
|
||||
getDocumentTemplates,
|
||||
type DepartmentOption,
|
||||
type DocumentTemplateOption,
|
||||
} from './actions';
|
||||
|
||||
interface ProcessFormProps {
|
||||
@@ -67,6 +69,18 @@ export function ProcessForm({ mode, initialData }: ProcessFormProps) {
|
||||
);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
// 중간검사/작업일지 설정 (Process 레벨)
|
||||
const [documentTemplateId, setDocumentTemplateId] = useState<number | undefined>(
|
||||
initialData?.documentTemplateId
|
||||
);
|
||||
const [needsWorkLog, setNeedsWorkLog] = useState(
|
||||
initialData?.needsWorkLog ?? false
|
||||
);
|
||||
const [workLogTemplateId, setWorkLogTemplateId] = useState<number | undefined>(
|
||||
initialData?.workLogTemplateId
|
||||
);
|
||||
const [documentTemplates, setDocumentTemplates] = useState<DocumentTemplateOption[]>([]);
|
||||
|
||||
// 품목 분류 규칙 (기존 로직 유지)
|
||||
const [classificationRules, setClassificationRules] = useState<ClassificationRule[]>(
|
||||
initialData?.classificationRules || []
|
||||
@@ -124,15 +138,21 @@ export function ProcessForm({ mode, initialData }: ProcessFormProps) {
|
||||
);
|
||||
}, []);
|
||||
|
||||
// 부서 목록 + 단계 목록 로드
|
||||
// 부서 목록 + 문서양식 목록 로드
|
||||
useEffect(() => {
|
||||
const loadDepartments = async () => {
|
||||
const loadInitialData = async () => {
|
||||
setIsDepartmentsLoading(true);
|
||||
const departments = await getDepartmentOptions();
|
||||
const [departments, templates] = await Promise.all([
|
||||
getDepartmentOptions(),
|
||||
getDocumentTemplates(),
|
||||
]);
|
||||
setDepartmentOptions(departments);
|
||||
if (templates.success && templates.data) {
|
||||
setDocumentTemplates(templates.data);
|
||||
}
|
||||
setIsDepartmentsLoading(false);
|
||||
};
|
||||
loadDepartments();
|
||||
loadInitialData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -300,6 +320,9 @@ export function ProcessForm({ mode, initialData }: ProcessFormProps) {
|
||||
processType,
|
||||
processCategory: processCategory || undefined,
|
||||
department,
|
||||
documentTemplateId: documentTemplateId || undefined,
|
||||
needsWorkLog,
|
||||
workLogTemplateId: needsWorkLog ? workLogTemplateId : undefined,
|
||||
classificationRules: classificationRules.map((rule) => ({
|
||||
registrationType: rule.registrationType,
|
||||
ruleType: rule.ruleType,
|
||||
@@ -463,6 +486,64 @@ export function ProcessForm({ mode, initialData }: ProcessFormProps) {
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
{/* Row 3: 중간검사양식 | 작업일지여부 | 작업일지양식 */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mt-6">
|
||||
<div className="space-y-2">
|
||||
<Label>중간검사 양식</Label>
|
||||
<Select
|
||||
key={`doc-template-${documentTemplateId ?? 'none'}`}
|
||||
value={documentTemplateId ? String(documentTemplateId) : ''}
|
||||
onValueChange={(v) => setDocumentTemplateId(v ? Number(v) : undefined)}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="선택하세요" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{documentTemplates.map((tmpl) => (
|
||||
<SelectItem key={tmpl.id} value={String(tmpl.id)}>
|
||||
{tmpl.name} ({tmpl.category})
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>작업일지 여부</Label>
|
||||
<Select
|
||||
value={needsWorkLog ? '사용' : '미사용'}
|
||||
onValueChange={(v) => setNeedsWorkLog(v === '사용')}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="사용">사용</SelectItem>
|
||||
<SelectItem value="미사용">미사용</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
{needsWorkLog && (
|
||||
<div className="space-y-2">
|
||||
<Label>작업일지 양식</Label>
|
||||
<Select
|
||||
key={`worklog-template-${workLogTemplateId ?? 'none'}`}
|
||||
value={workLogTemplateId ? String(workLogTemplateId) : ''}
|
||||
onValueChange={(v) => setWorkLogTemplateId(v ? Number(v) : undefined)}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="선택하세요" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{documentTemplates.map((tmpl) => (
|
||||
<SelectItem key={tmpl.id} value={String(tmpl.id)}>
|
||||
{tmpl.name} ({tmpl.category})
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -679,6 +760,10 @@ export function ProcessForm({ mode, initialData }: ProcessFormProps) {
|
||||
manager,
|
||||
useProductionDate,
|
||||
isActive,
|
||||
documentTemplateId,
|
||||
needsWorkLog,
|
||||
workLogTemplateId,
|
||||
documentTemplates,
|
||||
classificationRules,
|
||||
steps,
|
||||
isStepsLoading,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* - 완료 정보: 유형(선택 완료 시 완료/클릭 시 완료)
|
||||
*/
|
||||
|
||||
import { useState, useCallback, useEffect } from 'react';
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Input } from '@/components/ui/input';
|
||||
@@ -37,8 +37,7 @@ import {
|
||||
STEP_CONNECTION_TARGET_OPTIONS,
|
||||
DEFAULT_INSPECTION_SETTING,
|
||||
} from '@/types/process';
|
||||
import { createProcessStep, updateProcessStep, getDocumentTemplates } from './actions';
|
||||
import type { DocumentTemplateOption } from './actions';
|
||||
import { createProcessStep, updateProcessStep } from './actions';
|
||||
import type { DetailConfig } from '@/components/templates/IntegratedDetailTemplate/types';
|
||||
import { InspectionSettingModal } from './InspectionSettingModal';
|
||||
import { InspectionPreviewModal } from './InspectionPreviewModal';
|
||||
@@ -105,12 +104,6 @@ export function StepForm({ mode, processId, initialData }: StepFormProps) {
|
||||
initialData?.completionType || '클릭 시 완료'
|
||||
);
|
||||
|
||||
// 문서양식 선택
|
||||
const [documentTemplateId, setDocumentTemplateId] = useState<number | undefined>(
|
||||
initialData?.documentTemplateId
|
||||
);
|
||||
const [documentTemplates, setDocumentTemplates] = useState<DocumentTemplateOption[]>([]);
|
||||
|
||||
// 검사 설정
|
||||
const [inspectionSetting, setInspectionSetting] = useState<InspectionSetting>(
|
||||
initialData?.inspectionSetting || DEFAULT_INSPECTION_SETTING
|
||||
@@ -125,17 +118,6 @@ export function StepForm({ mode, processId, initialData }: StepFormProps) {
|
||||
// 검사여부가 "사용"인지 확인
|
||||
const isInspectionEnabled = needsInspection === '사용';
|
||||
|
||||
// 검사여부가 "사용"이면 문서양식 목록 조회
|
||||
useEffect(() => {
|
||||
if (isInspectionEnabled && documentTemplates.length === 0) {
|
||||
getDocumentTemplates().then((result) => {
|
||||
if (result.success && result.data) {
|
||||
setDocumentTemplates(result.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [isInspectionEnabled, documentTemplates.length]);
|
||||
|
||||
// 제출
|
||||
const handleSubmit = async (): Promise<{ success: boolean; error?: string }> => {
|
||||
if (!stepName.trim()) {
|
||||
@@ -149,7 +131,6 @@ export function StepForm({ mode, processId, initialData }: StepFormProps) {
|
||||
isRequired: isRequired === '필수',
|
||||
needsApproval: needsApproval === '필요',
|
||||
needsInspection: needsInspection === '사용',
|
||||
documentTemplateId: isInspectionEnabled ? documentTemplateId : undefined,
|
||||
isActive: isActive === '사용',
|
||||
order: initialData?.order || 0,
|
||||
connectionType,
|
||||
@@ -269,33 +250,6 @@ export function StepForm({ mode, processId, initialData }: StepFormProps) {
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
{/* 문서양식 선택 (검사여부가 "사용"일 때만 표시) */}
|
||||
{isInspectionEnabled && (
|
||||
<div className="mt-4 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
|
||||
<div className="space-y-2">
|
||||
<Label>문서양식 (검사 템플릿)</Label>
|
||||
<Select
|
||||
key={`doc-template-${documentTemplateId ?? 'none'}`}
|
||||
value={documentTemplateId ? String(documentTemplateId) : ''}
|
||||
onValueChange={(v) => setDocumentTemplateId(v ? Number(v) : undefined)}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="문서양식을 선택하세요" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{documentTemplates.map((tmpl) => (
|
||||
<SelectItem key={tmpl.id} value={String(tmpl.id)}>
|
||||
{tmpl.name} ({tmpl.category})
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
중간검사 시 사용할 문서양식을 선택합니다. MNG에서 등록한 양식이 표시됩니다.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -384,8 +338,6 @@ export function StepForm({ mode, processId, initialData }: StepFormProps) {
|
||||
completionType,
|
||||
initialData?.stepCode,
|
||||
isInspectionEnabled,
|
||||
documentTemplateId,
|
||||
documentTemplates,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ interface ApiProcess {
|
||||
process_category: string | null;
|
||||
use_production_date: boolean;
|
||||
work_log_template: string | null;
|
||||
document_template_id: number | null;
|
||||
document_template?: { id: number; name: string; category: string } | null;
|
||||
needs_work_log: boolean;
|
||||
work_log_template_id: number | null;
|
||||
work_log_template_relation?: { id: number; name: string; category: string } | null;
|
||||
required_workers: number;
|
||||
equipment_info: string | null;
|
||||
work_steps: string[] | null;
|
||||
@@ -88,6 +93,11 @@ function transformApiToFrontend(apiData: ApiProcess): Process {
|
||||
processCategory: apiData.process_category ?? undefined,
|
||||
useProductionDate: apiData.use_production_date ?? false,
|
||||
workLogTemplate: apiData.work_log_template ?? undefined,
|
||||
documentTemplateId: apiData.document_template_id ?? undefined,
|
||||
documentTemplateName: apiData.document_template?.name ?? undefined,
|
||||
needsWorkLog: apiData.needs_work_log ?? false,
|
||||
workLogTemplateId: apiData.work_log_template_id ?? undefined,
|
||||
workLogTemplateName: apiData.work_log_template_relation?.name ?? undefined,
|
||||
classificationRules: [...patternRules, ...individualRules],
|
||||
requiredWorkers: apiData.required_workers,
|
||||
equipmentInfo: apiData.equipment_info ?? undefined,
|
||||
@@ -179,6 +189,9 @@ function transformFrontendToApi(data: ProcessFormData): Record<string, unknown>
|
||||
process_category: data.processCategory || null,
|
||||
use_production_date: data.useProductionDate ?? false,
|
||||
work_log_template: data.workLogTemplate || null,
|
||||
document_template_id: data.documentTemplateId || null,
|
||||
needs_work_log: data.needsWorkLog ?? false,
|
||||
work_log_template_id: data.workLogTemplateId || null,
|
||||
required_workers: data.requiredWorkers,
|
||||
equipment_info: data.equipmentInfo || null,
|
||||
work_steps: data.workSteps ? data.workSteps.split(',').map((s) => s.trim()).filter(Boolean) : [],
|
||||
@@ -567,12 +580,6 @@ interface ApiProcessStep {
|
||||
is_required: boolean;
|
||||
needs_approval: boolean;
|
||||
needs_inspection: boolean;
|
||||
document_template_id: number | null;
|
||||
document_template?: {
|
||||
id: number;
|
||||
name: string;
|
||||
category: string;
|
||||
} | null;
|
||||
is_active: boolean;
|
||||
sort_order: number;
|
||||
connection_type: string | null;
|
||||
@@ -590,8 +597,6 @@ function transformStepApiToFrontend(apiStep: ApiProcessStep): ProcessStep {
|
||||
isRequired: apiStep.is_required,
|
||||
needsApproval: apiStep.needs_approval,
|
||||
needsInspection: apiStep.needs_inspection,
|
||||
documentTemplateId: apiStep.document_template_id ?? undefined,
|
||||
documentTemplateName: apiStep.document_template?.name ?? undefined,
|
||||
isActive: apiStep.is_active,
|
||||
order: apiStep.sort_order,
|
||||
connectionType: (apiStep.connection_type as ProcessStep['connectionType']) || '없음',
|
||||
@@ -647,7 +652,6 @@ export async function createProcessStep(
|
||||
is_required: data.isRequired,
|
||||
needs_approval: data.needsApproval,
|
||||
needs_inspection: data.needsInspection,
|
||||
document_template_id: data.documentTemplateId || null,
|
||||
is_active: data.isActive,
|
||||
connection_type: data.connectionType || null,
|
||||
connection_target: data.connectionTarget || null,
|
||||
@@ -672,7 +676,6 @@ export async function updateProcessStep(
|
||||
if (data.isRequired !== undefined) apiData.is_required = data.isRequired;
|
||||
if (data.needsApproval !== undefined) apiData.needs_approval = data.needsApproval;
|
||||
if (data.needsInspection !== undefined) apiData.needs_inspection = data.needsInspection;
|
||||
if (data.documentTemplateId !== undefined) apiData.document_template_id = data.documentTemplateId || null;
|
||||
if (data.isActive !== undefined) apiData.is_active = data.isActive;
|
||||
if (data.connectionType !== undefined) apiData.connection_type = data.connectionType || null;
|
||||
if (data.connectionTarget !== undefined) apiData.connection_target = data.connectionTarget || null;
|
||||
|
||||
@@ -366,6 +366,7 @@ export default function WorkerScreen() {
|
||||
const [currentInspectionSetting, setCurrentInspectionSetting] = useState<InspectionSetting | undefined>();
|
||||
// 문서 템플릿 데이터 (document_template 기반 동적 검사용)
|
||||
const [inspectionTemplateData, setInspectionTemplateData] = useState<InspectionTemplateData | undefined>();
|
||||
const [inspectionDimensions, setInspectionDimensions] = useState<{ width?: number; height?: number }>({});
|
||||
|
||||
// 중간검사 체크 상태 관리: { [itemId]: boolean }
|
||||
const [inspectionCheckedMap, setInspectionCheckedMap] = useState<Record<string, boolean>>({});
|
||||
@@ -432,6 +433,15 @@ export default function WorkerScreen() {
|
||||
return 'screen';
|
||||
}, [activeTab, processListCache]);
|
||||
|
||||
// 선택된 공정의 작업일지/검사성적서 설정
|
||||
const activeProcessSettings = useMemo(() => {
|
||||
const process = processListCache.find((p) => p.id === activeTab);
|
||||
return {
|
||||
needsWorkLog: process?.needsWorkLog ?? false,
|
||||
hasDocumentTemplate: !!process?.documentTemplateId,
|
||||
};
|
||||
}, [activeTab, processListCache]);
|
||||
|
||||
// activeTab 변경 시 해당 공정의 중간검사 설정 조회
|
||||
useEffect(() => {
|
||||
if (processListCache.length === 0 || !activeTab) return;
|
||||
@@ -570,22 +580,60 @@ export default function WorkerScreen() {
|
||||
const itemNames = group.items.map((it) => it.itemName).filter(Boolean);
|
||||
const itemSummary = itemNames.length > 0 ? itemNames.join(', ') : '-';
|
||||
|
||||
apiItems.push({
|
||||
// 첫 번째 아이템의 options에서 사이즈/공정별 정보 추출
|
||||
const firstItem = group.items[0];
|
||||
const opts = (firstItem?.options || {}) as Record<string, unknown>;
|
||||
|
||||
const workItem: WorkItemData = {
|
||||
id: `${selectedOrder.id}-node-${nodeKey}`,
|
||||
apiItemId: group.items[0]?.id as number | undefined,
|
||||
apiItemId: firstItem?.id as number | undefined,
|
||||
workOrderId: selectedOrder.id,
|
||||
itemNo: index + 1,
|
||||
itemCode: selectedOrder.orderNo || '-',
|
||||
itemName: `${group.nodeName} : ${itemSummary}`,
|
||||
floor: '-',
|
||||
code: '-',
|
||||
width: 0,
|
||||
height: 0,
|
||||
floor: (opts.floor as string) || '-',
|
||||
code: (opts.code as string) || '-',
|
||||
width: (opts.width as number) || 0,
|
||||
height: (opts.height as number) || 0,
|
||||
quantity: group.totalQuantity,
|
||||
processType: activeProcessTabKey,
|
||||
steps,
|
||||
materialInputs: [],
|
||||
});
|
||||
};
|
||||
|
||||
// 공정별 추가 정보 추출
|
||||
if (opts.cutting_info) {
|
||||
const ci = opts.cutting_info as { width: number; sheets: number };
|
||||
workItem.cuttingInfo = { width: ci.width, sheets: ci.sheets };
|
||||
}
|
||||
if (opts.slat_info) {
|
||||
const si = opts.slat_info as { length: number; slat_count: number; joint_bar: number };
|
||||
workItem.slatInfo = { length: si.length, slatCount: si.slat_count, jointBar: si.joint_bar };
|
||||
}
|
||||
if (opts.bending_info) {
|
||||
const bi = opts.bending_info as {
|
||||
common: { kind: string; type: string; length_quantities: { length: number; quantity: number }[] };
|
||||
detail_parts: { part_name: string; material: string; barcy_info: string }[];
|
||||
};
|
||||
workItem.bendingInfo = {
|
||||
common: { kind: bi.common.kind, type: bi.common.type, lengthQuantities: bi.common.length_quantities || [] },
|
||||
detailParts: (bi.detail_parts || []).map(dp => ({ partName: dp.part_name, material: dp.material, barcyInfo: dp.barcy_info })),
|
||||
};
|
||||
}
|
||||
if (opts.is_wip) {
|
||||
workItem.isWip = true;
|
||||
const wi = opts.wip_info as { specification: string; length_quantity: string; drawing_url?: string } | undefined;
|
||||
if (wi) {
|
||||
workItem.wipInfo = { specification: wi.specification, lengthQuantity: wi.length_quantity, drawingUrl: wi.drawing_url };
|
||||
}
|
||||
}
|
||||
if (opts.is_joint_bar) {
|
||||
workItem.isJointBar = true;
|
||||
const jb = opts.slat_joint_bar_info as { specification: string; length: number; quantity: number } | undefined;
|
||||
if (jb) workItem.slatJointBarInfo = jb;
|
||||
}
|
||||
|
||||
apiItems.push(workItem);
|
||||
});
|
||||
} else if (selectedOrder) {
|
||||
// nodeGroups가 없는 경우 폴백 (단일 항목)
|
||||
@@ -868,6 +916,7 @@ export default function WorkerScreen() {
|
||||
createdAt: '',
|
||||
};
|
||||
setSelectedOrder(syntheticOrder);
|
||||
setInspectionDimensions({ width: item.width, height: item.height });
|
||||
|
||||
// 실제 API 아이템인 경우 검사 템플릿 로딩 시도
|
||||
if (item.workOrderId && !item.id.startsWith('mock-')) {
|
||||
@@ -1238,34 +1287,40 @@ export default function WorkerScreen() {
|
||||
</div>
|
||||
|
||||
{/* 하단 고정 버튼 */}
|
||||
<div className={`fixed bottom-4 left-4 right-4 px-4 py-3 bg-background/95 backdrop-blur rounded-xl border shadow-lg z-50 transition-all duration-300 md:bottom-6 md:px-6 md:right-[48px] ${sidebarCollapsed ? 'md:left-[156px]' : 'md:left-[316px]'}`}>
|
||||
<div className="flex gap-3">
|
||||
{hasWipItems ? (
|
||||
<Button
|
||||
onClick={handleInspection}
|
||||
className="flex-1 py-6 text-base font-medium bg-gray-900 hover:bg-gray-800"
|
||||
>
|
||||
작업일지 및 검사성적서 보기
|
||||
</Button>
|
||||
) : (
|
||||
<>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handleWorkLog}
|
||||
className="flex-1 py-6 text-base font-medium"
|
||||
>
|
||||
작업일지 보기
|
||||
</Button>
|
||||
{(hasWipItems || activeProcessSettings.needsWorkLog || activeProcessSettings.hasDocumentTemplate) && (
|
||||
<div className={`fixed bottom-4 left-4 right-4 px-4 py-3 bg-background/95 backdrop-blur rounded-xl border shadow-lg z-50 transition-all duration-300 md:bottom-6 md:px-6 md:right-[48px] ${sidebarCollapsed ? 'md:left-[156px]' : 'md:left-[316px]'}`}>
|
||||
<div className="flex gap-3">
|
||||
{hasWipItems ? (
|
||||
<Button
|
||||
onClick={handleInspection}
|
||||
className="flex-1 py-6 text-base font-medium bg-gray-900 hover:bg-gray-800"
|
||||
>
|
||||
검사성적서 보기
|
||||
작업일지 및 검사성적서 보기
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
) : (
|
||||
<>
|
||||
{activeProcessSettings.needsWorkLog && (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handleWorkLog}
|
||||
className="flex-1 py-6 text-base font-medium"
|
||||
>
|
||||
작업일지 보기
|
||||
</Button>
|
||||
)}
|
||||
{activeProcessSettings.hasDocumentTemplate && (
|
||||
<Button
|
||||
onClick={handleInspection}
|
||||
className="flex-1 py-6 text-base font-medium bg-gray-900 hover:bg-gray-800"
|
||||
>
|
||||
검사성적서 보기
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 모달/다이얼로그 */}
|
||||
<CompletionConfirmDialog
|
||||
@@ -1328,6 +1383,7 @@ export default function WorkerScreen() {
|
||||
initialData={selectedOrder ? inspectionDataMap.get(selectedOrder.id) : undefined}
|
||||
onComplete={handleInspectionComplete}
|
||||
templateData={inspectionTemplateData}
|
||||
workItemDimensions={inspectionDimensions}
|
||||
/>
|
||||
</PageLayout>
|
||||
);
|
||||
|
||||
@@ -57,7 +57,14 @@ export interface Process {
|
||||
description?: string; // 공정 설명 (테이블에 표시)
|
||||
processType: ProcessType; // 생산, 검사 등
|
||||
department: string; // 담당부서
|
||||
workLogTemplate?: string; // 작업일지 양식
|
||||
workLogTemplate?: string; // 작업일지 양식 (레거시 string)
|
||||
|
||||
// 중간검사/작업일지 설정 (Process 레벨)
|
||||
documentTemplateId?: number; // 중간검사 양식 ID
|
||||
documentTemplateName?: string; // 중간검사 양식명 (표시용)
|
||||
needsWorkLog: boolean; // 작업일지 여부
|
||||
workLogTemplateId?: number; // 작업일지 양식 ID
|
||||
workLogTemplateName?: string; // 작업일지 양식명 (표시용)
|
||||
|
||||
// 자동 분류 규칙
|
||||
classificationRules: ClassificationRule[];
|
||||
@@ -99,6 +106,9 @@ export interface ProcessFormData {
|
||||
processCategory?: string;
|
||||
useProductionDate?: boolean;
|
||||
workLogTemplate?: string;
|
||||
documentTemplateId?: number;
|
||||
needsWorkLog: boolean;
|
||||
workLogTemplateId?: number;
|
||||
classificationRules: ClassificationRuleInput[];
|
||||
requiredWorkers: number;
|
||||
equipmentInfo?: string;
|
||||
@@ -169,8 +179,6 @@ export interface ProcessStep {
|
||||
isRequired: boolean; // 필수여부
|
||||
needsApproval: boolean; // 승인여부
|
||||
needsInspection: boolean; // 검사여부
|
||||
documentTemplateId?: number; // 문서양식 ID (검사 시 사용할 템플릿)
|
||||
documentTemplateName?: string; // 문서양식명 (표시용)
|
||||
isActive: boolean; // 사용여부
|
||||
order: number; // 순서 (드래그&드롭)
|
||||
// 연결 정보
|
||||
|
||||
Reference in New Issue
Block a user