[ST] - fix: 2-3 매설연장 관리자일시 수정 가능하도록 적용, SearchFrom 로직 수정
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user