[ST] - fix: 2-3 매설연장 관리자일시 수정 가능하도록 적용, SearchFrom 로직 수정

This commit is contained in:
2026-09-03 11:26:23 +09:00
parent 261941452a
commit afca685fd4
2 changed files with 53 additions and 31 deletions
+47 -28
View File
@@ -28,7 +28,7 @@ import {
SelectValue,
} from "@common/components";
import { doList } from "@/components/util/column/input/DoList";
import { doList, doNameList } from "@/components/util/column/input/DoList";
import {
defaultSearchFormProps,
@@ -41,12 +41,27 @@ function isDoListBsnm(bsnmCd: string | undefined): boolean {
return Boolean(bsnmCd && doList.includes(bsnmCd));
}
function isDoSido(sido?: { bsnmCd?: string; sido?: string }): boolean {
if (!sido) return false;
if (isDoListBsnm(sido.bsnmCd)) return true;
return Boolean(sido.sido && doNameList.includes(sido.sido));
}
function isAllGugunValue(gugun: string | undefined): boolean {
const value = (gugun ?? "").trim();
return !value || value === "ALL" || value === "전체";
}
function firstConcreteSgg(list: Sgg[] | undefined): Sgg | undefined {
return (list ?? []).find((sgg) => !isAllGugunValue(sgg.gugun));
}
const getSggListFetcher = async (
key: [string, string, string, "Y" | "N"],
): Promise<ApiResponse<Sgg[]>> => {
const [, sidoName, instSeCd, gugunSkipYn] = key;
const [kind, sidoName, instSeCd, gugunSkipYn] = key;
const params = { instSeCd, gugunSkipYn };
if (gugunSkipYn === "N") {
if (kind === "sgg-all") {
return statisticsApi.getSggAllList(sidoName, params);
}
return statisticsApi.getSggList(sidoName, params);
@@ -69,7 +84,7 @@ function buildSearchFormValues(
);
const gugun =
d.gugun ||
(sidoItem && !isDoListBsnm(sidoItem.bsnmCd) ? "ALL" : "");
(sidoItem && !isDoSido(sidoItem) ? "ALL" : "");
return {
sido: d.sido,
gugun,
@@ -105,7 +120,7 @@ function buildSearchFormValues(
return {
sido: useFirstSido ? first.sido : "",
gugun:
useFirstSido && first && !isDoListBsnm(first.bsnmCd) ? "ALL" : "",
useFirstSido && first && !isDoSido(first) ? "ALL" : "",
year: d?.year || defaultYear.toString(),
order: d?.order || "",
fctName: d?.fctName || "",
@@ -171,7 +186,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
: {
...prev,
sido: first.sido,
gugun: isDoListBsnm(first.bsnmCd) ? "" : "ALL",
gugun: isDoSido(first) ? "" : "ALL",
bsnmCd: first.bsnmCd,
},
);
@@ -186,10 +201,12 @@ const SearchForm = (props: SearchFormProps = {}) => {
(item) => item.sido === values.sido,
);
const gugunSkipYn = selectedSido?.gugunSkipYn ?? "Y";
const useSggAllList =
gugunSkipYn === "N" && !isDoListBsnm(selectedSido?.bsnmCd);
const sggKey: [string, string, string, "Y" | "N"] | null =
values.sido && values.sido !== "ALL" && sidoList?.data
? [
gugunSkipYn === "N" ? "sgg-all" : "sgg-list",
useSggAllList ? "sgg-all" : "sgg-list",
values.sido,
instSeCd,
gugunSkipYn,
@@ -217,45 +234,49 @@ const SearchForm = (props: SearchFormProps = {}) => {
},
);
const sggOptions = sggList?.data ?? [];
const isDoSelected = isDoSido(selectedSido);
const firstConcreteSggOption = firstConcreteSgg(sggOptions);
const gugunSelectValue =
isDoSelected && isAllGugunValue(values.gugun)
? (firstConcreteSggOption?.gugun ?? undefined)
: values.gugun || undefined;
// 도(doList): 시군구 목록 첫 항목. 광역시·세종·제주: 전체
// 도: 전체(ALL/"")가 아니라 그 다음 시군구. 그 외: 전체
useEffect(() => {
if (!mergedProps.gugun) return;
if (props.defaultRegionAll) return;
if (props.defaultValues?.gugun) return;
if (!values.sido || values.sido === "ALL") return;
if (!selectedSido) return;
if (!isDoListBsnm(selectedSido.bsnmCd)) {
if (!isDoSelected) {
setValues((prev) => {
if (prev.gugun) return prev;
return {
...prev,
gugun: "ALL",
bsnmCd: selectedSido?.bsnmCd || prev.bsnmCd,
bsnmCd: selectedSido.bsnmCd || prev.bsnmCd,
};
});
return;
}
const firstSgg = sggList?.data?.[0];
if (!firstSgg) return;
if (!firstConcreteSggOption) return;
setValues((prev) => {
if (prev.gugun) return prev;
if (!isAllGugunValue(prev.gugun)) return prev;
return {
...prev,
gugun: firstSgg.gugun,
bsnmCd: firstSgg.bsnmCd,
gugun: firstConcreteSggOption.gugun,
bsnmCd: firstConcreteSggOption.bsnmCd,
};
});
}, [
sggList,
values.sido,
selectedSido?.bsnmCd,
firstConcreteSggOption,
isDoSelected,
mergedProps.gugun,
props.defaultValues?.gugun,
props.defaultRegionAll,
selectedSido,
values.sido,
]);
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
@@ -269,15 +290,13 @@ const SearchForm = (props: SearchFormProps = {}) => {
};
const handleSidoChange = (value: string) => {
const selectedBsnm =
const selected =
value === "ALL"
? ""
: sidoList?.data?.sidoList?.find((v) => v.sido === value)
?.bsnmCd || "";
? undefined
: sidoList?.data?.sidoList?.find((v) => v.sido === value);
const selectedBsnm = selected?.bsnmCd || "";
const gugunAll =
props.defaultRegionAll ||
value === "ALL" ||
!isDoListBsnm(selectedBsnm);
props.defaultRegionAll || value === "ALL" || !isDoSido(selected);
setValues((prev) => ({
...prev,
sido: value,
@@ -341,7 +360,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
<div className="flex items-center gap-2">
<Label className="text-label">시군구</Label>
<Select
value={values.gugun}
value={gugunSelectValue}
onValueChange={handleSggChange}
>
<SelectTrigger className="w-[12rem]">
@@ -175,12 +175,13 @@ const applyPipeTypeStatusColumnLayout = (
return walk(layout ?? []);
};
/** ST00020003: 입력기간 통과 시 조회 연도의 매설연장(y{year}LyngPrlg)만 편집 가능, 해당 연도 철거연장 컬럼 숨김 */
/** ST00020003: 일반 사용자는 조회 연도 매설연장만, 관리자는 매설연장 컬럼 전체 편집 가능. 해당 연도 철거연장 컬럼 숨김 */
const applyPipeTypeStatusEditableColumns = (
cols: ColumnConfig[] | undefined,
canEdit: boolean,
periodEnterable: boolean,
statsYr: string | null,
isAdmin: boolean,
): ColumnConfig[] => {
const hideDmltnYear = shouldHidePipeTypeEditableYearDmltn(canEdit, periodEnterable, statsYr);
@@ -205,11 +206,12 @@ const applyPipeTypeStatusEditableColumns = (
if (fieldName === "lyngPrlg" || isYearLyngField) {
const editableLyngField = periodEnterable ? resolvePipeTypeEditableLyngField(statsYr) : null;
const isTargetYear = editableLyngField !== null && fieldName === editableLyngField;
if (isTargetYear) {
const { styleName: _readonlyStyle, ...rest } = col;
if (isAdmin || isTargetYear) {
const { styleName, ...rest } = col;
return {
...rest,
editable: true as const,
...(styleName && styleName !== "rg-cell-readonly" ? { styleName } : {}),
};
}
return { ...col, editable: false as const, styleName: col.styleName ?? "rg-cell-readonly" };
@@ -640,6 +642,7 @@ const SewagePipeInp = () => {
canEdit,
inputPeriodEnterable,
lastSearchedYear,
isAdminInfo,
)
: (cols ?? []).map((col: ColumnConfig) =>
canEdit