summaryrefslogtreecommitdiff
path: root/lib/avl/table/standard-avl-table.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/avl/table/standard-avl-table.tsx')
-rw-r--r--lib/avl/table/standard-avl-table.tsx146
1 files changed, 73 insertions, 73 deletions
diff --git a/lib/avl/table/standard-avl-table.tsx b/lib/avl/table/standard-avl-table.tsx
index cc39540b..bacb5812 100644
--- a/lib/avl/table/standard-avl-table.tsx
+++ b/lib/avl/table/standard-avl-table.tsx
@@ -15,6 +15,14 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "@/components/ui/dialog"
import { Search } from "lucide-react"
import { toast } from "sonner"
import { standardAvlColumns } from "./standard-avl-table-columns"
@@ -22,13 +30,9 @@ import { AvlVendorAddAndModifyDialog } from "./avl-vendor-add-and-modify-dialog"
import { createAvlVendorInfo, updateAvlVendorInfo, deleteAvlVendorInfo, finalizeStandardAvl } from "../service"
import { AvlVendorInfoInput } from "../types"
import { useSession } from "next-auth/react"
+import { ShipTypeSelector, ShipTypeItem } from "@/components/common/ship-type"
/**
- * 조선인 경우, 선종:
- * A-max, S-max, VLCC, LNGC, CONT
- * 해양인 경우, 선종:
- * FPSO, FLNG, FPU, Platform, WTIV, GOM
- *
* AVL종류:
* Nearshore, Offshore, IOC, NOC
*/
@@ -39,31 +43,6 @@ const constructionSectorOptions = [
{ value: "해양", label: "해양" },
]
-// 공사부문에 따른 선종 옵션들
-const getShipTypeOptions = (constructionSector: string) => {
- if (constructionSector === "조선") {
- return [
- { value: "A-max", label: "A-max" },
- { value: "S-max", label: "S-max" },
- { value: "VLCC", label: "VLCC" },
- { value: "LNGC", label: "LNGC" },
- { value: "CONT", label: "CONT" },
- ]
- } else if (constructionSector === "해양") {
- return [
- { value: "FPSO", label: "FPSO" },
- { value: "FLNG", label: "FLNG" },
- { value: "FPU", label: "FPU" },
- { value: "Platform", label: "Platform" },
- { value: "WTIV", label: "WTIV" },
- { value: "GOM", label: "GOM" },
- ]
- } else {
- // 공사부문이 선택되지 않은 경우 빈 배열
- return []
- }
-}
-
const avlKindOptions = [
{ value: "Nearshore", label: "Nearshore" },
{ value: "Offshore", label: "Offshore" },
@@ -123,7 +102,9 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
// 검색 상태
const [searchConstructionSector, setSearchConstructionSector] = React.useState(initialConstructionSector || "")
- const [searchShipType, setSearchShipType] = React.useState(initialShipType || "")
+ const [selectedShipType, setSelectedShipType] = React.useState<ShipTypeItem | undefined>(
+ initialShipType ? { CD: initialShipType, CDNM: initialShipType, displayText: initialShipType } : undefined
+ )
const [searchAvlKind, setSearchAvlKind] = React.useState(initialAvlKind || "")
const [searchHtDivision, setSearchHtDivision] = React.useState(initialHtDivision || "")
@@ -173,34 +154,29 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
const handleConstructionSectorChange = React.useCallback((value: string) => {
setSearchConstructionSector(value)
// 공사부문이 변경되면 선종을 빈 값으로 초기화
- setSearchShipType("")
+ setSelectedShipType(undefined)
}, [])
// 검색 상태 변경 시 부모 컴포넌트에 전달
React.useEffect(() => {
onSearchConditionsChange?.({
constructionSector: searchConstructionSector,
- shipType: searchShipType,
+ shipType: selectedShipType?.CD || "",
avlKind: searchAvlKind,
htDivision: searchHtDivision
})
- }, [searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision, onSearchConditionsChange])
+ }, [searchConstructionSector, selectedShipType, searchAvlKind, searchHtDivision, onSearchConditionsChange])
- // 현재 공사부문에 따른 선종 옵션들
- const currentShipTypeOptions = React.useMemo(() =>
- getShipTypeOptions(searchConstructionSector),
- [searchConstructionSector]
- )
// 모든 검색 조건이 선택되었는지 확인
const isAllSearchConditionsSelected = React.useMemo(() => {
return (
searchConstructionSector.trim() !== "" &&
- searchShipType.trim() !== "" &&
+ selectedShipType?.CD?.trim() !== "" &&
searchAvlKind.trim() !== "" &&
searchHtDivision.trim() !== ""
)
- }, [searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision])
+ }, [searchConstructionSector, selectedShipType, searchAvlKind, searchHtDivision])
// 데이터 로드 함수
const loadData = React.useCallback(async (searchParams: Partial<GetStandardAvlSchema> = {}) => {
@@ -213,7 +189,7 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
sort: searchParams.sort ?? [{ id: "no", desc: false }],
flags: searchParams.flags ?? [],
constructionSector: searchConstructionSector,
- shipType: searchShipType,
+ shipType: selectedShipType?.CD || "",
avlKind: searchAvlKind,
htDivision: searchHtDivision as "공통" | "H" | "T" | "",
equipBulkDivision: searchParams.equipBulkDivision || "",
@@ -249,7 +225,7 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
} finally {
setLoading(false)
}
- }, [searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision])
+ }, [searchConstructionSector, selectedShipType, searchAvlKind, searchHtDivision])
// reloadTrigger가 변경될 때마다 데이터 리로드
React.useEffect(() => {
@@ -262,7 +238,7 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
// 검색 초기화 핸들러
const handleResetSearch = React.useCallback(() => {
setSearchConstructionSector("")
- setSearchShipType("")
+ setSelectedShipType(undefined)
setSearchAvlKind("")
setSearchHtDivision("")
// 초기화 시 빈 데이터로 설정
@@ -365,6 +341,9 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
}
}, [table, loadData])
+ // 최종 확정 다이얼로그 상태
+ const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React.useState(false)
+
// 최종 확정 핸들러 (표준 AVL)
const handleFinalizeStandardAvl = React.useCallback(async () => {
// 1. 필수 조건 검증
@@ -378,27 +357,20 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
return
}
- // 2. 사용자 확인
- const confirmed = window.confirm(
- `현재 표준 AVL을 최종 확정하시겠습니까?\n\n` +
- `- 공사부문: ${searchConstructionSector}\n` +
- `- 선종: ${searchShipType}\n` +
- `- AVL종류: ${searchAvlKind}\n` +
- `- H/T 구분: ${searchHtDivision}\n` +
- `- 벤더 정보: ${data.length}개\n\n` +
- `확정 후에는 수정이 어려울 수 있습니다.`
- )
-
- if (!confirmed) return
+ // 2. 확인 다이얼로그 열기
+ setIsConfirmDialogOpen(true)
+ }, [isAllSearchConditionsSelected, data.length])
+ // 실제 최종 확정 실행 함수
+ const executeFinalizeStandardAvl = React.useCallback(async () => {
try {
- // 3. 현재 데이터의 모든 ID 수집
+ // 3. 현재 데이터의 모든 ID 수집 (전체 레코드 기준)
const avlVendorInfoIds = data.map(item => item.id)
// 4. 최종 확정 실행
const standardAvlInfo = {
constructionSector: searchConstructionSector,
- shipType: searchShipType,
+ shipType: selectedShipType?.CD || "",
avlKind: searchAvlKind,
htDivision: searchHtDivision
}
@@ -423,8 +395,10 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
} catch (error) {
console.error("표준 AVL 최종 확정 실패:", error)
toast.error("표준 AVL 최종 확정 중 오류가 발생했습니다.")
+ } finally {
+ setIsConfirmDialogOpen(false)
}
- }, [searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision, isAllSearchConditionsSelected, data, table, loadData, sessionData?.user?.name])
+ }, [searchConstructionSector, selectedShipType, searchAvlKind, searchHtDivision, data, table, loadData, sessionData?.user?.name])
// 초기 데이터 로드 (검색 조건이 모두 입력되었을 때만)
React.useEffect(() => {
@@ -437,7 +411,8 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
setData([])
setPageCount(0)
}
- }, [isAllSearchConditionsSelected, pagination.pageSize, searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision])
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [isAllSearchConditionsSelected, pagination.pageSize, searchConstructionSector, selectedShipType, searchAvlKind, searchHtDivision])
@@ -547,18 +522,13 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
{/* 선종 */}
<div className="space-y-2">
<label className="text-sm font-medium">선종</label>
- <Select value={searchShipType} onValueChange={setSearchShipType}>
- <SelectTrigger>
- <SelectValue />
- </SelectTrigger>
- <SelectContent>
- {currentShipTypeOptions.map((option) => (
- <SelectItem key={option.value} value={option.value}>
- {option.label}
- </SelectItem>
- ))}
- </SelectContent>
- </Select>
+ <ShipTypeSelector
+ selectedShipType={selectedShipType}
+ onShipTypeSelect={setSelectedShipType}
+ placeholder="선종을 선택하세요"
+ disabled={!searchConstructionSector}
+ className="h-10"
+ />
</div>
{/* AVL종류 */}
@@ -640,10 +610,40 @@ export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTable
isTemplate={true} // 표준 AVL 모드
// 검색 조건에서 선택한 값들을 초기값으로 전달
initialConstructionSector={searchConstructionSector}
- initialShipType={searchShipType}
+ initialShipType={selectedShipType?.CD || ""}
initialAvlKind={searchAvlKind}
initialHtDivision={searchHtDivision}
/>
+
+ {/* 최종 확정 확인 다이얼로그 */}
+ <Dialog open={isConfirmDialogOpen} onOpenChange={setIsConfirmDialogOpen}>
+ <DialogContent>
+ <DialogHeader>
+ <DialogTitle>표준 AVL 최종 확정</DialogTitle>
+ <DialogDescription>
+ 현재 표준 AVL을 최종 확정하시겠습니까?
+ </DialogDescription>
+ </DialogHeader>
+ <div className="space-y-2 text-sm">
+ <div>• 공사부문: {searchConstructionSector}</div>
+ <div>• 선종: {selectedShipType?.CD || ""}</div>
+ <div>• AVL종류: {searchAvlKind}</div>
+ <div>• H/T 구분: {searchHtDivision}</div>
+ <div>• 벤더 정보: {data.length}개 (전체 레코드)</div>
+ {/* <div className="text-amber-600 font-medium mt-4">
+ ⚠️ 확정 후 내용 수정을 필요로 하는 경우 동일 건을 다시 최종확정해 revision 처리로 수정해야 합니다.
+ </div> */}
+ </div>
+ <DialogFooter>
+ <Button variant="outline" onClick={() => setIsConfirmDialogOpen(false)}>
+ 취소
+ </Button>
+ <Button onClick={executeFinalizeStandardAvl}>
+ 최종 확정
+ </Button>
+ </DialogFooter>
+ </DialogContent>
+ </Dialog>
</div>
)
})