[as fr] 리스트에서 뷰로 들어갈경우에 TanStack Query(React Query) 캐시 시스템과의 충돌 여부 및 웹한글기안기 등 인접 기능에 미치는 영향을 검토한 뒤 실질적인 해결 방안 추가

This commit is contained in:
2026-10-23 15:20:07 +09:00
parent bedefd7e2e
commit 23d62ab5e6
10 changed files with 105 additions and 30 deletions
@@ -1,5 +1,10 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type {
DesignCnstnApplySaveRequestDto,
DesignCnstnMngSaveRequestDto,
DesignCnstnRvwOpnnSaveRequestDto,
} from "../model/design-cnstn-apply-payload-schema";
import type {
DesignCnstnBizCstSaveRequestDto,
DesignCnstnBizCstSearchDto,
@@ -15,11 +20,6 @@ import type {
DesignCnstnEsntlAtchFileSearchDto,
DesignCnstnEsntlAtchFileUpdateRequestDto,
} from "../model/design-cnstn-esntl-atch-file-interface";
import type {
DesignCnstnApplySaveRequestDto,
DesignCnstnMngSaveRequestDto,
DesignCnstnRvwOpnnSaveRequestDto,
} from "../model/design-cnstn-apply-payload-schema";
import type {
DesignCnstnMngSearchDto,
DesignCnstnMngUpdateRequestDto,
@@ -83,6 +83,8 @@ export function useDesignCnstnMng(id: string | null | undefined) {
queryKey: designCnstnKeys.detail(id!),
queryFn: () => designCnstnMngService.findById(id!),
enabled: Boolean(id),
staleTime: 0,
refetchOnMount: "always",
});
}
@@ -35,6 +35,8 @@ export function useFnrsCnsltnMng(fnrsCnsltnDocNo: string | null | undefined) {
queryKey: fnrsCnsltnKeys.detail(fnrsCnsltnDocNo!),
queryFn: () => fnrsCnsltnMngService.findById(fnrsCnsltnDocNo!),
enabled: Boolean(fnrsCnsltnDocNo),
staleTime: 0,
refetchOnMount: "always",
});
}
@@ -43,6 +45,8 @@ export function useFnrsCnsltnFileVrfcResults(fnrsCnsltnDocNo: string | null | un
queryKey: fnrsCnsltnKeys.fileVrfcResults(fnrsCnsltnDocNo!),
queryFn: () => fnrsCnsltnMngService.findFileVrfcResults(fnrsCnsltnDocNo!),
enabled: Boolean(fnrsCnsltnDocNo),
staleTime: 0,
refetchOnMount: "always",
});
}
@@ -35,6 +35,8 @@ export function useInstlSncnDetail(id: string) {
queryKey: instlSncnKeys.detail(id),
queryFn: () => instlSncnService.getById(id),
enabled: Boolean(id),
staleTime: 0,
refetchOnMount: "always",
});
}
@@ -33,6 +33,8 @@ export function useSewerBscPlan(sewerBscPlanDocNo: string | null | undefined) {
queryKey: sewerBscPlanKeys.detail(sewerBscPlanDocNo!),
queryFn: () => sewerBscPlanService.findById(sewerBscPlanDocNo!),
enabled: Boolean(sewerBscPlanDocNo),
staleTime: 0,
refetchOnMount: "always",
});
}
@@ -44,6 +46,8 @@ export function useSewerBscPlanDetails(
queryKey: sewerBscPlanKeys.details(sewerBscPlanDocNo!, chgCycl ?? undefined),
queryFn: () => sewerBscPlanService.findDetails(sewerBscPlanDocNo!, chgCycl!),
enabled: Boolean(sewerBscPlanDocNo) && chgCycl != null,
staleTime: 0,
refetchOnMount: "always",
});
}
@@ -2,13 +2,15 @@
import { useMemo, useRef } from "react";
import { RefreshCw } from "lucide-react";
import { useUserStore } from "@/shared/lib";
import { SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import { useDesignCnstnMng } from "@/entities/design-cnstn";
import { ElaprDocPrgrsStatus } from "@/entities/elapr";
import { useRvwMnpwMngLoginUserList } from "@/entities/rvw-mnpw";
import { AttachmentsViewSection, ProgressStatusSection } from "@/widgets/pbadms-sprt";
import { Skeleton } from "@common/components";
import { Button, cn, Skeleton } from "@common/components";
import { needsRoleUser01AtrzResolve } from "../lib/button-config";
import { getEditableReviewStep } from "../lib/review-step-utils";
@@ -30,7 +32,7 @@ interface DesignViewPageProps {
function DesignViewPage({ id }: DesignViewPageProps) {
const userInfo = useUserStore((state) => state.userInfo);
const techReviewOpinionRef = useRef<TechReviewOpinionSectionHandle>(null);
const { data, isLoading, isError } = useDesignCnstnMng(id);
const { data, isLoading, isError, refetch, isFetching } = useDesignCnstnMng(id);
const prgrsSttsComCd = data?.detDto?.prgrsSttsComCd || "";
const needsAtrzResolve = needsRoleUser01AtrzResolve(userInfo?.dtlInstCd, prgrsSttsComCd);
@@ -83,8 +85,20 @@ function DesignViewPage({ id }: DesignViewPageProps) {
return (
<div className="mt-4">
<SectionCollapsibleGroup>
<div className="sticky top-[6rem] z-30 bg-container px-4 py-2">
<div className="sticky top-[6rem] z-30 flex items-center gap-3 bg-container px-4 py-2">
<SectionCollapsibleToggle />
<Button
type="button"
variant="outline"
size="xs"
onClick={() => refetch()}
disabled={isFetching}
className="flex items-center gap-1.5 h-[2.8rem] px-3 text-[1.2rem] font-normal"
title="최신 데이터 새로고침"
>
<RefreshCw className={cn("size-3.5", isFetching && "animate-spin")} />
<span>새로 고침</span>
</Button>
</div>
<div className="space-y-4">
<ProgressStatusSection
@@ -381,6 +381,9 @@ function PwrkCnsltnDocMngDialog({
},
select: (response) => response.data,
enabled: open && Boolean(crtDmndUuid),
staleTime: Infinity,
refetchOnWindowFocus: false,
refetchOnMount: false,
});
const branchLabel = isForkJoin
@@ -2,6 +2,8 @@
import { useMemo, useRef } from "react";
import { RefreshCw } from "lucide-react";
import { useUserStore } from "@/shared/lib";
import { SectionCollapsibleGroup, SectionCollapsibleToggle, TextShimmer } from "@/shared/ui";
import { ElaprDocPrgrsStatus } from "@/entities/elapr";
@@ -12,7 +14,7 @@ import {
ProgressStatusSection,
SupplementDemandSection,
} from "@/widgets/pbadms-sprt";
import { Skeleton } from "@common/components";
import { Button, cn, Skeleton } from "@common/components";
import {
getAiPendingMessage,
@@ -20,8 +22,8 @@ import {
isRagIndexingInProgress,
} from "../lib/ai-pending-utils";
import { needsRoleUser01AtrzResolve } from "../lib/button-config";
import { getEditableReviewStep } from "../lib/review-step-utils";
import { normalizeTaskSeComCdForElapr } from "../lib/fnrs-cnsltn-regist-schema";
import { getEditableReviewStep } from "../lib/review-step-utils";
import { EMPTY_CKLST_RESULT_LIST, useChecklistFormState } from "../lib/use-checklist-form-state";
import { PROGRESS_STATUS_COLUMNS } from "../model/columns";
@@ -44,7 +46,7 @@ interface FnrsViewPageProps {
function FnrsViewPage({ id }: FnrsViewPageProps) {
const userInfo = useUserStore((state) => state.userInfo);
const techReviewOpinionRef = useRef<TechReviewOpinionSectionHandle>(null);
const { data, isLoading, isError } = useFnrsCnsltnMng(id);
const { data, isLoading, isError, refetch, isFetching } = useFnrsCnsltnMng(id);
const { formState: checklistFormState, setFormState: setChecklistFormState } =
useChecklistFormState(data?.cklstResultList ?? EMPTY_CKLST_RESULT_LIST);
@@ -109,19 +111,33 @@ function FnrsViewPage({ id }: FnrsViewPageProps) {
return (
<div className="mt-4">
<SectionCollapsibleGroup>
<div className="sticky top-[6rem] z-30 flex items-center gap-4 bg-container px-4 py-2">
<SectionCollapsibleToggle />
{showPendingBanner && (
<div className="flex items-center gap-2">
<span className="relative flex size-3">
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-primary opacity-75"></span>
<span className="relative inline-flex size-3 rounded-full bg-primary"></span>
</span>
<TextShimmer active className="text-xl">
{pendingMessage}
</TextShimmer>
</div>
)}
<div className="sticky top-[6rem] z-30 flex items-center justify-between bg-container px-4 py-2">
<div className="flex items-center gap-3">
<SectionCollapsibleToggle />
<Button
type="button"
variant="outline"
size="xs"
onClick={() => refetch()}
disabled={isFetching}
className="flex items-center gap-1.5 h-[2.8rem] px-3 text-[1.2rem] font-normal"
title="최신 데이터 새로고침"
>
<RefreshCw className={cn("size-3.5", isFetching && "animate-spin")} />
<span>새로 고침</span>
</Button>
{showPendingBanner && (
<div className="flex items-center gap-2">
<span className="relative flex size-3">
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-primary opacity-75"></span>
<span className="relative inline-flex size-3 rounded-full bg-primary"></span>
</span>
<TextShimmer active className="text-xl">
{pendingMessage}
</TextShimmer>
</div>
)}
</div>
</div>
<div className="space-y-4">
<ProgressStatusSection
@@ -2,6 +2,8 @@
import { useMemo, useRef } from "react";
import { RefreshCw } from "lucide-react";
import { useUserStore } from "@/shared/lib";
import { SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import { ElaprDocPrgrsStatus } from "@/entities/elapr";
@@ -12,7 +14,7 @@ import {
ProgressStatusSection,
SupplementDemandSection,
} from "@/widgets/pbadms-sprt";
import { Skeleton } from "@common/components";
import { Button, cn, Skeleton } from "@common/components";
import { needsRoleUser01AtrzResolve } from "../lib/button-config";
import { getEditableReviewStep } from "../lib/review-step-utils";
@@ -36,7 +38,7 @@ interface InstlViewPageProps {
function InstlViewPage({ id }: InstlViewPageProps) {
const userInfo = useUserStore((state) => state.userInfo);
const techReviewOpinionRef = useRef<TechReviewOpinionSectionHandle>(null);
const { data, isLoading, isError } = useInstlSncnDetail(id);
const { data, isLoading, isError, refetch, isFetching } = useInstlSncnDetail(id);
const { formState: checklistFormState } = useChecklistFormState(
data?.cklstResultList ?? EMPTY_CKLST_RESULT_LIST,
);
@@ -94,8 +96,20 @@ function InstlViewPage({ id }: InstlViewPageProps) {
return (
<div className="mt-4">
<SectionCollapsibleGroup>
<div className="sticky top-[6rem] z-30 bg-container px-4 py-2">
<div className="sticky top-[6rem] z-30 flex items-center gap-3 bg-container px-4 py-2">
<SectionCollapsibleToggle />
<Button
type="button"
variant="outline"
size="xs"
onClick={() => refetch()}
disabled={isFetching}
className="flex items-center gap-1.5 h-[2.8rem] px-3 text-[1.2rem] font-normal"
title="최신 데이터 새로고침"
>
<RefreshCw className={cn("size-3.5", isFetching && "animate-spin")} />
<span>새로 고침</span>
</Button>
</div>
<div className="space-y-4">
<ProgressStatusSection
@@ -2,6 +2,8 @@
import { useMemo, useRef } from "react";
import { RefreshCw } from "lucide-react";
import { useUserStore } from "@/shared/lib";
import { SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import { ElaprDocPrgrsStatus } from "@/entities/elapr";
@@ -12,7 +14,7 @@ import {
ProgressStatusSection,
SupplementDemandSection,
} from "@/widgets/pbadms-sprt";
import { Skeleton } from "@common/components";
import { Button, cn, Skeleton } from "@common/components";
import { needsRoleUser01AtrzResolve } from "../lib/button-config";
import { getEditableReviewStep } from "../lib/review-step-utils";
@@ -41,7 +43,7 @@ function SewerBscPlanViewPage({ id, propChgCycl }: SewerBscPlanViewPageProps) {
const userInfo = useUserStore((state) => state.userInfo);
const techReviewOpinionRef = useRef<TechReviewOpinionSectionHandle>(null);
const chgCycl = propChgCycl ?? 1;
const { data, isLoading, isError } = useSewerBscPlanDetails(id, chgCycl);
const { data, isLoading, isError, refetch, isFetching } = useSewerBscPlanDetails(id, chgCycl);
const { formState: checklistFormState, setFormState: setChecklistFormState } =
useChecklistFormState(data?.cklstResultRows ?? EMPTY_CKLST_RESULT_LIST);
@@ -102,8 +104,20 @@ function SewerBscPlanViewPage({ id, propChgCycl }: SewerBscPlanViewPageProps) {
return (
<div className="mt-4">
<SectionCollapsibleGroup>
<div className="sticky top-[6rem] z-30 bg-container px-4 py-2">
<div className="sticky top-[6rem] z-30 flex items-center gap-3 bg-container px-4 py-2">
<SectionCollapsibleToggle />
<Button
type="button"
variant="outline"
size="xs"
onClick={() => refetch()}
disabled={isFetching}
className="flex items-center gap-1.5 h-[2.8rem] px-3 text-[1.2rem] font-normal"
title="최신 데이터 새로고침"
>
<RefreshCw className={cn("size-3.5", isFetching && "animate-spin")} />
<span>새로 고침</span>
</Button>
</div>
<div className="space-y-4">
<ProgressStatusSection
+2
View File
@@ -22,6 +22,8 @@ class Client {
headers: {
"Content-Type": "application/json",
"X-Site-Id": config.siteId,
"Cache-Control": "no-cache",
Pragma: "no-cache",
},
withCredentials: true,
});