[st] - 일정등록, 입력단 지난검증결과 알림 뱃지, 로그 상세조회, 검토단 cell style 적용
This commit is contained in:
@@ -3,9 +3,20 @@ import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doNameList } from "@/components/util/column/input/DoList";
|
||||
import { menuMatchesStatisticsTabId } from "@/shared/lib/statistics-menu-url";
|
||||
import {
|
||||
EXCRETA_TREATMENT_FACILITY_INP_TAB_KEYS,
|
||||
INPUT_TAB_KEY_BY_STATS_CD,
|
||||
PRIVATE_SEWAGE_FACILITY_INP_TAB_KEYS,
|
||||
PUBLIC_SEWAGE_FACILITY_INP_TAB_KEYS,
|
||||
PUMPING_STATION_INP_TAB_KEYS,
|
||||
SEWAGE_EXCRETA_RELATED_INP_TAB_KEYS,
|
||||
SEWAGE_EXCRETA_SLURGE_INP_TAB_KEYS,
|
||||
SEWAGE_PIPE_INP_TAB_KEYS,
|
||||
SEWAGE_PIPE_MAINTAIN_INP_TAB_KEYS,
|
||||
SEWAGE_RESERVOIR_PUMP_INP_TAB_KEYS,
|
||||
SEWERAGE_FINANCE_INP_TAB_KEYS,
|
||||
SEWERAGE_PENETRATION_RATE_INP_TAB_KEYS,
|
||||
SEWERAGE_SERVICE_LEVEL_INP_TAB_KEYS,
|
||||
WATER_REUSE_INP_TAB_KEYS,
|
||||
} from "@/components/util/MenuMatchList";
|
||||
|
||||
/** 검증 결과에서 입력 화면 자동 조회에 사용하는 조건 */
|
||||
@@ -35,15 +46,21 @@ export function verificationSearchToFormValues(
|
||||
|
||||
/** `statistics-page` 동적 import 경로의 파일명(확장자 제외)과 일치해야 함 */
|
||||
export const STATISTICS_INPUT_URL_PATH = {
|
||||
SEWERAGE_PENETRATION_RATE: "SeweragePenetrationRateInp",
|
||||
SEWAGE_PIPE: "SewagePipeInp",
|
||||
SEWAGE_PIPE_MAINTAIN: "SewagePipeMaintainInp",
|
||||
SEWERAGE_PENETRATION_RATE: "SeweragePenetrationRateInp",
|
||||
SEWAGE_RESERVOIR_PUMP: "SewageReservoirPumpInp",
|
||||
PUMPING_STATION: "PumpingStationInp",
|
||||
PUBLIC_SEWAGE_FACILITY: "PublicSewageFacilityInp",
|
||||
EXCRETA_TREATMENT_FACILITY: "ExcretaTreatmentFacilityInp",
|
||||
PRIVATE_SEWAGE_FACILITY: "PrivateSewageFacilityInp",
|
||||
SEWERAGE_FINANCE: "SewerageFinanceInp",
|
||||
WATER_REUSE: "WaterReuseInp",
|
||||
SEWAGE_EXCRETA_SLURGE: "SewageExcretaSlurgeInp",
|
||||
SEWAGE_EXCRETA_RELATED: "SewageExcretaRelatedInp",
|
||||
SEWERAGE_SERVICE_LEVEL: "SewerageServiceLevelInp",
|
||||
} as const;
|
||||
|
||||
/** `PublicSewageFacilityInp.tsx` — 공공하수처리시설 탭 */
|
||||
const PUBLIC_SEWAGE_FACILITY_INP_TAB_KEYS = ["ST00060001"] as const;
|
||||
|
||||
function normalizeSewagePipeTabKey(tabKey: string): string {
|
||||
if (
|
||||
tabKey === "adminAreaConnectionInp" ||
|
||||
@@ -54,20 +71,66 @@ function normalizeSewagePipeTabKey(tabKey: string): string {
|
||||
return tabKey;
|
||||
}
|
||||
|
||||
function resolveInputTabKey(urlPath: string, statsCd: string): string {
|
||||
if (urlPath === STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE) {
|
||||
return normalizeSewagePipeTabKey(statsCd);
|
||||
}
|
||||
return INPUT_TAB_KEY_BY_STATS_CD[statsCd] ?? statsCd;
|
||||
}
|
||||
|
||||
const NAV_ROWS: { urlPath: string; tabKeys: readonly string[] }[] = [
|
||||
{ urlPath: STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE, tabKeys: SEWAGE_PIPE_INP_TAB_KEYS },
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE_MAINTAIN,
|
||||
tabKeys: SEWAGE_PIPE_MAINTAIN_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.SEWERAGE_PENETRATION_RATE,
|
||||
tabKeys: SEWERAGE_PENETRATION_RATE_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE,
|
||||
tabKeys: SEWAGE_PIPE_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE_MAINTAIN,
|
||||
tabKeys: SEWAGE_PIPE_MAINTAIN_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.SEWAGE_RESERVOIR_PUMP,
|
||||
tabKeys: SEWAGE_RESERVOIR_PUMP_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.PUMPING_STATION,
|
||||
tabKeys: PUMPING_STATION_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.PUBLIC_SEWAGE_FACILITY,
|
||||
tabKeys: PUBLIC_SEWAGE_FACILITY_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.EXCRETA_TREATMENT_FACILITY,
|
||||
tabKeys: EXCRETA_TREATMENT_FACILITY_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.PRIVATE_SEWAGE_FACILITY,
|
||||
tabKeys: PRIVATE_SEWAGE_FACILITY_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.SEWERAGE_FINANCE,
|
||||
tabKeys: SEWERAGE_FINANCE_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.WATER_REUSE,
|
||||
tabKeys: WATER_REUSE_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.SEWAGE_EXCRETA_SLURGE,
|
||||
tabKeys: SEWAGE_EXCRETA_SLURGE_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.SEWAGE_EXCRETA_RELATED,
|
||||
tabKeys: SEWAGE_EXCRETA_RELATED_INP_TAB_KEYS,
|
||||
},
|
||||
{
|
||||
urlPath: STATISTICS_INPUT_URL_PATH.SEWERAGE_SERVICE_LEVEL,
|
||||
tabKeys: SEWERAGE_SERVICE_LEVEL_INP_TAB_KEYS,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -83,11 +146,10 @@ export function resolveInputPageNavigationFromStatsCd(statsCd: string): {
|
||||
|
||||
for (const row of NAV_ROWS) {
|
||||
if (row.tabKeys.includes(trimmed)) {
|
||||
const tabKey =
|
||||
row.urlPath === STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE
|
||||
? normalizeSewagePipeTabKey(trimmed)
|
||||
: trimmed;
|
||||
return { urlPath: row.urlPath, tabKey };
|
||||
return {
|
||||
urlPath: row.urlPath,
|
||||
tabKey: resolveInputTabKey(row.urlPath, trimmed),
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
||||
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import {
|
||||
verificationSearchToFormValues,
|
||||
type StatisticsInputPendingSearch,
|
||||
} from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useStatisticsInputFocusStore } from "@/store/statistics-input-focus-store";
|
||||
import { useTabStore } from "@/store/tab-store";
|
||||
|
||||
type PendingNavigation = {
|
||||
tabKey: string;
|
||||
search: StatisticsInputPendingSearch | null;
|
||||
};
|
||||
|
||||
type UseStatisticsInputPendingNavigationOptions = {
|
||||
urlPath: string;
|
||||
onPending?: (pending: PendingNavigation) => void;
|
||||
onAutoSearch?: (
|
||||
values: SearchFormValues,
|
||||
tabKey: string,
|
||||
) => void | Promise<void>;
|
||||
};
|
||||
|
||||
/** 이상치 선별 보고서 등에서 넘어온 입력 화면·탭·검색조건을 적용합니다. */
|
||||
export function useStatisticsInputPendingNavigation({
|
||||
urlPath,
|
||||
onPending,
|
||||
onAutoSearch,
|
||||
}: UseStatisticsInputPendingNavigationOptions) {
|
||||
const [verificationSearchDefaults, setVerificationSearchDefaults] =
|
||||
useState<SearchFormValues | null>(null);
|
||||
const [searchFormRemountKey, setSearchFormRemountKey] = useState(0);
|
||||
const autoSearchRef = useRef<{
|
||||
values: SearchFormValues;
|
||||
tabKey: string;
|
||||
} | null>(null);
|
||||
const handlersRef = useRef({ onPending, onAutoSearch });
|
||||
handlersRef.current = { onPending, onAutoSearch };
|
||||
|
||||
const activeTabId = useTabStore((s) => s.activeTabId);
|
||||
const inputFocusNonce = useStatisticsInputFocusStore((s) => s.nonce);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (activeTabId !== urlPath) return;
|
||||
const pending = useStatisticsInputFocusStore
|
||||
.getState()
|
||||
.takePendingForUrl(urlPath);
|
||||
if (!pending) return;
|
||||
|
||||
handlersRef.current.onPending?.(pending);
|
||||
|
||||
if (pending.search) {
|
||||
const values = verificationSearchToFormValues(pending.search);
|
||||
setVerificationSearchDefaults(values);
|
||||
autoSearchRef.current = { values, tabKey: pending.tabKey };
|
||||
setSearchFormRemountKey((k) => k + 1);
|
||||
}
|
||||
}, [activeTabId, inputFocusNonce, urlPath]);
|
||||
|
||||
useEffect(() => {
|
||||
const job = autoSearchRef.current;
|
||||
if (!job) return;
|
||||
autoSearchRef.current = null;
|
||||
void handlersRef.current.onAutoSearch?.(job.values, job.tabKey);
|
||||
}, [searchFormRemountKey]);
|
||||
|
||||
return { verificationSearchDefaults, searchFormRemountKey };
|
||||
}
|
||||
Reference in New Issue
Block a user