st: feat: 그리드 해더 색상 통일, 통계입력현황 조회 기능 추가 & 검색폼 컴포넌트 로직 수정(통계입력현황 조회시 도를 제외한 시는 행정구역(sggNm)을 조회하지 않도록)

This commit is contained in:
2026-02-26 15:13:56 +09:00
parent 690bca4c06
commit c957c2ff8d
15 changed files with 289 additions and 133 deletions
@@ -449,6 +449,7 @@ const DataGrid = ({
target: "local",
fileName: `${menuName}.xlsx`,
footer: "hidden",
allColumns: true, // 숨김(visible: false) 컬럼도 엑셀에 포함
done: () => {
// 헤더 원복
columns.forEach((col) => {
@@ -852,6 +853,7 @@ const DataGrid = ({
editable: col.editable,
valueType: col.valueType,
dataFormat: col.dataFormat,
...(col.width != null && { width: col.width }),
...(col.styleName != null && {
styleName: col.styleName,
}),
@@ -1146,6 +1148,7 @@ const DataGrid = ({
{...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.000' })}
header={column.header}
editable={column.editable}
{...(column.width != null && { width: column.width })}
{...(baseStyleName != null && { styleName: baseStyleName })}
{...(column.visible === false && { visible: false })}
{...(cellTooltipCallback && { renderer: { showTooltip: true } })}
+16 -6
View File
@@ -1,6 +1,6 @@
"use client";
import { useState, useEffect } from "react";
import { useState, useEffect, useRef } from "react";
import useSWR from 'swr';
import {
@@ -19,6 +19,7 @@ import { useAlertStore } from "@/shared/lib";
import { type SearchFormProps, type SearchFormValues, defaultSearchFormProps } from "../type/SearchForm.type";
import { statisticsAPi } from "@/entities/statistics/api/statistics-service";
import type { ApiResponse, SearchCondition, Sgg } from "@/entities/statistics/model/statistics-interface";
import { doList } from "../util/column/input/DoList";
const getSidoListFetcher = async (): Promise<ApiResponse<SearchCondition>> => {
return statisticsAPi.getSidoList();
@@ -66,8 +67,13 @@ const SearchForm = (props: SearchFormProps = {}) => {
bsnmCd: props.defaultValues?.bsnmCd || '',
});
// isStatusMenu면 bsnmCd가 doList에 있을 때만 시군구 조회. 선택 후 옵션 유지를 위해 마지막 목록 ref 사용
const sggKey: [string, string] | null =
values.sido && values.sido !== "ALL" && (!mergedProps.isStatusMenu || doList.includes(values.bsnmCd ?? ""))
? ["sgg-list", values.sido]
: null;
const { data: sggList } = useSWR<ApiResponse<Sgg[]>>(
values.sido && values.sido !== "ALL" ? ["sgg-list", values.sido] : null,
sggKey,
getSggListFetcher,
{
revalidateOnFocus: false,
@@ -87,7 +93,9 @@ const SearchForm = (props: SearchFormProps = {}) => {
},
}
);
const lastSggListRef = useRef<Sgg[]>([]);
if (sggList?.data) lastSggListRef.current = sggList.data;
const sggOptions = sggList?.data ?? (values.sido && values.sido !== "ALL" ? lastSggListRef.current : []);
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
@@ -95,6 +103,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
};
const handleReset = () => {
lastSggListRef.current = [];
const resetValues: SearchFormValues = {
sido: '',
gugun: '',
@@ -109,7 +118,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
const handleSidoChange = (value: string) => {
const selectedBsnm = sidoList?.data.sidoList.find((v) => v.sido === value)?.bsnmCd || '';
lastSggListRef.current = []; // 시도 변경 시 이전 시군구 목록 제거(조건 안 맞는 시도로 바꿀 때 옵션 안 남도록)
setValues((prev) => ({
...prev,
sido: value,
@@ -119,9 +128,10 @@ const SearchForm = (props: SearchFormProps = {}) => {
};
const handleSggChange = (value: string) => {
const listForBsnm = sggList?.data ?? lastSggListRef.current;
const selectedBsnm = value === 'ALL'
? (sidoList?.data.sidoList.find((v) => v.sido === values.sido)?.bsnmCd || '')
: (sggList?.data?.find((v) => v.gugun === value)?.bsnmCd || '');
: (listForBsnm.find((v) => v.gugun === value)?.bsnmCd || '');
setValues((prev) => ({
...prev,
@@ -169,7 +179,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
</SelectTrigger>
<SelectContent>
<SelectItem value="ALL">전체</SelectItem>
{sggList?.data?.map((sgg) => (
{sggOptions?.map((sgg) => (
<SelectItem key={sgg.adstDstrCd} value={sgg.gugun}>
{sgg.gugun}
</SelectItem>
@@ -419,6 +419,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
target: 'local',
fileName: `${menuName}_${tabLabel}.xlsx`,
footer: 'hidden',
allColumns: true, // 숨김(visible: false) 컬럼도 엑셀에 포함
done: () => {
// 헤더 원복
columns.forEach((col) => {
@@ -772,7 +773,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
return (
<div className="flex flex-col gap-[0.6rem] mx-[0.6rem]">
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full" variant="outline">
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full" variant="default">
<TabsList className="mb-4">
{columnInfo.map((info) => {
const tabKey = info.tabKey;