From a56712a8a63d6b64b4ec4d75f7e3b86ebcfcbb78 Mon Sep 17 00:00:00 2001 From: swcho Date: Tue, 13 May 2025 15:52:59 +0900 Subject: [PATCH] =?UTF-8?q?feat,=20fix:=20FeatureClickEventPopup=EC=97=90?= =?UTF-8?q?=EC=84=9C=20featureID=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A0=88=EC=9D=B4=EC=96=B4=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=20=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80,?= =?UTF-8?q?=20=ED=83=AD=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EC=9C=84=ED=95=9C?= =?UTF-8?q?=20UITab2=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/sn/app/map/SearchModal.tsx | 1234 ++++++++++++----- apps/sn/app/map/featureClickEventPopup.tsx | 34 +- .../src/ui/tab/index-2.tsx | 38 + 3 files changed, 956 insertions(+), 350 deletions(-) create mode 100644 packages/common/business_components/src/ui/tab/index-2.tsx diff --git a/apps/sn/app/map/SearchModal.tsx b/apps/sn/app/map/SearchModal.tsx index ba8b34df0..6f7ae8dfb 100644 --- a/apps/sn/app/map/SearchModal.tsx +++ b/apps/sn/app/map/SearchModal.tsx @@ -4,6 +4,8 @@ import axios from 'axios'; import { UiModal } from '@common/business_components/ui/dialog_ui'; import { Button } from '@common/components'; import { UiTable2 } from '@common/business_components/ui/table/index-2'; +import { UITab2 } from '@common/business_components/ui/tab/index-2'; + const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`; @@ -16,15 +18,13 @@ const TABS = [ ]; // 기본정보 '구분' 선택 목록 const BASIC_TYPES = [ - { key: 'SEWER_PIPE', label: '하수관로' }, + { key: 'tb_ms_swage_ppl', label: '하수관로' }, { key: 'tb_il_swage_prcs_fclt', label: '하수처리시설' }, { key: 'tb_ms_swage_prcs_zone', label: '하수처리구역' }, - { key: 'MANHOLE', label: '하수맨홀' }, - { key: 'WASTEWATER_PUMP', label: '오수펌프' }, - { key: 'RAINWATER_PUMP', label: '빗물펌프' }, - { key: 'OUTFALL', label: '우수토실' }, - { key: 'RETENTION_FACILITY', label: '하수저류시설' }, - { key: 'PRIORITY_OUTFALL', label: '중점우수토실' }, + { key: 'tb_ms_swage_mh', label: '하수맨홀' }, + { key: 'tb_ms_swage_psmtn_1', label: '오수펌프' }, + { key: 'tb_ms_swage_psmtn_2', label: '빗물펌프' }, + { key: 'tb_ms_otfl', label: '우수토실' }, ]; // 운영정보 '구분' 선택 목록 const WORK_TYPES = [ @@ -34,8 +34,12 @@ const WORK_TYPES = [ ]; const YEARS = Array.from({ length: 100 }, (_, i) => `${2025 - i}`); - -// 하수처리구역 테이블 헤더 리스트 +// 테이블 헤더 리스트 +// 하수관로 (추후 작성 예정) +const swagePplTableHeadlist = [ + { id: 'ctpvNm', title: '시도명' }, +] +// 하수처리구역 const swageZoneTableHeadlist = [ // { id: 'ctpvCd', title: '시도코드' }, { id: 'ctpvNm', title: '시도명' }, @@ -46,7 +50,7 @@ const swageZoneTableHeadlist = [ { id: 'swtrmtFcltCd', title: '하수처리시설번호' }, { id: 'swtrmtFcltNm', title: '하수처리시설명' }, ] -// 하수처리시설 테이블 헤더 리스트 +// 하수처리시설 const swageFcltTableHeadlist = [ { id: 'swtrmtFcltCd', title: '하수처리시설코드' }, { id: 'swtrmtFcltNm', title: '하수처리시설명' }, @@ -82,6 +86,10 @@ const swageFcltTableHeadlist = [ { id: 'sttyCrtrClbclCnt', title: '법정기준대장균수' }, { id: 'bsnNm', title: '유역명' }, ]; +// 하수맨홀 (추후 작성 예정) +const swageMhTableHeadlist = [ + { id: 'swtrmtFcltCd', title: '하수처리시설코드' }, +]; const sidoList = [ { id: 0, name: '선택' }, @@ -196,7 +204,6 @@ const sigunguMap: Record = { }; const 처리구역List = ['선택', 'A', 'B']; -const 설치년도List = ['선택', ...YEARS]; interface SearchModalProps { open: boolean; @@ -204,15 +211,6 @@ interface SearchModalProps { onFeatureSelect: (row: any) => void; } -// filterParams 타입 정의 추가 -type FilterParams = { - swtrmt_zone_nm?: string; - ctpv_cd?: number; - sgg_cd?: number; - swtrmt_fclt_nm?: string; - // 추가 필터 속성들... -}; - // 날짜 조합 함수 const getDateString = (year: string, month: string, day: string, defaultDate: string) => { if (!year && !month && !day) return defaultDate; @@ -223,10 +221,8 @@ const getDateString = (year: string, month: string, day: string, defaultDate: st }; const SearchModal: React.FC = ({ open, onOpenChange, onFeatureSelect }) => { - const [activeTab, setActiveTab] = useState('basic'); + const [activeTab, setActiveTab] = useState(TABS[0]?.key ?? 'basic'); const [workType, setWorkType] = useState(WORK_TYPES[0]?.key ?? ''); - const [startYear, setStartYear] = useState(''); - const [endYear, setEndYear] = useState(''); const [showTable, setShowTable] = useState(false); const [curPage, setCurPage] = useState(1); const [basicType, setBasicType] = useState(BASIC_TYPES[0]?.key ?? ''); @@ -235,19 +231,33 @@ const SearchModal: React.FC = ({ open, onOpenChange, onFeature const [시도, set시도] = useState(0); const [시군구, set시군구] = useState(0); const [처리구역, set처리구역] = useState(''); - const [설치년도1, set설치년도1] = useState(''); - const [설치년도2, set설치년도2] = useState(''); const [tableData, setTableData] = useState([]); - const [시설용량최소, set시설용량최소] = useState(''); - const [시설용량최대, set시설용량최대] = useState(''); // 날짜 상태 선언 - const [가동개시_시작_년, set가동개시_시작_년] = useState(''); + const [시작1, set시작1] = useState(''); + const [시작2, set시작2] = useState(''); + const [종료1, set종료1] = useState(''); + const [종료2, set종료2] = useState(''); + const [변수1, set변수1] = useState(''); + const [변수2, set변수2] = useState(''); + const [변수3, set변수3] = useState(''); + const [변수4, set변수4] = useState(''); + // 하수관로 변수 + const [하수관로용도코드, set하수관로용도코드] = useState(''); + const [하수관로재질코드, set하수관로재질코드] = useState(''); + const [행정읍면동코드, set행정읍면동코드] = useState(''); + // 시작, 종료, 경과년도 + const [yearFilter, setYearFilter] = useState({ + 시작: '', + 종료: '', + 경과년도: '' + }); + const [가동개시_시작_월, set가동개시_시작_월] = useState(''); - const [가동개시_시작_일, set가동개시_시작_일] = useState(''); - const [가동개시_종료_년, set가동개시_종료_년] = useState(''); const [가동개시_종료_월, set가동개시_종료_월] = useState(''); + const [가동개시_시작_일, set가동개시_시작_일] = useState(''); const [가동개시_종료_일, set가동개시_종료_일] = useState(''); + // 상세 정보 조회를 위한 상태 추가 const [popupFeature, setPopupFeature] = useState(null); @@ -259,11 +269,10 @@ const SearchModal: React.FC = ({ open, onOpenChange, onFeature // UiTable2에 넘길 headlist를 BASIC_TYPES 값에 따라 분기 처리 let dynamicHeadlist = swageZoneTableHeadlist; - if (basicType === 'tb_ms_swage_prcs_zone') { - dynamicHeadlist = swageZoneTableHeadlist; // 하수처리구역 - } else if (basicType === 'tb_il_swage_prcs_fclt') { - dynamicHeadlist = swageFcltTableHeadlist; // 하수처리시설 - } + if (basicType === 'tb_ms_swage_ppl') dynamicHeadlist = swagePplTableHeadlist; // 하수관로 + else if (basicType === 'tb_il_swage_prcs_fclt') dynamicHeadlist = swageFcltTableHeadlist; // 하수처리시설 + else if (basicType === 'tb_ms_swage_prcs_zone') dynamicHeadlist = swageZoneTableHeadlist; // 하수처리구역 + else if (basicType === 'tb_ms_swage_mh') dynamicHeadlist = swageMhTableHeadlist; // 하수맨홀 // 선택된 시도에 따라 시군구 리스트 가져오기 const selectedSigunguList = sigunguMap[시도] || [{ id: 0, name: '선택' }]; @@ -276,10 +285,10 @@ const SearchModal: React.FC = ({ open, onOpenChange, onFeature }; // 선택된 필터 값을 저장할 상태 추가 - const [filterParams, setFilterParams] = useState({}); + // const [filterParams, setFilterParams] = useState({}); // cellClick 함수 타입 지정 - const handleCellClick = (index: number | undefined, headId: string) => { + const handleCellClick = (index?: number, headId?: string) => { // 원하는 동작 구현 console.log('Cell clicked:', index, headId); if (typeof index === "number") { @@ -299,56 +308,33 @@ const SearchModal: React.FC = ({ open, onOpenChange, onFeature // 구분(basicType)이 바뀔 때마다 queryParams, filterParams 초기화 React.useEffect(() => { // filterParams 초기화 - setFilterParams({}); - set시설용량최소(''); - set시설용량최대(''); - set가동개시_시작_년(''); + // setFilterParams({}); + set시작1(''); + set시작2(''); + set종료1(''); + set종료2(''); + set변수1(''); + set변수2(''); + set변수3(''); + set변수4(''); set가동개시_시작_월(''); - set가동개시_시작_일(''); - set가동개시_종료_년(''); set가동개시_종료_월(''); + set가동개시_시작_일(''); set가동개시_종료_일(''); set하수처리구역명(''); set하수처리시설명(''); set시도(0); set시군구(0); set처리구역(''); - set설치년도1(''); - set설치년도2(''); + setYearFilter({ + 시작: '', + 종료: '', + 경과년도: '' + }); + setShowTable(false); + setTableData([]); // queryParams는 fetchFilteredData 내에서 매번 새로 생성되므로 별도 상태 초기화는 필요 없음 - }, [basicType]); - - // 필터 값이 변경될 때 쿼리 파라미터 업데이트 - React.useEffect(() => { - const params: FilterParams = {}; - - if (하수처리구역명) { - params.swtrmt_zone_nm = 하수처리구역명; - } - - // 시도 선택 시 (0이 아닌 경우) - if (시도 !== 0) { - const selectedSido = sidoList.find(item => item.id === 시도); - if (selectedSido) { - params.ctpv_cd = selectedSido.id; - } - } - - // 시군구 선택 시 (0이 아닌 경우) - if (시군구 !== 0) { - const selectedSigungu = (sigunguMap[시도] || []).find((item: { id: number; name: string }) => item.id === 시군구); - if (selectedSigungu) { - params.sgg_cd = selectedSigungu.id; - } - } - - // 하수처리시설명이 있으면 추가 - if (하수처리시설명) { - params.swtrmt_fclt_nm = 하수처리시설명; - } - - setFilterParams(params); - }, [하수처리구역명, 시도, 시군구, 하수처리시설명]); + }, [activeTab, basicType]); React.useEffect(() => { @@ -358,36 +344,127 @@ const SearchModal: React.FC = ({ open, onOpenChange, onFeature }, [activeTab, showTable, curPage, tableData.length]); - // 하수처리구역용 CQL 필터 생성 - const buildZoneCqlFilters = (params: FilterParams) => { + // 하수관로용 CQL 필터 생성 + const pplCqlFilters = () => { const cqlFilters: string[] = []; - if (params.ctpv_cd) cqlFilters.push(`ctpv_cd='${params.ctpv_cd}'`); - if (params.sgg_cd) cqlFilters.push(`sgg_cd='${params.sgg_cd}'`); - if (params.swtrmt_zone_nm) cqlFilters.push(`swtrmt_zone_nm ILIKE '%${params.swtrmt_zone_nm}%'`); - if (params.swtrmt_fclt_nm) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${params.swtrmt_fclt_nm}%'`); + // 추후 작성 예정 + if (변수1) cqlFilters.push(`용도코드='${변수1}'`); + if (변수2) cqlFilters.push(`재질코드='${변수2}'`); + if (변수3) cqlFilters.push(`행정읍면동코드='${변수3}'`); + if (변수4) cqlFilters.push(`경과년도='${변수4}'`); + // 설치년도 범위 + const startDate = getDateString(yearFilter.시작, 가동개시_시작_월, 가동개시_시작_일, '19000101'); + const endDate = getDateString(yearFilter.종료, 가동개시_종료_월, 가동개시_종료_일, `${todayYear}${todayMonth}${todayDate}`); + cqlFilters.push(`설치시작년도 >= '${startDate}' and 설치시작년도 <= '${endDate}'`); + // 관경(mm) 범위 + if (시작1 && 종료1) cqlFilters.push(`관경 BETWEEN ${시작1} AND ${종료1}`); + else if (시작1) cqlFilters.push(`관경 >= ${시작1}`); + else if (종료1) cqlFilters.push(`관경 <= ${종료1}`); + // 연장(m) 범위 + if (시작2 && 종료2) cqlFilters.push(`연장 BETWEEN ${시작2} AND ${종료2}`); + else if (시작2) cqlFilters.push(`연장 >= ${시작2}`); + else if (종료2) cqlFilters.push(`연장 <= ${종료2}`); + return cqlFilters; }; // 하수처리시설용 CQL 필터 생성 - const buildFacilityCqlFilters = (params: FilterParams) => { + const facilityCqlFilters = () => { const cqlFilters: string[] = []; // 가동개시일자 범위 - const startDate = getDateString(가동개시_시작_년, 가동개시_시작_월, 가동개시_시작_일, '19000101'); - const endDate = getDateString(가동개시_종료_년, 가동개시_종료_월, 가동개시_종료_일, `${todayYear}${todayMonth}${todayDate}`); + const startDate = getDateString(yearFilter.시작, 가동개시_시작_월, 가동개시_시작_일, '19000101'); + const endDate = getDateString(yearFilter.종료, 가동개시_종료_월, 가동개시_종료_일, `${todayYear}${todayMonth}${todayDate}`); cqlFilters.push(`oprtng_strt_ymd >= '${startDate}' and oprtng_strt_ymd <= '${endDate}'`); // 시설용량 범위 - if (시설용량최소 && 시설용량최대) cqlFilters.push(`fclt_cpct BETWEEN ${시설용량최소} AND ${시설용량최대}`); - else if (시설용량최소) cqlFilters.push(`fclt_cpct >= ${시설용량최소}`); - else if (시설용량최대) cqlFilters.push(`fclt_cpct <= ${시설용량최대}`); + if (시작1 && 종료1) cqlFilters.push(`fclt_cpct BETWEEN ${시작1} AND ${종료1}`); + else if (시작1) cqlFilters.push(`fclt_cpct >= ${시작1}`); + else if (종료1) cqlFilters.push(`fclt_cpct <= ${종료1}`); // 하수처리시설명 - if (params.swtrmt_fclt_nm) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${params.swtrmt_fclt_nm}%'`); + if (변수1) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${변수1}%'`); return cqlFilters; }; - // 기타 구분용 CQL 필터 생성 - const buildDefaultCqlFilters = (params: FilterParams) => { + // 하수처리구역용 CQL 필터 생성 + const zoneCqlFilters = () => { const cqlFilters: string[] = []; - if (params.swtrmt_fclt_nm) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${params.swtrmt_fclt_nm}%'`); + if (시도) cqlFilters.push(`ctpv_cd='${시도}'`); + if (시군구) cqlFilters.push(`sgg_cd='${시군구}'`); + if (변수1) cqlFilters.push(`swtrmt_zone_nm ILIKE '%${변수1}%'`); + if (변수2) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${변수2}%'`); return cqlFilters; }; + // 하수맨홀용 CQL 필터 생성 + const mhCqlFilters = () => { + const cqlFilters: string[] = []; + // 설치년도 범위 + const startDate = getDateString(yearFilter.시작, 가동개시_시작_월, 가동개시_시작_일, '19000101'); + const endDate = getDateString(yearFilter.종료, 가동개시_종료_월, 가동개시_종료_일, `${todayYear}${todayMonth}${todayDate}`); + cqlFilters.push(`설치시작년도 >= '${startDate}' and 설치시작년도 <= '${endDate}'`); + if (변수1) cqlFilters.push(`경과년도='${변수1}'`); + if (변수2) cqlFilters.push(`용도코드='${변수2}'`); + // 구경(mm) 범위 + if (시작1 && 종료1) cqlFilters.push(`구경 BETWEEN ${시작1} AND ${종료1}`); + else if (시작1) cqlFilters.push(`구경 >= ${시작1}`); + else if (종료1) cqlFilters.push(`구경 <= ${종료1}`); + + return cqlFilters; + }; + // 하수펌프장용 CQL 필터 생성 + const psmtnCqlFilters = () => { + const cqlFilters: string[] = []; + // 설치년도 범위 + const startDate = getDateString(yearFilter.시작, 가동개시_시작_월, 가동개시_시작_일, '19000101'); + const endDate = getDateString(yearFilter.종료, 가동개시_종료_월, 가동개시_종료_일, `${todayYear}${todayMonth}${todayDate}`); + cqlFilters.push(`설치시작년도 >= '${startDate}' and 설치시작년도 <= '${endDate}'`); + if (변수1) cqlFilters.push(`경과년도='${변수1}'`); + // 일일처리용량 범위 + if (시작1 && 종료1) cqlFilters.push(`일일처리용량 BETWEEN ${시작1} AND ${종료1}`); + else if (시작1) cqlFilters.push(`일일처리용량 >= ${시작1}`); + else if (종료1) cqlFilters.push(`일일처리용량 <= ${종료1}`); + // 우수양수능력 범위 + if (시작2 && 종료2) cqlFilters.push(`우수양수능력 BETWEEN ${시작2} AND ${종료2}`); + else if (시작2) cqlFilters.push(`우수양수능력 >= ${시작2}`); + else if (종료2) cqlFilters.push(`우수양수능력 <= ${종료2}`); + + return cqlFilters; + }; + // 우수토실용 CQL 필터 생성 + const otflCqlFilters = () => { + const cqlFilters: string[] = []; + // 설치년도 범위 + const startDate = getDateString(yearFilter.시작, 가동개시_시작_월, 가동개시_시작_일, '19000101'); + const endDate = getDateString(yearFilter.종료, 가동개시_종료_월, 가동개시_종료_일, `${todayYear}${todayMonth}${todayDate}`); + cqlFilters.push(`설치시작년도 >= '${startDate}' and 설치시작년도 <= '${endDate}'`); + if (변수1) cqlFilters.push(`경과년도='${변수1}'`); + if (변수2) cqlFilters.push(`하천명 ILIKE '%${변수1}%'`); + // 계획방류량 범위 + if (시작1 && 종료1) cqlFilters.push(`계획방류량 BETWEEN ${시작1} AND ${종료1}`); + else if (시작1) cqlFilters.push(`계획방류량 >= ${시작1}`); + else if (종료1) cqlFilters.push(`계획방류량 <= ${종료1}`); + + return cqlFilters; + }; + // 운영정보용 CQL 필터 생성 + const operationCqlFilters = () => { + const cqlFilters: string[] = []; + // 설치년도 범위 + const startDate = getDateString(yearFilter.시작, 가동개시_시작_월, 가동개시_시작_일, '19000101'); + const endDate = getDateString(yearFilter.종료, 가동개시_종료_월, 가동개시_종료_일, `${todayYear}${todayMonth}${todayDate}`); + cqlFilters.push(`설치시작년도 >= '${startDate}' and 설치시작년도 <= '${endDate}'`); + return cqlFilters; + }; + // 하수도정비기본계획보고서용 CQL 필터 생성 + const reportCqlFilters = () => { + const cqlFilters: string[] = []; + // 설치년도 범위 + if (시도) cqlFilters.push(`ctpv_cd='${시도}'`); + if (시군구) cqlFilters.push(`sgg_cd='${시군구}'`); + if (처리구역) cqlFilters.push(`처리구역='${처리구역}'`); + if (변수1) cqlFilters.push(`처리구역코드='${변수1}'`); + const startDate = getDateString(yearFilter.시작, 가동개시_시작_월, 가동개시_시작_일, '19000101'); + const endDate = getDateString(yearFilter.종료, 가동개시_종료_월, 가동개시_종료_일, `${todayYear}${todayMonth}${todayDate}`); + cqlFilters.push(`설치시작년도 >= '${startDate}' and 설치시작년도 <= '${endDate}'`); + return cqlFilters; + }; + // 검색 API 호출 함수 const fetchFilteredData = () => { @@ -396,9 +473,15 @@ const SearchModal: React.FC = ({ open, onOpenChange, onFeature }); let cqlFilters: string[] = []; - if (basicType === 'tb_ms_swage_prcs_zone') cqlFilters = buildZoneCqlFilters(filterParams); - else if (basicType === 'tb_il_swage_prcs_fclt') cqlFilters = buildFacilityCqlFilters(filterParams); - else cqlFilters = buildDefaultCqlFilters(filterParams); + if (activeTab === 'basic') { + if (basicType === 'tb_ms_swage_prcs_zone') cqlFilters = zoneCqlFilters(); + else if (basicType === 'tb_il_swage_prcs_fclt') cqlFilters = facilityCqlFilters(); + else if (basicType === 'tb_ms_swage_ppl') cqlFilters = pplCqlFilters(); + } + else if (activeTab === 'operation') cqlFilters = zoneCqlFilters(); + else cqlFilters = reportCqlFilters(); + + // 탭 + 구분 별로 cqlFilter 추가 예정 if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and ')); @@ -421,115 +504,639 @@ const SearchModal: React.FC = ({ open, onOpenChange, onFeature const renderBody = () => ( <> {/* 탭 영역 */} -
+ {/*
{TABS.map(tab => ( ))} -
+
*/} + {/* 탭 영역 */} + ({ value: tab.key, label: tab.label, onClick: () => setActiveTab(tab.key), }))} + > + {/* 각각의 탭 영역 */} +
+ {/* 기본정보 탭 */} + {activeTab === 'basic' && ( +
+ {/* 구분 */} +
+
+ + +
+
+ {/* 분기처리: 하수관로 */} + {basicType === 'tb_ms_swage_ppl' && ( +
+
+ {/* 용도코드 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set하수관로용도코드(val); + }} + /> + {/* 재질코드 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set하수관로재질코드(val); + }} + /> + {/* 행정읍면동코드 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set행정읍면동코드(val); + }} + /> +
+ {/* 설치년도 */} +
+ + {/* 시작년도 */} + + ~ + {/* 종료년도 */} + + {/* 경과년도 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + setYearFilter({ ...yearFilter, 경과년도: val }); + }} + /> +
+
+ {/* 관경 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set시작1(val); + }} + /> + ~ + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set종료1(val); + }} + /> + {/* 연장 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set시작2(val); + }} + /> + ~ + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set종료2(val); + }} + /> - {/* 기본정보 탭 */} - {activeTab === 'basic' && ( -
- {/* 구분 */} -
-
- - -
-
- {/* 분기처리: 하수처리시설 */} - {basicType === 'tb_il_swage_prcs_fclt' && ( -
- {/* 가동개시일자 */} -
- - {/* 시작일자 */} - - ~ - {/* 종료일자 */} - - {/* 시설용량 */} - - { - // 숫자만 입력 허용 - const val = e.target.value.replace(/[^0-9]/g, ''); - set시설용량최소(val); - }} - /> - ~ - { - // 숫자만 입력 허용 - const val = e.target.value.replace(/[^0-9]/g, ''); - set시설용량최대(val); - }} - /> - {/* 하수처리시설명 */} - - set하수처리시설명(e.target.value)} /> +
+
+ )} + {/* 분기처리: 하수처리시설 */} + {basicType === 'tb_il_swage_prcs_fclt' && ( +
+ {/* 가동개시일자 */} +
+ + {/* 시작일자 */} + + ~ + {/* 종료일자 */} + + {/* 시설용량 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set시작1(val); + }} + /> + ~ + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set종료1(val); + }} + /> + {/* 하수처리시설명 */} + + set변수1(e.target.value)} /> +
+
+ )} + {/* 분기처리: 하수처리구역 */} + {basicType === 'tb_ms_swage_prcs_zone' && ( +
+
+ + + + + + set변수1(e.target.value)} /> + + set변수2(e.target.value)} /> +
+
+ )} + {/* 분기처리: 하수맨홀 */} + {basicType === 'tb_ms_swage_mh' && ( +
+
+ {/* 설치년도 */} +
+ + {/* 시작년도 */} + + ~ + {/* 종료년도 */} + + {/* 경과년도 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + setYearFilter({ ...yearFilter, 경과년도: val }); + }} + /> +
+
+
+ {/* 용도코드 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set변수1(val); + }} + /> + {/* 하수맨홀 구경 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set시작1(val); + }} + /> + ~ + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set종료1(val); + }} + /> +
+
+ )} + {/* 분기처리: 하수펌프장 */} + {(basicType === 'tb_ms_swage_psmtn_1' || basicType === 'tb_ms_swage_psmtn_2') && ( +
+
+ {/* 설치년도 */} +
+ + {/* 시작년도 */} + + ~ + {/* 종료년도 */} + + {/* 경과년도 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + setYearFilter({ ...yearFilter, 경과년도: val }); + }} + /> +
+
+
+ {/* 일일처리용량 - 오수맨홀 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set시작1(val); + }} + /> + ~ + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set종료1(val); + }} + /> + {/* 우수양수능력 - 우수맨홀 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set시작2(val); + }} + /> + ~ + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set종료2(val); + }} + /> +
+
+ )} + {/* 분기처리: 우수토실? 토구? */} + {basicType === 'tb_ms_otfl' && ( +
+
+ {/* 설치년도 */} +
+ + {/* 시작년도 */} + + ~ + {/* 종료년도 */} + + {/* 경과년도 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + setYearFilter({ ...yearFilter, 경과년도: val }); + }} + /> +
+
+
+ {/* 하천명 */} + + set변수1(e.target.value)} /> + {/* 계획방류량 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set시작1(val); + }} + /> + ~ + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + set종료1(val); + }} + /> +
+
+ )} + + {/* 조회 버튼 중앙 정렬 */} +
+
)} - {/* 분기처리: 하수처리구역 */} - {basicType === 'tb_ms_swage_prcs_zone' && ( -
-
+ {/* 운영정보 탭 */} + {activeTab === 'operation' && ( +
+
+ + + + {/* 설치년도 */} +
+ + {/* 시작년도 */} + + ~ + {/* 종료년도 */} + + {/* 경과년도 */} + + { + // 숫자만 입력 허용 + const val = e.target.value.replace(/[^0-9]/g, ''); + setYearFilter({ ...yearFilter, 경과년도: val }); + }} + /> +
+
+ {/* 조회 버튼 중앙 정렬 */} +
+ +
+
+ )} + {/* 하수도정비기본계획보고서 탭 */} + {activeTab === 'report' && ( +
+ {/* 시도, 시군구, 하수처리구역 한 줄 */} +
- - set하수처리구역명(e.target.value)} /> - - set하수처리시설명(e.target.value)} /> + + + + + {/* 시작일자 */} + + ~ + {/* 종료일자 */} + +
+ {/* 조회 버튼 중앙 정렬 */} +
+
)} - - {/* 조회 버튼 중앙 정렬 */} -
- -
- )} + - {/* 운영정보 탭 */} - {activeTab === 'operation' && ( -
-
- - - - - ~ - -
- {/* 조회 버튼 중앙 정렬 */} -
- -
-
- )} - - {/* 하수도정비기본계획보고서 탭 */} - {activeTab === 'report' && ( -
- {/* 시도, 시군구, 하수처리구역 한 줄 */} -
- - - - - - - - - - ~ - -
- {/* 조회 버튼 중앙 정렬 */} -
- -
-
- )} {/* 📋 결과 리스트 */} -
{ - // Shift+Wheel은 브라우저가 기본적으로 가로 스크롤을 처리하지만, // 세로 스크롤이 최상단/최하단에 도달했을 때 가로 스크롤이 막히는 현상을 해결 const container = e.currentTarget; const isShift = e.shiftKey; @@ -671,47 +1218,52 @@ const SearchModal: React.FC = ({ open, onOpenChange, onFeature }} > {/* 선택된 탭의 label */} -
+ < div className="text-2xl font-bold mb-2" > {TABS.find(tab => tab.key === activeTab)?.label} -
- {/* 조회 결과 라벨 및 건수 표시 */} - { - (() => { - // 조회 건수 변수 선언 - const resultCount = tableData.length; - // 탭별 라벨 - const label = - activeTab === 'basic' - ? BASIC_TYPES.find(type => type.key === basicType)?.label - : activeTab === 'operation' - ? WORK_TYPES.find(type => type.key === workType)?.label - : activeTab === 'report' - ? '하수도정비기본계획보고서' - : TABS.find(tab => tab.key === activeTab)?.label; - return ( -
- ▶ {label} 조회 결과 - ({resultCount.toLocaleString()}건) -
- ); - })() - } - - {/* FeatureClickEventPopup 표시 */} - { - popupFeature && ( - setPopupFeature(null)} - /> - ) - } + {/* 조회 결과 라벨 및 건수 표시 */} + { + (() => { + // 조회 건수 변수 선언 + const resultCount = tableData.length; + // 탭별 라벨 + const label = + activeTab === 'basic' + ? BASIC_TYPES.find(type => type.key === basicType)?.label + : activeTab === 'operation' + ? WORK_TYPES.find(type => type.key === workType)?.label + : activeTab === 'report' + ? '하수도정비기본계획보고서' + : TABS.find(tab => tab.key === activeTab)?.label; + return ( +
+ ▶ {label} 조회 결과 + ({resultCount.toLocaleString()}건) +
+ ); + })() + } + + {/* FeatureClickEventPopup 표시 */} + { + popupFeature && ( + setPopupFeature(null)} + /> + ) + } +
); @@ -721,9 +1273,11 @@ const SearchModal: React.FC = ({ open, onOpenChange, onFeature open={open} onOpenChange={onOpenChange} bodyClass={` - ${modalMaxWidth} ${modalMinWidth} - transition-all duration-300 - w-full overflow-hidden + h-[100vh] + w-[60vw] + max-w-none + max-h-none + overflow-hidden z-[200] `} body={renderBody()} diff --git a/apps/sn/app/map/featureClickEventPopup.tsx b/apps/sn/app/map/featureClickEventPopup.tsx index cc63caf76..946331c97 100644 --- a/apps/sn/app/map/featureClickEventPopup.tsx +++ b/apps/sn/app/map/featureClickEventPopup.tsx @@ -9,27 +9,41 @@ import { getLayerContentComponent } from "./components/common"; // TODO: const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, featureData: any }) => { const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; }; - const featureId = featureData.getId(); // 피처의 id 가져오기 + // const featureId = featureData.getId(); // 피처의 id 가져오기 + const featureId = typeof featureData.getId === 'function' + ? featureData.getId() + : featureData.fid; const [layerNm, setLayerNm] = useState(""); // 레이어 이름 상태 const [tableData, setTableData] = useState(null); // 피처 데이터 상태 const [headlist, setHeadlist] = useState<{ id: string; title: string; }[]>([]); // 컬럼리스트 변경상태 - let [buttonChk,setButtonChk] = useState(true) + let [buttonChk, setButtonChk] = useState(true) // 피쳐데이터의 현재 레이어 이름 가져오는 함수 const getSelectedLayers = () => { + let result = null; const layers = gisMap.getLayers().getArray(); // gisMap에서 모든 레이어 가져오기 let featureLayer: { get: (key: string) => any } = { get: (key: string) => null }; // 피처가 속한 레이어를 찾기 위한 변수 layers.forEach((layer: any) => { const source = layer.getSource(); - if (source && source.hasFeature && source.hasFeature(featureData)) { + if (source && source.hasFeature && featureData + && typeof featureData.getId === 'function' && source.hasFeature(featureData)) { featureLayer = layer; // 피처가 속한 레이어 찾기 } }); - return featureLayer.get('lyrNm'); // 레이어 이름 출력 + // SearchMoal 클릭 이벤트와 Gis 클릭 이벤트 구분하기 + if (featureLayer.get('lyrNm') === null) { + if (featureData.lyrTypeNm === 'tb_il_swage_prcs_fclt') result = '하수처리시설'; + else if (featureData.lyrTypeNm === 'tb_ms_swage_prcs_zone') result = '하수처리구역'; + } + else result = featureLayer.get('lyrNm'); + + return result; + // return featureLayer.get('lyrNm'); // 레이어 이름 출력 }; useEffect(() => { const fetchData = async () => { if (featureId) { const selectedLayerName = getSelectedLayers(); // 레이어 이름 가져오기 + console.log("selectedLayerName", selectedLayerName); setLayerNm(selectedLayerName); // 상태 업데이트 const data = await getData(`v1/map/features/${featureId}`); @@ -79,15 +93,15 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
-
- {buttonChk ? : null} -
- {ContentComponent && } + {buttonChk ? : null} +
+ {ContentComponent && }
) diff --git a/packages/common/business_components/src/ui/tab/index-2.tsx b/packages/common/business_components/src/ui/tab/index-2.tsx new file mode 100644 index 000000000..23647ac7e --- /dev/null +++ b/packages/common/business_components/src/ui/tab/index-2.tsx @@ -0,0 +1,38 @@ +import { Tabs, TabsList, TabsTrigger } from '@common/components/ui'; +import React from 'react'; + +interface TabItem { + value: string; + label: string; + onClick?: () => void; +} + +interface UITabProps extends React.HTMLAttributes { + defaultValue?: string; + tabList: TabItem[]; + children: React.ReactNode; +} + +const UITab2 = React.forwardRef< + HTMLDivElement, + UITabProps +>(({defaultValue, tabList, children}, ref)=>{ + return ( + + + {tabList.map((tab) => ( + + {tab.label} + + ))} + + {children} + + ) +}) +export { UITab2 };