feat: Enhance copy functionality for item inspection information

- Introduced state management for copy form and inspection rows to facilitate editing and copying of inspection data.
- Implemented logic to duplicate selected inspection data into a copy modal, allowing users to edit and manage copied information.
- Enhanced the copy process to include validation and user feedback, ensuring a smooth experience when copying inspection details to multiple target items.
- Updated the modal handling to support dynamic row management for copied inspection items, improving usability and flexibility.
This commit is contained in:
kjs
2026-04-21 10:31:40 +09:00
parent 51c4fddde0
commit e0b89036d0
16 changed files with 438 additions and 689 deletions
+15 -9
View File
@@ -47,9 +47,15 @@ export function SmartSelect({
const [search, setSearch] = useState("");
const scrollRef = useRef<HTMLDivElement | null>(null);
// code가 비어있는 옵션은 자동 제외 (Radix Select value 제약 + key 중복 방지)
const safeOptions = useMemo(
() => options.filter((o) => o.code !== null && o.code !== undefined && o.code !== ""),
[options],
);
const selectedLabel = useMemo(
() => options.find((o) => o.code === value)?.label,
[options, value],
() => safeOptions.find((o) => o.code === value)?.label,
[safeOptions, value],
);
// 팝오버 닫힐 때 검색어 리셋
@@ -60,9 +66,9 @@ export function SmartSelect({
// 검색어로 옵션 필터 (대소문자 무시)
const filtered = useMemo(() => {
const q = search.trim().toLowerCase();
if (!q) return options;
return options.filter((o) => o.label.toLowerCase().includes(q));
}, [options, search]);
if (!q) return safeOptions;
return safeOptions.filter((o) => o.label.toLowerCase().includes(q));
}, [safeOptions, search]);
const virtualizer = useVirtualizer({
count: filtered.length,
@@ -78,15 +84,15 @@ export function SmartSelect({
return () => cancelAnimationFrame(id);
}, [open, virtualizer, filtered.length]);
if (options.length < SEARCH_THRESHOLD) {
if (safeOptions.length < SEARCH_THRESHOLD) {
return (
<Select value={value} onValueChange={onValueChange} disabled={disabled}>
<SelectTrigger className={cn("h-9", className)}>
<SelectValue placeholder={placeholder} />
</SelectTrigger>
<SelectContent>
{options.map((o) => (
<SelectItem key={o.code} value={o.code}>
{safeOptions.map((o, idx) => (
<SelectItem key={`${o.code}-${idx}`} value={o.code}>
{o.label}
</SelectItem>
))}
@@ -146,7 +152,7 @@ export function SmartSelect({
const isSelected = value === o.code;
return (
<button
key={o.code}
key={`${o.code}-${vItem.index}`}
type="button"
onClick={() => {
onValueChange(o.code);