From 6f20ef7273be8701f3ce3df9f61b3c57614070cf Mon Sep 17 00:00:00 2001 From: bicochan Date: Tue, 29 Sep 2026 14:29:13 +0900 Subject: [PATCH] =?UTF-8?q?[as]=20feat:=20=EB=B3=B4=EC=99=84=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81=20(260929?= =?UTF-8?q?=5F1429)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/as/src/entities/adstdstr/index.ts | 1 + .../lib/use-find-user-sido-gugun-combo.ts | 26 ++++++++++ .../elapr/ui/elapr-approval-dialog.tsx | 10 ++-- .../design-cnstn/ui/design-form-page.tsx | 8 ++-- .../design-cnstn/ui/design-list-page.tsx | 16 ++----- .../pages/fnrs-cnsltn/ui/fnrs-form-page.tsx | 5 +- .../pages/fnrs-cnsltn/ui/fnrs-list-page.tsx | 16 ++----- .../pages/instl-sncn/ui/instl-form-page.tsx | 28 ++++++----- .../pages/instl-sncn/ui/instl-list-page.tsx | 24 +++++----- .../ui/sewer-bsc-plan-apply-dialog.tsx | 47 ++++++++----------- .../ui/sewer-bsc-plan-form-page.tsx | 21 ++++----- .../ui/sewer-bsc-plan-list-page.tsx | 16 ++----- .../ui/attachments-form-section.tsx | 2 +- .../ui/pbadms-task-apply-dialog.tsx | 35 +++++--------- 14 files changed, 125 insertions(+), 130 deletions(-) create mode 100644 apps/as/src/entities/adstdstr/lib/use-find-user-sido-gugun-combo.ts diff --git a/apps/as/src/entities/adstdstr/index.ts b/apps/as/src/entities/adstdstr/index.ts index 2fffe5a79..638fb3414 100644 --- a/apps/as/src/entities/adstdstr/index.ts +++ b/apps/as/src/entities/adstdstr/index.ts @@ -5,6 +5,7 @@ export { useFindUserGugunCombo, useFindUserSidoCombo, } from "./api/queries"; +export { useFindUserSidoGugunCombo } from "./lib/use-find-user-sido-gugun-combo"; export type { CmCdAdstDstrComboResponseDto, CmCdAdstDstrService, diff --git a/apps/as/src/entities/adstdstr/lib/use-find-user-sido-gugun-combo.ts b/apps/as/src/entities/adstdstr/lib/use-find-user-sido-gugun-combo.ts new file mode 100644 index 000000000..86fec66ea --- /dev/null +++ b/apps/as/src/entities/adstdstr/lib/use-find-user-sido-gugun-combo.ts @@ -0,0 +1,26 @@ +import { useUserStore } from "@/shared/lib"; + +import { useFindUserGugunCombo, useFindUserSidoCombo } from "../api/queries"; +import type { CmCdAdstDstrComboResponseDto } from "../model/adstdstr-interface"; + +const EMPTY_ADST_LIST: CmCdAdstDstrComboResponseDto[] = []; + +export function useFindUserSidoGugunCombo(sidoComCd: string) { + const userInfo = useUserStore((state) => state.userInfo); + const sidoFilterUserInfo = + userInfo?.dtlInstCd === "ROLE_USER04" || userInfo?.dtlInstCd === "ROLE_USER05" + ? userInfo + : undefined; + + const { data: userSidoData, isPending: isUserSidoPending } = + useFindUserSidoCombo(sidoFilterUserInfo); + const { data: userGugunData, isPending: isUserGugunPending } = + useFindUserGugunCombo(sidoComCd); + + return { + userSidoData: userSidoData ?? EMPTY_ADST_LIST, + userGugunData: userGugunData ?? EMPTY_ADST_LIST, + isUserSidoPending, + isUserGugunPending, + }; +} diff --git a/apps/as/src/entities/elapr/ui/elapr-approval-dialog.tsx b/apps/as/src/entities/elapr/ui/elapr-approval-dialog.tsx index ed8a5de01..72824428e 100644 --- a/apps/as/src/entities/elapr/ui/elapr-approval-dialog.tsx +++ b/apps/as/src/entities/elapr/ui/elapr-approval-dialog.tsx @@ -103,6 +103,8 @@ function ElaprApprovalDialog({ const currentUserPrgrs = findCurrentUserPendingApprovalRequest(cyclDocPrgrsList, currentUserUuid); const canApprove = Boolean(currentUserPrgrs?.elaprPrgrsId); + const canReject = + currentUserPrgrs?.atrzSeComCd === "ATRZ03" || currentUserPrgrs?.atrzSeComCd === "ATRZ99"; const pickingRow = pickingRowKey ? rows.find((r) => r.rowKey === pickingRowKey) : undefined; const isBusy = isProcessing || savePrgrsSttsMutation.isPending; @@ -392,9 +394,11 @@ function ElaprApprovalDialog({ - + {canReject && ( + + )} )} diff --git a/apps/as/src/pages/design-cnstn/ui/design-form-page.tsx b/apps/as/src/pages/design-cnstn/ui/design-form-page.tsx index 276073307..85242d34b 100644 --- a/apps/as/src/pages/design-cnstn/ui/design-form-page.tsx +++ b/apps/as/src/pages/design-cnstn/ui/design-form-page.tsx @@ -9,7 +9,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { useQueryClient } from "@tanstack/react-query"; import { getListHref, useAlertStore, useUserStore, withListQs } from "@/shared/lib"; -import { RhfDevTool, SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui"; +import { SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui"; import { designCnstnKeys, type DesignCnstnMngDetResponseDto, @@ -26,7 +26,10 @@ import { } from "@/widgets/pbadms-sprt"; import { Button } from "@common/components"; -import { type DesignCnstnRegistFormData, designCnstnRegistSchema } from "../lib/design-cnstn-regist-schema"; +import { + type DesignCnstnRegistFormData, + designCnstnRegistSchema, +} from "../lib/design-cnstn-regist-schema"; import { buildFormPayload, getCreateDefaultValues, @@ -217,7 +220,6 @@ function DesignFormPage({ mode, initialData, createDefaults }: DesignFormPagePro - ); } diff --git a/apps/as/src/pages/design-cnstn/ui/design-list-page.tsx b/apps/as/src/pages/design-cnstn/ui/design-list-page.tsx index 5bad9950a..d578c8725 100644 --- a/apps/as/src/pages/design-cnstn/ui/design-list-page.tsx +++ b/apps/as/src/pages/design-cnstn/ui/design-list-page.tsx @@ -5,11 +5,7 @@ import { useMemo, useState } from "react"; import type { PaginationState } from "@tanstack/react-table"; import { useSearchParamsState } from "@/shared/lib"; -import { - type CmCdAdstDstrComboResponseDto, - useFindGugunCombo, - useFindSidoCombo, -} from "@/entities/adstdstr"; +import { useFindUserSidoGugunCombo } from "@/entities/adstdstr"; import { CodeSelect } from "@/entities/code"; import type { DesignCnstnMngSearchDto } from "@/entities/design-cnstn"; import { @@ -28,7 +24,6 @@ import { DesignList } from "./design-list"; const DEFAULT_PAGE_INDEX = 0; const DEFAULT_PAGE_SIZE = 10; const DEFAULT_SORT = "designCnstnDocNo,desc"; -const EMPTY_ADST_LIST: CmCdAdstDstrComboResponseDto[] = []; const ALL_SELECT_VALUE = "__ALL__"; const DEFAULT_PARAMS = { @@ -47,10 +42,7 @@ function DesignListPage() { const [sidoComCd, setSidoComCd] = useState(params.sidoComCd); const [sggComCd, setSggComCd] = useState(params.sggComCd); - const { data: sidoData } = useFindSidoCombo(); - const { data: gugunData } = useFindGugunCombo(sidoComCd); - const sidoOptions = sidoData ?? EMPTY_ADST_LIST; - const gugunOptions = gugunData ?? EMPTY_ADST_LIST; + const { userSidoData, userGugunData } = useFindUserSidoGugunCombo(sidoComCd); const pagination: PaginationState = { pageIndex: params.page, @@ -104,7 +96,7 @@ function DesignListPage() { 전체 - {sidoOptions.map((option) => ( + {userSidoData.map((option) => ( {option.adstDstrNm} @@ -126,7 +118,7 @@ function DesignListPage() { 전체 - {gugunOptions.map((option) => ( + {userGugunData.map((option) => ( {option.adstDstrNm} diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx index ffb72dc38..80e59a4c4 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx @@ -9,7 +9,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { useQueryClient } from "@tanstack/react-query"; import { getListHref, useAlertStore, useUserStore, withListQs } from "@/shared/lib"; -import { RhfDevTool, SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui"; +import { SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui"; import { useAcntgSeMngTree } from "@/entities/acntg"; import { useEsntlAtchFileMngTree } from "@/entities/esntl"; import { @@ -303,7 +303,7 @@ function FnrsFormPage({ mode, initialData, createDefaults }: FnrsFormPageProps) onClick={handleApplyClick} disabled={isSubmitting} > - 신청완료 + 신청 완료 )} @@ -272,7 +279,6 @@ function InstlFormPage({ mode, initialData, createDefaults }: InstlFormPageProps - ); } diff --git a/apps/as/src/pages/instl-sncn/ui/instl-list-page.tsx b/apps/as/src/pages/instl-sncn/ui/instl-list-page.tsx index b9b7040a5..3142c9c2b 100644 --- a/apps/as/src/pages/instl-sncn/ui/instl-list-page.tsx +++ b/apps/as/src/pages/instl-sncn/ui/instl-list-page.tsx @@ -5,8 +5,7 @@ import { useMemo, useState } from "react"; import type { PaginationState } from "@tanstack/react-table"; import { useSearchParamsState } from "@/shared/lib"; -import type { CmCdAdstDstrComboResponseDto } from "@/entities/adstdstr"; -import { useFindGugunCombo, useFindSidoCombo } from "@/entities/adstdstr"; +import { useFindUserSidoGugunCombo } from "@/entities/adstdstr"; import { CodeSelect } from "@/entities/code"; import type { InstlSncnMngSearchParams } from "@/entities/instl-sncn"; import { @@ -25,7 +24,7 @@ import { InstlList } from "./instl-list"; const DEFAULT_PAGE_INDEX = 0; const DEFAULT_PAGE_SIZE = 10; const DEFAULT_SORT = "instlSncnDocNo,desc"; -const EMPTY_ADST_LIST: CmCdAdstDstrComboResponseDto[] = []; +const ALL_SELECT_VALUE = "__ALL__"; const DEFAULT_PARAMS = { sidoComCd: "", @@ -43,10 +42,7 @@ function InstlListPage() { const [sidoComCd, setSidoComCd] = useState(params.sidoComCd); const [sggComCd, setSggComCd] = useState(params.sggComCd); - const { data: sidoData } = useFindSidoCombo(); - const { data: gugunData } = useFindGugunCombo(sidoComCd); - const sidoOptions = sidoData ?? EMPTY_ADST_LIST; - const gugunOptions = gugunData ?? EMPTY_ADST_LIST; + const { userSidoData, userGugunData } = useFindUserSidoGugunCombo(sidoComCd); const pagination: PaginationState = { pageIndex: params.page, @@ -91,7 +87,7 @@ function InstlListPage() { + - {gugunOptions.map((option) => ( + {userGugunData.map((option) => ( {option.adstDstrNm} diff --git a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-form-page.tsx b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-form-page.tsx index 89adb71a8..e8bf86da3 100644 --- a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-form-page.tsx +++ b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-form-page.tsx @@ -9,7 +9,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { useQueryClient } from "@tanstack/react-query"; import { getListHref, useAlertStore, useUserStore, withListQs } from "@/shared/lib"; -import { RhfDevTool, SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui"; +import { SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui"; import { useAcntgSeMngTree } from "@/entities/acntg"; import { useEsntlAtchFileMngTree } from "@/entities/esntl"; import { @@ -165,9 +165,7 @@ function SewerBscPlanFormPage({ alert("신청 완료되었습니다."); router.push( - withListQs( - `/sewer-bsc-plan/${result.sewerBscPlanDocNo}?chgCycl=${result.chgCycl ?? 1}`, - ), + withListQs(`/sewer-bsc-plan/${result.sewerBscPlanDocNo}?chgCycl=${result.chgCycl ?? 1}`), ); queryClient.invalidateQueries({ queryKey: sewerBscPlanKeys.all }); } catch (error) { @@ -185,7 +183,7 @@ function SewerBscPlanFormPage({ (item) => item.cmptnYn === "N" && (!item.splmntCn || !item.splmntCn.trim()), ); if (hasEmptySplmntCn) { - alert("보완요청 항목이 있습니다.\n보완완료 내용을 입력해 주세요."); + alert("보완 요청 항목이 있습니다.\n보완 완료 내용을 입력해 주세요."); return; } @@ -203,13 +201,13 @@ function SewerBscPlanFormPage({ const result = await sewerBscPlanService.submitSupplement(docNo, payload); if (!result) return; - alert("보완완료 처리되었습니다."); + alert("보완 완료 처리되었습니다."); + await queryClient.invalidateQueries({ queryKey: sewerBscPlanKeys.all }); const chgCycl = data.sewerBscPlanDtl.chgCycl ?? initialData?.detDto?.chgCycl ?? 1; router.push(withListQs(`/sewer-bsc-plan/${docNo}?chgCycl=${chgCycl}`)); - queryClient.invalidateQueries({ queryKey: sewerBscPlanKeys.all }); } catch (error) { - console.error("보완완료 실패:", error); - alert("보완완료 처리 중 오류가 발생했습니다."); + console.error("보완 완료 실패:", error); + alert("보완 완료 처리 중 오류가 발생했습니다."); } finally { setIsSubmitting(false); } @@ -298,7 +296,7 @@ function SewerBscPlanFormPage({ onClick={handleApplyClick} disabled={isSubmitting} > - 신청완료 + 신청 완료 )} @@ -325,7 +323,6 @@ function SewerBscPlanFormPage({ - ); } diff --git a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-list-page.tsx b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-list-page.tsx index 136e42d26..c1ca4a39e 100644 --- a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-list-page.tsx +++ b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-list-page.tsx @@ -5,11 +5,7 @@ import { useMemo, useState } from "react"; import type { PaginationState } from "@tanstack/react-table"; import { useSearchParamsState } from "@/shared/lib"; -import { - type CmCdAdstDstrComboResponseDto, - useFindGugunCombo, - useFindSidoCombo, -} from "@/entities/adstdstr"; +import { useFindUserSidoGugunCombo } from "@/entities/adstdstr"; import { CodeSelect } from "@/entities/code"; import type { SewerBscPlanSearchRequestDto } from "@/entities/sewer-bsc-plan"; import { @@ -28,7 +24,6 @@ import { SewerBscPlanList } from "./sewer-bsc-plan-list"; const DEFAULT_PAGE_INDEX = 0; const DEFAULT_PAGE_SIZE = 10; const DEFAULT_SORT = "sewerBscPlanDocNo,desc"; -const EMPTY_ADST_LIST: CmCdAdstDstrComboResponseDto[] = []; const ALL_SELECT_VALUE = "__ALL__"; const DEFAULT_PARAMS = { @@ -49,10 +44,7 @@ function SewerBscPlanListPage() { const [sidoComCd, setSidoComCd] = useState(params.sidoComCd); const [sggComCd, setSggComCd] = useState(params.sggComCd); - const { data: sidoData } = useFindSidoCombo(); - const { data: gugunData } = useFindGugunCombo(sidoComCd); - const sidoOptions = sidoData ?? EMPTY_ADST_LIST; - const gugunOptions = gugunData ?? EMPTY_ADST_LIST; + const { userSidoData, userGugunData } = useFindUserSidoGugunCombo(sidoComCd); const pagination: PaginationState = { pageIndex: params.page, @@ -108,7 +100,7 @@ function SewerBscPlanListPage() { 전체 - {sidoOptions.map((option) => ( + {userSidoData.map((option) => ( {option.adstDstrNm} @@ -130,7 +122,7 @@ function SewerBscPlanListPage() { 전체 - {gugunOptions.map((option) => ( + {userGugunData.map((option) => ( {option.adstDstrNm} diff --git a/apps/as/src/widgets/pbadms-sprt/ui/attachments-form-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/attachments-form-section.tsx index b69640568..8e61c7f03 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/attachments-form-section.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/attachments-form-section.tsx @@ -377,7 +377,7 @@ function AttachmentsFormSection({ return (
- {essentialFiles.length === 0 && ( + {essentialFiles.length > 0 && (

필수 첨부파일

diff --git a/apps/as/src/widgets/pbadms-sprt/ui/pbadms-task-apply-dialog.tsx b/apps/as/src/widgets/pbadms-sprt/ui/pbadms-task-apply-dialog.tsx index 640073573..0551ea6f8 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/pbadms-task-apply-dialog.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/pbadms-task-apply-dialog.tsx @@ -4,11 +4,7 @@ import { useEffect, useState } from "react"; import { useUserStore } from "@/shared/lib"; import { Field, FieldGroup, FieldLabel, FieldSet } from "@/shared/ui/field"; -import { - type CmCdAdstDstrComboResponseDto, - useFindUserGugunCombo, - useFindUserSidoCombo, -} from "@/entities/adstdstr"; +import { useFindUserSidoGugunCombo } from "@/entities/adstdstr"; import { useCodeList } from "@/entities/code"; import { Button, @@ -46,8 +42,6 @@ interface PbadmsTaskApplyDialogProps { codeUpCd?: string; } -const EMPTY_ADST_LIST: CmCdAdstDstrComboResponseDto[] = []; - function PbadmsTaskApplyDialog({ open, onOpenChange, @@ -60,18 +54,15 @@ function PbadmsTaskApplyDialog({ const [sggComCd, setSggComCd] = useState(""); const [selectedCodes, setSelectedCodes] = useState([]); - const sidoFilterUserInfo = - userInfo?.dtlInstCd === "ROLE_USER04" || userInfo?.dtlInstCd === "ROLE_USER05" - ? userInfo - : undefined; - - const { data: sidoData, isPending: isSidoPending } = useFindUserSidoCombo(sidoFilterUserInfo); - const { data: gugunData, isPending: isGugunPending } = useFindUserGugunCombo(sidoComCd); + const { + userSidoData, + userGugunData, + isUserSidoPending, + isUserGugunPending, + } = useFindUserSidoGugunCombo(sidoComCd); const { data: taskOptions, isPending: isTaskSePending } = useCodeList(codeUpCd); - const sidoOptions = sidoData ?? EMPTY_ADST_LIST; - const gugunOptions = gugunData ?? EMPTY_ADST_LIST; - const isPending = isSidoPending || isTaskSePending; + const isPending = isUserSidoPending || isTaskSePending; const canSidoGugunSelectable = userInfo?.dtlInstCd !== "ROLE_USER05"; const canConfirm = selectedCodes.length > 0 && (!canSidoGugunSelectable || !!sidoComCd); @@ -93,8 +84,8 @@ function PbadmsTaskApplyDialog({ function handleConfirm() { if (!canConfirm) return; - const sidoOption = sidoOptions.find((option) => option.adstDstrCd === sidoComCd); - const gugunOption = gugunOptions.find((option) => option.adstDstrCd === sggComCd); + const sidoOption = userSidoData.find((option) => option.adstDstrCd === sidoComCd); + const gugunOption = userGugunData.find((option) => option.adstDstrCd === sggComCd); onConfirm({ admdstCd: sggComCd || sidoComCd, @@ -137,7 +128,7 @@ function PbadmsTaskApplyDialog({ - {sidoOptions.map((option) => ( + {userSidoData.map((option) => ( {option.adstDstrNm} @@ -150,13 +141,13 @@ function PbadmsTaskApplyDialog({