summaryrefslogtreecommitdiff
path: root/lib/avl/table/avl-table.tsx
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-09-23 20:05:46 +0900
committerjoonhoekim <26rote@gmail.com>2025-09-23 20:05:46 +0900
commit3cde5c2c7d157bb0fe353de5e67e4b35506bb4e2 (patch)
treeea2dd4927ce79543317ad5fc37a45d4bf193f670 /lib/avl/table/avl-table.tsx
parenta72c894c5b65b45f99fe03770f2d54098c5507c3 (diff)
(김준회) Vendorpool 수정요청사항
- 컬럼리사이징 관련 문제 해결 - 공통컴포넌트에 columnResizeMode: "onChange" 속성 추가
Diffstat (limited to 'lib/avl/table/avl-table.tsx')
-rw-r--r--lib/avl/table/avl-table.tsx187
1 files changed, 6 insertions, 181 deletions
diff --git a/lib/avl/table/avl-table.tsx b/lib/avl/table/avl-table.tsx
index 45da6268..61db658d 100644
--- a/lib/avl/table/avl-table.tsx
+++ b/lib/avl/table/avl-table.tsx
@@ -12,7 +12,7 @@ import { Button } from "@/components/ui/button"
import { toast } from "sonner"
import { getColumns } from "./avl-table-columns"
-import { updateAvlListAction, deleteAvlListAction, handleAvlActionAction } from "../service"
+import { handleAvlActionAction } from "../service"
import type { AvlListItem } from "../types"
import { AvlHistoryModal, type AvlHistoryRecord } from "@/lib/avl/components/avl-history-modal"
import { getAvlHistory } from "@/lib/avl/history-service"
@@ -33,21 +33,16 @@ declare module "@tanstack/react-table" {
interface AvlTableProps {
data: AvlListItem[]
pageCount?: number
- onRefresh?: () => void // 데이터 새로고침 콜백
isLoading?: boolean // 로딩 상태
onRegistrationModeChange?: (mode: 'standard' | 'project') => void // 등록 모드 변경 콜백
onRowSelect?: (selectedRow: AvlListItem | null) => void // 행 선택 콜백
}
-export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistrationModeChange, onRowSelect }: AvlTableProps) {
+export function AvlTable({ data, pageCount, isLoading, onRegistrationModeChange, onRowSelect }: AvlTableProps) {
// 단일 선택을 위한 상태 (shi-vendor-po 방식)
const [selectedRows, setSelectedRows] = React.useState<number[]>([])
- // 수정사항 추적 (일괄 저장용)
- const [pendingChanges, setPendingChanges] = React.useState<Record<string, Partial<AvlListItem>>>({})
- const [isSaving, setIsSaving] = React.useState(false)
-
// 히스토리 모달 관리
const [historyModalOpen, setHistoryModalOpen] = React.useState(false)
const [selectedAvlItem, setSelectedAvlItem] = React.useState<AvlListItem | null>(null)
@@ -101,56 +96,6 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
},
]
-
- // 인라인 편집 핸들러 (일괄 저장용)
- const handleCellUpdate = React.useCallback(async (id: string, field: keyof AvlListItem, newValue: string | boolean) => {
- const isEmptyRow = String(id).startsWith('temp-')
-
- if (isEmptyRow) {
- // 빈 행의 경우 pendingChanges 상태도 업데이트
- setPendingChanges(prev => ({
- ...prev,
- [id]: {
- ...prev[id],
- [field]: newValue
- }
- }))
- }
-
- // pendingChanges에 변경사항 저장 (실시간 표시용)
- setPendingChanges(prev => ({
- ...prev,
- [id]: {
- ...prev[id],
- [field]: newValue
- }
- }))
- }, [])
-
- // 편집 취소 핸들러
- const handleCellCancel = React.useCallback((id: string, field: keyof AvlListItem) => {
- const isEmptyRow = String(id).startsWith('temp-')
-
- if (isEmptyRow) {
- // 빈 행의 경우 pendingChanges 취소
- setPendingChanges(prev => {
- const itemChanges = { ...prev[id] }
- delete itemChanges[field]
-
- if (Object.keys(itemChanges).length === 0) {
- const newChanges = { ...prev }
- delete newChanges[id]
- return newChanges
- }
-
- return {
- ...prev,
- [id]: itemChanges
- }
- })
- }
- }, [])
-
// 액션 핸들러
const handleAction = React.useCallback(async (action: string, data?: Partial<AvlListItem>) => {
try {
@@ -166,89 +111,6 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
}
break
- case 'project-registration':
- // 프로젝트 AVL 등록
- const projectResult = await handleAvlActionAction('project-registration')
- if (projectResult.success) {
- toast.success(projectResult.message)
- onRegistrationModeChange?.('project') // 등록 모드 변경 콜백 호출
- } else {
- toast.error(projectResult.message)
- }
- break
-
- case 'bulk-import':
- // 일괄 입력
- const bulkResult = await handleAvlActionAction('bulk-import')
- if (bulkResult.success) {
- toast.success(bulkResult.message)
- } else {
- toast.error(bulkResult.message)
- }
- break
-
- case 'save':
- // 변경사항 저장
- if (Object.keys(pendingChanges).length === 0) {
- toast.info("저장할 변경사항이 없습니다.")
- return
- }
-
- setIsSaving(true)
- try {
- // 각 변경사항을 순차적으로 저장
- for (const [id, changes] of Object.entries(pendingChanges)) {
- if (String(id).startsWith('temp-')) continue // 빈 행은 제외
-
- // id 속성을 명시적으로 추가
- const updateData = {
- ...changes,
- id: Number(id)
- }
-
- const result = await updateAvlListAction(Number(id), updateData)
- if (!result) {
- throw new Error(`항목 ${id} 저장 실패`)
- }
- }
-
- setPendingChanges({})
- toast.success("변경사항이 저장되었습니다.")
- onRefresh?.()
- } catch (error) {
- console.error('저장 실패:', error)
- toast.error("저장 중 오류가 발생했습니다.")
- } finally {
- setIsSaving(false)
- }
- break
-
- case 'edit':
- // 수정 모달 열기 (현재는 간단한 토스트로 처리)
- toast.info(`${data?.id} 항목 수정`)
- break
-
- case 'delete':
- // 삭제 확인 및 실행
- if (!data?.id || String(data.id).startsWith('temp-')) return
-
- const confirmed = window.confirm(`항목 ${data.id}을(를) 삭제하시겠습니까?`)
- if (!confirmed) return
-
- try {
- const result = await deleteAvlListAction(Number(data.id))
- if (result) {
- toast.success("항목이 삭제되었습니다.")
- onRefresh?.()
- } else {
- toast.error("삭제에 실패했습니다.")
- }
- } catch (error) {
- console.error('삭제 실패:', error)
- toast.error("삭제 중 오류가 발생했습니다.")
- }
- break
-
case 'view-detail':
// 상세 조회 (페이지 이동)
if (data?.id && !String(data.id).startsWith('temp-')) {
@@ -271,7 +133,7 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
console.error('액션 처리 실패:', error)
toast.error("액션 처리 중 오류가 발생했습니다.")
}
- }, [pendingChanges, onRefresh, onRegistrationModeChange])
+ }, [onRegistrationModeChange])
// 빈 행 포함한 전체 데이터
const allData = React.useMemo(() => {
@@ -297,15 +159,6 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
}
}, [allData, onRowSelect])
- // 테이블 메타 설정
- const tableMeta = React.useMemo(() => ({
- onCellUpdate: handleCellUpdate,
- onCellCancel: handleCellCancel,
- onAction: handleAction,
- isEmptyRow: (id: string) => String(id).startsWith('temp-'),
- getPendingChanges: () => pendingChanges,
- }), [handleCellUpdate, handleCellCancel, handleAction, pendingChanges])
-
// 데이터 테이블 설정
const { table } = useDataTable({
@@ -320,14 +173,12 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
pageIndex: 0,
pageSize: 10,
},
+ // 기본 컬럼 사이즈 설정
+ columnSizing: {},
},
getRowId: (row) => String(row.id),
- meta: tableMeta,
})
- // 변경사항이 있는지 확인
- const hasPendingChanges = Object.keys(pendingChanges).length > 0
-
return (
<div className="space-y-4">
{/* 툴바 */}
@@ -353,31 +204,11 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
프로젝트AVL등록
</Button>
- {/* 저장 버튼 - 변경사항이 있을 때만 활성화 */}
- {(hasPendingChanges) && (
- <Button
- variant="default"
- size="sm"
- onClick={() => handleAction('save')}
- disabled={isSaving}
- >
- {isSaving ? "저장 중..." : "저장"}
- </Button>
- )}
-
- {/* 새로고침 버튼 */}
- <Button
- variant="outline"
- size="sm"
- onClick={onRefresh}
- >
- 새로고침
- </Button>
</div>
</DataTableAdvancedToolbar>
{/* 데이터 테이블 */}
- <DataTable table={table} />
+ <DataTable table={table} autoSizeColumns={false} />
{/* 히스토리 모달 */}
<AvlHistoryModal
@@ -390,12 +221,6 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
onLoadHistory={loadHistoryData}
/>
- {/* 디버그 정보 (개발 환경에서만 표시) */}
- {process.env.NODE_ENV === 'development' && (hasPendingChanges) && (
- <div className="text-xs text-muted-foreground p-2 bg-muted rounded">
- <div>Pending Changes: {Object.keys(pendingChanges).length}</div>
- </div>
- )}
</div>
)
}