diff options
Diffstat (limited to 'lib/evaluation-target-list')
6 files changed, 91 insertions, 21 deletions
diff --git a/lib/evaluation-target-list/service.ts b/lib/evaluation-target-list/service.ts index 8d890604..36251c2d 100644 --- a/lib/evaluation-target-list/service.ts +++ b/lib/evaluation-target-list/service.ts @@ -35,7 +35,7 @@ import { authOptions } from "@/app/api/auth/[...nextauth]/route" import { sendEmail } from "../mail/sendEmail"; import type { SQL } from "drizzle-orm" import { DEPARTMENT_CODE_LABELS } from "@/types/evaluation"; -import { revalidatePath } from "next/cache"; +import { revalidatePath,unstable_noStore } from "next/cache"; export async function selectEvaluationTargetsFromView( tx: PgTransaction<any, any, any>, @@ -72,11 +72,8 @@ export async function countEvaluationTargetsFromView( // ============= 메인 서버 액션도 함께 수정 ============= export async function getEvaluationTargets(input: GetEvaluationTargetsSchema) { + unstable_noStore() try { - console.log("=== 서버 액션 호출 ==="); - console.log("필터 수:", input.filters?.length || 0); - console.log("조인 연산자:", input.joinOperator); - const offset = (input.page - 1) * input.perPage; // ✅ 단순화된 필터 처리 @@ -297,6 +294,8 @@ export async function createEvaluationTarget( ) .limit(1); + console.log(existing,input ) + if (existing.length > 0) { throw new Error("이미 동일한 평가 대상이 존재합니다."); } @@ -434,6 +433,8 @@ export async function updateEvaluationTarget(input: UpdateEvaluationTargetInput) throw new Error("인증이 필요합니다.") } + console.log(input,"input") + return await db.transaction(async (tx) => { // 평가 대상 존재 확인 const existing = await tx @@ -533,6 +534,9 @@ export async function updateEvaluationTarget(input: UpdateEvaluationTargetInput) for (const review of reviewUpdates) { if (review.isApproved !== undefined) { + + console.log(review.departmentCode,"review.departmentCode"); + // 해당 부서의 담당자 조회 const reviewer = await tx .select({ @@ -547,6 +551,8 @@ export async function updateEvaluationTarget(input: UpdateEvaluationTargetInput) ) .limit(1) + console.log(reviewer,"reviewer") + if (reviewer.length > 0) { // 기존 평가 결과 삭제 await tx @@ -554,21 +560,33 @@ export async function updateEvaluationTarget(input: UpdateEvaluationTargetInput) .where( and( eq(evaluationTargetReviews.evaluationTargetId, input.id), - eq(evaluationTargetReviews.reviewerUserId, reviewer[0].reviewerUserId) + eq(evaluationTargetReviews.reviewerUserId, reviewer[0].reviewerUserId), + eq(evaluationTargetReviews.departmentCode, review.departmentCode) // 추가 + ) ) // 새 평가 결과 추가 (null이 아닌 경우만) if (review.isApproved !== null) { - await tx - .insert(evaluationTargetReviews) - .values({ - evaluationTargetId: input.id, - reviewerUserId: reviewer[0].reviewerUserId, - departmentCode: review.departmentCode, - isApproved: review.isApproved, - reviewedAt: new Date(), - }) + console.log("INSERT 시도:", review.departmentCode, review.isApproved); + + try { + const insertResult = await tx + .insert(evaluationTargetReviews) + .values({ + evaluationTargetId: input.id, + reviewerUserId: reviewer[0].reviewerUserId, + departmentCode: review.departmentCode, + isApproved: review.isApproved, + reviewedAt: new Date(), + }) + .returning({ id: evaluationTargetReviews.id }); // returning 추가 + + console.log("INSERT 성공:", insertResult); + } catch (insertError) { + console.error("INSERT 에러:", insertError); + throw insertError; + } } } } @@ -599,8 +617,12 @@ export async function updateEvaluationTarget(input: UpdateEvaluationTargetInput) reviewedDepartments.includes(dept) ) + console.log(allRequiredDepartmentsReviewed,"allRequiredDepartmentsReviewed") + + if (allRequiredDepartmentsReviewed) { const approvals = currentReviews.map(r => r.isApproved) + console.log(approvals,"approvals") const allApproved = approvals.every(approval => approval === true) const allRejected = approvals.every(approval => approval === false) const hasConsensus = allApproved || allRejected @@ -621,7 +643,11 @@ export async function updateEvaluationTarget(input: UpdateEvaluationTargetInput) updatedAt: new Date() }) .where(eq(evaluationTargets.id, input.id)) - } + } + + + revalidatePath('/evcp/evaluation-target-list') + revalidatePath('/procurement/evaluation-target-list') return { success: true, @@ -649,7 +675,7 @@ export async function getAvailableReviewers(departmentCode?: string) { }) .from(users) .orderBy(users.name) - .limit(100); + // .limit(100); return reviewers; } catch (error) { @@ -683,7 +709,7 @@ export async function getAvailableVendors(search?: string) { ) ) .orderBy(vendors.vendorName) - .limit(100); + // .limit(100); return await query; } catch (error) { diff --git a/lib/evaluation-target-list/table/evaluation-target-table.tsx b/lib/evaluation-target-list/table/evaluation-target-table.tsx index c65a7815..9cc73003 100644 --- a/lib/evaluation-target-list/table/evaluation-target-table.tsx +++ b/lib/evaluation-target-list/table/evaluation-target-table.tsx @@ -323,6 +323,39 @@ export function EvaluationTargetsTable({ promises, evaluationYear, className }: return () => clearTimeout(timeoutId); }, [searchString, evaluationYear, getSearchParam]); + const refreshData = React.useCallback(async () => { + try { + setIsDataLoading(true); + + // 현재 URL 파라미터로 데이터 새로고침 + const currentFilters = getSearchParam("filters"); + const currentJoinOperator = getSearchParam("joinOperator", "and"); + const currentPage = parseInt(getSearchParam("page", "1")); + const currentPerPage = parseInt(getSearchParam("perPage", "10")); + const currentSort = getSearchParam('sort') ? JSON.parse(getSearchParam('sort')!) : [{ id: "createdAt", desc: true }]; + const currentSearch = getSearchParam("search", ""); + + const searchParams = { + filters: currentFilters ? JSON.parse(currentFilters) : [], + joinOperator: currentJoinOperator as "and" | "or", + page: currentPage, + perPage: currentPerPage, + sort: currentSort, + search: currentSearch, + evaluationYear: evaluationYear + }; + + const newData = await getEvaluationTargets(searchParams); + setTableData(newData); + + console.log("=== 데이터 새로고침 완료 ===", newData.data.length, "건"); + } catch (error) { + console.error("데이터 새로고침 오류:", error); + } finally { + setIsDataLoading(false); + } + }, [evaluationYear, getSearchParam]); + /* --------------------------- layout refs --------------------------- */ const containerRef = React.useRef<HTMLDivElement>(null); const [containerTop, setContainerTop] = React.useState(0); @@ -597,7 +630,7 @@ export function EvaluationTargetsTable({ promises, evaluationYear, className }: onRenamePreset={renamePreset} /> - <EvaluationTargetsTableToolbarActions table={table} /> + <EvaluationTargetsTableToolbarActions table={table}onRefresh={refreshData} /> </div> </DataTableAdvancedToolbar> </DataTable> @@ -607,6 +640,7 @@ export function EvaluationTargetsTable({ promises, evaluationYear, className }: open={rowAction?.type === "update"} onOpenChange={() => setRowAction(null)} evaluationTarget={rowAction?.row.original ?? null} + onDataChange={refreshData} /> </div> </div> diff --git a/lib/evaluation-target-list/table/evaluation-targets-toolbar-actions.tsx b/lib/evaluation-target-list/table/evaluation-targets-toolbar-actions.tsx index 6a493d8e..714f96c3 100644 --- a/lib/evaluation-target-list/table/evaluation-targets-toolbar-actions.tsx +++ b/lib/evaluation-target-list/table/evaluation-targets-toolbar-actions.tsx @@ -364,6 +364,7 @@ export function EvaluationTargetsTableToolbarActions({ open={manualCreateDialogOpen} onOpenChange={setManualCreateDialogOpen} onSuccess={handleActionSuccess} + onDataChange={onRefresh} /> {/* 확정 컨펌 다이얼로그 */} diff --git a/lib/evaluation-target-list/table/manual-create-evaluation-target-dialog.tsx b/lib/evaluation-target-list/table/manual-create-evaluation-target-dialog.tsx index 44497cdb..a00df0f0 100644 --- a/lib/evaluation-target-list/table/manual-create-evaluation-target-dialog.tsx +++ b/lib/evaluation-target-list/table/manual-create-evaluation-target-dialog.tsx @@ -61,15 +61,18 @@ import { EVALUATION_TARGET_FILTER_OPTIONS, getDefaultEvaluationYear } from "../v import { useSession } from "next-auth/react" - interface ManualCreateEvaluationTargetDialogProps { open: boolean onOpenChange: (open: boolean) => void + onSuccess?: () => void + onDataChange?: () => void } export function ManualCreateEvaluationTargetDialog({ open, onOpenChange, + onSuccess, + onDataChange }: ManualCreateEvaluationTargetDialogProps) { const router = useRouter() const [isSubmitting, setIsSubmitting] = React.useState(false) @@ -262,6 +265,8 @@ type CreateEvaluationTargetFormValues = z.infer<typeof createEvaluationTargetSch setVendorSearch("") setReviewerSearches({}) setReviewerOpens({}) + onSuccess?.() // 기존 방식 (table.resetRowSelection, router.refresh 등) + onDataChange?.() // 새로운 방식 (클라이언트 상태 업데이트) router.refresh() } else { toast.error(result.error || "평가 대상 생성에 실패했습니다.") diff --git a/lib/evaluation-target-list/table/update-evaluation-target.tsx b/lib/evaluation-target-list/table/update-evaluation-target.tsx index ef24aa9f..9b1f4868 100644 --- a/lib/evaluation-target-list/table/update-evaluation-target.tsx +++ b/lib/evaluation-target-list/table/update-evaluation-target.tsx @@ -88,6 +88,7 @@ interface EditEvaluationTargetSheetProps { open: boolean onOpenChange: (open: boolean) => void evaluationTarget: EvaluationTargetWithDepartments | null + onDataChange?: () => void // ✅ 새로 추가 } // 권한 타입 정의 @@ -102,6 +103,7 @@ export function EditEvaluationTargetSheet({ open, onOpenChange, evaluationTarget, + onDataChange }: EditEvaluationTargetSheetProps) { const router = useRouter() const [isSubmitting, setIsSubmitting] = React.useState(false) @@ -259,7 +261,10 @@ export function EditEvaluationTargetSheet({ if (result.success) { toast.success(result.message || "평가 대상이 성공적으로 수정되었습니다.") onOpenChange(false) + onDataChange?.() router.refresh() + // window.location.reload() + } else { toast.error(result.error || "평가 대상 수정에 실패했습니다.") } diff --git a/lib/evaluation-target-list/validation.ts b/lib/evaluation-target-list/validation.ts index d37ca0ed..c24b8de5 100644 --- a/lib/evaluation-target-list/validation.ts +++ b/lib/evaluation-target-list/validation.ts @@ -27,7 +27,6 @@ export const searchParamsEvaluationTargetsCache = createSearchParamsCache({ // 검색 search: parseAsString.withDefault(""), - aggregated: z.boolean().default(false), }); |
