Compare commits

...
7 Commits
54 changed files with 1354 additions and 707 deletions
+1
View File
@@ -36,6 +36,7 @@
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@hookform/devtools": "^4.4.0",
"@types/js-cookie": "^3.0.6",
"eslint": "^9.0.0",
"eslint-config-next": "15.3.8",
@@ -0,0 +1,24 @@
import { client } from "@/shared/api";
import { ENDPOINT } from "@/shared/config";
import type {
AiAutoPrcsLatestResponseDto,
AiAutoPrcsMngService,
} from "../model/ai-auto-prcs-mng-interface";
const BASE = ENDPOINT.AS_SERVICE.AI_AUTO_PRCS_MNG;
async function findLatestPerAutoSeByFnrsDocNo(
fnrsCnsltnDocNo: string,
atmtnSeComCd?: string,
): Promise<AiAutoPrcsLatestResponseDto[]> {
const response = await client.get<AiAutoPrcsLatestResponseDto[]>(
`${BASE}/fnrs/${fnrsCnsltnDocNo}/latest`,
{ params: atmtnSeComCd ? { atmtnSeComCd } : undefined },
);
return response.data;
}
export const aiAutoPrcsMngService = {
findLatestPerAutoSeByFnrsDocNo,
} satisfies AiAutoPrcsMngService;
@@ -0,0 +1,30 @@
import { useQuery } from "@tanstack/react-query";
import { ENDPOINT } from "@/shared/config";
import { aiAutoPrcsMngService } from "./ai-auto-prcs-mng-service";
export const aiAutoPrcsMngKeys = {
all: [ENDPOINT.AS_SERVICE.AI_AUTO_PRCS_MNG] as const,
latest: (fnrsCnsltnDocNo: string, atmtnSeComCd?: string) =>
[...aiAutoPrcsMngKeys.all, "latest", fnrsCnsltnDocNo, atmtnSeComCd ?? "all"] as const,
};
interface UseAiAutoPrcsLatestOptions {
enabled?: boolean;
atmtnSeComCd?: string;
}
export function useAiAutoPrcsLatest(
fnrsCnsltnDocNo: string | null | undefined,
options: UseAiAutoPrcsLatestOptions = {},
) {
const { enabled = true, atmtnSeComCd } = options;
return useQuery({
queryKey: aiAutoPrcsMngKeys.latest(fnrsCnsltnDocNo!, atmtnSeComCd),
queryFn: () =>
aiAutoPrcsMngService.findLatestPerAutoSeByFnrsDocNo(fnrsCnsltnDocNo!, atmtnSeComCd),
enabled: Boolean(fnrsCnsltnDocNo) && enabled,
});
}
@@ -0,0 +1,8 @@
export { aiAutoPrcsMngService } from "./api/ai-auto-prcs-mng-service";
export { aiAutoPrcsMngKeys, useAiAutoPrcsLatest } from "./api/queries";
export type {
AiAutoPrcsLatestResponseDto,
AiAutoPrcsMngService,
AiAutoSeComCd,
} from "./model/ai-auto-prcs-mng-interface";
export { AI_AUTO_SE } from "./model/ai-auto-prcs-mng-interface";
@@ -0,0 +1,44 @@
/** 자동화구분 공통코드 (AIAUTOSE) */
export const AI_AUTO_SE = {
FILE_VRFC: "FILE_VRFC",
DRAFT_GEN: "DRAFT_GEN",
COST_VRFC: "COST_VRFC",
} as const;
export type AiAutoSeComCd = (typeof AI_AUTO_SE)[keyof typeof AI_AUTO_SE];
/** 백엔드 AiAutoPrcsLatestResponseDto */
export interface AiAutoPrcsLatestResponseDto {
atmtnPrcsUuid?: string;
fnrsCnsltnDocNo?: string;
pwrkCnsltnDocNo?: string;
crtDmndUuid?: string;
atmtnSeComCd?: string;
atmtnSeComNm?: string;
bfrDocSttsComCd?: string;
bfrDocSttsComNm?: string;
aftrDocSttsComCd?: string;
aftrDocSttsComNm?: string;
atmtnPrcsSttsComCd?: string;
atmtnPrcsSttsComNm?: string;
dmndDt?: string;
dmndSysId?: string;
rplyDt?: string;
rplyRsltComCd?: string;
prcsErrCn?: string | null;
lastSttsInqDt?: string;
sttsInqRsltComCd?: string;
rtrsmCtpvNmtm?: number;
lastRtrsmDt?: string;
lastFrcSttsChgYn?: string;
isFailed?: boolean;
isRetryable?: boolean;
}
/** Controller public 메서드명·시그니처와 동일 */
export interface AiAutoPrcsMngService {
findLatestPerAutoSeByFnrsDocNo(
fnrsCnsltnDocNo: string,
atmtnSeComCd?: string,
): Promise<AiAutoPrcsLatestResponseDto[]>;
}
@@ -46,9 +46,40 @@ async function requestCostVerification(
return response.data;
}
async function reTransferDocument(
body: DcRagDocumentTransferRequestDto,
): Promise<DcRagCommonResponseDto> {
const response = await client.post<DcRagCommonResponseDto>(
`${BASE}/documents/re-transfer`,
body,
);
return response.data;
}
async function reGenerateDraft(
body: DcRagDraftGenerateRequestDto,
): Promise<DcRagDraftGenerateResponseDto> {
const response = await client.post<DcRagDraftGenerateResponseDto>(
`${BASE}/documents/draft/re-generate`,
body,
);
return response.data;
}
async function reVerifyCost(body: DcRagCostVerifyRequestDto): Promise<DcRagCommonResponseDto> {
const response = await client.post<DcRagCommonResponseDto>(
`${BASE}/documents/cost/re-verify`,
body,
);
return response.data;
}
export const dcRagApiToService = {
requestDocumentTransfer,
requestDraftGeneration,
getDraftGenerationStatus,
requestCostVerification,
reTransferDocument,
reGenerateDraft,
reVerifyCost,
} satisfies DcRagApiToService;
@@ -1,6 +1,9 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { ENDPOINT } from "@/shared/config";
import { useMutationWrapper } from "@/shared/lib";
import { aiAutoPrcsMngKeys } from "@/entities/ai-auto-prcs-mng";
import { fnrsCnsltnKeys } from "@/entities/fnrs-cnsltn";
import type { DcRagDraftStatusResponseDto } from "../model/dcrag-to-interface";
import type {
@@ -21,6 +24,18 @@ function isDraftGenerationSettled(data: DcRagDraftStatusResponseDto | undefined)
return data.events?.some((event) => event.eventType === "COMPLETED") ?? false;
}
function invalidateAfterAiRetry(
queryClient: ReturnType<typeof useQueryClient>,
fnrsCnsltnDocNo?: string,
) {
queryClient.invalidateQueries({ queryKey: dcRagApiToBaseKey });
queryClient.invalidateQueries({ queryKey: aiAutoPrcsMngKeys.all });
if (fnrsCnsltnDocNo) {
queryClient.invalidateQueries({ queryKey: fnrsCnsltnKeys.detail(fnrsCnsltnDocNo) });
queryClient.invalidateQueries({ queryKey: fnrsCnsltnKeys.all });
}
}
export function useDraftGenerationStatus(crtDmndUuid: string | null | undefined) {
return useQuery({
queryKey: [...dcRagApiToBaseKey, "getDraftGenerationStatus", crtDmndUuid],
@@ -68,3 +83,39 @@ export function useRequestCostVerification() {
},
});
}
export function useReTransferDocument() {
const queryClient = useQueryClient();
return useMutationWrapper({
mutationFn: (body: DcRagDocumentTransferRequestDto) =>
dcRagApiToService.reTransferDocument(body),
onSuccess: (_data, body) => {
invalidateAfterAiRetry(queryClient, body.fnrsCnsltnDocNo);
},
});
}
export function useReGenerateDraft() {
const queryClient = useQueryClient();
return useMutationWrapper({
mutationFn: (body: DcRagDraftGenerateRequestDto) => dcRagApiToService.reGenerateDraft(body),
onSuccess: (_data, body) => {
invalidateAfterAiRetry(queryClient, body.fnrsCnsltnDocNo);
if (body.crtDmndUuid) {
queryClient.invalidateQueries({
queryKey: [...dcRagApiToBaseKey, "getDraftGenerationStatus", body.crtDmndUuid],
});
}
},
});
}
export function useReVerifyCost() {
const queryClient = useQueryClient();
return useMutationWrapper({
mutationFn: (body: DcRagCostVerifyRequestDto) => dcRagApiToService.reVerifyCost(body),
onSuccess: (_data, body) => {
invalidateAfterAiRetry(queryClient, body.fnrsCnsltnDocNo);
},
});
}
+3
View File
@@ -2,9 +2,12 @@ export { dcRagApiToService } from "./api/dcrag-to-service";
export { dcRagApiToBaseKey } from "./api/queries";
export {
useDraftGenerationStatus,
useReGenerateDraft,
useRequestCostVerification,
useRequestDocumentTransfer,
useRequestDraftGeneration,
useReTransferDocument,
useReVerifyCost,
} from "./api/queries";
export type {
DcRagApiToService,
@@ -49,4 +49,7 @@ export interface DcRagApiToService {
): Promise<DcRagDraftGenerateResponseDto>;
getDraftGenerationStatus(crtDmndUuid: string): Promise<DcRagDraftStatusResponseDto>;
requestCostVerification(body: DcRagCostVerifyRequestDto): Promise<DcRagCommonResponseDto>;
reTransferDocument(body: DcRagDocumentTransferRequestDto): Promise<DcRagCommonResponseDto>;
reGenerateDraft(body: DcRagDraftGenerateRequestDto): Promise<DcRagDraftGenerateResponseDto>;
reVerifyCost(body: DcRagCostVerifyRequestDto): Promise<DcRagCommonResponseDto>;
}
@@ -4,9 +4,11 @@ import type { PageResponse } from "@/shared/model";
import type {
DesignCnstnApplySaveRequestDto,
DesignCnstnMngSaveRequestDto,
} from "../model/design-cnstn-apply-payload-schema";
import type {
DesignCnstnMngDetResponseDto,
DesignCnstnMngResponseDto,
DesignCnstnMngSaveRequestDto,
DesignCnstnMngSearchDto,
DesignCnstnMngService,
DesignCnstnMngUpdateRequestDto,
@@ -2,10 +2,10 @@ import { client } from "@/shared/api";
import { ENDPOINT } from "@/shared/config";
import type { PageResponse } from "@/shared/model";
import type { DesignCnstnRvwOpnnSaveRequestDto } from "../model/design-cnstn-apply-payload-schema";
import type {
DesignCnstnRvwOpnnId,
DesignCnstnRvwOpnnResponseDto,
DesignCnstnRvwOpnnSaveRequestDto,
DesignCnstnRvwOpnnSearchDto,
DesignCnstnRvwOpnnService,
DesignCnstnRvwOpnnUpdateRequestDto,
@@ -18,11 +18,13 @@ import type {
import type {
DesignCnstnApplySaveRequestDto,
DesignCnstnMngSaveRequestDto,
DesignCnstnRvwOpnnSaveRequestDto,
} from "../model/design-cnstn-apply-payload-schema";
import type {
DesignCnstnMngSearchDto,
DesignCnstnMngUpdateRequestDto,
} from "../model/design-cnstn-mng-interface";
import type {
DesignCnstnRvwOpnnSaveRequestDto,
DesignCnstnRvwOpnnSearchDto,
DesignCnstnRvwOpnnUpdateRequestDto,
} from "../model/design-cnstn-rvw-opnn-interface";
+16 -6
View File
@@ -37,6 +37,22 @@ export {
useUpdateDesignCnstnMng,
useUpdateDesignCnstnRvwOpnn,
} from "./api/queries";
export type {
BizCstItem,
BzScaleItem,
DesignCnstnApplySaveRequestDto,
DesignCnstnMngSaveRequestDto,
DesignCnstnRvwOpnnSaveRequestDto,
EsntlAtchFileItem,
} from "./model/design-cnstn-apply-payload-schema";
export {
designCnstnApplySaveSchema,
designCnstnBizCstItemSchema,
designCnstnBzScaleItemSchema,
designCnstnEsntlAtchFileItemSchema,
designCnstnMngSaveSchema,
designCnstnRvwOpnnSaveSchema,
} from "./model/design-cnstn-apply-payload-schema";
export type {
DesignCnstnBizCstId,
DesignCnstnBizCstResponseDto,
@@ -63,21 +79,15 @@ export type {
} from "./model/design-cnstn-esntl-atch-file-interface";
export type {
AtflMngClientResponseDto,
BizCstItem,
BizCstTreeDto,
BizSclTreeDto,
BzScaleItem,
DesignCnstnApplySaveRequestDto,
DesignCnstnMngDetResponseDto,
DesignCnstnMngResponseDto,
DesignCnstnMngSaveRequestDto,
DesignCnstnMngSearchDto,
DesignCnstnMngService,
DesignCnstnMngUpdateRequestDto,
DesignCnstnRvwOpnnResponseDto,
DesignCnstnRvwOpnnSaveRequestDto,
ElaprDocPrgrsClientResponseDto,
EsntlAtchFileItem,
EsntlAtchFileMngTreeResponseDto,
} from "./model/design-cnstn-mng-interface";
export type {
@@ -0,0 +1,74 @@
import { z } from "zod";
/** 백엔드 DesignCnstnMngSaveRequestDto */
export const designCnstnMngSaveSchema = z.object({
designCnstnDocNo: z.string().optional(),
admdstCd: z.string().optional(),
envoSeComCd: z.string().optional(),
taskSeComCd: z.string().optional(),
bizNm: z.string().optional(),
bizBgngYr: z.string().optional(),
bizEndYr: z.string().optional(),
bizCn: z.string().optional(),
aplcntNm: z.string().optional(),
aplcntMblTelno: z.string().optional(),
aplcntOgdpNm: z.string().optional(),
aplcntEmlAddr: z.string().optional(),
dsgnrNm: z.string().optional(),
dsgnrTelno: z.string().optional(),
dsgnrOgdpNm: z.string().optional(),
dsgnrEmlAddr: z.string().optional(),
atchFileGroupId: z.string().optional(),
prgrsSttsComCd: z.string().optional(),
});
/** 백엔드 DesignCnstnApplySaveRequestDto.BzScaleItem */
export const designCnstnBzScaleItemSchema = z.object({
cnstpSeCd: z.string().optional(),
bscPl: z.number().optional(),
budgetReflct: z.number().optional(),
thtiDsgn: z.number().optional(),
});
/** 백엔드 DesignCnstnApplySaveRequestDto.BizCstItem */
export const designCnstnBizCstItemSchema = z.object({
acntgSeCd: z.string().optional(),
bscPlanAmt: z.number().optional(),
bgtRfltAmt: z.number().optional(),
tstmDesignAmt: z.number().optional(),
});
/** 백엔드 DesignCnstnApplySaveRequestDto.EsntlAtchFileItem */
export const designCnstnEsntlAtchFileItemSchema = z.object({
esntlAtchFileId: z.string().optional(),
atchFileGroupId: z.string().optional(),
});
/** 백엔드 DesignCnstnRvwOpnnSaveRequestDto */
export const designCnstnRvwOpnnSaveSchema = z.object({
designCnstnDocNo: z.string(),
rvwOpnnSn: z.number().optional(),
opnrSeComCd: z.string().optional(),
opnrNm: z.string().optional(),
rvwRsltCn: z.string().optional(),
rvwRsltAnmlyYn: z.string().optional(),
atchFileGroupId: z.string().optional(),
});
/** 백엔드 DesignCnstnApplySaveRequestDto */
export const designCnstnApplySaveSchema = z.object({
techReViewSaveCd: z.string().optional(),
rvwStpCd: z.string().optional(),
designCnstnMng: designCnstnMngSaveSchema,
bzScaleList: z.array(designCnstnBzScaleItemSchema).optional(),
bizCstList: z.array(designCnstnBizCstItemSchema).optional(),
esntlAtchFileList: z.array(designCnstnEsntlAtchFileItemSchema).optional(),
rvwOpnnList: z.array(designCnstnRvwOpnnSaveSchema).optional(),
});
export type DesignCnstnMngSaveRequestDto = z.infer<typeof designCnstnMngSaveSchema>;
export type BzScaleItem = z.infer<typeof designCnstnBzScaleItemSchema>;
export type BizCstItem = z.infer<typeof designCnstnBizCstItemSchema>;
export type EsntlAtchFileItem = z.infer<typeof designCnstnEsntlAtchFileItemSchema>;
export type DesignCnstnRvwOpnnSaveRequestDto = z.infer<typeof designCnstnRvwOpnnSaveSchema>;
export type DesignCnstnApplySaveRequestDto = z.infer<typeof designCnstnApplySaveSchema>;
@@ -1,22 +1,12 @@
import type {
BizCstSaveBase,
BzScaleSaveBase,
EsntlAtchFileSaveBase,
PageableParams,
PageResponse,
PbadmsApplySaveHeader,
PbadmsMngDetResponseBase,
} from "@/shared/model";
import type { PageableParams, PageResponse, PbadmsMngDetResponseBase } from "@/shared/model";
import type {
DesignCnstnRvwOpnnResponseDto,
DesignCnstnRvwOpnnSaveRequestDto,
} from "./design-cnstn-rvw-opnn-interface";
DesignCnstnApplySaveRequestDto,
DesignCnstnMngSaveRequestDto,
} from "./design-cnstn-apply-payload-schema";
import type { DesignCnstnRvwOpnnResponseDto } from "./design-cnstn-rvw-opnn-interface";
export type {
DesignCnstnRvwOpnnResponseDto,
DesignCnstnRvwOpnnSaveRequestDto,
} from "./design-cnstn-rvw-opnn-interface";
export type { DesignCnstnRvwOpnnResponseDto } from "./design-cnstn-rvw-opnn-interface";
export type {
AtflMngClientResponseDto,
BizCstTreeDto,
@@ -25,28 +15,6 @@ export type {
EsntlAtchFileMngTreeResponseDto,
} from "@/shared/model";
/** 백엔드 DesignCnstnMngSaveRequestDto */
export interface DesignCnstnMngSaveRequestDto {
designCnstnDocNo?: string;
admdstCd?: string;
envoSeComCd?: string;
taskSeComCd?: string;
bizNm?: string;
bizBgngYr?: string;
bizEndYr?: string;
bizCn?: string;
aplcntNm?: string;
aplcntMblTelno?: string;
aplcntOgdpNm?: string;
aplcntEmlAddr?: string;
dsgnrNm?: string;
dsgnrTelno?: string;
dsgnrOgdpNm?: string;
dsgnrEmlAddr?: string;
atchFileGroupId?: string;
prgrsSttsComCd?: string;
}
/** 백엔드 DesignCnstnMngUpdateRequestDto */
export type DesignCnstnMngUpdateRequestDto = Omit<DesignCnstnMngSaveRequestDto, "designCnstnDocNo">;
@@ -88,30 +56,12 @@ interface DesignCnstnMngResponseExtension {
export type DesignCnstnMngResponseDto = Omit<DesignCnstnMngSaveRequestDto, "designCnstnDocNo"> &
DesignCnstnMngResponseExtension;
/** 백엔드 DesignCnstnApplySaveRequestDto.BzScaleItem */
export type BzScaleItem = BzScaleSaveBase;
/** 백엔드 DesignCnstnApplySaveRequestDto.BizCstItem */
export type BizCstItem = BizCstSaveBase;
/** 백엔드 DesignCnstnApplySaveRequestDto.EsntlAtchFileItem */
export type EsntlAtchFileItem = EsntlAtchFileSaveBase;
/** 백엔드 DesignCnstnMngDetResponseDto */
export type DesignCnstnMngDetResponseDto = PbadmsMngDetResponseBase<
DesignCnstnMngResponseDto,
DesignCnstnRvwOpnnResponseDto
>;
/** 백엔드 DesignCnstnApplySaveRequestDto */
export interface DesignCnstnApplySaveRequestDto extends PbadmsApplySaveHeader {
designCnstnMng: DesignCnstnMngSaveRequestDto;
bzScaleList?: BzScaleItem[];
bizCstList?: BizCstItem[];
esntlAtchFileList?: EsntlAtchFileItem[];
rvwOpnnList?: DesignCnstnRvwOpnnSaveRequestDto[];
}
/** Controller public 메서드명·시그니처와 동일 */
export interface DesignCnstnMngService {
findPage(searchDto: DesignCnstnMngSearchDto): Promise<PageResponse<DesignCnstnMngResponseDto>>;
@@ -1,22 +1,13 @@
import type { PageableParams, PageResponse, RvwOpnnResponseExtension } from "@/shared/model";
import type { DesignCnstnRvwOpnnSaveRequestDto } from "./design-cnstn-apply-payload-schema";
/** 백엔드 DesignCnstnRvwOpnnId */
export interface DesignCnstnRvwOpnnId {
designCnstnMng: string;
rvwOpnnSn: number;
}
/** 백엔드 DesignCnstnRvwOpnnSaveRequestDto */
export interface DesignCnstnRvwOpnnSaveRequestDto {
designCnstnDocNo: string;
rvwOpnnSn?: number;
opnrSeComCd?: string;
opnrNm?: string;
rvwRsltCn?: string;
rvwRsltAnmlyYn?: string;
atchFileGroupId?: string;
}
/** 백엔드 DesignCnstnRvwOpnnUpdateRequestDto */
export interface DesignCnstnRvwOpnnUpdateRequestDto {
opnrSeComCd?: string;
@@ -3,12 +3,14 @@ import { ENDPOINT } from "@/shared/config";
import type { PageResponse } from "@/shared/model";
import type {
DocPrgrsUpdateRequestDto,
FnrsCnsltnApplySaveRequestDto,
FnrsCnsltnMngSaveRequestDto,
} from "../model/fnrs-cnsltn-apply-payload-schema";
import type {
DocPrgrsUpdateRequestDto,
FnrsCnsltnFileVrfcRsltResponseDto,
FnrsCnsltnMngDetResponseDto,
FnrsCnsltnMngResponseDto,
FnrsCnsltnMngSaveRequestDto,
FnrsCnsltnMngSearchDto,
FnrsCnsltnMngService,
FnrsCnsltnMngUpdateRequestDto,
@@ -1,9 +1,11 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type {
DocPrgrsUpdateRequestDto,
FnrsCnsltnApplySaveRequestDto,
FnrsCnsltnMngSaveRequestDto,
} from "../model/fnrs-cnsltn-apply-payload-schema";
import type {
DocPrgrsUpdateRequestDto,
FnrsCnsltnMngSearchDto,
FnrsCnsltnMngUpdateRequestDto,
} from "../model/fnrs-cnsltn-interface";
+23 -9
View File
@@ -16,30 +16,44 @@ export {
useUpdateFnrsCnsltnMng,
} from "./api/queries";
export type {
AtflMngClientResponseDto,
BizCstItem,
BizCstTreeDto,
BizSclTreeDto,
BzScaleItem,
CklstResultItem,
EsntlAtchFileItem,
FnrsCnsltnApplySaveRequestDto,
FnrsCnsltnMngSaveRequestDto,
FnrsCnsltnRvwOpnnSaveRequestDto,
FnrsCnsltnSplmntDmndItem,
FnrsSharItem,
} from "./model/fnrs-cnsltn-apply-payload-schema";
export {
fnrsCnsltnApplySaveSchema,
fnrsCnsltnBizCstItemSchema,
fnrsCnsltnBzScaleItemSchema,
fnrsCnsltnCklstResultItemSchema,
fnrsCnsltnEsntlAtchFileItemSchema,
fnrsCnsltnMngSaveSchema,
fnrsCnsltnRvwOpnnSaveSchema,
fnrsCnsltnSplmntDmndItemSchema,
fnrsSharItemSchema,
} from "./model/fnrs-cnsltn-apply-payload-schema";
export type {
AtflMngClientResponseDto,
BizCstTreeDto,
BizSclTreeDto,
CklstRvwRsltTreeDto,
DocPrgrsUpdateRequestDto,
ElaprDocPrgrsClientResponseDto,
EsntlAtchFileItem,
EsntlAtchFileMngTreeResponseDto,
FnrsCnsltnApplySaveRequestDto,
FnrsCnsltnFileVrfcRsltResponseDto,
FnrsCnsltnMngDetResponseDto,
FnrsCnsltnMngResponseDto,
FnrsCnsltnMngSaveRequestDto,
FnrsCnsltnMngSearchDto,
FnrsCnsltnMngService,
FnrsCnsltnMngUpdateRequestDto,
FnrsCnsltnRvwOpnnResponseDto,
FnrsCnsltnRvwOpnnSaveRequestDto,
FnrsCnsltnSplmntDmndItem,
FnrsCnsltnSplmntDmndResponseDto,
FnrsSharItem,
RagIndexingInfoDto,
} from "./model/fnrs-cnsltn-interface";
export type {
EnvoActnReviewReqDto,
@@ -0,0 +1,120 @@
import { z } from "zod";
/** 백엔드 FnrsCnsltnMngSaveRequestDto */
export const fnrsCnsltnMngSaveSchema = z.object({
fnrsCnsltnDocNo: z.string().optional(),
admdstCd: z.string().optional(),
envoSeComCd: z.string().optional(),
taskSeComCd: z.string().optional(),
cfmtnBgtBizNo: z.string().optional(),
bgtAplyYr: z.string().optional(),
bizNm: z.string().optional(),
bizBgngYr: z.string().optional(),
bizEndYr: z.string().optional(),
bizCn: z.string().optional(),
aplcntNm: z.string().optional(),
aplcntMblTelno: z.string().optional(),
aplcntOgdpNm: z.string().optional(),
aplcntEmlAddr: z.string().optional(),
dsgnrNm: z.string().optional(),
dsgnrTelno: z.string().optional(),
dsgnrOgdpNm: z.string().optional(),
dsgnrEmlAddr: z.string().optional(),
atchFileGroupId: z.string().optional(),
sharAtchFileGroupId: z.string().optional(),
prgrsSttsComCd: z.string().optional(),
rtlztnFcltSeComCd: z.string().optional(),
rtlztnUsgSeComCd: z.string().optional(),
});
/** 백엔드 FnrsCnsltnApplySaveRequestDto.BzScaleItem */
export const fnrsCnsltnBzScaleItemSchema = z.object({
cnstpSeCd: z.string().optional(),
bscPl: z.number().optional(),
budgetReflct: z.number().optional(),
thtiDsgn: z.number().optional(),
});
/** 백엔드 FnrsCnsltnApplySaveRequestDto.BizCstItem */
export const fnrsCnsltnBizCstItemSchema = z.object({
acntgSeCd: z.string().optional(),
bscPlanAmt: z.number().optional(),
bgtRfltAmt: z.number().optional(),
tstmDesignAmt: z.number().optional(),
});
/** 백엔드 FnrsCnsltnApplySaveRequestDto.CklstResultItem */
export const fnrsCnsltnCklstResultItemSchema = z.object({
cklstRvwSn: z.number().optional(),
cklstArtclSn: z.number().optional(),
cklstSn: z.number().optional(),
rvwStpComCd: z.string().nullish(),
selected: z.enum(["Y", "N"]).nullish(),
picRvwCn: z.string().nullish(),
});
/** 백엔드 FnrsCnsltnApplySaveRequestDto.EsntlAtchFileItem */
export const fnrsCnsltnEsntlAtchFileItemSchema = z.object({
esntlAtchFileId: z.string().optional(),
atchFileGroupId: z.string().optional(),
});
/** 백엔드 FnrsCnsltnApplySaveRequestDto.FnrsCnsltnSplmntDmndItem */
export const fnrsCnsltnSplmntDmndItemSchema = z.object({
splmntDmndSn: z.number().nullish(),
splmntArtclComCd: z.string().nullish(),
splmntDmndCn: z.string().optional(),
splmntDmndDt: z.string().optional(),
splmntDmndAtchFileGroupId: z.string().optional(),
splmntCn: z.string().optional(),
splmntPicNm: z.string().optional(),
splmntCmptnDt: z.string().optional(),
splmntAtchFileGroupId: z.string().optional(),
cmptnYn: z.string().optional(),
});
/** 백엔드 FnrsCnsltnRvwOpnnSaveRequestDto */
export const fnrsCnsltnRvwOpnnSaveSchema = z.object({
fnrsCnsltnDocNo: z.string(),
rvwOpnnSn: z.number().optional(),
opnrSeComCd: z.string().optional(),
opnrNm: z.string().optional(),
rvwRsltCn: z.string().optional(),
rvwRsltAnmlyYn: z.string().optional(),
atchFileGroupId: z.string().optional(),
});
/** 백엔드 FnrsCnsltnApplySaveRequestDto.FnrsSharItem */
export const fnrsSharItemSchema = z.object({
fnrsSharSeCd: z.string().optional(),
exstnAmt: z.number().optional(),
chgRqtAmt: z.number().optional(),
ajmtAmt: z.number().optional(),
rmrkCn: z.string().optional(),
envoRmrkCn: z.string().optional(),
});
/** 백엔드 FnrsCnsltnApplySaveRequestDto */
export const fnrsCnsltnApplySaveSchema = z.object({
techReViewSaveCd: z.string().optional(),
rvwStpCd: z.string().optional(),
fnrsCnsltnMng: fnrsCnsltnMngSaveSchema,
bzScaleList: z.array(fnrsCnsltnBzScaleItemSchema).optional(),
bizCstList: z.array(fnrsCnsltnBizCstItemSchema).optional(),
cklstResultList: z.array(fnrsCnsltnCklstResultItemSchema).optional(),
cklstResultMap: z.record(z.array(fnrsCnsltnCklstResultItemSchema)).optional(),
esntlAtchFileList: z.array(fnrsCnsltnEsntlAtchFileItemSchema).optional(),
rvwOpnnList: z.array(fnrsCnsltnRvwOpnnSaveSchema).optional(),
splmntDmndList: z.array(fnrsCnsltnSplmntDmndItemSchema).optional(),
fnrsSharList: z.array(fnrsSharItemSchema).optional(),
});
export type FnrsCnsltnMngSaveRequestDto = z.infer<typeof fnrsCnsltnMngSaveSchema>;
export type BzScaleItem = z.infer<typeof fnrsCnsltnBzScaleItemSchema>;
export type BizCstItem = z.infer<typeof fnrsCnsltnBizCstItemSchema>;
export type CklstResultItem = z.infer<typeof fnrsCnsltnCklstResultItemSchema>;
export type EsntlAtchFileItem = z.infer<typeof fnrsCnsltnEsntlAtchFileItemSchema>;
export type FnrsCnsltnSplmntDmndItem = z.infer<typeof fnrsCnsltnSplmntDmndItemSchema>;
export type FnrsCnsltnRvwOpnnSaveRequestDto = z.infer<typeof fnrsCnsltnRvwOpnnSaveSchema>;
export type FnrsSharItem = z.infer<typeof fnrsSharItemSchema>;
export type FnrsCnsltnApplySaveRequestDto = z.infer<typeof fnrsCnsltnApplySaveSchema>;
@@ -1,21 +1,20 @@
import type {
AtflMngClientResponseDto,
BizCstSaveBase,
BzScaleSaveBase,
CklstResultSaveBase,
DocPrgrsUpdateRequestDto,
EsntlAtchFileSaveBase,
PageableParams,
PageResponse,
PbadmsApplySaveHeader,
PbadmsMngDetResponseBase,
RvwOpnnResponseExtension,
RvwOpnnSaveBase,
SplmntDmndResponseExtension,
SplmntDmndSaveBase,
} from "@/shared/model";
import type { FnrsSharBizCstTreeDto } from "@/entities/fnrs-shar-se";
import type {
FnrsCnsltnApplySaveRequestDto,
FnrsCnsltnMngSaveRequestDto,
FnrsCnsltnRvwOpnnSaveRequestDto,
FnrsCnsltnSplmntDmndItem,
} from "./fnrs-cnsltn-apply-payload-schema";
import type {
EnvoActnReviewReqDto,
FnrsExamineRequestDto,
@@ -31,33 +30,6 @@ export type {
EsntlAtchFileMngTreeResponseDto,
} from "@/shared/model";
/** 백엔드 FnrsCnsltnMngSaveRequestDto */
export interface FnrsCnsltnMngSaveRequestDto {
fnrsCnsltnDocNo?: string;
admdstCd?: string;
envoSeComCd?: string;
taskSeComCd?: string;
cfmtnBgtBizNo?: string;
bgtAplyYr?: string;
bizNm?: string;
bizBgngYr?: string;
bizEndYr?: string;
bizCn?: string;
aplcntNm?: string;
aplcntMblTelno?: string;
aplcntOgdpNm?: string;
aplcntEmlAddr?: string;
dsgnrNm?: string;
dsgnrTelno?: string;
dsgnrOgdpNm?: string;
dsgnrEmlAddr?: string;
atchFileGroupId?: string;
sharAtchFileGroupId?: string;
prgrsSttsComCd?: string;
rtlztnFcltSeComCd?: string;
rtlztnUsgSeComCd?: string;
}
/** 백엔드 FnrsCnsltnMngUpdateRequestDto */
export type FnrsCnsltnMngUpdateRequestDto = Omit<FnrsCnsltnMngSaveRequestDto, "fnrsCnsltnDocNo">;
@@ -110,34 +82,6 @@ interface FnrsCnsltnMngResponseExtension {
export type FnrsCnsltnMngResponseDto = Omit<FnrsCnsltnMngSaveRequestDto, "fnrsCnsltnDocNo"> &
FnrsCnsltnMngResponseExtension;
export type BzScaleItem = BzScaleSaveBase;
export type BizCstItem = BizCstSaveBase;
export interface CklstResultItem extends CklstResultSaveBase {
selected?: string;
}
export type EsntlAtchFileItem = EsntlAtchFileSaveBase;
export type FnrsCnsltnSplmntDmndItem = SplmntDmndSaveBase;
/** 백엔드 FnrsCnsltnApplySaveRequestDto.FnrsSharItem */
export interface FnrsSharItem {
fnrsSharSeCd?: string;
exstnAmt?: number;
chgRqtAmt?: number;
ajmtAmt?: number;
rmrkCn?: string;
envoRmrkCn?: string;
}
/** 백엔드 FnrsCnsltnRvwOpnnSaveRequestDto */
export interface FnrsCnsltnRvwOpnnSaveRequestDto extends RvwOpnnSaveBase {
fnrsCnsltnDocNo: string;
rvwOpnnSn: number;
}
/** 백엔드 FnrsCnsltnRvwOpnnResponseDto */
export type FnrsCnsltnRvwOpnnResponseDto = Partial<
Pick<FnrsCnsltnRvwOpnnSaveRequestDto, "fnrsCnsltnDocNo" | "rvwOpnnSn">
@@ -151,6 +95,14 @@ export type FnrsCnsltnSplmntDmndResponseDto = FnrsCnsltnSplmntDmndItem &
fnrsCnsltnDocNo?: string;
};
/** 백엔드 RagIndexingInfoDto */
export interface RagIndexingInfoDto {
isInProgress: boolean;
elapsedSeconds?: number;
estimatedRemainingSeconds?: number;
message?: string;
}
/** 백엔드 FnrsCnsltnMngDetResponseDto */
export type FnrsCnsltnMngDetResponseDto = PbadmsMngDetResponseBase<
FnrsCnsltnMngResponseDto,
@@ -159,21 +111,9 @@ export type FnrsCnsltnMngDetResponseDto = PbadmsMngDetResponseBase<
> & {
fnrsSharList?: FnrsSharBizCstTreeDto[];
sharAtchFileList?: AtflMngClientResponseDto[];
ragIndexingInfo?: RagIndexingInfoDto | null;
};
/** 백엔드 FnrsCnsltnApplySaveRequestDto */
export interface FnrsCnsltnApplySaveRequestDto extends PbadmsApplySaveHeader {
fnrsCnsltnMng: FnrsCnsltnMngSaveRequestDto;
bzScaleList?: BzScaleItem[];
bizCstList?: BizCstItem[];
cklstResultList?: CklstResultItem[];
cklstResultMap?: Record<string, CklstResultItem[]>;
esntlAtchFileList?: EsntlAtchFileItem[];
rvwOpnnList?: FnrsCnsltnRvwOpnnSaveRequestDto[];
splmntDmndList?: FnrsCnsltnSplmntDmndItem[];
fnrsSharList?: FnrsSharItem[];
}
/** 백엔드 FnrsCnsltnFileVrfcRsltResponseDto */
export interface FnrsCnsltnFileVrfcRsltResponseDto {
fileSeComCd?: string;
@@ -2,13 +2,15 @@ import { client } from "@/shared/api";
import { ENDPOINT } from "@/shared/config";
import type { PageResponse } from "@/shared/model";
import type {
InstlSncnApplySaveRequestDto,
InstlSncnMngSaveRequestDto,
} from "../model/instl-sncn-apply-payload-schema";
import type {
AdstZoneResponseDto,
DocPrgrsUpdateRequestDto,
InstlSncnApplySaveRequestDto,
InstlSncnMngDetResponse,
InstlSncnMngResponseDto,
InstlSncnMngSaveRequestDto,
InstlSncnMngSearchParams,
InstlSncnMngService,
InstlSncnMngUpdateRequestDto,
@@ -3,9 +3,11 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { ENDPOINT } from "@/shared/config";
import type {
DocPrgrsUpdateRequestDto,
InstlSncnApplySaveRequestDto,
InstlSncnMngSaveRequestDto,
} from "../model/instl-sncn-apply-payload-schema";
import type {
DocPrgrsUpdateRequestDto,
InstlSncnMngSearchParams,
InstlSncnMngUpdateRequestDto,
} from "../model/instl-sncn-interface";
+20 -8
View File
@@ -9,6 +9,26 @@ export {
useInstlSncnSubmitSupplement,
useInstlSncnTechReview,
} from "./api/queries";
export type {
InstlSncnApplySaveRequestDto,
InstlSncnBizCstSaveRequestDto,
InstlSncnBzScaleSaveDto,
InstlSncnCklstResultSaveDto,
InstlSncnEsntlAtchFileSaveDto,
InstlSncnMngSaveRequestDto,
InstlSncnRvwOpnnSaveRequestDto,
InstlSncnSplmntDmndSaveDto,
} from "./model/instl-sncn-apply-payload-schema";
export {
instlSncnApplySaveSchema,
instlSncnBizCstItemSchema,
instlSncnBzScaleItemSchema,
instlSncnCklstResultItemSchema,
instlSncnEsntlAtchFileItemSchema,
instlSncnMngSaveSchema,
instlSncnRvwOpnnSaveSchema,
instlSncnSplmntDmndItemSchema,
} from "./model/instl-sncn-apply-payload-schema";
export {
type AdstZoneResponseDto,
type AtflMngClientResponseDto,
@@ -19,18 +39,10 @@ export {
type ElaprDocPrgrsClientResponseDto,
type EsntlAtchFileMngTreeResponseDto,
INSTL_SNCN_REGISTER_SELECTION_KEY,
type InstlSncnApplySaveRequestDto,
type InstlSncnBizCstSaveRequestDto,
type InstlSncnBzScaleSaveDto,
type InstlSncnCklstResultSaveDto,
type InstlSncnEsntlAtchFileSaveDto,
type InstlSncnMngDetResponse,
type InstlSncnMngResponseDto,
type InstlSncnMngSaveRequestDto,
type InstlSncnMngSearchParams,
type InstlSncnRvwOpnnResponseDto,
type InstlSncnRvwOpnnSaveRequestDto,
type InstlSncnSplmntDmndResponseDto,
type InstlSncnSplmntDmndSaveDto,
type ReviewStepCode,
} from "./model/instl-sncn-interface";
@@ -0,0 +1,108 @@
import { z } from "zod";
/** 백엔드 InstlSncnMngSaveRequestDto */
export const instlSncnMngSaveSchema = z.object({
instlSncnDocNo: z.string().optional(),
admdstCd: z.string().optional(),
envoSeComCd: z.string().optional(),
sncnSeComCd: z.string().optional(),
taskSeComCd: z.string().optional(),
bgtBizCd: z.string().optional(),
bgtAplyYr: z.string().optional(),
bizNm: z.string().optional(),
bizBgngYr: z.string().optional(),
bizEndYr: z.string().optional(),
bizCn: z.string().optional(),
aplcntNm: z.string().optional(),
aplcntMblTelno: z.string().optional(),
aplcntOgdpNm: z.string().optional(),
aplcntEmlAddr: z.string().optional(),
dsgnrNm: z.string().optional(),
dsgnrTelno: z.string().optional(),
dsgnrOgdpNm: z.string().optional(),
dsgnrEmlAddr: z.string().optional(),
atchFileGroupId: z.string().optional(),
prgrsSttsComCd: z.string().optional(),
rtlztnFcltSeComCd: z.string().optional(),
rtlztnUsgSeComCd: z.string().optional(),
});
/** 백엔드 InstlSncnApplySaveRequestDto.BzScaleItem (diff는 API 미전송) */
export const instlSncnBzScaleItemSchema = z.object({
cnstpSeCd: z.string().optional(),
bscPl: z.number().optional(),
budgetReflct: z.number().optional(),
thtiDsgn: z.number().optional(),
});
/** 백엔드 InstlSncnApplySaveRequestDto.BizCstItem */
export const instlSncnBizCstItemSchema = z.object({
acntgSeCd: z.string().optional(),
bscPlanAmt: z.number().optional(),
bgtRfltAmt: z.number().optional(),
tstmDesignAmt: z.number().optional(),
});
/** 백엔드 InstlSncnApplySaveRequestDto.CklstResultItem */
export const instlSncnCklstResultItemSchema = z.object({
cklstRvwSn: z.number().optional(),
cklstArtclSn: z.number().optional(),
cklstSn: z.number().optional(),
rvwStpComCd: z.string().nullish(),
selected: z.enum(["Y", "N"]).nullish(),
picRvwCn: z.string().nullish(),
});
/** 백엔드 InstlSncnApplySaveRequestDto.EsntlAtchFileItem */
export const instlSncnEsntlAtchFileItemSchema = z.object({
esntlAtchFileId: z.string().optional(),
atchFileGroupId: z.string().optional(),
});
/** 백엔드 InstlSncnRvwOpnnSaveRequestDto */
export const instlSncnRvwOpnnSaveSchema = z.object({
instlSncnDocNo: z.string(),
rvwOpnnSn: z.number().optional(),
opnrSeComCd: z.string().optional(),
opnrNm: z.string().optional(),
rvwRsltCn: z.string().optional(),
rvwRsltAnmlyYn: z.string().optional(),
atchFileGroupId: z.string().optional(),
});
/** 백엔드 InstlSncnApplySaveRequestDto.InstlSncnSplmntDmndItem */
export const instlSncnSplmntDmndItemSchema = z.object({
splmntDmndSn: z.number().nullish(),
splmntArtclComCd: z.string().nullish(),
splmntDmndCn: z.string().optional(),
splmntDmndDt: z.string().optional(),
splmntDmndAtchFileGroupId: z.string().optional(),
splmntCn: z.string().optional(),
splmntPicNm: z.string().optional(),
splmntCmptnDt: z.string().optional(),
splmntAtchFileGroupId: z.string().optional(),
cmptnYn: z.string().optional(),
});
/** 백엔드 InstlSncnApplySaveRequestDto */
export const instlSncnApplySaveSchema = z.object({
techReViewSaveCd: z.string().optional(),
rvwStpCd: z.string().optional(),
instlSncnMng: instlSncnMngSaveSchema,
bzScaleList: z.array(instlSncnBzScaleItemSchema).optional(),
bizCstList: z.array(instlSncnBizCstItemSchema).optional(),
cklstResultList: z.array(instlSncnCklstResultItemSchema).optional(),
cklstResultMap: z.record(z.array(instlSncnCklstResultItemSchema)).optional(),
esntlAtchFileList: z.array(instlSncnEsntlAtchFileItemSchema).optional(),
rvwOpnnList: z.array(instlSncnRvwOpnnSaveSchema).optional(),
splmntDmndList: z.array(instlSncnSplmntDmndItemSchema).optional(),
});
export type InstlSncnMngSaveRequestDto = z.infer<typeof instlSncnMngSaveSchema>;
export type InstlSncnBzScaleSaveDto = z.infer<typeof instlSncnBzScaleItemSchema>;
export type InstlSncnBizCstSaveRequestDto = z.infer<typeof instlSncnBizCstItemSchema>;
export type InstlSncnCklstResultSaveDto = z.infer<typeof instlSncnCklstResultItemSchema>;
export type InstlSncnEsntlAtchFileSaveDto = z.infer<typeof instlSncnEsntlAtchFileItemSchema>;
export type InstlSncnRvwOpnnSaveRequestDto = z.infer<typeof instlSncnRvwOpnnSaveSchema>;
export type InstlSncnSplmntDmndSaveDto = z.infer<typeof instlSncnSplmntDmndItemSchema>;
export type InstlSncnApplySaveRequestDto = z.infer<typeof instlSncnApplySaveSchema>;
@@ -1,24 +1,24 @@
import type {
AtflMngClientResponseDto,
BizCstSaveBase,
BizCstTreeDto,
BizSclTreeDto,
BzScaleSaveBase,
CklstResultSaveBase,
DocPrgrsUpdateRequestDto,
ElaprDocPrgrsClientResponseDto,
EsntlAtchFileMngTreeResponseDto,
EsntlAtchFileSaveBase,
PageableParams,
PageResponse,
PbadmsApplySaveHeader,
PbadmsMngDetResponseBase,
RvwOpnnResponseExtension,
RvwOpnnSaveBase,
SplmntDmndResponseExtension,
SplmntDmndSaveBase,
} from "@/shared/model";
import type {
InstlSncnApplySaveRequestDto,
InstlSncnMngSaveRequestDto,
InstlSncnRvwOpnnSaveRequestDto,
InstlSncnSplmntDmndSaveDto,
} from "./instl-sncn-apply-payload-schema";
export type {
AtflMngClientResponseDto,
BizCstTreeDto,
@@ -41,189 +41,48 @@ export const INSTL_SNCN_REGISTER_SELECTION_KEY = "instlSncnRegisterSelection";
/** 백엔드 InstlSncnMngSearchDto + Pageable */
export interface InstlSncnMngSearchParams extends PageableParams {
/** 설치인가문서번호 */
instlSncnDocNo?: string;
/** 행정구역코드 */
admdstCd?: string;
/** 환경청구분공통코드 */
envoSeComCd?: string;
/** 업무구분공통코드 */
taskSeComCd?: string;
/** 예산사업코드 */
bgtBizCd?: string;
/** 예산신청연도 */
bgtAplyYr?: string;
/** 사업명 */
bizNm?: string;
/** 사업시작연도 */
bizBgngYr?: string;
/** 사업종료연도 */
bizEndYr?: string;
/** 사업내용 */
bizCn?: string;
/** 신청자명 */
aplcntNm?: string;
/** 신청자휴대전화번호 */
aplcntMblTelno?: string;
/** 신청자소속명 */
aplcntOgdpNm?: string;
/** 신청자이메일주소 */
aplcntEmlAddr?: string;
/** 설계자명 */
dsgnrNm?: string;
/** 설계자전화번호 */
dsgnrTelno?: string;
/** 설계자소속명 */
dsgnrOgdpNm?: string;
/** 설계자이메일주소 */
dsgnrEmlAddr?: string;
/** 첨부파일그룹아이디 */
atchFileGroupId?: string;
/** 진행상태공통코드 */
prgrsSttsComCd?: string;
}
/** 설치인가관리 저장 요청 DTO */
export interface InstlSncnMngSaveRequestDto {
/** 설치인가문서번호 */
instlSncnDocNo?: string;
/** 행정구역코드 */
admdstCd?: string;
/** 환경청구분공통코드 */
envoSeComCd?: string;
/** 인가구분공통코드 */
sncnSeComCd: string;
/** 업무구분공통코드 */
taskSeComCd: string;
/** 예산사업코드 */
bgtBizCd?: string;
/** 예산신청연도 */
bgtAplyYr?: string;
/** 사업명 */
bizNm: string;
/** 사업시작연도 */
bizBgngYr: string;
/** 사업종료연도 */
bizEndYr: string;
/** 사업내용 */
bizCn: string;
/** 신청자명 */
aplcntNm?: string;
/** 신청자휴대전화번호 */
aplcntMblTelno?: string;
/** 신청자소속명 */
aplcntOgdpNm?: string;
/** 신청자이메일주소 */
aplcntEmlAddr?: string;
/** 설계자명 */
dsgnrNm: string;
/** 설계자전화번호 */
dsgnrTelno: string;
/** 설계자소속명 */
dsgnrOgdpNm: string;
/** 설계자이메일주소 */
dsgnrEmlAddr: string;
/** 첨부파일그룹아이디 */
atchFileGroupId?: string;
/** 진행상태공통코드 */
prgrsSttsComCd?: string;
/** 재이용시설구분공통코드 */
rtlztnFcltSeComCd?: string;
/** 재이용용도구분공통코드 */
rtlztnUsgSeComCd?: string;
}
/** 설치인가관리 수정 요청 DTO */
/** 백엔드 InstlSncnMngUpdateRequestDto */
export type InstlSncnMngUpdateRequestDto = InstlSncnMngSaveRequestDto;
/** 설치인가관리 응답 DTO */
export interface InstlSncnMngResponseDto extends InstlSncnMngSaveRequestDto {
/** 설치인가문서번호 (필수로 재정의) */
/** 백엔드 InstlSncnMngResponseDto */
export type InstlSncnMngResponseDto = InstlSncnMngSaveRequestDto & {
instlSncnDocNo: string;
/** 환경청구분공통코드명 */
envoSeCdNm: string;
/** 인가구분공통코드명 */
sncnSeCdNm: string;
/** 업무구분공통코드명 */
taskSeCdNm: string;
/** 진행상태공통코드명 */
prgrsSttsCdNm: string;
/** 기술검토회신이력여부 */
techRplyHstryYn: "Y" | "N";
/** 재이용시설구분공통코드명 */
rtlztnFcltSeComNm: string;
/** 재이용용도구분공통코드명 */
rtlztnUsgSeComNm: string;
/** 등록일시 */
regDt: string;
/** 등록자 UUID */
rgtr: string;
/** 등록자명 */
rgtrNm: string;
/** 수정 일시 */
mdfcnDt: string;
/** 시도 */
sido: string;
/** 구군 */
gugun: string;
}
/** 설치인가 신청 - 사업규모 저장 DTO(배열 원소) */
export interface InstlSncnBzScaleSaveDto extends BzScaleSaveBase {
/** 공종구분코드 */
cnstpSeCd: string;
/** 기본계획수량 */
bscPl: number;
/** 예산반영수량 */
budgetReflct: number;
/** 금회설계수량 */
thtiDsgn: number;
/** 증감(C-B) — 클라이언트 계산용, API 미전송 */
diff?: number;
}
/** 설치인가 신청 - 총사업비 저장 DTO(배열 원소) */
export interface InstlSncnBizCstSaveRequestDto extends BizCstSaveBase {
/** 회계구분코드 */
acntgSeCd: string;
/** 기본계획금액 */
bscPlanAmt: number;
/** 예산반영금액 */
bgtRfltAmt: number;
/** 금회설계금액 */
tstmDesignAmt: number;
}
/** 설치인가 신청 - 체크리스트 결과 저장 DTO(배열 원소) */
export interface InstlSncnCklstResultSaveDto extends CklstResultSaveBase {
/** 점검표일련번호 */
cklstSn: number;
/** 점검표항목일련번호 */
cklstArtclSn: number;
/** 점검표검토일련번호 */
cklstRvwSn: number;
/** 선택값(Y/N/null) */
selected: "Y" | "N" | null;
/** 담당자검토내용(기술검토의견) */
picRvwCn?: string | null;
}
/** 설치인가 신청 - 필수첨부파일 저장 DTO(배열 원소) */
export interface InstlSncnEsntlAtchFileSaveDto extends EsntlAtchFileSaveBase {
/** 필수첨부파일아이디 */
esntlAtchFileId: string;
/** 첨부파일그룹아이디 */
atchFileGroupId: string;
}
/** 설치인가검토의견 저장 요청 DTO */
export interface InstlSncnRvwOpnnSaveRequestDto extends RvwOpnnSaveBase {
/** 설치인가문서번호 */
instlSncnDocNo: string;
}
/** 설치인가 보완요구 저장 DTO(배열 원소) */
export type InstlSncnSplmntDmndSaveDto = SplmntDmndSaveBase;
};
/** 설치인가 보완요구 응답 DTO */
export type InstlSncnSplmntDmndResponseDto = InstlSncnSplmntDmndSaveDto &
@@ -231,26 +90,6 @@ export type InstlSncnSplmntDmndResponseDto = InstlSncnSplmntDmndSaveDto &
instlSncnDocNo?: string;
};
/** 설치인가 신청 - 통합 저장 요청 DTO */
export interface InstlSncnApplySaveRequestDto extends PbadmsApplySaveHeader {
/** 설치인가관리 정보 */
instlSncnMng: InstlSncnMngSaveRequestDto;
/** 사업규모 목록 */
bzScaleList?: InstlSncnBzScaleSaveDto[];
/** 총사업비 목록 */
bizCstList?: InstlSncnBizCstSaveRequestDto[];
/** 체크리스트 검토결과 목록 */
cklstResultList?: InstlSncnCklstResultSaveDto[];
/** 체크리스트 검토결과 맵 (rvwStpComCd -> 목록) */
cklstResultMap?: Record<string, InstlSncnCklstResultSaveDto[]>;
/** 필수첨부파일 목록 */
esntlAtchFileList?: InstlSncnEsntlAtchFileSaveDto[];
/** 검토의견 목록 */
rvwOpnnList?: InstlSncnRvwOpnnSaveRequestDto[];
/** 보완요구 목록 */
splmntDmndList?: InstlSncnSplmntDmndSaveDto[];
}
export type ReviewStepCode = "LOCAL" | "ENV" | "KECO";
/** 설치인가검토의견 응답 DTO */
@@ -47,7 +47,7 @@ export const sewerBscPlanCklstResultItemSchema = z.object({
cklstArtclSn: z.number().optional(),
cklstSn: z.number().optional(),
rvwStpComCd: z.string(),
selected: z.string().optional(),
selected: z.enum(["Y", "N"]).nullish(),
picRvwCn: z.string().nullish(),
});
@@ -1,7 +1,13 @@
import { z } from "zod";
import {
designCnstnBzScaleItemSchema,
designCnstnEsntlAtchFileItemSchema,
designCnstnMngSaveSchema,
} from "@/entities/design-cnstn";
export const designCnstnRegistSchema = z.object({
designCnstnMng: z.object({
designCnstnMng: designCnstnMngSaveSchema.extend({
bizNm: z.string().min(1, "사업명은 필수입니다"),
bizBgngYr: z.string().min(1, "사업시작연도는 필수입니다"),
bizEndYr: z.string().min(1, "사업종료연도는 필수입니다"),
@@ -17,27 +23,11 @@ export const designCnstnRegistSchema = z.object({
.string()
.min(1, "설계자 이메일은 필수입니다")
.email("올바른 이메일 형식이 아닙니다"),
aplcntNm: z.string().optional(),
aplcntMblTelno: z.string().optional(),
aplcntOgdpNm: z.string().optional(),
aplcntEmlAddr: z.string().optional(),
designCnstnDocNo: z.string().optional(),
admdstCd: z.string().optional(),
envoSeComCd: z.string().optional(),
prgrsSttsComCd: z.string().optional(),
atchFileGroupId: z.string().optional(),
envoSeCdNm: z.string().optional(),
taskSeCdNm: z.string().optional(),
prgrsSttsCdNm: z.string().optional(),
sido: z.string().optional(),
gugun: z.string().optional(),
regDt: z.string().optional(),
rgtr: z.string().optional(),
rgtrNm: z.string().optional(),
mdfcnDt: z.string().optional(),
}),
bzScaleList: z.array(
z.object({
designCnstnBzScaleItemSchema.extend({
cnstpSeCd: z.string(),
bscPl: z.number(),
budgetReflct: z.number(),
@@ -46,7 +36,7 @@ export const designCnstnRegistSchema = z.object({
}),
),
esntlAtchFileList: z.array(
z.object({
designCnstnEsntlAtchFileItemSchema.extend({
esntlAtchFileId: z.string(),
atchFileGroupId: z.string(),
}),
@@ -1,9 +1,13 @@
import type { IUserInfo } from "@/shared/store";
import type { DesignCnstnMngDetResponseDto } from "@/entities/design-cnstn";
import {
type DesignCnstnApplySaveRequestDto,
designCnstnApplySaveSchema,
type DesignCnstnMngDetResponseDto,
} from "@/entities/design-cnstn";
import { toEsntlAtchFileSaveList } from "@/widgets/pbadms-sprt";
import type { DesignCnstnRegistFormData } from "./design-cnstn-regist-schema";
import { parseTaskSeComCdFromApi } from "./design-cnstn-regist-schema";
import { formatTaskSeComCdForApi, parseTaskSeComCdFromApi } from "./design-cnstn-regist-schema";
export function mapDetailToFormData(data: DesignCnstnMngDetResponseDto): DesignCnstnRegistFormData {
const detDto = data.detDto;
@@ -33,15 +37,8 @@ export function mapDetailToFormData(data: DesignCnstnMngDetResponseDto): DesignC
envoSeComCd: detDto.envoSeComCd,
prgrsSttsComCd: detDto.prgrsSttsComCd,
atchFileGroupId: detDto.atchFileGroupId ?? "",
envoSeCdNm: detDto.envoSeCdNm,
taskSeCdNm: detDto.taskSeCdNm,
prgrsSttsCdNm: detDto.prgrsSttsCdNm,
sido: detDto.sido,
gugun: detDto.gugun,
regDt: detDto.regDt,
rgtr: detDto.rgtr,
rgtrNm: detDto.rgtrNm,
mdfcnDt: detDto.mdfcnDt,
},
bzScaleList: bizSclList.map((item) => ({
cnstpSeCd: item.cnstpSeCd,
@@ -90,3 +87,20 @@ export function getCreateDefaultValues(
privacyConsent: "N",
};
}
export function buildFormPayload(
data: DesignCnstnRegistFormData,
prgrsSttsComCd: "CV" | "CT",
options: { isEditMode: boolean; docNo?: string },
): DesignCnstnApplySaveRequestDto {
return designCnstnApplySaveSchema.parse({
designCnstnMng: {
...data.designCnstnMng,
taskSeComCd: formatTaskSeComCdForApi(data.designCnstnMng.taskSeComCd),
designCnstnDocNo: options.isEditMode ? options.docNo : undefined,
prgrsSttsComCd,
},
bzScaleList: data.bzScaleList,
esntlAtchFileList: data.esntlAtchFileList,
});
}
@@ -4,6 +4,7 @@ import type {
DesignCnstnApplySaveRequestDto,
DesignCnstnMngDetResponseDto,
} from "@/entities/design-cnstn";
import { designCnstnApplySaveSchema } from "@/entities/design-cnstn";
import { toEsntlAtchFileSaveList } from "@/widgets/pbadms-sprt";
import type { ReviewStepCode } from "../model/view-types";
@@ -30,11 +31,11 @@ export function buildSavePayload(
throw new Error("상세 정보(detDto)가 없습니다.");
}
return {
return designCnstnApplySaveSchema.parse({
designCnstnMng: { ...detDto, prgrsSttsComCd },
bzScaleList: toBzScaleSaveDto(data.bizSclList ?? []),
esntlAtchFileList: toEsntlAtchFileSaveList(data.esntlFileList),
};
});
}
export function buildTechReviewPayload(
@@ -45,10 +46,10 @@ export function buildTechReviewPayload(
reviewOpinionFormData?: ReviewOpinionGetFormDataResult | null,
opnrNm?: string,
): DesignCnstnApplySaveRequestDto {
return {
return designCnstnApplySaveSchema.parse({
...buildSavePayload(data, prgrsSttsComCd),
techReViewSaveCd,
rvwStpCd: reviewStep,
rvwOpnnList: toRvwOpnnSaveDto(data, reviewOpinionFormData, opnrNm),
};
});
}
@@ -9,9 +9,8 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useQueryClient } from "@tanstack/react-query";
import { useAlertStore, useUserStore } from "@/shared/lib";
import { SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import { RhfDevTool, SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import {
type DesignCnstnApplySaveRequestDto,
designCnstnKeys,
type DesignCnstnMngDetResponseDto,
designCnstnMngService,
@@ -27,12 +26,12 @@ import {
} from "@/widgets/pbadms-sprt";
import { Button } from "@common/components";
import { type DesignCnstnRegistFormData, designCnstnRegistSchema } from "../lib/design-cnstn-regist-schema";
import {
type DesignCnstnRegistFormData,
designCnstnRegistSchema,
formatTaskSeComCdForApi,
} from "../lib/design-cnstn-regist-schema";
import { getCreateDefaultValues, mapDetailToFormData } from "../lib/form-data-mapper";
buildFormPayload,
getCreateDefaultValues,
mapDetailToFormData,
} from "../lib/form-data-mapper";
import { PROGRESS_STATUS_COLUMNS } from "../model/columns";
import { BasicInfoFormSection } from "./sections/basic-info-form-section";
@@ -68,29 +67,18 @@ function DesignFormPage({ mode, initialData, createDefaults }: DesignFormPagePro
: getCreateDefaultValues(userInfo, createDefaults),
});
function buildFormPayload(
data: DesignCnstnRegistFormData,
prgrsSttsComCd: "CV" | "CT",
): DesignCnstnApplySaveRequestDto {
const { taskSeComCd: formTaskSeComCd, ...designCnstnMngRest } = data.designCnstnMng;
return {
designCnstnMng: {
...designCnstnMngRest,
taskSeComCd: formatTaskSeComCdForApi(formTaskSeComCd),
designCnstnDocNo: isEditMode ? initialData?.detDto?.designCnstnDocNo : undefined,
prgrsSttsComCd,
},
bzScaleList: data.bzScaleList,
esntlAtchFileList: data.esntlAtchFileList,
};
function createFormPayload(data: DesignCnstnRegistFormData, prgrsSttsComCd: "CV" | "CT") {
return buildFormPayload(data, prgrsSttsComCd, {
isEditMode,
docNo: initialData?.detDto?.designCnstnDocNo,
});
}
async function submitForm(
data: DesignCnstnRegistFormData,
prgrsSttsComCd: "CV" | "CT",
): Promise<string | undefined> {
return designCnstnMngService.saveApply(buildFormPayload(data, prgrsSttsComCd));
return designCnstnMngService.saveApply(createFormPayload(data, prgrsSttsComCd));
}
async function onSave(data: DesignCnstnRegistFormData) {
@@ -229,6 +217,7 @@ function DesignFormPage({ mode, initialData, createDefaults }: DesignFormPagePro
</div>
</SectionCollapsibleGroup>
</form>
<RhfDevTool control={form.control} />
</FormProvider>
);
}
@@ -1,3 +1,5 @@
import type { RagIndexingInfoDto } from "@/entities/fnrs-cnsltn";
const AI_PENDING_STATUS_CODES = ["FV", "AC", "AV"] as const;
type AiPendingStatusCode = (typeof AI_PENDING_STATUS_CODES)[number];
@@ -17,5 +19,17 @@ function getAiPendingMessage(prgrsSttsComCd: string): string {
return AI_PENDING_MESSAGES[prgrsSttsComCd as AiPendingStatusCode];
}
export { AI_PENDING_STATUS_CODES, getAiPendingMessage, isAiPendingStatus };
function isRagIndexingInProgress(
prgrsSttsComCd: string,
ragIndexingInfo?: RagIndexingInfoDto | null,
): boolean {
return prgrsSttsComCd === "ER" && ragIndexingInfo?.isInProgress === true;
}
export {
AI_PENDING_STATUS_CODES,
getAiPendingMessage,
isAiPendingStatus,
isRagIndexingInProgress,
};
export type { AiPendingStatusCode };
@@ -9,6 +9,7 @@ export const FNRS_CNSLTN_VIEW_BUTTON_ACTION = {
rvwOpnnRply: "rvwOpnnRply",
rqstTechRvw: "rqstTechRvw",
fileSplmnt: "fileSplmnt",
fileVrfc: "fileVrfc",
dsgntRvwr: "dsgntRvwr",
pwrkCnsltnDocCrt: "pwrkCnsltnDocCrt",
pwrkCnsltnDocMng: "pwrkCnsltnDocMng",
@@ -20,6 +21,7 @@ export const FNRS_CNSLTN_VIEW_BUTTON_ACTION = {
atrzRply: "atrzRply",
actnCmptn: "actnCmptn",
rqstActnRvw: "rqstActnRvw",
costVrfc: "costVrfc",
} as const;
export type FnrsCnsltnViewButtonAction =
@@ -80,7 +82,11 @@ const ROLE_USER01_ATRZ_STATUS_ACTIONS: Record<
Record<string, FnrsCnsltnViewButtonAction[]>
> = {
ER: {
ATRZ01: [FNRS_CNSLTN_VIEW_BUTTON_ACTION.fileSplmnt, FNRS_CNSLTN_VIEW_BUTTON_ACTION.dsgntRvwr],
ATRZ01: [
FNRS_CNSLTN_VIEW_BUTTON_ACTION.fileSplmnt,
FNRS_CNSLTN_VIEW_BUTTON_ACTION.fileVrfc,
FNRS_CNSLTN_VIEW_BUTTON_ACTION.dsgntRvwr,
],
},
SL: {
ATRZ01: [FNRS_CNSLTN_VIEW_BUTTON_ACTION.pwrkCnsltnDocMng],
@@ -136,7 +142,10 @@ const ROLE_USER01_ATRZ_STATUS_ACTIONS: Record<
FNRS_CNSLTN_VIEW_BUTTON_ACTION.pwrkCnsltnDocMng,
FNRS_CNSLTN_VIEW_BUTTON_ACTION.dsgntRvwr,
],
ATRZ02: [FNRS_CNSLTN_VIEW_BUTTON_ACTION.pwrkCnsltnDocMng],
ATRZ02: [
FNRS_CNSLTN_VIEW_BUTTON_ACTION.pwrkCnsltnDocMng,
FNRS_CNSLTN_VIEW_BUTTON_ACTION.costVrfc,
],
ATRZ03: [FNRS_CNSLTN_VIEW_BUTTON_ACTION.pwrkCnsltnDocMng],
ATRZ99: [FNRS_CNSLTN_VIEW_BUTTON_ACTION.pwrkCnsltnDocMng],
},
@@ -183,6 +192,9 @@ function resolveButtonConfigs(actions: FnrsCnsltnViewButtonAction[]): FnrsCnsltn
interface GetButtonConfigsOptions {
hasPendingApprovalRequest?: boolean;
hasCompletedDraft?: boolean;
canRetryFileVrfc?: boolean;
canRetryDraftGen?: boolean;
canRetryCostVrfc?: boolean;
}
const PENDING_APPROVAL_ACTIONS = new Set<FnrsCnsltnViewButtonAction>([
@@ -220,6 +232,16 @@ function resolveRoleUser01AtrzButtonActions(
const needsPendingApproval = PENDING_APPROVAL_ACTIONS.has(action);
if (needsPendingApproval && options?.hasPendingApprovalRequest === false) return false;
if (action === FNRS_CNSLTN_VIEW_BUTTON_ACTION.fileVrfc) {
return options?.canRetryFileVrfc === true;
}
if (action === FNRS_CNSLTN_VIEW_BUTTON_ACTION.pwrkCnsltnDocCrt) {
return options?.canRetryDraftGen === true;
}
if (action === FNRS_CNSLTN_VIEW_BUTTON_ACTION.costVrfc) {
return options?.canRetryCostVrfc === true;
}
if (options?.hasCompletedDraft != null) {
if (prgrsSttsComCd === "SL" || prgrsSttsComCd === "TE" || prgrsSttsComCd === "RK") {
if (action === FNRS_CNSLTN_VIEW_BUTTON_ACTION.pwrkCnsltnDocMng) {
@@ -230,9 +252,6 @@ function resolveRoleUser01AtrzButtonActions(
if (action === FNRS_CNSLTN_VIEW_BUTTON_ACTION.rvwRsltInq) {
return options.hasCompletedDraft;
}
if (action === FNRS_CNSLTN_VIEW_BUTTON_ACTION.pwrkCnsltnDocCrt) {
return !options.hasCompletedDraft;
}
}
}
@@ -1,14 +1,22 @@
import { z } from "zod";
import {
fnrsCnsltnBizCstItemSchema,
fnrsCnsltnBzScaleItemSchema,
fnrsCnsltnCklstResultItemSchema,
fnrsCnsltnEsntlAtchFileItemSchema,
fnrsCnsltnMngSaveSchema,
fnrsCnsltnSplmntDmndItemSchema,
fnrsSharItemSchema,
} from "@/entities/fnrs-cnsltn";
export const fnrsCnsltnRegistSchema = z.object({
fnrsCnsltnMng: z.object({
fnrsCnsltnMng: fnrsCnsltnMngSaveSchema.extend({
bizNm: z.string().min(1, "사업명은 필수입니다"),
bizBgngYr: z.string().min(1, "사업시작연도는 필수입니다"),
bizEndYr: z.string().min(1, "사업종료연도는 필수입니다"),
bizCn: z.string().min(1, "사업내용은 필수입니다"),
taskSeComCd: z.array(z.string()).min(1, "구분은 필수입니다"),
cfmtnBgtBizNo: z.string().optional(),
bgtAplyYr: z.string().optional(),
dsgnrNm: z.string().min(1, "설계자 이름은 필수입니다"),
dsgnrTelno: z
.string()
@@ -19,30 +27,11 @@ export const fnrsCnsltnRegistSchema = z.object({
.string()
.min(1, "설계자 이메일은 필수입니다")
.email("올바른 이메일 형식이 아닙니다"),
aplcntNm: z.string().optional(),
aplcntMblTelno: z.string().optional(),
aplcntOgdpNm: z.string().optional(),
aplcntEmlAddr: z.string().optional(),
fnrsCnsltnDocNo: z.string().optional(),
admdstCd: z.string().optional(),
envoSeComCd: z.string().optional(),
rtlztnFcltSeComCd: z.string().optional(),
rtlztnUsgSeComCd: z.string().optional(),
prgrsSttsComCd: z.string().optional(),
atchFileGroupId: z.string().optional(),
sharAtchFileGroupId: z.string().optional(),
envoSeCdNm: z.string().optional(),
taskSeCdNm: z.string().optional(),
prgrsSttsCdNm: z.string().optional(),
sido: z.string().optional(),
gugun: z.string().optional(),
regDt: z.string().optional(),
rgtr: z.string().optional(),
rgtrNm: z.string().optional(),
mdfcnDt: z.string().optional(),
}),
bzScaleList: z.array(
z.object({
fnrsCnsltnBzScaleItemSchema.extend({
cnstpSeCd: z.string(),
bscPl: z.number(),
budgetReflct: z.number(),
@@ -51,7 +40,7 @@ export const fnrsCnsltnRegistSchema = z.object({
}),
),
bizCstList: z.array(
z.object({
fnrsCnsltnBizCstItemSchema.extend({
acntgSeCd: z.string(),
bscPlanAmt: z.number(),
bgtRfltAmt: z.number(),
@@ -59,7 +48,7 @@ export const fnrsCnsltnRegistSchema = z.object({
}),
),
fnrsSharList: z.array(
z.object({
fnrsSharItemSchema.extend({
fnrsSharSeCd: z.string(),
exstnAmt: z.number(),
chgRqtAmt: z.number(),
@@ -68,37 +57,24 @@ export const fnrsCnsltnRegistSchema = z.object({
}),
),
cklstResultList: z.array(
z.object({
fnrsCnsltnCklstResultItemSchema.extend({
cklstSn: z.number(),
cklstArtclSn: z.number(),
cklstRvwSn: z.number(),
rvwStpComCd: z.string().nullish(),
selected: z.enum(["Y", "N"]).nullable(),
selected: z.enum(["Y", "N"]).nullish(),
picRvwCn: z.string().nullish(),
}),
),
esntlAtchFileList: z.array(
z.object({
fnrsCnsltnEsntlAtchFileItemSchema.extend({
esntlAtchFileId: z.string(),
atchFileGroupId: z.string(),
}),
),
splmntDmndList: z.array(
z.object({
splmntDmndSn: z.number().nullish(),
splmntArtclComCd: z.string().nullish(),
fnrsCnsltnSplmntDmndItemSchema.extend({
splmntArtclCdNm: z.string().nullish(),
splmntDmndCn: z.string().optional(),
splmntDmndDt: z.string().optional(),
splmntDmndAtchFileGroupId: z.string().optional(),
splmntDmndAtchFileNm: z.string().optional(),
splmntCn: z.string().optional(),
splmntPicNm: z.string().optional(),
splmntCmptnDt: z.string().optional(),
splmntAtchFileGroupId: z.string().optional(),
splmntAtchFileNm: z.string().optional(),
splmntAtchFileAtflId: z.string().optional(),
cmptnYn: z.string().optional(),
}),
),
privacyConsent: z.enum(["Y", "N"], {
@@ -1,9 +1,21 @@
import type { IUserInfo } from "@/shared/store";
import type { FnrsCnsltnMngDetResponseDto } from "@/entities/fnrs-cnsltn";
import { mapFnrsSharDetToFormList, toEsntlAtchFileSaveList } from "@/widgets/pbadms-sprt";
import {
type FnrsCnsltnApplySaveRequestDto,
fnrsCnsltnApplySaveSchema,
type FnrsCnsltnMngDetResponseDto,
} from "@/entities/fnrs-cnsltn";
import {
type CostItemDef,
type FnrsSharItemDef,
mapFnrsSharDetToFormList,
recalculateFnrsSharTotals,
toEsntlAtchFileSaveList,
toFnrsSharSaveList,
validateBizCstSharBalance,
} from "@/widgets/pbadms-sprt";
import type { FnrsCnsltnRegistFormData } from "./fnrs-cnsltn-regist-schema";
import { parseTaskSeComCdFromApi } from "./fnrs-cnsltn-regist-schema";
import { formatTaskSeComCdForApi, parseTaskSeComCdFromApi } from "./fnrs-cnsltn-regist-schema";
function mapSelectedValue(value?: string | null): "Y" | "N" | null {
if (value === "Y" || value === "N") return value;
@@ -47,15 +59,8 @@ export function mapDetailToFormData(data: FnrsCnsltnMngDetResponseDto): FnrsCnsl
prgrsSttsComCd: detDto.prgrsSttsComCd,
atchFileGroupId: detDto.atchFileGroupId ?? "",
sharAtchFileGroupId: detDto.sharAtchFileGroupId ?? "",
envoSeCdNm: detDto.envoSeCdNm,
taskSeCdNm: detDto.taskSeCdNm,
prgrsSttsCdNm: detDto.prgrsSttsCdNm,
sido: detDto.sido,
gugun: detDto.gugun,
regDt: detDto.regDt,
rgtr: detDto.rgtr,
rgtrNm: detDto.rgtrNm,
mdfcnDt: detDto.mdfcnDt,
},
bzScaleList: bizSclList.map((item) => ({
cnstpSeCd: item.cnstpSeCd,
@@ -94,8 +99,6 @@ export function mapDetailToFormData(data: FnrsCnsltnMngDetResponseDto): FnrsCnsl
splmntPicNm: item.splmntPicNm ?? "",
splmntCmptnDt: item.splmntCmptnDt ?? "",
splmntAtchFileGroupId: item.splmntAtchFileGroupId ?? "",
splmntAtchFileNm: item.splmntAtchFileInfo?.orgnlFileNm ?? "",
splmntAtchFileAtflId: item.splmntAtchFileInfo?.atflId ?? "",
cmptnYn: item.cmptnYn,
})) ?? [],
privacyConsent: "Y",
@@ -146,3 +149,46 @@ export function getCreateDefaultValues(
privacyConsent: "N",
};
}
export function buildFormPayload(
data: FnrsCnsltnRegistFormData,
prgrsSttsComCd: string,
options: {
isEditMode: boolean;
docNo?: string;
sharItems: FnrsSharItemDef[];
costItems: CostItemDef[];
},
): FnrsCnsltnApplySaveRequestDto | { validationMessage: string } {
const withTotals = recalculateFnrsSharTotals(data.fnrsSharList, options.sharItems);
const validationMessage = validateBizCstSharBalance(
data.bizCstList,
withTotals,
options.sharItems,
options.costItems,
);
if (validationMessage) {
return { validationMessage };
}
return fnrsCnsltnApplySaveSchema.parse({
fnrsCnsltnMng: {
...data.fnrsCnsltnMng,
taskSeComCd: formatTaskSeComCdForApi(data.fnrsCnsltnMng.taskSeComCd),
fnrsCnsltnDocNo: options.isEditMode ? options.docNo : undefined,
prgrsSttsComCd,
},
bzScaleList: data.bzScaleList,
bizCstList: data.bizCstList,
fnrsSharList: toFnrsSharSaveList(withTotals),
cklstResultList: data.cklstResultList.map((item) => ({
...item,
selected: item.selected ?? undefined,
})),
esntlAtchFileList: data.esntlAtchFileList,
splmntDmndList: data.splmntDmndList.map((item) => ({
...item,
...(prgrsSttsComCd !== "SV" && prgrsSttsComCd !== "ST" && { cmptnYn: "Y" }),
})),
});
}
@@ -10,6 +10,7 @@ import type {
FnrsCnsltnMngResponseDto,
FnrsCnsltnSplmntDmndItem,
} from "@/entities/fnrs-cnsltn";
import { fnrsCnsltnApplySaveSchema } from "@/entities/fnrs-cnsltn";
import type { PwrkCnsltnCnsltnResponseDto } from "@/entities/pwrk-cnsltn-mng";
import {
mapFnrsSharDetToFormList,
@@ -61,14 +62,14 @@ export function buildSavePayload(
const cklstResultList = data.cklstResultList ?? [];
const esntlFileList = data.esntlFileList ?? [];
return {
return fnrsCnsltnApplySaveSchema.parse({
fnrsCnsltnMng: { ...detDto, prgrsSttsComCd },
bzScaleList: toBzScaleSaveDto(bizSclList),
bizCstList: toBizCstSaveDto(bizCstList),
cklstResultList: toCklstSaveDto(cklstResultList, checklistFormState, reviewStep),
esntlAtchFileList: toEsntlAtchFileSaveList(esntlFileList),
fnrsSharList: toFnrsSharSaveList(mapFnrsSharDetToFormList(data.fnrsSharList ?? [])),
};
});
}
export function buildTechReviewReplyPayload(
@@ -80,12 +81,12 @@ export function buildTechReviewReplyPayload(
reviewOpinionFormData?: ReviewOpinionGetFormDataResult | null,
opnrNm?: string,
): FnrsCnsltnApplySaveRequestDto {
return {
return fnrsCnsltnApplySaveSchema.parse({
...buildSavePayload(data, checklistFormState, reviewStep, prgrsSttsComCd),
techReViewSaveCd,
rvwStpCd: reviewStep,
rvwOpnnList: toRvwOpnnSaveDto(data, reviewOpinionFormData, opnrNm),
};
});
}
export function buildSupplementReqPayload(
@@ -107,10 +108,10 @@ export function buildSupplementReqPayload(
cmptnYn: "N",
}));
return {
return fnrsCnsltnApplySaveSchema.parse({
...buildSavePayload(data, checklistFormState, "LOCAL", "SL"),
splmntDmndList: [...existingItems, ...newItems],
};
});
}
export function buildFileSplmntReqPayload(
@@ -124,10 +125,10 @@ export function buildFileSplmntReqPayload(
cmptnYn: "N",
}));
return {
return fnrsCnsltnApplySaveSchema.parse({
...buildSavePayload(data, checklistFormState, "LOCAL", "SL"),
splmntDmndList: [...newItems],
};
});
}
export function buildRvwRsltSplmntReqPayload(
@@ -144,10 +145,10 @@ export function buildRvwRsltSplmntReqPayload(
cmptnYn: "N",
}));
return {
return fnrsCnsltnApplySaveSchema.parse({
...buildSavePayload(data, checklistFormState, "LOCAL", "SL"),
splmntDmndList: [...existingItems, ...newItems],
};
});
}
export function toSplmntDmndSaveItem(item: FnrsCnsltnSplmntDmndItem): FnrsCnsltnSplmntDmndItem {
@@ -169,21 +170,21 @@ export function buildSupplementSubmitPayload(
data: FnrsCnsltnMngDetResponseDto,
checklistFormState: ChecklistFormState,
): FnrsCnsltnApplySaveRequestDto {
return {
return fnrsCnsltnApplySaveSchema.parse({
...buildSavePayload(data, checklistFormState, "LOCAL", "SL"),
splmntDmndList: data.splmntDmndList,
};
splmntDmndList: (data.splmntDmndList ?? []).map(toSplmntDmndSaveItem),
});
}
export function buildTechReviewPayload(
det: FnrsCnsltnMngResponseDto,
cklstResultList: CklstResultItem[],
): FnrsCnsltnApplySaveRequestDto {
return {
return fnrsCnsltnApplySaveSchema.parse({
fnrsCnsltnMng: { ...det, prgrsSttsComCd: "ER" },
bzScaleList: [],
bizCstList: [],
cklstResultList,
esntlAtchFileList: [],
};
});
}
@@ -9,6 +9,12 @@ import { AxiosError } from "axios";
import { ENDPOINT } from "@/shared/config";
import { useAlertStore, useUserStore } from "@/shared/lib";
import {
AI_AUTO_SE,
type AiAutoPrcsLatestResponseDto,
useAiAutoPrcsLatest,
} from "@/entities/ai-auto-prcs-mng";
import { useReGenerateDraft, useReTransferDocument, useReVerifyCost } from "@/entities/dcrag-to";
import {
buildElaprPrgrsSttsListFromAplnRows,
ElaprApprovalDialog,
@@ -41,6 +47,7 @@ import {
import { SplmntDmndDialog, type SplmntDmndDialogConfirmPayload } from "@/widgets/pbadms-sprt";
import { Button } from "@common/components";
import { isRagIndexingInProgress } from "../../lib/ai-pending-utils";
import {
FNRS_CNSLTN_VIEW_BUTTON_ACTION,
type FnrsCnsltnViewButtonAction,
@@ -63,6 +70,15 @@ import { FileVrfcSplmntDialog } from "./file-vrfc-splmnt-dialog";
import { PwrkCnsltnDocMngDialog } from "./pwrk-cnsltn-doc-mng-dialog";
import { PwrkCnsltnRvwRsltInqDialog } from "./pwrk-cnsltn-rvw-rslt-inq-dialog";
const AI_RETRY_PRGRS_STTS = new Set(["ER", "TE", "EV"]);
function findLatestByAutoSe(
list: AiAutoPrcsLatestResponseDto[] | undefined,
atmtnSeComCd: string,
): AiAutoPrcsLatestResponseDto | undefined {
return list?.find((item) => item.atmtnSeComCd === atmtnSeComCd);
}
interface FloatingActionButtonsProps {
data: FnrsCnsltnMngDetResponseDto;
docSeComCd: string;
@@ -117,7 +133,9 @@ function FloatingActionButtons({
const needsPwrkDraftCheck =
dtlInstCd === "ROLE_USER01" && ["SL", "TE", "RK"].includes(prgrsSttsComCd);
const needsPwrkForRb = dtlInstCd === "ROLE_USER05" && prgrsSttsComCd === "RB";
const needsPwrkLookup = needsPwrkDraftCheck || needsPwrkForRb;
const needsPwrkForAiRetry = dtlInstCd === "ROLE_USER01" && ["TE", "EV"].includes(prgrsSttsComCd);
const needsPwrkLookup = needsPwrkDraftCheck || needsPwrkForRb || needsPwrkForAiRetry;
const needsAiAutoLatest = dtlInstCd === "ROLE_USER01" && AI_RETRY_PRGRS_STTS.has(prgrsSttsComCd);
const { data: elaprDocPrgrsList = [], isLoading: isElaprDocPrgrsLoading } =
useElaprDocPrgrsByDocNo(needsElaprPrgrsCheck ? docNo : null);
@@ -127,8 +145,31 @@ function FloatingActionButtons({
needsPwrkLookup,
);
const { data: aiAutoLatestList, isLoading: isAiAutoLatestLoading } = useAiAutoPrcsLatest(docNo, {
enabled: needsAiAutoLatest,
});
const fileVrfcLatest = findLatestByAutoSe(aiAutoLatestList, AI_AUTO_SE.FILE_VRFC);
const draftGenLatest = findLatestByAutoSe(aiAutoLatestList, AI_AUTO_SE.DRAFT_GEN);
const costVrfcLatest = findLatestByAutoSe(aiAutoLatestList, AI_AUTO_SE.COST_VRFC);
const canRetryFileVrfc = fileVrfcLatest?.isRetryable === true;
const canRetryDraftGen = draftGenLatest?.isRetryable === true;
const canRetryCostVrfc = costVrfcLatest?.isRetryable === true;
const reTransferDocument = useReTransferDocument();
const reGenerateDraft = useReGenerateDraft();
const reVerifyCost = useReVerifyCost();
const isBusy =
isProcessing ||
reTransferDocument.isPending ||
reGenerateDraft.isPending ||
reVerifyCost.isPending;
const hasCompletedDraft = Boolean(findCompletedPwrkDraft(pwrkCnsltnData));
const pwrkCnsltnDocNo = pwrkCnsltnData?.pwrkCnsltnDocNo;
const pwrkCnsltnDocNo =
pwrkCnsltnData?.pwrkCnsltnDocNo ??
draftGenLatest?.pwrkCnsltnDocNo ??
costVrfcLatest?.pwrkCnsltnDocNo;
const elaprPrgrsForPending =
prgrsSttsComCd === "RK"
@@ -145,18 +186,27 @@ function FloatingActionButtons({
if (needsAtrzResolve && isRvwLoginUserLoading) return [];
if (needsElaprPrgrsCheck && isElaprDocPrgrsLoading) return [];
if (needsPwrkDraftCheck && isPwrkCnsltnLoading) return [];
if (needsAiAutoLatest && isAiAutoLatestLoading) return [];
return getButtonConfigs(dtlInstCd, prgrsSttsComCd, atrzSeComCdList, {
hasPendingApprovalRequest: needsElaprPrgrsCheck ? hasPendingApprovalRequest : undefined,
hasCompletedDraft: needsPwrkDraftCheck ? hasCompletedDraft : undefined,
canRetryFileVrfc: needsAiAutoLatest ? canRetryFileVrfc : undefined,
canRetryDraftGen: needsAiAutoLatest ? canRetryDraftGen : undefined,
canRetryCostVrfc: needsAiAutoLatest ? canRetryCostVrfc : undefined,
});
}, [
atrzSeComCdList,
canRetryCostVrfc,
canRetryDraftGen,
canRetryFileVrfc,
dtlInstCd,
hasCompletedDraft,
hasPendingApprovalRequest,
isAiAutoLatestLoading,
isElaprDocPrgrsLoading,
isPwrkCnsltnLoading,
isRvwLoginUserLoading,
needsAiAutoLatest,
needsAtrzResolve,
needsElaprPrgrsCheck,
needsPwrkDraftCheck,
@@ -369,19 +419,6 @@ function FloatingActionButtons({
}
async function handleRqstTechRvwClick() {
if (prgrsSttsComCd === "LE") {
const { percent } = computeReviewStepChecklistProgress(
data.cklstResultList ?? [],
checklistFormState.results,
"ENV",
);
if (percent !== 100) {
alert("모든 체크리스트 항목을 체크해야 기술 검토 의뢰가 가능합니다.");
return;
}
}
const payload: FnrsExamineRequestDto = {
prgrsSttsComCd: "FV",
};
@@ -543,17 +580,60 @@ function FloatingActionButtons({
});
}
function handleFileVrfcClick() {
reTransferDocument.mutate(
{ fnrsCnsltnDocNo: docNo },
{ onSuccess: () => alert("파일 검증을 요청했습니다.") },
);
}
function handlePwrkCnsltnDocCrtClick() {
if (!pwrkCnsltnDocNo) {
alert("실무협의 문서번호를 찾을 수 없습니다.");
return;
}
reGenerateDraft.mutate(
{
fnrsCnsltnDocNo: docNo,
pwrkCnsltnDocNo,
crtDmndUuid: draftGenLatest?.crtDmndUuid,
},
{ onSuccess: () => alert("초안 생성을 요청했습니다.") },
);
}
function handleCostVrfcClick() {
if (!pwrkCnsltnDocNo) {
alert("실무협의 문서번호를 찾을 수 없습니다.");
return;
}
reVerifyCost.mutate(
{
fnrsCnsltnDocNo: docNo,
pwrkCnsltnDocNo,
},
{ onSuccess: () => alert("금액 검증을 요청했습니다.") },
);
}
return (
<>
<div className="sticky bottom-0 z-40 !-mb-2 border-t bg-white pb-8 pt-6 shadow-[0_-4px_12px_rgba(0,0,0,0.06)]">
<div className="mx-4 flex flex-wrap justify-center gap-3 sm:gap-4">
<Button color="white" type="button" onClick={handleGoToList} disabled={isProcessing}>
<Button color="white" type="button" onClick={handleGoToList} disabled={isBusy}>
목록
</Button>
{!isAiPending && (
<>
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.pwrkCnsltnDocCrt) && (
<Button color="orange" onClick={() => {}} disabled={isProcessing}>
<Button
color="orange"
onClick={handlePwrkCnsltnDocCrtClick}
disabled={isBusy}
title={draftGenLatest?.prcsErrCn ?? undefined}
>
실무협의서 초안 생성
</Button>
)}
@@ -561,103 +641,118 @@ function FloatingActionButtons({
<Button
color="orange"
onClick={() => setActiveDialog("pwrkCnsltnDocMng")}
disabled={isProcessing}
disabled={isBusy}
>
실무협의서 관리
</Button>
)}
{canEdit && (
<Button color="gray" onClick={handleEdit} disabled={isProcessing}>
<Button color="gray" onClick={handleEdit} disabled={isBusy}>
수정
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.strg) && (
<Button onClick={handleStrgClick} disabled={isProcessing}>
<Button onClick={handleStrgClick} disabled={isBusy}>
저장
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.aply) && (
<Button color="green" onClick={handleAplyClick} disabled={isProcessing}>
<Button color="green" onClick={handleAplyClick} disabled={isBusy}>
신청 완료
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.del) && (
<Button color="red" onClick={handleDelClick} disabled={isProcessing}>
<Button color="red" onClick={handleDelClick} disabled={isBusy}>
삭제
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.envoSbmsn) && (
<Button onClick={handleEnvoSbmsnClick} disabled={isProcessing}>
<Button onClick={handleEnvoSbmsnClick} disabled={isBusy}>
환경청 제출
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.rjct) && (
<Button color="red" onClick={handleRjctClick} disabled={isProcessing}>
<Button color="red" onClick={handleRjctClick} disabled={isBusy}>
반려
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.sncnAprv) && (
<Button color="green" onClick={handleSncnAprvClick} disabled={isProcessing}>
<Button color="green" onClick={handleSncnAprvClick} disabled={isBusy}>
결과 회신
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.rvwOpnnRply) && (
<Button onClick={handleRvwOpnnRplyClick} disabled={isProcessing}>
<Button onClick={handleRvwOpnnRplyClick} disabled={isBusy}>
검토 의견 회신
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.rvwRply) && (
<Button color="green" onClick={handleRvwRplyClick} disabled={isProcessing}>
<Button color="green" onClick={handleRvwRplyClick} disabled={isBusy}>
검토 결과 회신
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.rqstTechRvw) && (
<Button onClick={handleRqstTechRvwClick} disabled={isProcessing}>
<Button onClick={handleRqstTechRvwClick} disabled={isBusy}>
기술 검토 의뢰
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.rqstActnRvw) && (
<Button onClick={handleRqstActnRvwClick} disabled={isProcessing}>
<Button onClick={handleRqstActnRvwClick} disabled={isBusy}>
조치 결과 검토 의뢰
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.fileSplmnt) && (
<Button color="gray" onClick={handleFileSplmntClick} disabled={isProcessing}>
<Button color="gray" onClick={handleFileSplmntClick} disabled={isBusy}>
파일 보완 요청
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.dsgntRvwr) && (
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.fileVrfc) && (
<Button
onClick={() =>
setActiveDialog(prgrsSttsComCd === "EV" ? "elaprDocPrgrs" : "elaprTmplt")
}
disabled={isProcessing}
onClick={handleFileVrfcClick}
disabled={isBusy}
title={fileVrfcLatest?.prcsErrCn ?? undefined}
>
검토자 지정
파일 검증
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.dsgntRvwr) &&
!isRagIndexingInProgress(prgrsSttsComCd, data.ragIndexingInfo) && (
<Button
onClick={() =>
setActiveDialog(prgrsSttsComCd === "EV" ? "elaprDocPrgrs" : "elaprTmplt")
}
disabled={isBusy}
>
검토자 지정
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.costVrfc) && (
<Button
onClick={handleCostVrfcClick}
disabled={isBusy}
title={costVrfcLatest?.prcsErrCn ?? undefined}
>
금액 검증
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.actnCmptn) && (
<Button color="green" onClick={handleActnCmptnClick} disabled={isProcessing}>
<Button color="green" onClick={handleActnCmptnClick} disabled={isBusy}>
조치 완료
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.rvwRsltInq) && (
<Button
color="sky"
onClick={() => setActiveDialog("rvwRsltInq")}
disabled={isProcessing}
>
<Button color="sky" onClick={() => setActiveDialog("rvwRsltInq")} disabled={isBusy}>
검토 결과 조회
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.rvwStrg) && (
<Button onClick={handleRvwStrgClick} disabled={isProcessing}>
<Button onClick={handleRvwStrgClick} disabled={isBusy}>
저장
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.rvwCmptn) && (
<Button color="green" onClick={handleRvwCmptnClick} disabled={isProcessing}>
<Button color="green" onClick={handleRvwCmptnClick} disabled={isBusy}>
검토 완료
</Button>
)}
@@ -665,18 +760,18 @@ function FloatingActionButtons({
<Button
color="gray"
onClick={() => setActiveDialog("dmndSplmnt")}
disabled={isProcessing}
disabled={isBusy}
>
보완 요청
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.atrzAprv) && (
<Button onClick={() => setActiveDialog("elaprApproval")} disabled={isProcessing}>
<Button onClick={() => setActiveDialog("elaprApproval")} disabled={isBusy}>
결재(승인)
</Button>
)}
{shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.atrzRply) && (
<Button onClick={() => setActiveDialog("elaprApproval")} disabled={isProcessing}>
<Button onClick={() => setActiveDialog("elaprApproval")} disabled={isBusy}>
결재(회신)
</Button>
)}
@@ -705,14 +800,14 @@ function FloatingActionButtons({
splmntArtclUpCd="SPLMNTARTCL"
open={activeDialog === "dmndSplmnt"}
onOpenChange={() => setActiveDialog(null)}
isSubmitting={isProcessing}
isSubmitting={isBusy}
onConfirm={handleDmndSplmntConfirm}
/>
<FileVrfcSplmntDialog
open={activeDialog === "fileSplmnt"}
fnrsCnsltnDocNo={docNo}
isSubmitting={isProcessing}
isSubmitting={isBusy}
onClose={() => setActiveDialog(null)}
onConfirm={handleFileSplmntConfirm}
/>
@@ -746,7 +841,7 @@ function FloatingActionButtons({
<PwrkCnsltnRvwRsltInqDialog
open={activeDialog === "rvwRsltInq"}
fnrsCnsltnDocNo={docNo}
isSubmitting={isProcessing}
isSubmitting={isBusy}
onClose={() => setActiveDialog(null)}
onConfirm={handleRvwRsltSplmntConfirm}
/>
@@ -881,6 +976,7 @@ const buttonActionHandlers: Record<FnrsCnsltnViewButtonAction, ActionHandler> =
rvwOpnnRply: handleTechReview,
rqstTechRvw: handleRequestExamine,
fileSplmnt: handleDmndSplmnt,
fileVrfc: () => Promise.resolve(),
dsgntRvwr: handleDsgntRvwr,
pwrkCnsltnDocCrt: () => Promise.resolve(),
pwrkCnsltnDocMng: () => Promise.resolve(),
@@ -892,6 +988,7 @@ const buttonActionHandlers: Record<FnrsCnsltnViewButtonAction, ActionHandler> =
atrzRply: () => Promise.resolve(),
actnCmptn: handleActnCmptn,
rqstActnRvw: handleRequestActnReview,
costVrfc: () => Promise.resolve(),
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -9,11 +9,10 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useQueryClient } from "@tanstack/react-query";
import { useAlertStore, useUserStore } from "@/shared/lib";
import { SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import { RhfDevTool, SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import { useAcntgSeMngTree } from "@/entities/acntg";
import { useEsntlAtchFileMngTree } from "@/entities/esntl";
import {
type FnrsCnsltnApplySaveRequestDto,
fnrsCnsltnKeys,
type FnrsCnsltnMngDetResponseDto,
fnrsCnsltnMngService,
@@ -32,19 +31,16 @@ import {
isFormEsntlAtchComplete,
PrivacyConsentSection,
ProgressStatusSection,
recalculateFnrsSharTotals,
SplmntDmndFormSection,
toFnrsSharSaveList,
validateBizCstSharBalance,
} from "@/widgets/pbadms-sprt";
import { Button } from "@common/components";
import { type FnrsCnsltnRegistFormData, fnrsCnsltnRegistSchema } from "../lib/fnrs-cnsltn-regist-schema";
import {
type FnrsCnsltnRegistFormData,
fnrsCnsltnRegistSchema,
formatTaskSeComCdForApi,
} from "../lib/fnrs-cnsltn-regist-schema";
import { getCreateDefaultValues, mapDetailToFormData } from "../lib/form-data-mapper";
buildFormPayload,
getCreateDefaultValues,
mapDetailToFormData,
} from "../lib/form-data-mapper";
import { PROGRESS_STATUS_COLUMNS } from "../model/columns";
import { PwrkCnsltnDocMngDialog } from "./components/pwrk-cnsltn-doc-mng-dialog";
@@ -89,54 +85,25 @@ function FnrsFormPage({ mode, initialData, createDefaults }: FnrsFormPageProps)
: getCreateDefaultValues(userInfo, createDefaults),
});
function buildFormPayload(
data: FnrsCnsltnRegistFormData,
prgrsSttsComCd: string,
): FnrsCnsltnApplySaveRequestDto | undefined {
const withTotals = recalculateFnrsSharTotals(data.fnrsSharList, sharItems);
const validationMessage = validateBizCstSharBalance(
data.bizCstList,
withTotals,
function createFormPayload(data: FnrsCnsltnRegistFormData, prgrsSttsComCd: string) {
const result = buildFormPayload(data, prgrsSttsComCd, {
isEditMode,
docNo: initialData?.detDto?.fnrsCnsltnDocNo,
sharItems,
costItems,
);
if (validationMessage) {
alert(validationMessage);
});
if ("validationMessage" in result) {
alert(result.validationMessage);
return undefined;
}
const { taskSeComCd: formTaskSeComCd, ...fnrsCnsltnMngRest } = data.fnrsCnsltnMng;
return {
fnrsCnsltnMng: {
...fnrsCnsltnMngRest,
taskSeComCd: formatTaskSeComCdForApi(formTaskSeComCd),
fnrsCnsltnDocNo: isEditMode ? initialData?.detDto?.fnrsCnsltnDocNo : undefined,
prgrsSttsComCd,
},
bzScaleList: data.bzScaleList,
bizCstList: data.bizCstList,
fnrsSharList: toFnrsSharSaveList(withTotals),
cklstResultList: data.cklstResultList.map((item) => ({
...item,
selected: item.selected ?? undefined,
})),
esntlAtchFileList: data.esntlAtchFileList,
splmntDmndList: data.splmntDmndList.map(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
({ splmntAtchFileNm, splmntAtchFileAtflId, splmntDmndAtchFileNm, ...item }) => ({
...item,
...(prgrsSttsComCd !== "SV" && prgrsSttsComCd !== "ST" && { cmptnYn: "Y" }),
}),
),
};
return result;
}
async function submitForm(
data: FnrsCnsltnRegistFormData,
prgrsSttsComCd: "SV" | "ST",
): Promise<string | undefined> {
const payload = buildFormPayload(data, prgrsSttsComCd);
const payload = createFormPayload(data, prgrsSttsComCd);
if (!payload) return undefined;
return fnrsCnsltnMngService.saveApply(payload);
}
@@ -146,7 +113,7 @@ function FnrsFormPage({ mode, initialData, createDefaults }: FnrsFormPageProps)
if (!beforePrgrsSttsComCd) return undefined;
const docNo = initialData?.detDto?.fnrsCnsltnDocNo;
const payload = buildFormPayload(data, beforePrgrsSttsComCd);
const payload = createFormPayload(data, beforePrgrsSttsComCd);
if (!docNo || !payload) return undefined;
return fnrsCnsltnMngService.submitSupplement(docNo, payload);
@@ -365,6 +332,7 @@ function FnrsFormPage({ mode, initialData, createDefaults }: FnrsFormPageProps)
onClose={() => setIsPwrkCnsltnDocMngOpen(false)}
/>
) : null}
<RhfDevTool control={form.control} />
</FormProvider>
);
}
@@ -14,7 +14,7 @@ import {
} from "@/widgets/pbadms-sprt";
import { Skeleton } from "@common/components";
import { getAiPendingMessage, isAiPendingStatus } from "../lib/ai-pending-utils";
import { getAiPendingMessage, isAiPendingStatus, isRagIndexingInProgress } from "../lib/ai-pending-utils";
import { needsRoleUser01AtrzResolve } from "../lib/button-config";
import { getEditableReviewStep } from "../lib/review-step-utils";
import { EMPTY_CKLST_RESULT_LIST, useChecklistFormState } from "../lib/use-checklist-form-state";
@@ -95,20 +95,25 @@ function FnrsViewPage({ id }: FnrsViewPageProps) {
detDto.prgrsSttsComCd || "",
);
const isAiPending = isAiPendingStatus(detDto.prgrsSttsComCd || "");
const isRagIndexing = isRagIndexingInProgress(detDto.prgrsSttsComCd || "", data.ragIndexingInfo);
const showPendingBanner = isAiPending || isRagIndexing;
const pendingMessage = isRagIndexing
? (data.ragIndexingInfo?.message ?? "")
: getAiPendingMessage(detDto.prgrsSttsComCd || "");
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 />
{isAiPending && (
{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">
{getAiPendingMessage(detDto.prgrsSttsComCd || "")}
{pendingMessage}
</TextShimmer>
</div>
)}
@@ -1,9 +1,13 @@
import type { IUserInfo } from "@/shared/store/user-store";
import type { InstlSncnMngDetResponse } from "@/entities/instl-sncn";
import {
type InstlSncnApplySaveRequestDto,
instlSncnApplySaveSchema,
type InstlSncnMngDetResponse,
} from "@/entities/instl-sncn";
import { toEsntlAtchFileSaveList } from "@/widgets/pbadms-sprt";
import type { InstlSncnRegistFormData } from "./instl-sncn-regist-schema";
import { parseTaskSeComCdFromApi } from "./instl-sncn-regist-schema";
import { formatTaskSeComCdForApi, parseTaskSeComCdFromApi } from "./instl-sncn-regist-schema";
function mapSelectedValue(value?: string | null): "Y" | "N" | null {
if (value === "Y" || value === "N") return value;
@@ -16,12 +20,12 @@ export function mapDetailToFormData(data: InstlSncnMngDetResponse): InstlSncnReg
return {
instlSncnMng: {
instlSncnDocNo: detDto.instlSncnDocNo,
bizNm: detDto.bizNm,
bizBgngYr: detDto.bizBgngYr,
bizEndYr: detDto.bizEndYr,
bizCn: detDto.bizCn,
bizNm: detDto.bizNm ?? "",
bizBgngYr: detDto.bizBgngYr ?? "",
bizEndYr: detDto.bizEndYr ?? "",
bizCn: detDto.bizCn ?? "",
taskSeComCd: parseTaskSeComCdFromApi(detDto.taskSeComCd),
sncnSeComCd: detDto.sncnSeComCd,
sncnSeComCd: detDto.sncnSeComCd ?? "",
dsgnrNm: detDto.dsgnrNm ?? "",
dsgnrTelno: detDto.dsgnrTelno ?? "",
dsgnrOgdpNm: detDto.dsgnrOgdpNm ?? "",
@@ -38,16 +42,8 @@ export function mapDetailToFormData(data: InstlSncnMngDetResponse): InstlSncnReg
atchFileGroupId: detDto.atchFileGroupId ?? "",
rtlztnFcltSeComCd: detDto.rtlztnFcltSeComCd ?? "",
rtlztnUsgSeComCd: detDto.rtlztnUsgSeComCd ?? "",
envoSeCdNm: detDto.envoSeCdNm,
sncnSeCdNm: detDto.sncnSeCdNm,
taskSeCdNm: detDto.taskSeCdNm,
prgrsSttsCdNm: detDto.prgrsSttsCdNm,
sido: detDto.sido,
gugun: detDto.gugun,
regDt: detDto.regDt,
rgtr: detDto.rgtr,
rgtrNm: detDto.rgtrNm,
mdfcnDt: detDto.mdfcnDt,
},
bzScaleList: bizSclList.map((item) => ({
cnstpSeCd: item.cnstpSeCd,
@@ -85,8 +81,6 @@ export function mapDetailToFormData(data: InstlSncnMngDetResponse): InstlSncnReg
splmntPicNm: item.splmntPicNm ?? "",
splmntCmptnDt: item.splmntCmptnDt ?? "",
splmntAtchFileGroupId: item.splmntAtchFileGroupId ?? "",
splmntAtchFileNm: item.splmntAtchFileInfo?.orgnlFileNm ?? "",
splmntAtchFileAtflId: item.splmntAtchFileInfo?.atflId ?? "",
cmptnYn: item.cmptnYn,
})) ?? [],
privacyConsent: "Y",
@@ -132,3 +126,29 @@ export function getCreateDefaultValues(
privacyConsent: "N",
};
}
export function buildFormPayload(
data: InstlSncnRegistFormData,
prgrsSttsComCd: "SV" | "ST" | "TE",
options: { isEditMode: boolean; docNo?: string },
): InstlSncnApplySaveRequestDto {
return instlSncnApplySaveSchema.parse({
instlSncnMng: {
...data.instlSncnMng,
instlSncnDocNo: options.isEditMode ? options.docNo : undefined,
taskSeComCd: formatTaskSeComCdForApi(data.instlSncnMng.taskSeComCd),
prgrsSttsComCd,
},
bzScaleList: data.bzScaleList,
bizCstList: data.bizCstList,
cklstResultList: data.cklstResultList.map((item) => ({
...item,
selected: item.selected ?? undefined,
})),
esntlAtchFileList: data.esntlAtchFileList,
splmntDmndList: data.splmntDmndList.map((item) => ({
...item,
...(prgrsSttsComCd === "TE" ? { cmptnYn: "Y" } : null),
})),
});
}
@@ -1,7 +1,16 @@
import { z } from "zod";
import {
instlSncnBizCstItemSchema,
instlSncnBzScaleItemSchema,
instlSncnCklstResultItemSchema,
instlSncnEsntlAtchFileItemSchema,
instlSncnMngSaveSchema,
instlSncnSplmntDmndItemSchema,
} from "@/entities/instl-sncn";
export const instlSncnRegistSchema = z.object({
instlSncnMng: z.object({
instlSncnMng: instlSncnMngSaveSchema.extend({
bizNm: z.string().min(1, "사업명은 필수입니다"),
bizBgngYr: z.string().min(1, "사업시작연도는 필수입니다"),
bizEndYr: z.string().min(1, "사업종료연도는 필수입니다"),
@@ -18,32 +27,13 @@ export const instlSncnRegistSchema = z.object({
.string()
.min(1, "설계자 이메일은 필수입니다")
.email("올바른 이메일 형식이 아닙니다"),
bgtBizCd: z.string().optional(),
bgtAplyYr: z.string().optional(),
aplcntNm: z.string().optional(),
aplcntMblTelno: z.string().optional(),
aplcntOgdpNm: z.string().optional(),
aplcntEmlAddr: z.string().optional(),
instlSncnDocNo: z.string().nullish(),
admdstCd: z.string().optional(),
envoSeComCd: z.string().optional(),
prgrsSttsComCd: z.string().nullish(),
atchFileGroupId: z.string().optional(),
rtlztnFcltSeComCd: z.string().optional(),
rtlztnUsgSeComCd: z.string().optional(),
envoSeCdNm: z.string().nullish(),
sncnSeCdNm: z.string().nullish(),
taskSeCdNm: z.string().nullish(),
prgrsSttsCdNm: z.string().nullish(),
sido: z.string().nullish(),
gugun: z.string().nullish(),
regDt: z.string().nullish(),
rgtr: z.string().nullish(),
rgtrNm: z.string().nullish(),
mdfcnDt: z.string().nullish(),
}),
bzScaleList: z.array(
z.object({
instlSncnBzScaleItemSchema.extend({
cnstpSeCd: z.string(),
bscPl: z.number(),
budgetReflct: z.number(),
@@ -52,7 +42,7 @@ export const instlSncnRegistSchema = z.object({
}),
),
bizCstList: z.array(
z.object({
instlSncnBizCstItemSchema.extend({
acntgSeCd: z.string(),
bscPlanAmt: z.number(),
bgtRfltAmt: z.number(),
@@ -60,37 +50,25 @@ export const instlSncnRegistSchema = z.object({
}),
),
cklstResultList: z.array(
z.object({
instlSncnCklstResultItemSchema.extend({
cklstSn: z.number(),
cklstArtclSn: z.number(),
cklstRvwSn: z.number(),
rvwStpComCd: z.string(),
selected: z.enum(["Y", "N"]).nullable(),
selected: z.enum(["Y", "N"]).nullish(),
picRvwCn: z.string().nullish(),
}),
),
esntlAtchFileList: z.array(
z.object({
instlSncnEsntlAtchFileItemSchema.extend({
esntlAtchFileId: z.string(),
atchFileGroupId: z.string(),
}),
),
splmntDmndList: z.array(
z.object({
splmntDmndSn: z.number().nullish(),
splmntArtclComCd: z.string().nullish(),
instlSncnSplmntDmndItemSchema.extend({
splmntArtclCdNm: z.string().nullish(),
splmntDmndCn: z.string().optional(),
splmntDmndDt: z.string().optional(),
splmntDmndAtchFileGroupId: z.string().optional(),
splmntDmndAtchFileNm: z.string().optional(),
splmntCn: z.string().optional(),
splmntPicNm: z.string().optional(),
splmntCmptnDt: z.string().optional(),
splmntAtchFileGroupId: z.string().optional(),
splmntAtchFileNm: z.string().optional(),
splmntAtchFileAtflId: z.string().optional(),
cmptnYn: z.string().optional(),
}),
),
privacyConsent: z.enum(["Y", "N"], {
@@ -8,6 +8,7 @@ import type {
InstlSncnSplmntDmndSaveDto,
ReviewStepCode,
} from "@/entities/instl-sncn";
import { instlSncnApplySaveSchema } from "@/entities/instl-sncn";
import { type SplmntDmndDialogConfirmPayload, toEsntlAtchFileSaveList } from "@/widgets/pbadms-sprt";
import type { ChecklistFormState } from "../model/view-types";
@@ -23,7 +24,6 @@ export function toBzScaleSaveDto(bizSclList: BizSclTreeDto[]): InstlSncnBzScaleS
bscPl: node.bscPlanQty,
budgetReflct: node.bgtRfltQty,
thtiDsgn: node.tstmDesignQty,
diff: node.tstmDesignQty - node.bgtRfltQty,
}));
}
@@ -46,13 +46,13 @@ export function buildSavePayload(
): InstlSncnApplySaveRequestDto {
const { detDto, bizSclList, bizCstList, cklstResultList = [], esntlFileList } = data;
return {
return instlSncnApplySaveSchema.parse({
instlSncnMng: { ...detDto, prgrsSttsComCd },
bzScaleList: toBzScaleSaveDto(bizSclList),
bizCstList: toBizCstSaveDto(bizCstList),
cklstResultList: toCklstSaveDto(cklstResultList, checklistFormState, reviewStep),
esntlAtchFileList: toEsntlAtchFileSaveList(esntlFileList),
};
});
}
export function buildTechReviewReplyPayload(
@@ -64,12 +64,12 @@ export function buildTechReviewReplyPayload(
reviewOpinionFormData?: ReviewOpinionFormData | null,
opnrNm?: string,
): InstlSncnApplySaveRequestDto {
return {
return instlSncnApplySaveSchema.parse({
...buildSavePayload(data, checklistFormState, reviewStep, prgrsSttsComCd),
techReViewSaveCd,
rvwStpCd: reviewStep,
rvwOpnnList: toRvwOpnnSaveDto(data, reviewOpinionFormData, opnrNm),
};
});
}
export function buildSupplementReqPayload(
@@ -91,10 +91,10 @@ export function buildSupplementReqPayload(
cmptnYn: "N",
}));
return {
return instlSncnApplySaveSchema.parse({
...buildSavePayload(data, checklistFormState, "LOCAL", "SL"),
splmntDmndList: [...existingItems, ...newItems],
};
});
}
export function toSplmntDmndSaveItem(item: InstlSncnSplmntDmndSaveDto): InstlSncnSplmntDmndSaveDto {
@@ -9,10 +9,9 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useQueryClient } from "@tanstack/react-query";
import { useAlertStore, useUserStore } from "@/shared/lib";
import { SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import { RhfDevTool, SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import { useEsntlAtchFileMngTree } from "@/entities/esntl";
import {
type InstlSncnApplySaveRequestDto,
instlSncnKeys,
type InstlSncnMngDetResponse,
instlSncnService,
@@ -31,12 +30,8 @@ import {
} from "@/widgets/pbadms-sprt";
import { Button } from "@common/components";
import { getCreateDefaultValues, mapDetailToFormData } from "../lib/form-data-mapper";
import {
formatTaskSeComCdForApi,
type InstlSncnRegistFormData,
instlSncnRegistSchema,
} from "../lib/instl-sncn-regist-schema";
import { buildFormPayload, getCreateDefaultValues, mapDetailToFormData } from "../lib/form-data-mapper";
import { type InstlSncnRegistFormData, instlSncnRegistSchema } from "../lib/instl-sncn-regist-schema";
import { PROGRESS_STATUS_COLUMNS } from "../model/columns";
import { BasicInfoFormSection } from "./sections/basic-info-form-section";
@@ -72,47 +67,24 @@ function InstlFormPage({ mode, initialData, createDefaults }: InstlFormPageProps
: getCreateDefaultValues(userInfo, createDefaults),
});
function buildFormPayload(
data: InstlSncnRegistFormData,
prgrsSttsComCd: "SV" | "ST" | "TE",
): InstlSncnApplySaveRequestDto {
const { taskSeComCd: formTaskSeComCd, ...instlSncnMngRest } = data.instlSncnMng;
return {
instlSncnMng: {
...instlSncnMngRest,
instlSncnDocNo: isEditMode ? initialData?.detDto.instlSncnDocNo : undefined,
taskSeComCd: formatTaskSeComCdForApi(formTaskSeComCd),
prgrsSttsComCd,
},
bzScaleList: data.bzScaleList,
bizCstList: data.bizCstList,
cklstResultList: data.cklstResultList.map((item) => ({
...item,
selected: item.selected,
})),
esntlAtchFileList: data.esntlAtchFileList,
splmntDmndList: data.splmntDmndList.map(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
({ splmntAtchFileNm, splmntAtchFileAtflId, splmntDmndAtchFileNm, ...item }) => ({
...item,
...(prgrsSttsComCd === "TE" ? { cmptnYn: "Y" } : null),
}),
),
};
function createFormPayload(data: InstlSncnRegistFormData, prgrsSttsComCd: "SV" | "ST" | "TE") {
return buildFormPayload(data, prgrsSttsComCd, {
isEditMode,
docNo: initialData?.detDto.instlSncnDocNo,
});
}
async function submitForm(
data: InstlSncnRegistFormData,
prgrsSttsComCd: "SV" | "ST",
): Promise<string | undefined> {
return instlSncnService.saveApply(buildFormPayload(data, prgrsSttsComCd));
return instlSncnService.saveApply(createFormPayload(data, prgrsSttsComCd));
}
async function submitSupplementForm(data: InstlSncnRegistFormData): Promise<string | undefined> {
const docNo = initialData?.detDto.instlSncnDocNo;
if (!docNo) return undefined;
return instlSncnService.submitSupplement(docNo, buildFormPayload(data, "TE"));
return instlSncnService.submitSupplement(docNo, createFormPayload(data, "TE"));
}
async function onSplmntCmptn(data: InstlSncnRegistFormData) {
@@ -300,6 +272,7 @@ function InstlFormPage({ mode, initialData, createDefaults }: InstlFormPageProps
</div>
</SectionCollapsibleGroup>
</form>
<RhfDevTool control={form.control} />
</FormProvider>
);
}
@@ -3,6 +3,7 @@ import type {
SewerBscPlanDetResponseDto,
SewerBscPlanSplmntDmndItem,
} from "@/entities/sewer-bsc-plan";
import { sewerBscPlanApplySaveSchema } from "@/entities/sewer-bsc-plan";
import { type SplmntDmndDialogConfirmPayload, toEsntlAtchFileSaveList } from "@/widgets/pbadms-sprt";
import type { ChecklistFormState, ReviewStepCode } from "../model/view-types";
@@ -26,7 +27,7 @@ export function buildSavePayload(
const cklstResultRows = data.cklstResultRows ?? [];
const esntlFileList = data.esntlFileList ?? [];
return {
return sewerBscPlanApplySaveSchema.parse({
sewerBscPlan: {
sewerBscPlanDocNo: detDto.sewerBscPlanDocNo,
admdstCd: detDto.admdstCd,
@@ -99,7 +100,7 @@ export function buildSavePayload(
})),
cklstResultList: toCklstSaveDto(cklstResultRows, checklistFormState, reviewStep),
esntlAtchFileList: toEsntlAtchFileSaveList(esntlFileList),
};
});
}
export function buildTechReviewReplyPayload(
@@ -111,12 +112,12 @@ export function buildTechReviewReplyPayload(
reviewOpinionFormData?: ReviewOpinionGetFormDataResult | null,
opnrNm?: string,
): SewerBscPlanApplySaveRequestDto {
return {
return sewerBscPlanApplySaveSchema.parse({
...buildSavePayload(data, checklistFormState, reviewStep, prgrsSttsComCd),
techReViewSaveCd,
rvwStpCd: reviewStep,
rvwOpnnList: toRvwOpnnSaveDto(data, reviewOpinionFormData, opnrNm),
};
});
}
export function buildSupplementReqPayload(
@@ -136,10 +137,10 @@ export function buildSupplementReqPayload(
cmptnYn: "N",
}));
return {
return sewerBscPlanApplySaveSchema.parse({
...buildSavePayload(data, checklistFormState, "LOCAL", "SL"),
splmntDmndList: [...existingItems, ...newItems],
};
});
}
export function toSplmntDmndSaveItem(item: SewerBscPlanSplmntDmndItem): SewerBscPlanSplmntDmndItem {
@@ -77,7 +77,7 @@ export const sewerBscPlanRegistSchema = z.object({
cklstSn: z.number(),
cklstArtclSn: z.number(),
cklstRvwSn: z.number(),
selected: z.enum(["Y", "N"]).nullable(),
selected: z.enum(["Y", "N"]).nullish(),
picRvwCn: z.string().nullable().optional(),
}),
),
@@ -9,7 +9,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useQueryClient } from "@tanstack/react-query";
import { useAlertStore, useUserStore } from "@/shared/lib";
import { SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import { RhfDevTool, SectionCollapsibleGroup, SectionCollapsibleToggle } from "@/shared/ui";
import { useAcntgSeMngTree } from "@/entities/acntg";
import { useEsntlAtchFileMngTree } from "@/entities/esntl";
import {
@@ -319,6 +319,7 @@ function SewerBscPlanFormPage({
</div>
</SectionCollapsibleGroup>
</form>
<RhfDevTool control={form.control} />
</FormProvider>
);
}
+1
View File
@@ -26,6 +26,7 @@ export const ENDPOINT = {
SEWER_BSC_PLAN: "/as-service/api/v1/sewer-bsc-plans",
DASHBOARD: "/as-service/api/v1/dashboard",
DCRAG_TO: "/as-service/api/v1/dcrag-to",
AI_AUTO_PRCS_MNG: "/as-service/api/v1/ai-auto-prcs-mng",
PWRK_CNSLTN_MNG: "/as-service/api/v1/pwrk-cnsltn-mng",
PWRK_CNSLTN_DOC_CRT_RSLT: "/as-service/api/v1/pwrk-cnsltn-doc-crt-rslt",
PWRK_CNSLTN_DOC_PJTCO_AJMT_MNG: "/as-service/api/v1/pwrk-cnsltn-doc-pjtco-ajmt-mng",
@@ -1,3 +1,5 @@
"use client";
import type { HTMLAttributes } from "react";
import type { UseQueryResult } from "@tanstack/react-query";
+2
View File
@@ -1,3 +1,5 @@
"use client";
import { useCallback, useState } from "react";
import { type Upload } from "tus-js-client";
+2 -1
View File
@@ -4,6 +4,7 @@ export type { FileAddButtonProps } from "./file-add-button";
export { FileAddButton } from "./file-add-button";
export { NoData } from "./no-data";
export { PageLayout } from "./page-layout";
export { RhfDevTool } from "./rhf-devtool";
export { SectionCollapsible } from "./section-collapsible";
export {
SectionCollapsibleGroup,
@@ -12,4 +13,4 @@ export {
export type { TextShimmerProps } from "./text-shimmer";
export { TEXT_SHIMMER_CLASS, TextShimmer } from "./text-shimmer";
export type { UploadedFileChipProps } from "./uploaded-file-chip";
export { UploadedFileChip } from "./uploaded-file-chip";
export { UploadedFileChip } from "./uploaded-file-chip";
+23
View File
@@ -0,0 +1,23 @@
"use client";
import type { Control, FieldValues } from "react-hook-form";
import dynamic from "next/dynamic";
const DevTool = dynamic(() => import("@hookform/devtools").then((mod) => mod.DevTool), {
ssr: false,
});
interface RhfDevToolProps<T extends FieldValues> {
control: Control<T>;
}
export function RhfDevTool<T extends FieldValues>({ control }: RhfDevToolProps<T>) {
if (process.env.NODE_ENV !== "development") return null;
return (
<DevTool
control={control as Control<FieldValues>}
placement="bottom-right"
styles={{ button: { right: "80px", bottom: "22px", scale: 2.5 } }}
/>
);
}
@@ -22,7 +22,7 @@ interface CklstResultListItem {
cklstArtclSn: number;
cklstRvwSn: number;
rvwStpComCd?: string | null;
selected: "Y" | "N" | null;
selected?: "Y" | "N" | null;
picRvwCn?: string | null;
}
@@ -30,7 +30,7 @@ import {
buildChecklistTabs,
normalizeTaskSeComCdArray,
syncCklstResultListFromTree,
} from "../lib/checklist-form-utils";
} from "../lib/checklist-form-utils";
type FieldPrefix = "fnrsCnsltnMng" | "instlSncnMng" | "designCnstnMng" | "sewerBscPlan";
@@ -39,7 +39,7 @@ interface CklstResultListItem {
cklstArtclSn: number;
cklstRvwSn: number;
rvwStpComCd: string;
selected: "Y" | "N" | null;
selected?: "Y" | "N" | null;
picRvwCn?: string | null;
}
+275 -15
View File
@@ -202,6 +202,9 @@ importers:
'@eslint/eslintrc':
specifier: ^3
version: 3.3.5
'@hookform/devtools':
specifier: ^4.4.0
version: 4.4.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@types/js-cookie':
specifier: ^3.0.6
version: 3.0.6
@@ -282,7 +285,7 @@ importers:
version: 4.1.3(react-hook-form@7.72.0(react@19.2.4))
'@minoru/react-dnd-treeview':
specifier: 3.5.1-alpha.1
version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
version: 3.5.1-alpha.1(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-icons':
specifier: ^1.3.2
version: 1.3.2(react@19.2.4)
@@ -418,7 +421,7 @@ importers:
version: 4.1.3(react-hook-form@7.72.0(react@19.2.4))
'@minoru/react-dnd-treeview':
specifier: ^3.5.0
version: 3.5.3(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
version: 3.5.3(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-icons':
specifier: ^1.3.2
version: 1.3.2(react@19.2.4)
@@ -566,7 +569,7 @@ importers:
version: 4.1.3(react-hook-form@7.72.0(react@19.2.4))
'@minoru/react-dnd-treeview':
specifier: 3.5.1-alpha.1
version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
version: 3.5.1-alpha.1(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-icons':
specifier: ^1.3.2
version: 1.3.2(react@19.2.4)
@@ -696,7 +699,7 @@ importers:
version: 4.1.3(react-hook-form@7.72.0(react@19.2.4))
'@minoru/react-dnd-treeview':
specifier: ^3.5.0
version: 3.5.3(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
version: 3.5.3(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-label':
specifier: ^2.1.2
version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -899,7 +902,7 @@ importers:
version: 4.1.3(react-hook-form@7.72.0(react@19.2.4))
'@minoru/react-dnd-treeview':
specifier: 3.5.1-alpha.1
version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
version: 3.5.1-alpha.1(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@tailwindcss/vite':
specifier: ^4.0.10
version: 4.2.2(vite@6.4.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.1)(yaml@2.8.3))
@@ -1002,7 +1005,7 @@ importers:
version: 4.1.3(react-hook-form@7.72.0(react@19.2.4))
'@minoru/react-dnd-treeview':
specifier: 3.5.1-alpha.1
version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
version: 3.5.1-alpha.1(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-label':
specifier: ^2.1.2
version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -1174,7 +1177,7 @@ importers:
version: 4.1.3(react-hook-form@7.72.0(react@19.2.4))
'@minoru/react-dnd-treeview':
specifier: 3.5.1-alpha.1
version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
version: 3.5.1-alpha.1(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-icons':
specifier: ^1.3.2
version: 1.3.2(react@19.2.4)
@@ -1349,7 +1352,7 @@ importers:
version: 4.1.3(react-hook-form@7.72.0(react@19.2.4))
'@minoru/react-dnd-treeview':
specifier: 3.5.1-alpha.1
version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
version: 3.5.1-alpha.1(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-label':
specifier: ^2.1.2
version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -1501,7 +1504,7 @@ importers:
version: 4.1.3(react-hook-form@7.72.0(react@19.2.4))
'@minoru/react-dnd-treeview':
specifier: 3.5.1-alpha.1
version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
version: 3.5.1-alpha.1(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-label':
specifier: ^2.1.2
version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -1691,7 +1694,7 @@ importers:
version: 1.1.4
'@minoru/react-dnd-treeview':
specifier: ^3.5.0
version: 3.5.3(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
version: 3.5.3(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-accordion':
specifier: ^1.2.3
version: 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -2139,6 +2142,60 @@ packages:
'@emnapi/wasi-threads@1.2.0':
resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==}
'@emotion/babel-plugin@11.13.5':
resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==}
'@emotion/cache@11.14.0':
resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==}
'@emotion/hash@0.9.2':
resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==}
'@emotion/is-prop-valid@1.4.0':
resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==}
'@emotion/memoize@0.9.0':
resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==}
'@emotion/react@11.14.0':
resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==}
peerDependencies:
'@types/react': '*'
react: ^19.2.1
peerDependenciesMeta:
'@types/react':
optional: true
'@emotion/serialize@1.3.3':
resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==}
'@emotion/sheet@1.4.0':
resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==}
'@emotion/styled@11.14.1':
resolution: {integrity: sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==}
peerDependencies:
'@emotion/react': ^11.0.0-rc.0
'@types/react': '*'
react: ^19.2.1
peerDependenciesMeta:
'@types/react':
optional: true
'@emotion/unitless@0.10.0':
resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==}
'@emotion/use-insertion-effect-with-fallbacks@1.2.0':
resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==}
peerDependencies:
react: ^19.2.1
'@emotion/utils@1.4.2':
resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==}
'@emotion/weak-memoize@0.4.0':
resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==}
'@esbuild/aix-ppc64@0.21.5':
resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
engines: {node: '>=12'}
@@ -2677,6 +2734,12 @@ packages:
peerDependencies:
'@fullcalendar/core': ~6.1.20
'@hookform/devtools@4.4.0':
resolution: {integrity: sha512-Mtlic+uigoYBPXlfvPBfiYYUZuyMrD3pTjDpVIhL6eCZTvQkHsKBSKeZCvXWUZr8fqrkzDg27N+ZuazLKq6Vmg==}
peerDependencies:
react: ^19.2.1
react-dom: ^19.2.1
'@hookform/resolvers@4.1.3':
resolution: {integrity: sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==}
peerDependencies:
@@ -4106,6 +4169,9 @@ packages:
'@types/json5@0.0.29':
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
'@types/lodash@4.17.25':
resolution: {integrity: sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==}
'@types/mdx@2.0.13':
resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
@@ -4115,6 +4181,9 @@ packages:
'@types/node@22.19.15':
resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==}
'@types/parse-json@4.0.2':
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
'@types/react-dom@19.2.3':
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
peerDependencies:
@@ -4554,6 +4623,10 @@ packages:
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
engines: {node: '>= 0.4'}
babel-plugin-macros@3.1.0:
resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==}
engines: {node: '>=10', npm: '>=6'}
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
@@ -4753,12 +4826,19 @@ packages:
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
engines: {node: ^14.18.0 || >=16.10.0}
convert-source-map@1.9.0:
resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
cosmiconfig@7.1.0:
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
engines: {node: '>=10'}
cosmiconfig@9.0.1:
resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==}
engines: {node: '>=14'}
@@ -5254,6 +5334,7 @@ packages:
eslint@9.39.4:
resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
hasBin: true
peerDependencies:
jiti: '*'
@@ -5358,6 +5439,9 @@ packages:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
find-root@1.1.0:
resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==}
find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
@@ -5973,6 +6057,11 @@ packages:
resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==}
engines: {node: '>=20.0.0'}
little-state-machine@4.8.1:
resolution: {integrity: sha512-liPHqaWMQ7rzZryQUDnbZ1Gclnnai3dIyaJ0nAgwZRXMzqbYrydrlCI0NDojRUbE5VYh5vu6hygEUZiH77nQkQ==}
peerDependencies:
react: ^19.2.1
load-tsconfig@0.2.5:
resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -6334,6 +6423,10 @@ packages:
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
engines: {node: '>=16 || 14 >=14.18'}
path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
path-type@6.0.0:
resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==}
engines: {node: '>=18'}
@@ -6727,6 +6820,11 @@ packages:
'@types/react':
optional: true
react-simple-animate@3.5.3:
resolution: {integrity: sha512-Ob+SmB5J1tXDEZyOe2Hf950K4M8VaWBBmQ3cS2BUnTORqHjhK0iKG8fB+bo47ZL15t8d3g/Y0roiqH05UBjG7A==}
peerDependencies:
react-dom: ^19.2.1
react-smooth@4.0.4:
resolution: {integrity: sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==}
peerDependencies:
@@ -7127,6 +7225,9 @@ packages:
babel-plugin-macros:
optional: true
stylis@4.2.0:
resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==}
sucrase@3.35.1:
resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -7405,6 +7506,12 @@ packages:
'@types/react':
optional: true
use-deep-compare-effect@1.8.1:
resolution: {integrity: sha512-kbeNVZ9Zkc0RFGpfMN3MNfaKNvcLNyxOAAd9O4CBZ+kCBXXscn9s/4I+8ytUER4RDpEYs5+O6Rs4PqiZ+rHr5Q==}
engines: {node: '>=10', npm: '>=6'}
peerDependencies:
react: ^19.2.1
use-sidecar@1.1.3:
resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
engines: {node: '>=10'}
@@ -7436,6 +7543,11 @@ packages:
resolution: {integrity: sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==}
hasBin: true
uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).
hasBin: true
uuid@9.0.1:
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).
@@ -7639,6 +7751,10 @@ packages:
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
yaml@1.10.3:
resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==}
engines: {node: '>= 6'}
yaml@2.8.3:
resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==}
engines: {node: '>= 14.6'}
@@ -7913,6 +8029,89 @@ snapshots:
tslib: 2.8.1
optional: true
'@emotion/babel-plugin@11.13.5':
dependencies:
'@babel/helper-module-imports': 7.28.6
'@babel/runtime': 7.29.2
'@emotion/hash': 0.9.2
'@emotion/memoize': 0.9.0
'@emotion/serialize': 1.3.3
babel-plugin-macros: 3.1.0
convert-source-map: 1.9.0
escape-string-regexp: 4.0.0
find-root: 1.1.0
source-map: 0.7.6
stylis: 4.2.0
transitivePeerDependencies:
- supports-color
'@emotion/cache@11.14.0':
dependencies:
'@emotion/memoize': 0.9.0
'@emotion/sheet': 1.4.0
'@emotion/utils': 1.4.2
'@emotion/weak-memoize': 0.4.0
stylis: 4.2.0
'@emotion/hash@0.9.2': {}
'@emotion/is-prop-valid@1.4.0':
dependencies:
'@emotion/memoize': 0.9.0
'@emotion/memoize@0.9.0': {}
'@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4)':
dependencies:
'@babel/runtime': 7.29.2
'@emotion/babel-plugin': 11.13.5
'@emotion/cache': 11.14.0
'@emotion/serialize': 1.3.3
'@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.4)
'@emotion/utils': 1.4.2
'@emotion/weak-memoize': 0.4.0
hoist-non-react-statics: 3.3.2
react: 19.2.4
optionalDependencies:
'@types/react': 19.2.14
transitivePeerDependencies:
- supports-color
'@emotion/serialize@1.3.3':
dependencies:
'@emotion/hash': 0.9.2
'@emotion/memoize': 0.9.0
'@emotion/unitless': 0.10.0
'@emotion/utils': 1.4.2
csstype: 3.2.3
'@emotion/sheet@1.4.0': {}
'@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4)':
dependencies:
'@babel/runtime': 7.29.2
'@emotion/babel-plugin': 11.13.5
'@emotion/is-prop-valid': 1.4.0
'@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.4)
'@emotion/serialize': 1.3.3
'@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.4)
'@emotion/utils': 1.4.2
react: 19.2.4
optionalDependencies:
'@types/react': 19.2.14
transitivePeerDependencies:
- supports-color
'@emotion/unitless@0.10.0': {}
'@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.4)':
dependencies:
react: 19.2.4
'@emotion/utils@1.4.2': {}
'@emotion/weak-memoize@0.4.0': {}
'@esbuild/aix-ppc64@0.21.5':
optional: true
@@ -8253,6 +8452,22 @@ snapshots:
'@fullcalendar/core': 6.1.20
'@fullcalendar/daygrid': 6.1.20(@fullcalendar/core@6.1.20)
'@hookform/devtools@4.4.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
'@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.4)
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4)
'@types/lodash': 4.17.25
little-state-machine: 4.8.1(react@19.2.4)
lodash: 4.17.23
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
react-simple-animate: 3.5.3(react-dom@19.2.4(react@19.2.4))
use-deep-compare-effect: 1.8.1(react@19.2.4)
uuid: 8.3.2
transitivePeerDependencies:
- '@types/react'
- supports-color
'@hookform/resolvers@4.1.3(react-hook-form@7.72.0(react@19.2.4))':
dependencies:
'@standard-schema/utils': 0.3.0
@@ -8435,11 +8650,11 @@ snapshots:
'@types/react': 19.2.14
react: 19.2.4
'@minoru/react-dnd-treeview@3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
'@minoru/react-dnd-treeview@3.5.1-alpha.1(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
'@juggle/resize-observer': 3.4.0
dnd-multi-backend: 8.1.2(dnd-core@16.0.1)
framer-motion: 11.18.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
framer-motion: 11.18.2(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
react: 19.2.4
react-dnd: 16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4)
react-dnd-html5-backend: 16.0.1
@@ -8450,11 +8665,11 @@ snapshots:
- '@emotion/is-prop-valid'
- dnd-core
'@minoru/react-dnd-treeview@3.5.3(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
'@minoru/react-dnd-treeview@3.5.3(@emotion/is-prop-valid@1.4.0)(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
'@juggle/resize-observer': 3.4.0
dnd-multi-backend: 8.1.2(dnd-core@16.0.1)
framer-motion: 11.18.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
framer-motion: 11.18.2(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
react: 19.2.4
react-dnd: 16.0.1(@types/node@22.19.15)(@types/react@19.2.14)(react@19.2.4)
react-dnd-html5-backend: 16.0.1
@@ -9637,6 +9852,8 @@ snapshots:
'@types/json5@0.0.29': {}
'@types/lodash@4.17.25': {}
'@types/mdx@2.0.13': {}
'@types/node@20.19.37':
@@ -9647,6 +9864,8 @@ snapshots:
dependencies:
undici-types: 6.21.0
'@types/parse-json@4.0.2': {}
'@types/react-dom@19.2.3(@types/react@19.2.14)':
dependencies:
'@types/react': 19.2.14
@@ -10301,6 +10520,12 @@ snapshots:
axobject-query@4.1.0: {}
babel-plugin-macros@3.1.0:
dependencies:
'@babel/runtime': 7.29.2
cosmiconfig: 7.1.0
resolve: 1.22.11
balanced-match@1.0.2: {}
balanced-match@4.0.4: {}
@@ -10495,10 +10720,20 @@ snapshots:
consola@3.4.2: {}
convert-source-map@1.9.0: {}
convert-source-map@2.0.0: {}
core-util-is@1.0.3: {}
cosmiconfig@7.1.0:
dependencies:
'@types/parse-json': 4.0.2
import-fresh: 3.3.1
parse-json: 5.2.0
path-type: 4.0.0
yaml: 1.10.3
cosmiconfig@9.0.1(typescript@5.9.3):
dependencies:
env-paths: 2.2.1
@@ -11430,6 +11665,8 @@ snapshots:
dependencies:
to-regex-range: 5.0.1
find-root@1.1.0: {}
find-up@4.1.0:
dependencies:
locate-path: 5.0.0
@@ -11470,12 +11707,13 @@ snapshots:
fraction.js@5.3.4: {}
framer-motion@11.18.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
framer-motion@11.18.2(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
motion-dom: 11.18.1
motion-utils: 11.18.1
tslib: 2.8.1
optionalDependencies:
'@emotion/is-prop-valid': 1.4.0
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
@@ -11997,6 +12235,10 @@ snapshots:
rfdc: 1.4.1
wrap-ansi: 9.0.2
little-state-machine@4.8.1(react@19.2.4):
dependencies:
react: 19.2.4
load-tsconfig@0.2.5: {}
loader-runner@4.3.1: {}
@@ -12345,6 +12587,8 @@ snapshots:
lru-cache: 10.4.3
minipass: 7.1.3
path-type@4.0.0: {}
path-type@6.0.0: {}
path@0.12.7:
@@ -12668,6 +12912,10 @@ snapshots:
optionalDependencies:
'@types/react': 19.2.14
react-simple-animate@3.5.3(react-dom@19.2.4(react@19.2.4)):
dependencies:
react-dom: 19.2.4(react@19.2.4)
react-smooth@4.0.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
fast-equals: 5.4.0
@@ -13185,6 +13433,8 @@ snapshots:
client-only: 0.0.1
react: 19.2.4
stylis@4.2.0: {}
sucrase@3.35.1:
dependencies:
'@jridgewell/gen-mapping': 0.3.13
@@ -13541,6 +13791,12 @@ snapshots:
optionalDependencies:
'@types/react': 19.2.14
use-deep-compare-effect@1.8.1(react@19.2.4):
dependencies:
'@babel/runtime': 7.29.2
dequal: 2.0.3
react: 19.2.4
use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.4):
dependencies:
detect-node-es: 1.1.0
@@ -13573,6 +13829,8 @@ snapshots:
uuid@14.0.1: {}
uuid@8.3.2: {}
uuid@9.0.1: {}
victory-vendor@36.9.2:
@@ -13781,6 +14039,8 @@ snapshots:
yallist@3.1.1: {}
yaml@1.10.3: {}
yaml@2.8.3: {}
yargs-parser@18.1.3: