diff --git a/apps/as/src/entities/rvw-mnpw/api/queries.ts b/apps/as/src/entities/rvw-mnpw/api/queries.ts index 651906de0..6e075e4d5 100644 --- a/apps/as/src/entities/rvw-mnpw/api/queries.ts +++ b/apps/as/src/entities/rvw-mnpw/api/queries.ts @@ -12,10 +12,11 @@ import { rvwMnpwMngService } from "./rvw-mnpw-service"; const rvwMnpwMngBaseKey = [ENDPOINT.AS_COMMON_SERVICE.RVW_MNPW] as const; -export function useRvwMnpwMngPage(params: RvwMnpwMngSearchDto) { +export function useRvwMnpwMngPage(params: RvwMnpwMngSearchDto, options?: { enabled?: boolean }) { return useQuery({ queryKey: [...rvwMnpwMngBaseKey, "findPage", params], queryFn: () => rvwMnpwMngService.findPage(params), + enabled: options?.enabled, }); } diff --git a/apps/as/src/entities/rvw-mnpw/model/rvw-mnpw-interface.ts b/apps/as/src/entities/rvw-mnpw/model/rvw-mnpw-interface.ts index 73aef5961..92cbff071 100644 --- a/apps/as/src/entities/rvw-mnpw/model/rvw-mnpw-interface.ts +++ b/apps/as/src/entities/rvw-mnpw/model/rvw-mnpw-interface.ts @@ -7,6 +7,9 @@ export interface RvwMnpwMngResponseDto { ognzSn: number; userUuid: string; userUuidNm?: string; + ognzNm?: string; + jbpsSeNm?: string; + jbgdSeNm?: string; rgtr?: string; regDt?: string; } diff --git a/apps/as/src/pages/approval-line-management/lib/validators.ts b/apps/as/src/pages/approval-line-management/lib/validators.ts index c5fbe0b71..4e301afa9 100644 --- a/apps/as/src/pages/approval-line-management/lib/validators.ts +++ b/apps/as/src/pages/approval-line-management/lib/validators.ts @@ -1,10 +1,7 @@ import type { ElaprAplnRow } from "../model/apln-row-types"; -export const ATRZ_RECEIVER_CD = "ATRZ00"; -export const ATRZ_REVIEWER_1_CD = "ATRZ01"; -export const ATRZ_REVIEWER_2_CD = "ATRZ02"; -export const ATRZ_APPROVER_CD = "ATRZ03"; -export const ATRZ_FINAL_CD = "ATRZ99"; +const ATRZ_RECEIVER_CD = "ATRZ01"; +const ATRZ_FINAL_CD = "ATRZ99"; export function getVisibleRows(rows: ElaprAplnRow[]): ElaprAplnRow[] { return rows.filter((row) => !row.isDeleted); diff --git a/apps/as/src/pages/approval-line-management/model/reviewer-option.ts b/apps/as/src/pages/approval-line-management/model/reviewer-option.ts index 3b4658acd..cb79bbf13 100644 --- a/apps/as/src/pages/approval-line-management/model/reviewer-option.ts +++ b/apps/as/src/pages/approval-line-management/model/reviewer-option.ts @@ -1,4 +1,4 @@ -import type { SelectedOgnzUser } from "@/widgets/ognz-user-tree"; +import type { RvwMnpwMngResponseDto } from "@/entities/rvw-mnpw"; export interface ReviewerOption { uuid: string; @@ -6,10 +6,10 @@ export interface ReviewerOption { deptNm: string; } -export function fromSelectedOgnzUser(user: SelectedOgnzUser): ReviewerOption { +export function fromRvwMnpwMng(item: RvwMnpwMngResponseDto): ReviewerOption { return { - uuid: user.userUuid, - name: user.userNm, - deptNm: user.ognzNm, + uuid: item.userUuid, + name: item.userUuidNm ?? "", + deptNm: item.ognzNm ?? "", }; } diff --git a/apps/as/src/pages/approval-line-management/ui/aprvr-picker-dialog.tsx b/apps/as/src/pages/approval-line-management/ui/aprvr-picker-dialog.tsx index 7fbab9f17..38f7c810d 100644 --- a/apps/as/src/pages/approval-line-management/ui/aprvr-picker-dialog.tsx +++ b/apps/as/src/pages/approval-line-management/ui/aprvr-picker-dialog.tsx @@ -1,14 +1,6 @@ "use client"; -import { useCallback, useEffect, useState } from "react"; - -import { useOgnzUserTree } from "@/entities/user-organization"; -import { - collectExpandedOgnzSnIds, - filterOgnzUserTree, - OgnzUserTree, - type SelectedOgnzUser, -} from "@/widgets/ognz-user-tree"; +import { useRvwMnpwMngPage } from "@/entities/rvw-mnpw"; import { Button, Dialog, @@ -16,113 +8,109 @@ import { DialogFooter, DialogHeader, DialogTitle, - Input, + Skeleton, + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, } from "@common/components"; -import { fromSelectedOgnzUser, type ReviewerOption } from "../model/reviewer-option"; +import { fromRvwMnpwMng, type ReviewerOption } from "../model/reviewer-option"; + +const PAGE_SIZE = 500; interface AprvrPickerDialogProps { open: boolean; onOpenChange: (open: boolean) => void; + atrzSeComCd: string; onSelect: (reviewer: ReviewerOption) => void; } -function AprvrPickerDialog({ open, onOpenChange, onSelect }: AprvrPickerDialogProps) { - const [keyword, setKeyword] = useState(""); - const [displayTree, setDisplayTree] = useState>([]); - const [expandedOgnzSnIds, setExpandedOgnzSnIds] = useState>(new Set()); - const [selectedUserId, setSelectedUserId] = useState(); - const [isSearchActive, setIsSearchActive] = useState(false); +function AprvrPickerDialog({ + open, + onOpenChange, + atrzSeComCd, + onSelect, +}: AprvrPickerDialogProps) { + const { data, isPending, isError } = useRvwMnpwMngPage( + { + atrzSeComCd, + page: 0, + size: PAGE_SIZE, + sort: "userUuidNm,asc", + }, + { enabled: open }, + ); - const { data, isPending, isError } = useOgnzUserTree({ enabled: open }); + const items = data?.content ?? []; - const resetState = useCallback(() => { - setKeyword(""); - setSelectedUserId(undefined); - setExpandedOgnzSnIds(new Set()); - setIsSearchActive(false); - setDisplayTree(data ?? []); - }, [data]); - - useEffect(() => { - if (!open) { - setKeyword(""); - setSelectedUserId(undefined); - setExpandedOgnzSnIds(new Set()); - setIsSearchActive(false); - return; - } - - setDisplayTree(data ?? []); - }, [open, data]); - - const handleToggle = (ognzSn: number, isExpanded: boolean) => { - setExpandedOgnzSnIds((prev) => { - const next = new Set(prev); - if (isExpanded) next.add(ognzSn); - else next.delete(ognzSn); - return next; - }); - }; - - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - e.stopPropagation(); - - const filtered = filterOgnzUserTree(data ?? [], keyword); - setDisplayTree(filtered); - setExpandedOgnzSnIds(collectExpandedOgnzSnIds(filtered)); - setIsSearchActive(keyword.trim().length > 0); - }; - - const handleReset = () => { - resetState(); - }; - - const handleSelect = (user: SelectedOgnzUser) => { - setSelectedUserId(user.userUuid); - onSelect(fromSelectedOgnzUser(user)); + const handleSelect = (item: (typeof items)[number]) => { + onSelect(fromRvwMnpwMng(item)); onOpenChange(false); }; return ( - + 검토인력 선택 -
-
-
- setKeyword(e.target.value)} - /> - - -
-
- -
- -
+
+ {isPending ? ( +
+ + +
+ ) : isError ? ( +

+ 검토인력 목록을 불러오지 못했습니다. +

+ ) : items.length === 0 ? ( +

+ 배치된 검토인력이 없습니다. +

+ ) : ( + + + + + + + + + + + 성명 + 부서 + 직위 + 직급 + 선택 + + + + {items.map((item) => ( + + + {item.userUuidNm || item.userUuid} + + {item.ognzNm || "-"} + {item.jbpsSeNm || "-"} + {item.jbgdSeNm || "-"} + + + + + ))} + +
+ )}
diff --git a/apps/as/src/pages/approval-line-management/ui/elapr-apln-grid.tsx b/apps/as/src/pages/approval-line-management/ui/elapr-apln-grid.tsx index 1371db596..c2393715b 100644 --- a/apps/as/src/pages/approval-line-management/ui/elapr-apln-grid.tsx +++ b/apps/as/src/pages/approval-line-management/ui/elapr-apln-grid.tsx @@ -75,6 +75,7 @@ function ElaprAplnGrid({ elaprTmpltId }: ElaprAplnGridProps) { const isDisabled = !elaprTmpltId; const serverRows = aplnQuery.data?.content ?? []; const canSave = hasUnsavedChanges(rows, serverRows); + const pickingRow = pickingRowKey ? rows.find((r) => r.rowKey === pickingRowKey) : undefined; const handleDragEnd = (event: DragEndEvent) => { const { active, over } = event; @@ -236,6 +237,7 @@ function ElaprAplnGrid({ elaprTmpltId }: ElaprAplnGridProps) { diff --git a/apps/as/src/pages/approval-line-management/ui/sortable-apln-row.tsx b/apps/as/src/pages/approval-line-management/ui/sortable-apln-row.tsx index 266fe0b45..fcb315bdb 100644 --- a/apps/as/src/pages/approval-line-management/ui/sortable-apln-row.tsx +++ b/apps/as/src/pages/approval-line-management/ui/sortable-apln-row.tsx @@ -36,7 +36,7 @@ function SortableAplnRow({ onChange, onPickAprvr, }: SortableAplnRowProps) { - const { data: atrzSeCodes } = useCodeList("ATRZSECD"); + const { data: atrzSeCodes } = useCodeList("ATRZSE"); const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: row.rowKey, @@ -50,7 +50,7 @@ function SortableAplnRow({ }; const rowDisabled = isLocked && !isEditing; - const atrzSeLabel = row.atrzSeComNm ?? findCodeLabel(atrzSeCodes, row.atrzSeComCd); + const atrzSeLabel = row.atrzSeComNm || findCodeLabel(atrzSeCodes, row.atrzSeComCd); return ( @@ -72,7 +72,7 @@ function SortableAplnRow({ {isEditing ? ( diff --git a/apps/as/src/pages/rvw-mnpw-mng/model/rvw-mnpw-block-config.ts b/apps/as/src/pages/rvw-mnpw-mng/model/rvw-mnpw-block-config.ts index 30dff1f37..5a6c681e1 100644 --- a/apps/as/src/pages/rvw-mnpw-mng/model/rvw-mnpw-block-config.ts +++ b/apps/as/src/pages/rvw-mnpw-mng/model/rvw-mnpw-block-config.ts @@ -4,11 +4,10 @@ export interface RvwMnpwBlockConfig { atrzSeComCd: string; } -/** 결재선 관리 validators.ts ATRZ 코드와 동일. ATRZSE / ATRZSECD 배포 환경 코드표 최종 확인 필요 */ +/** 결재선 관리 validators.ts ATRZ 코드와 동일 */ export const RVW_MNPW_BLOCKS: RvwMnpwBlockConfig[] = [ - { id: "receiver", title: "접수", atrzSeComCd: "ATRZ00" }, - // TBD: ATRZ02(검토2) 별도 블록 필요 여부 — 현재 ATRZ01만 검토 블록으로 사용 - { id: "reviewer", title: "검토", atrzSeComCd: "ATRZ01" }, + { id: "receiver", title: "접수", atrzSeComCd: "ATRZ01" }, + { id: "reviewer", title: "검토", atrzSeComCd: "ATRZ02" }, { id: "approver", title: "승인", atrzSeComCd: "ATRZ03" }, { id: "final", title: "최종승인", atrzSeComCd: "ATRZ99" }, ];