From 59b5715ebb3e1fd7bd4eb02ce50399715734f865 Mon Sep 17 00:00:00 2001 From: 0-Zz-ang Date: Mon, 4 Aug 2025 14:59:15 +0900 Subject: (박서영) docu-list-rule detail sheet 컴포넌트 추가 및 검색 필터 기능 오류 수정 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../table/document-class-options-sheet.tsx | 436 --------------------- 1 file changed, 436 deletions(-) delete mode 100644 lib/docu-list-rule/combo-box-settings/table/document-class-options-sheet.tsx (limited to 'lib/docu-list-rule/combo-box-settings/table/document-class-options-sheet.tsx') diff --git a/lib/docu-list-rule/combo-box-settings/table/document-class-options-sheet.tsx b/lib/docu-list-rule/combo-box-settings/table/document-class-options-sheet.tsx deleted file mode 100644 index 8585d9a3..00000000 --- a/lib/docu-list-rule/combo-box-settings/table/document-class-options-sheet.tsx +++ /dev/null @@ -1,436 +0,0 @@ -"use client" - -import * as React from "react" -import { useState, useEffect } from "react" -import { Plus, Trash2, Save, X } from "lucide-react" -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import { - Sheet, - SheetContent, - SheetDescription, - SheetHeader, - SheetTitle, -} from "@/components/ui/sheet" -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/ui/table" -import { toast } from "sonner" -import { - getDocumentClassOptions, - createDocumentClassOption, - updateDocumentClassOption, - deleteDocumentClassOption -} from "../service" - -interface DocumentClassOptionsSheetProps { - open: boolean - onOpenChange: (open: boolean) => void - comboBoxOption: { - id: number - code: string - description: string - } - onSuccess: () => void -} - -interface DocumentClassOption { - id: number - comboBoxSettingId: number - optionValue: string - optionCode: string | null - sortOrder: number - isActive: boolean - createdAt: Date - updatedAt: Date -} - -interface NewOptionRow { - id: string - optionValue: string - optionCode: string - sortOrder: number -} - -export function DocumentClassOptionsSheet({ - open, - onOpenChange, - comboBoxOption, - onSuccess -}: DocumentClassOptionsSheetProps) { - const [options, setOptions] = useState([]) - const [loading, setLoading] = useState(true) - const [newOptionRows, setNewOptionRows] = useState([]) - const [editingOption, setEditingOption] = useState(null) - - // 하위 옵션 목록 로드 - const loadOptions = async () => { - try { - setLoading(true) - const result = await getDocumentClassOptions(comboBoxOption.id) - if (result.success && result.data) { - setOptions(result.data) - } else { - toast.error("하위 옵션 목록을 불러오는데 실패했습니다.") - } - } catch (error) { - console.error("하위 옵션 로드 실패:", error) - toast.error("하위 옵션 목록을 불러오는데 실패했습니다.") - } finally { - setLoading(false) - } - } - - useEffect(() => { - if (open) { - loadOptions() - } - }, [open, comboBoxOption.id]) - - // 새 행 추가 - const addNewRow = () => { - const newRow: NewOptionRow = { - id: `new-${Date.now()}-${Math.random()}`, - optionValue: "", - optionCode: "", - sortOrder: options.length + newOptionRows.length + 1, - } - setNewOptionRows(prev => [...prev, newRow]) - } - - // 새 행 삭제 - const removeNewRow = (id: string) => { - setNewOptionRows(prev => prev.filter(row => row.id !== id)) - } - - // 새 행 업데이트 - const updateNewRow = (id: string, field: keyof NewOptionRow, value: string | number) => { - setNewOptionRows(prev => - prev.map(row => - row.id === id ? { ...row, [field]: value } : row - ) - ) - } - - // 새 하위 옵션 저장 - const handleSaveNewOptions = async () => { - const validRows = newOptionRows.filter(row => row.optionValue.trim()) - - if (validRows.length === 0) { - toast.error("최소 하나의 옵션 값을 입력해주세요.") - return - } - - try { - let successCount = 0 - let errorCount = 0 - - for (const row of validRows) { - try { - const result = await createDocumentClassOption({ - comboBoxSettingId: comboBoxOption.id, - optionValue: row.optionValue.trim(), - optionCode: row.optionCode.trim() || undefined, - sortOrder: row.sortOrder, - }) - - if (result.success) { - successCount++ - } else { - errorCount++ - } - } catch (error) { - console.error("하위 옵션 추가 실패:", error) - errorCount++ - } - } - - if (successCount > 0) { - toast.success(`${successCount}개의 하위 옵션이 추가되었습니다.${errorCount > 0 ? ` (${errorCount}개 실패)` : ''}`) - setNewOptionRows([]) - await loadOptions() - onSuccess() - } else { - toast.error("모든 하위 옵션 추가에 실패했습니다.") - } - } catch (error) { - console.error("하위 옵션 추가 실패:", error) - toast.error("하위 옵션 추가에 실패했습니다.") - } - } - - // 기존 하위 옵션 수정 - const handleUpdateOption = async (option: DocumentClassOption) => { - if (!option.optionValue.trim()) { - toast.error("옵션 값은 필수 입력 항목입니다.") - return - } - - try { - const result = await updateDocumentClassOption({ - id: option.id, - optionValue: option.optionValue.trim(), - optionCode: option.optionCode || undefined, - sortOrder: option.sortOrder, - isActive: option.isActive, - }) - - if (result.success) { - await loadOptions() - setEditingOption(null) - toast.success("하위 옵션이 수정되었습니다.") - } else { - toast.error("하위 옵션 수정에 실패했습니다.") - } - } catch (error) { - console.error("하위 옵션 수정 실패:", error) - toast.error("하위 옵션 수정에 실패했습니다.") - } - } - - // 하위 옵션 삭제 - const handleDeleteOption = async (optionId: number) => { - if (!confirm("정말로 이 하위 옵션을 삭제하시겠습니까?")) { - return - } - - try { - const result = await deleteDocumentClassOption(optionId) - if (result.success) { - await loadOptions() - toast.success("하위 옵션이 삭제되었습니다.") - } else { - toast.error("하위 옵션 삭제에 실패했습니다.") - } - } catch (error) { - console.error("하위 옵션 삭제 실패:", error) - toast.error("하위 옵션 삭제에 실패했습니다.") - } - } - - return ( - - - - 하위 옵션 관리 - - {comboBoxOption.description} ({comboBoxOption.code})의 하위 옵션을 관리합니다. - - - -
- {/* 새 하위 옵션 추가 */} -
-
-

