Files
wace_rps/frontend/components/common/CommCodeSelect.tsx
T
hjjeong 489fa50d11 영업관리 4개 메뉴 검색폼 wace 일치 + 공통 UX(초기화·date input) 정비
- 검색 폼 정합성: wace JSP `<!-- 주석처리된 검색필터 -->` 블록까지 잘못 이식했던 부분 정정
  - 견적: 11→7개 (제품구분/국내해외/유무상/요청납기 제거)
  - 주문: 13→9개 (제품구분/국내해외/유무상/견적환종 제거)
  - 매출: 10→11개 (출하지시상태 제거 + 제품구분·국내/해외 추가, JSP 순서로 재배치)
  - 판매: 변경 없음 (원본 그대로 일치)
- 매출 백엔드: SaleListFilter에 productType/nation 추가, getRevenueList에 partObjId/serialNo/orderDate/productType/nation 5개 필터 처리
- 공통 UX
  - 초기화 버튼을 4개 메뉴 동일하게 통일 (variant=ghost, 버튼 영역 끝)
  - <Input type="date">는 빈 값 placeholder 숨김 + 캘린더 아이콘 숨김 + 영역 클릭으로 picker 자동(showPicker)
- 신규 공통 컴포넌트: CommCodeSelect/CustomerSelect/CustomerSearchDialog/PartSelect/ItemSearchDialog + backend salesCommonRoutes
- 문서: 01/02/04 검색 폼 표를 활성/비활성 분리 형식으로 정정, README에 8. 공통 UX 규칙 섹션 신설

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 10:42:16 +09:00

83 lines
2.4 KiB
TypeScript

"use client";
import React, { useEffect, useState } from "react";
import { SmartSelect, SmartSelectOption } from "@/components/common/SmartSelect";
import { apiClient } from "@/lib/api/client";
/**
* 영업관리 4개 메뉴 공통: wace_plm comm_code 그룹키 단위 옵션 셀렉트.
*
* group_id (parent_code_id) 별 알려진 키:
* - 0000167: 주문유형 (category_cd)
* - 0000001: 제품구분 (product)
* - 0001219: 국내/해외 (area_cd)
* - 0000156: 유/무상 (paid_type, code_id 0000157=유상, 0000158=무상)
* - 0000963: 수주상태 (contract_result)
* - 0001533: 환종 (contract_currency)
* - 0900207: 판매상태
* - 0900215: 과세구분 (tax_type)
*/
interface CommCodeSelectProps {
groupId: string;
value: string;
onValueChange: (value: string) => void;
placeholder?: string;
/** "전체" 옵션을 맨 앞에 추가 (기본 true) */
withAll?: boolean;
disabled?: boolean;
className?: string;
}
const cache = new Map<string, SmartSelectOption[]>();
const inflight = new Map<string, Promise<SmartSelectOption[]>>();
const fetchGroup = async (groupId: string): Promise<SmartSelectOption[]> => {
if (cache.has(groupId)) return cache.get(groupId)!;
if (inflight.has(groupId)) return inflight.get(groupId)!;
const p = (async () => {
const res = await apiClient.get(`/sales/codes/${groupId}`);
const rows = (res.data?.data ?? []) as Array<{ code: string; label: string }>;
const opts = rows
.filter((r) => r.code)
.map((r) => ({ code: r.code, label: r.label || r.code }));
cache.set(groupId, opts);
return opts;
})();
inflight.set(groupId, p);
try {
return await p;
} finally {
inflight.delete(groupId);
}
};
export function CommCodeSelect({
groupId, value, onValueChange,
placeholder = "전체",
withAll = true,
disabled, className,
}: CommCodeSelectProps) {
const [options, setOptions] = useState<SmartSelectOption[]>(cache.get(groupId) ?? []);
useEffect(() => {
let alive = true;
fetchGroup(groupId)
.then((opts) => { if (alive) setOptions(opts); })
.catch(() => {});
return () => { alive = false; };
}, [groupId]);
// SmartSelect 자체는 빈 string value 처리 못함 → withAll은 placeholder로 표현
return (
<SmartSelect
options={options}
value={value}
onValueChange={onValueChange}
placeholder={placeholder}
disabled={disabled}
className={className}
/>
);
}