From 4f5dd8b47f1e6ae7f2df29999057cee20c303ab0 Mon Sep 17 00:00:00 2001 From: hjjeong Date: Wed, 13 May 2026 17:10:07 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=B5=EC=9A=A9=20=E2=80=94=20=EC=98=81?= =?UTF-8?q?=EC=97=85=204=20+=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=202=20?= =?UTF-8?q?+=20=EA=B0=9C=EB=B0=9C=205=EB=A9=94=EB=89=B4=20PageHeader=20+?= =?UTF-8?q?=20CompactFilterBar=20=EC=9D=BC=EA=B4=84=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 총 11개 페이지를 동일한 페이지 구조 표준으로 마이그레이션. 페이지 메뉴명은 PageHeader 가 useMenu() 자동 매칭, 검색 영역은 CompactFilterBar/CompactFilterField, 날짜 범위는 CompactDateRange 로 통일. 모든 자체 grid 검색폼 + 자체 h1 + 자체 액션 버튼 그룹 제거. 영업관리 4: - sales/estimate (견적관리) — 7필드 + 결재상태 SmartSelect - sales/order (주문서관리) — 9필드 (날짜 2종) - sales/sale (판매관리) — 10필드 (출하지시상태 SmartSelect) - sales/revenue (매출관리) — 11필드 (날짜 3종) 프로젝트관리 2: - project/progress (진행관리) — 11필드 (그리드 6→자동 wrap) - project/wbs-template (제품구분_WBS관리) — 1필드 개발관리 5: - development/part-regist (PART 등록) — 2필드 (자동완성) + 7 액션 - development/part-search (PART 조회) — 2필드 + 5 액션 - development/ebom-regist (E-BOM 등록) — 4필드 + 3 액션 (잔재 Field helper 제거) - development/ebom-search (E-BOM 조회) — 3필드 + 4 액션 (정/역전개) - development/change-list (설계변경 리스트) — 8필드 (read-only) DB: - menu_info.menu_desc 11개 메뉴 보강 (PageHeader 자동 표시) - docs/migration/common/menu_desc_sync.sql (멱등 UPDATE) Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/migration/common/menu_desc_sync.sql | 20 ++ .../development/change-list/page.tsx | 132 +++++------ .../development/ebom-regist/page.tsx | 140 ++++++------ .../development/ebom-search/page.tsx | 163 +++++++------- .../development/part-regist/page.tsx | 125 +++++------ .../development/part-search/page.tsx | 110 +++++----- .../COMPANY_16/project/progress/page.tsx | 206 ++++++++---------- .../COMPANY_16/project/wbs-template/page.tsx | 68 +++--- .../(main)/COMPANY_16/sales/estimate/page.tsx | 155 ++++++------- .../(main)/COMPANY_16/sales/order/page.tsx | 160 ++++++-------- .../(main)/COMPANY_16/sales/revenue/page.tsx | 175 +++++++-------- .../app/(main)/COMPANY_16/sales/sale/page.tsx | 171 +++++++-------- 12 files changed, 736 insertions(+), 889 deletions(-) create mode 100644 docs/migration/common/menu_desc_sync.sql diff --git a/docs/migration/common/menu_desc_sync.sql b/docs/migration/common/menu_desc_sync.sql new file mode 100644 index 00000000..a92e6bd0 --- /dev/null +++ b/docs/migration/common/menu_desc_sync.sql @@ -0,0 +1,20 @@ +-- ============================================================ +-- 영업관리 4 + 프로젝트관리 2 + M-BOM 2 메뉴 menu_desc 보강 +-- (PageHeader 자동 매칭용) +-- 2026-05-13 +-- ============================================================ + +UPDATE menu_info SET menu_desc='고객사 견적 작성 · 발송 · 승인 (wace estimateList 1:1)' WHERE objid=100002; +UPDATE menu_info SET menu_desc='고객사 주문서 등록 · 항목 관리 (wace orderList 1:1)' WHERE objid=100003; +UPDATE menu_info SET menu_desc='출하 · 판매 처리 및 시리얼 · 송장 관리 (wace saleList 1:1)' WHERE objid=100004; +UPDATE menu_info SET menu_desc='매출 등록 · 세금계산서 · 수금 관리 (wace revenueList 1:1)' WHERE objid=100005; +UPDATE menu_info SET menu_desc='제품구분 별 WBS 템플릿 + 표준 작업 (wace 1:1)' WHERE objid=100007; +UPDATE menu_info SET menu_desc='프로젝트 진행 현황 + 8그룹 컬럼 (wace projectMgmtWbsList3 1:1)' WHERE objid=100008; +UPDATE menu_info SET menu_desc='생산용 BOM 트리 + read-only 조회 (운영판 mBomMgmtList 1:1)' WHERE objid IN (100016, 100032); + +-- 개발관리 5메뉴 +UPDATE menu_info SET menu_desc='PART 마스터 등록 · 수정 (wace partMngList 1:1)' WHERE objid=100010; +UPDATE menu_info SET menu_desc='PART 마스터 조회 (wace partMngListSearch 1:1)' WHERE objid=100011; +UPDATE menu_info SET menu_desc='E-BOM 등록 · CSV Import (wace structureList 1:1)' WHERE objid=100012; +UPDATE menu_info SET menu_desc='E-BOM 트리 정/역전개 조회 + Excel 다운로드 (wace 1:1)' WHERE objid=100013; +UPDATE menu_info SET menu_desc='설계변경 리스트 (read-only, wace partMngHisList 1:1)' WHERE objid=100014; diff --git a/frontend/app/(main)/COMPANY_16/development/change-list/page.tsx b/frontend/app/(main)/COMPANY_16/development/change-list/page.tsx index c175b976..29699a58 100644 --- a/frontend/app/(main)/COMPANY_16/development/change-list/page.tsx +++ b/frontend/app/(main)/COMPANY_16/development/change-list/page.tsx @@ -6,14 +6,13 @@ // 참조: docs/migration/development/03-eo-history.md import React, { useCallback, useEffect, useMemo, useState } from "react"; -import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { Search, Loader2, RotateCcw } from "lucide-react"; import { toast } from "sonner"; import { DataGrid, DataGridColumn } from "@/components/common/DataGrid"; import { CommCodeSelect } from "@/components/common/CommCodeSelect"; import { SmartSelect, SmartSelectOption } from "@/components/common/SmartSelect"; +import { PageHeader } from "@/components/common/PageHeader"; +import { CompactFilterBar, CompactFilterField, CompactDateRange } from "@/components/common/CompactFilterBar"; import { devEoHistoryApi, EoHistoryListFilter, EoHistoryRow } from "@/lib/api/devEoHistory"; import { PartHisDetailDialog } from "@/components/development/PartHisDetailDialog"; @@ -92,73 +91,62 @@ export default function EoHistoryPage() { ); return ( -
-
-
- - setFilter({ ...filter, Year: v })} - placeholder="전체" - /> - - - setFilter({ ...filter, contract_objid: e.target.value })} - placeholder="project_mgmt.objid" /> - - - setFilter({ ...filter, part_no: e.target.value })} - placeholder="part_no LIKE" /> - - - setFilter({ ...filter, part_name: e.target.value })} - placeholder="part_name LIKE" /> - +
+ - - setFilter({ ...filter, eo_start_date: e.target.value })} /> - - - setFilter({ ...filter, eo_end_date: e.target.value })} /> - - - setFilter({ ...filter, part_type: v })} /> - - -
- setFilter({ ...filter, change_type: e.target.value })} - placeholder="EO구분 code_id" /> - setFilter({ ...filter, change_option: e.target.value })} - placeholder="EO사유 code_id" /> -
-
-
-
-
총 {total.toLocaleString()}건 (read-only)
-
- - -
-
-
+ fetchList()} + onReset={() => { setFilter(EMPTY_FILTER); fetchList(EMPTY_FILTER); }} + totalText={<>총 {total.toLocaleString()}건 (read-only)} + > + + setFilter({ ...filter, Year: v })} + placeholder="전체" + /> + + + setFilter({ ...filter, contract_objid: e.target.value })} + placeholder="project_mgmt.objid" /> + + + setFilter({ ...filter, part_no: e.target.value })} + placeholder="part_no LIKE" /> + + + setFilter({ ...filter, part_name: e.target.value })} + placeholder="part_name LIKE" /> + + + setFilter({ ...filter, eo_start_date: v })} + to={filter.eo_end_date ?? ""} + setTo={(v) => setFilter({ ...filter, eo_end_date: v })} + /> + + + setFilter({ ...filter, part_type: v })} /> + + + setFilter({ ...filter, change_type: e.target.value })} /> + + + setFilter({ ...filter, change_option: e.target.value })} /> + + -
+
- - {children} -
- ); -} diff --git a/frontend/app/(main)/COMPANY_16/development/ebom-regist/page.tsx b/frontend/app/(main)/COMPANY_16/development/ebom-regist/page.tsx index 5bc09508..4a3e8343 100644 --- a/frontend/app/(main)/COMPANY_16/development/ebom-regist/page.tsx +++ b/frontend/app/(main)/COMPANY_16/development/ebom-regist/page.tsx @@ -7,15 +7,13 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { - Search, Loader2, RotateCcw, Trash2, Settings, FileSpreadsheet, -} from "lucide-react"; +import { Trash2, Settings, FileSpreadsheet } from "lucide-react"; import { toast } from "sonner"; import { DataGrid, DataGridColumn } from "@/components/common/DataGrid"; import { CommCodeSelect } from "@/components/common/CommCodeSelect"; import { SmartSelect, SmartSelectOption } from "@/components/common/SmartSelect"; +import { PageHeader } from "@/components/common/PageHeader"; +import { CompactFilterBar, CompactFilterField } from "@/components/common/CompactFilterBar"; import { devBomApi, BomReportListFilter, BomReportRow } from "@/lib/api/devBom"; import { BomReportStatusDialog } from "@/components/development/BomReportStatusDialog"; import { DevPartSelect } from "@/components/development/DevPartSelect"; @@ -116,72 +114,66 @@ export default function EbomRegistPage() { const gridRows = useMemo(() => rows.map((r) => ({ ...r, id: r.objid })), [rows]); return ( -
-
-
- - setFilter({ ...filter, product_cd: v })} - /> - - - setFilter({ ...filter, status: v })} - placeholder="전체" - /> - - {/* wace structureList.jsp 1:1 — select2-part 자동완성 (양방향 동기) */} - - setFilter((prev) => ({ - ...prev, - search_part_no: v, - search_part_name: row?.part_name ?? prev.search_part_name, - }))} /> - - - setFilter((prev) => ({ - ...prev, - search_part_name: v, - search_part_no: row?.part_no ?? prev.search_part_no, - }))} /> - -
-
-
총 {total.toLocaleString()}건
-
- - - - - -
-
-
+
+ + + + + + } /> -
+ fetchList()} + onReset={() => { setFilter(EMPTY_FILTER); fetchList(EMPTY_FILTER); }} + totalText={<>총 {total.toLocaleString()}건} + > + + setFilter({ ...filter, product_cd: v })} + /> + + + setFilter({ ...filter, status: v })} + placeholder="전체" + /> + + + setFilter((prev) => ({ + ...prev, + search_part_no: v, + search_part_name: row?.part_name ?? prev.search_part_name, + }))} /> + + + setFilter((prev) => ({ + ...prev, + search_part_name: v, + search_part_no: row?.part_no ?? prev.search_part_no, + }))} /> + + + +
- - {children} -
- ); -} diff --git a/frontend/app/(main)/COMPANY_16/development/ebom-search/page.tsx b/frontend/app/(main)/COMPANY_16/development/ebom-search/page.tsx index 1239e682..3d7fa329 100644 --- a/frontend/app/(main)/COMPANY_16/development/ebom-search/page.tsx +++ b/frontend/app/(main)/COMPANY_16/development/ebom-search/page.tsx @@ -6,11 +6,9 @@ import React, { useCallback, useMemo, useState } from "react"; import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { - Search, Loader2, RotateCcw, ChevronsRight, ChevronsLeft, FileSpreadsheet, -} from "lucide-react"; +import { PageHeader } from "@/components/common/PageHeader"; +import { CompactFilterBar, CompactFilterField } from "@/components/common/CompactFilterBar"; +import { Loader2, ChevronsRight, ChevronsLeft, FileSpreadsheet } from "lucide-react"; import { toast } from "sonner"; import { DataGrid, DataGridColumn } from "@/components/common/DataGrid"; import { devBomApi, BomTreeFilter, BomTreeRow } from "@/lib/api/devBom"; @@ -186,81 +184,80 @@ export default function EbomSearchPage() { }, [rows, maxLevel, hasChildSet, ancestorsByChildId, collapsedChildIds]); return ( -
-
- {/* 운영판 wace structureAscendingList.jsp 1:1 — 노출 검색 필드 3개 - (고객사/프로젝트번호/유닛명 은 운영판에서도 주석 처리되어 노출 안 됨) */} -
- - setFilter((prev) => ({ - ...prev, - search_part_no: v, - // 품번 선택 시 품명 자동 채움 (wace select2-part 1:1) - search_part_name: row?.part_name ?? prev.search_part_name, - }))} /> - - - setFilter((prev) => ({ - ...prev, - search_part_name: v, - // 품명 선택 시 품번 자동 채움 - search_part_no: row?.part_no ?? prev.search_part_no, - }))} /> - - - setFilter({ ...filter, search_level: v })} - placeholder="전체" - /> - -
-
-
- 모드: {direction === "ascending" ? "정전개 (루트 → 리프)" : "역전개 (리프 → 부모)"} · {rows.length.toLocaleString()}행 · MAX_LEVEL = {maxLevel} -
-
- - - - - -
-
- {direction === "descending" && ( -
- 역전개는 품번 또는 품명 검색 조건이 필요합니다. -
- )} -
+
+ + + + + + + } /> -
+ {/* 운영판 wace structureAscendingList.jsp 1:1 — 노출 검색 필드 3개 + (고객사/프로젝트번호/유닛명 은 운영판에서도 주석 처리되어 노출 안 됨) */} + { setFilter(EMPTY_FILTER); setRows([]); setMaxLevel(0); }} + totalText={<>모드: {direction === "ascending" ? "정전개 (루트 → 리프)" : "역전개 (리프 → 부모)"} · {rows.length.toLocaleString()}행 · MAX_LEVEL = {maxLevel}} + > + + setFilter((prev) => ({ + ...prev, + search_part_no: v, + // 품번 선택 시 품명 자동 채움 (wace select2-part 1:1) + search_part_name: row?.part_name ?? prev.search_part_name, + }))} /> + + + setFilter((prev) => ({ + ...prev, + search_part_name: v, + // 품명 선택 시 품번 자동 채움 + search_part_no: row?.part_no ?? prev.search_part_no, + }))} /> + + + setFilter({ ...filter, search_level: v })} + placeholder="전체" + /> + + + + {direction === "descending" && ( +
+ 역전개는 품번 또는 품명 검색 조건이 필요합니다. +
+ )} + +
- - {children} -
- ); -} diff --git a/frontend/app/(main)/COMPANY_16/development/part-regist/page.tsx b/frontend/app/(main)/COMPANY_16/development/part-regist/page.tsx index ca80b6d6..a84f37da 100644 --- a/frontend/app/(main)/COMPANY_16/development/part-regist/page.tsx +++ b/frontend/app/(main)/COMPANY_16/development/part-regist/page.tsx @@ -7,10 +7,10 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; +import { PageHeader } from "@/components/common/PageHeader"; +import { CompactFilterBar, CompactFilterField } from "@/components/common/CompactFilterBar"; import { - Search, Loader2, RotateCcw, Plus, Pencil, Trash2, CheckSquare, FileSpreadsheet, + Plus, Pencil, Trash2, CheckSquare, FileSpreadsheet, } from "lucide-react"; import { toast } from "sonner"; import { DataGrid, DataGridColumn } from "@/components/common/DataGrid"; @@ -155,71 +155,62 @@ export default function PartRegistPage() { }; return ( -
- {/* 검색폼 — wace partMngTempList.jsp 활성 2필드 */} -
-
- {/* wace partMngTempList.jsp 1:1 — select2-part 자동완성 (양방향 동기) */} -
- - setFilter((prev) => ({ - ...prev, - search_part_no: v, - search_part_name: row?.part_name ?? prev.search_part_name, - }))} /> -
-
- - setFilter((prev) => ({ - ...prev, - search_part_name: v, - search_part_no: row?.part_no ?? prev.search_part_no, - }))} /> -
-
- - - - - - - r.part_no).filter(Boolean) as string[]} - onUploaded={() => fetchList()} - /> - -
-
-
- 총 {total.toLocaleString()}건 (M1: status ≠ 'release') -
-
+
+ + + + + + r.part_no).filter(Boolean) as string[]} + onUploaded={() => fetchList()} + /> + + + } /> -
+ fetchList()} + onReset={() => { setFilter(EMPTY_FILTER); fetchList(EMPTY_FILTER); }} + totalText={<>총 {total.toLocaleString()}건 (M1: status ≠ 'release')} + > + + setFilter((prev) => ({ + ...prev, + search_part_no: v, + search_part_name: row?.part_name ?? prev.search_part_name, + }))} /> + + + setFilter((prev) => ({ + ...prev, + search_part_name: v, + search_part_no: row?.part_no ?? prev.search_part_no, + }))} /> + + + +
-
-
- {/* wace partMngList.jsp 1:1 — select2-part 자동완성 (양방향 동기) */} -
- - setFilter((prev) => ({ - ...prev, - search_part_no: v, - search_part_name: row?.part_name ?? prev.search_part_name, - }))} /> -
-
- - setFilter((prev) => ({ - ...prev, - search_part_name: v, - search_part_no: row?.part_no ?? prev.search_part_no, - }))} /> -
-
- - - - - - - {/* M2 조회 — partNoList 미전달: IS_LAST='1' 전체 part_mng 매칭 (페이지 밖도 허용) */} - fetchList()} /> -
-
-
- 총 {total.toLocaleString()}건 (M2: status = 'release') -
-
+
+ + + + + + {/* M2 조회 — partNoList 미전달: IS_LAST='1' 전체 part_mng 매칭 (페이지 밖도 허용) */} + fetchList()} /> + + } /> -
+ fetchList()} + onReset={() => { setFilter(EMPTY_FILTER); fetchList(EMPTY_FILTER); }} + totalText={<>총 {total.toLocaleString()}건 (M2: status = 'release')} + > + + setFilter((prev) => ({ + ...prev, + search_part_no: v, + search_part_name: row?.part_name ?? prev.search_part_name, + }))} /> + + + setFilter((prev) => ({ + ...prev, + search_part_name: v, + search_part_no: row?.part_no ?? prev.search_part_no, + }))} /> + + + +
- {/* 검색폼 — wace projectMgmtWbsList3.jsp:222-313 활성 11필드 */} -
-
- {/* 1행 */} - - setFilter({ ...filter, Year: v })} - placeholder="전체" - /> - - - setFilter({ ...filter, project_nos: v })} - placeholder="전체" - /> - - - setFilter({ ...filter, category_cd: v })} - /> - - - setFilter({ ...filter, customer_objid: v })} - /> - - - setFilter({ ...filter, product: v })} - /> - - -
- setFilter({ ...filter, contract_start_date: e.target.value })} /> - ~ - setFilter({ ...filter, contract_end_date: e.target.value })} /> -
-
+
+ - {/* 2행 */} - - setFilter({ ...filter, area_cd: v })} - placeholder="전체" - /> - - - setFilter({ ...filter, free_of_charge: v })} - placeholder="전체" - /> - - - setFilter({ ...filter, search_partObjId: v })} - /> - - - setFilter({ ...filter, search_partObjId: v })} - /> - - - setFilter({ ...filter, serial_no: e.target.value })} - placeholder="S/N LIKE" - /> - + 총 {rows.length.toLocaleString()}건} + > + + setFilter({ ...filter, Year: v })} + placeholder="전체" + /> + + + setFilter({ ...filter, project_nos: v })} + placeholder="전체" + /> + + + setFilter({ ...filter, category_cd: v })} + /> + + + setFilter({ ...filter, customer_objid: v })} + /> + + + setFilter({ ...filter, product: v })} + /> + + + setFilter({ ...filter, area_cd: v })} + placeholder="전체" + /> + + + setFilter({ ...filter, free_of_charge: v })} + placeholder="전체" + /> + + + setFilter({ ...filter, search_partObjId: v })} + /> + + + setFilter({ ...filter, search_partObjId: v })} + /> + + + setFilter({ ...filter, serial_no: e.target.value })} + placeholder="S/N LIKE" + /> + + + setFilter({ ...filter, contract_start_date: v })} + to={filter.contract_end_date ?? ""} + setTo={(v) => setFilter({ ...filter, contract_end_date: v })} + /> + + - {/* 액션 */} -
- - -
-
-
- - {/* 그리드 (8그룹 18셀 평탄화) */} -
+
); } - -function Field({ label, children }: { label: string; children: React.ReactNode }) { - return ( -
- - {children} -
- ); -} diff --git a/frontend/app/(main)/COMPANY_16/project/wbs-template/page.tsx b/frontend/app/(main)/COMPANY_16/project/wbs-template/page.tsx index c3d747cb..b3bd66ca 100644 --- a/frontend/app/(main)/COMPANY_16/project/wbs-template/page.tsx +++ b/frontend/app/(main)/COMPANY_16/project/wbs-template/page.tsx @@ -12,11 +12,12 @@ import React, { useCallback, useEffect, useState } from "react"; import { Button } from "@/components/ui/button"; -import { Search, Loader2, RotateCcw, Plus, Trash2 } from "lucide-react"; +import { Plus, Trash2 } from "lucide-react"; import { toast } from "sonner"; import { DataGrid, DataGridColumn } from "@/components/common/DataGrid"; import { CommCodeSelect } from "@/components/common/CommCodeSelect"; -import { Label } from "@/components/ui/label"; +import { PageHeader } from "@/components/common/PageHeader"; +import { CompactFilterBar, CompactFilterField } from "@/components/common/CompactFilterBar"; import { wbsTemplateApi, TemplateRow } from "@/lib/api/wbsTemplate"; import { WbsTemplateDialog } from "@/components/project/WbsTemplateDialog"; @@ -110,43 +111,34 @@ export default function WbsTemplatePage() { ); return ( -
- {/* 검색폼 — wace wbsTemplateMngList.jsp:361-371 (제품구분 1필드) */} -
-
-
- - -
-
- - - - -
-
-
+
+ + + + + } /> - {/* 그리드 (5컬럼) */} -
+ 총 {rows.length.toLocaleString()}건} + > + + + + + +
setSearchForm({ + category_cd: "", customer_objid: "", + search_partObjId: "", search_partName: "", search_serialNo: "", + appr_status: "", + receipt_start_date: "", receipt_end_date: "", + }); + return ( -
+
{ConfirmDialogComponent} - {/* 헤더 */} -
-
-

영업관리 _ 견적관리

-

총 {rows.length}건

-
-
- - - - - - - -
-
+ + } /> - {/* 검색 폼 — wace 원본 estimateList_new.jsp 활성 7개 */} -
-
- + 총 {rows.length.toLocaleString()}건} + > + setSearchForm({ ...searchForm, category_cd: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, category_cd: v })} /> + + setSearchForm({ ...searchForm, customer_objid: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, customer_objid: v })} /> + + setSearchForm({ ...searchForm, search_partObjId: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, search_partObjId: v })} /> + + setSearchForm({ ...searchForm, search_partObjId: v })} - className="h-8 text-xs" /> -
-
- - setSearchForm({ ...searchForm, search_partObjId: v })} /> + + + setSearchForm({ ...searchForm, search_serialNo: e.target.value })} /> -
-
- - -
-
- -
- setSearchForm({ ...searchForm, receipt_start_date: e.target.value })} /> - ~ - setSearchForm({ ...searchForm, receipt_end_date: e.target.value })} /> -
-
-
+ + + setSearchForm({ ...searchForm, appr_status: v })} + placeholder="전체" + /> + + + setSearchForm({ ...searchForm, receipt_start_date: v })} + to={searchForm.receipt_end_date} + setTo={(v) => setSearchForm({ ...searchForm, receipt_end_date: v })} + /> + + {/* 그리드 — 첫 컬럼 체크박스 (행 아무 셀 클릭으로 단일 선택, 클립/폴더 등 팝업 컬럼은 stopPropagation으로 제외) */} setSearchForm({ + category_cd: "", search_poNo: "", customer_objid: "", + search_partObjId: "", search_partName: "", search_serialNo: "", contract_result: "", + order_start_date: "", order_end_date: "", + due_start_date: "", due_end_date: "", + }); + return ( -
+
{ConfirmDialogComponent} -
-
-

주문서관리

-

총 {rows.length}건

-
-
- - - - - - - - -
-
+ + } /> - {/* 검색 폼 — wace 원본 orderMgmtList.jsp 활성 9개 */} -
-
- + 총 {rows.length.toLocaleString()}건} + > + setSearchForm({ ...searchForm, category_cd: v })} - className="h-8 text-xs" /> -
-
- - setSearchForm({ ...searchForm, category_cd: v })} /> + + + setSearchForm({ ...searchForm, search_poNo: e.target.value })} /> -
-
- + + setSearchForm({ ...searchForm, customer_objid: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, customer_objid: v })} /> + + setSearchForm({ ...searchForm, search_partObjId: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, search_partObjId: v })} /> + + setSearchForm({ ...searchForm, search_partObjId: v })} - className="h-8 text-xs" /> -
-
- - setSearchForm({ ...searchForm, search_partObjId: v })} /> + + + setSearchForm({ ...searchForm, search_serialNo: e.target.value })} /> -
-
- + + setSearchForm({ ...searchForm, contract_result: v })} - className="h-8 text-xs" /> -
- {/* 2줄 */} -
- -
- setSearchForm({ ...searchForm, order_start_date: e.target.value })} /> - ~ - setSearchForm({ ...searchForm, order_end_date: e.target.value })} /> -
-
-
- -
- setSearchForm({ ...searchForm, due_start_date: e.target.value })} /> - ~ - setSearchForm({ ...searchForm, due_end_date: e.target.value })} /> -
-
-
+ onValueChange={(v) => setSearchForm({ ...searchForm, contract_result: v })} /> + + + setSearchForm({ ...searchForm, order_start_date: v })} + to={searchForm.order_end_date} + setTo={(v) => setSearchForm({ ...searchForm, order_end_date: v })} + /> + + + setSearchForm({ ...searchForm, due_start_date: v })} + to={searchForm.due_end_date} + setTo={(v) => setSearchForm({ ...searchForm, due_end_date: v })} + /> + + setSearchForm({ + orderType: "", poNo: "", customer_objid: "", + productType: "", search_partObjId: "", nation: "", + serialNo: "", + salesDeadlineFrom: "", salesDeadlineTo: "", + orderDateFrom: "", orderDateTo: "", + shippingDateFrom: "", shippingDateTo: "", + }); + return ( -
+
{ConfirmDialogComponent} -
-
-

매출관리

-

총 {rows.length}건 (출하/매출 이력)

-
-
- - - - -
-
+ + } /> - {/* 검색 폼 — wace 원본 revenueMgmtList.jsp 활성 11개 */} -
-
- + 총 {rows.length.toLocaleString()}건 (출하/매출 이력)} + > + setSearchForm({ ...searchForm, orderType: v })} - className="h-8 text-xs" /> -
-
- - setSearchForm({ ...searchForm, orderType: v })} /> + + + setSearchForm({ ...searchForm, poNo: e.target.value })} /> -
-
- + + setSearchForm({ ...searchForm, customer_objid: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, customer_objid: v })} /> + + setSearchForm({ ...searchForm, productType: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, productType: v })} /> + + setSearchForm({ ...searchForm, search_partObjId: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, search_partObjId: v })} /> + + setSearchForm({ ...searchForm, search_partObjId: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, search_partObjId: v })} /> + + setSearchForm({ ...searchForm, nation: v })} - className="h-8 text-xs" /> -
- {/* 2줄 */} -
- - setSearchForm({ ...searchForm, nation: v })} /> + + + setSearchForm({ ...searchForm, serialNo: e.target.value })} /> -
-
- -
- setSearchForm({ ...searchForm, salesDeadlineFrom: e.target.value })} /> - ~ - setSearchForm({ ...searchForm, salesDeadlineTo: e.target.value })} /> -
-
-
- -
- setSearchForm({ ...searchForm, orderDateFrom: e.target.value })} /> - ~ - setSearchForm({ ...searchForm, orderDateTo: e.target.value })} /> -
-
-
- -
- setSearchForm({ ...searchForm, shippingDateFrom: e.target.value })} /> - ~ - setSearchForm({ ...searchForm, shippingDateTo: e.target.value })} /> -
-
-
+ + + setSearchForm({ ...searchForm, salesDeadlineFrom: v })} + to={searchForm.salesDeadlineTo} + setTo={(v) => setSearchForm({ ...searchForm, salesDeadlineTo: v })} + /> + + + setSearchForm({ ...searchForm, orderDateFrom: v })} + to={searchForm.orderDateTo} + setTo={(v) => setSearchForm({ ...searchForm, orderDateTo: v })} + /> + + + setSearchForm({ ...searchForm, shippingDateFrom: v })} + to={searchForm.shippingDateTo} + setTo={(v) => setSearchForm({ ...searchForm, shippingDateTo: v })} + /> + + -
-
-