새 하위 옵션 추가

- -
- - {newOptionRows.length > 0 && ( -
- - - - 옵션 값 * - 옵션 코드 - 순서 - - - - - {newOptionRows.map((row) => ( - - - updateNewRow(row.id, "optionValue", e.target.value)} - placeholder="옵션 값" - className="border-0 focus-visible:ring-1 bg-transparent h-8" - /> - - - updateNewRow(row.id, "optionCode", e.target.value)} - placeholder="옵션 코드 (선택)" - className="border-0 focus-visible:ring-1 bg-transparent h-8" - /> - - - updateNewRow(row.id, "sortOrder", parseInt(e.target.value) || 0)} - className="border-0 focus-visible:ring-1 bg-transparent h-8" - /> - - - - - - ))} - -
-
- -
-
- )} -
- - {/* 기존 하위 옵션 목록 */} -
-

기존 하위 옵션

-
- - - - 옵션 값 - 옵션 코드 - 순서 - 상태 - 작업 - - - - {loading ? ( - - - 로딩 중... - - - ) : options.length === 0 ? ( - - - 등록된 하위 옵션이 없습니다. - - - ) : ( - options.map((option) => ( - - - {editingOption?.id === option.id ? ( - setEditingOption(prev => prev ? { ...prev, optionValue: e.target.value } : null)} - placeholder="옵션 값" - className="border-0 focus-visible:ring-1 bg-transparent h-8" - /> - ) : ( - option.optionValue - )} - - - {editingOption?.id === option.id ? ( - setEditingOption(prev => prev ? { ...prev, optionCode: e.target.value } : null)} - placeholder="옵션 코드" - className="border-0 focus-visible:ring-1 bg-transparent h-8" - /> - ) : ( - option.optionCode || "-" - )} - - - {editingOption?.id === option.id ? ( - setEditingOption(prev => prev ? { ...prev, sortOrder: parseInt(e.target.value) || 0 } : null)} - className="border-0 focus-visible:ring-1 bg-transparent h-8" - /> - ) : ( - option.sortOrder - )} - - - - {option.isActive ? "활성" : "비활성"} - - - - {editingOption?.id === option.id ? ( -
- - -
- ) : ( -
- - -
- )} -
-
- )) - )} -
-
-
-
-
-
-
- ) -} \ No newline at end of file -- cgit v1.2.3