판매관리

-

총 {rows.length}건 (라인 단위)

-
-
- - - -
-
+ const shippingStatusOpts: SmartSelectOption[] = [ + { code: "PENDING", label: "대기" }, + { code: "COMPLETED", label: "완료" }, + { code: "CANCELLED", label: "취소" }, + ]; - {/* 검색 폼 — wace 원본 salesMgmtList.jsp 재현 (1줄 7개 / 2줄 3개) */} -
-
- + const handleReset = () => setSearchForm({ + orderType: "", poNo: "", customer_objid: "", search_partObjId: "", + serialNo: "", shippingStatus: "", salesStatus: "", + orderDateFrom: "", orderDateTo: "", + shippingDateFrom: "", shippingDateTo: "", + }); + + return ( +
+ + 출하지시/판매등록 + + } /> + + 총 {rows.length.toLocaleString()}건 (라인 단위)} + > + setSearchForm({ ...searchForm, orderType: v })} - className="h-8 text-xs" /> -
-
- - setSearchForm({ ...searchForm, orderType: v })} /> + + + setSearchForm({ ...searchForm, poNo: e.target.value })} /> -
-
- + + setSearchForm({ ...searchForm, customer_objid: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, customer_objid: v })} /> + + setSearchForm({ ...searchForm, search_partObjId: v })} - className="h-8 text-xs" /> -
-
- + onValueChange={(v) => setSearchForm({ ...searchForm, search_partObjId: v })} /> + + setSearchForm({ ...searchForm, search_partObjId: v })} - className="h-8 text-xs" /> -
-
- - setSearchForm({ ...searchForm, search_partObjId: v })} /> + + + setSearchForm({ ...searchForm, serialNo: e.target.value })} /> -
-
- - -
- {/* 2줄 */} -
- -
- setSearchForm({ ...searchForm, orderDateFrom: e.target.value })} /> - ~ - setSearchForm({ ...searchForm, orderDateTo: e.target.value })} /> -
-
-
- -
- setSearchForm({ ...searchForm, shippingDateFrom: e.target.value })} /> - ~ - setSearchForm({ ...searchForm, shippingDateTo: e.target.value })} /> -
-
-
- + + + setSearchForm({ ...searchForm, shippingStatus: v })} + placeholder="전체" + /> + + setSearchForm({ ...searchForm, salesStatus: v })} - className="h-8 text-xs" /> -
-
+ onValueChange={(v) => setSearchForm({ ...searchForm, salesStatus: v })} /> + + + setSearchForm({ ...searchForm, orderDateFrom: v })} + to={searchForm.orderDateTo} + setTo={(v) => setSearchForm({ ...searchForm, orderDateTo: v })} + /> + + + setSearchForm({ ...searchForm, shippingDateFrom: v })} + to={searchForm.shippingDateTo} + setTo={(v) => setSearchForm({ ...searchForm, shippingDateTo: v })} + /> + +