feat: 1차(수요일) 감리지적사항대응

- 하수관로, 하수맨홀, 하수펌프장, 우수토실 검색 구현
- UiTable number 값 가운데 정렬
- 일련번호 컬럼 삭제
- 환경청, 시도, 시군구 컬럼 추가
- 관리년도 삭제
- 오수전환율 0~1 사이의 값만 입력 가능하게 수정
This commit is contained in:
swcho
2025-07-03 09:35:36 +09:00
parent 3f7ea2bcd8
commit 711412b82e
15 changed files with 324 additions and 284 deletions
+199 -204
View File
@@ -115,7 +115,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
const [yearFilter, setYearFilter] = useState({
시작: "",
종료: "",
경과년도: "",
// 경과년도: "",
});
const [가동개시_시작_월, set가동개시_시작_월] = useState('');
@@ -182,7 +182,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
setYearFilter({
시작: "",
종료: "",
경과년도: "",
// 경과년도: "",
});
setShowTable(false);
setTableCount(0);
@@ -247,34 +247,34 @@ const SearchModal: React.FC<SearchModalProps> = ({
const pplCqlFilters = () => {
const cqlFilters: string[] = [];
// 추후 작성 예정
// if (변수1) cqlFilters.push(`용도코드='${변수1}'`);
// if (변수2) cqlFilters.push(`재질코드='${변수2}'`);
// if (변수3) cqlFilters.push(`행정읍면동코드='${변수3}'`);
if (변수1) cqlFilters.push(`usg_cd='${변수1}'`);
if (변수2) cqlFilters.push(`mqlt_cd='${변수2}'`);
if (변수3) cqlFilters.push(`pbadms_emd_cd='${변수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}`);
// 설치년도 범위
const startDate = getDateString(
yearFilter.시작,
가동개시_시작_월,
가동개시_시작_일,
"19000101",
);
const endDate = getDateString(
yearFilter.종료,
가동개시_종료_월,
가동개시_종료_일,
`${todayYear}${todayMonth}${todayDate}`,
);
cqlFilters.push(
`instl_ymd >= '${startDate}' and instl_ymd <= '${endDate}'`,
);
// 관경(mm) 범위
if (시작1 && 종료1) cqlFilters.push(`pdmt BETWEEN ${시작1} AND ${종료1}`);
else if (시작1) cqlFilters.push(`pdmt >= ${시작1}`);
else if (종료1) cqlFilters.push(`pdmt <= ${종료1}`);
// 연장(m) 범위
if (시작2 && 종료2) cqlFilters.push(`prlg BETWEEN ${시작2} AND ${종료2}`);
else if (시작2) cqlFilters.push(`prlg >= ${시작2}`);
else if (종료2) cqlFilters.push(`prlg <= ${종료2}`);
return cqlFilters;
};
@@ -319,27 +319,27 @@ const SearchModal: React.FC<SearchModalProps> = ({
const mhCqlFilters = () => {
const cqlFilters: string[] = [];
// // 설치년도 범위
// const startDate = getDateString(
// yearFilter.시작,
// 가동개시_시작_월,
// 가동개시_시작_일,
// "19000101",
// );
// const endDate = getDateString(
// yearFilter.종료,
// 가동개시_종료_월,
// 가동개시_종료_일,
// `${todayYear}${todayMonth}${todayDate}`,
// );
// cqlFilters.push(
// `설치시작년도 >= '${startDate}' and 설치시작년도 <= '${endDate}'`,
// );
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}`);
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;
};
@@ -347,32 +347,32 @@ const SearchModal: React.FC<SearchModalProps> = ({
const psmtnCqlFilters = () => {
const cqlFilters: string[] = [];
// 설치년도 범위
// const startDate = getDateString(
// yearFilter.시작,
// 가동개시_시작_월,
// 가동개시_시작_일,
// "19000101",
// );
// const endDate = getDateString(
// yearFilter.종료,
// 가동개시_종료_월,
// 가동개시_종료_일,
// `${todayYear}${todayMonth}${todayDate}`,
// );
// cqlFilters.push(
// `설치시작년도 >= '${startDate}' and 설치시작년도 <= '${endDate}'`,
// );
const startDate = getDateString(
yearFilter.시작,
가동개시_시작_월,
가동개시_시작_일,
"19000101",
);
const endDate = getDateString(
yearFilter.종료,
가동개시_종료_월,
가동개시_종료_일,
`${todayYear}${todayMonth}${todayDate}`,
);
cqlFilters.push(
`instl_ymd >= '${startDate}' and instl_ymd <= '${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}`);
// 일일처리용량 범위
if (시작1 && 종료1)
cqlFilters.push(`daily_prcs_cpct BETWEEN ${시작1} AND ${종료1}`);
else if (시작1) cqlFilters.push(`daily_prcs_cpct >= ${시작1}`);
else if (종료1) cqlFilters.push(`daily_prcs_cpct <= ${종료1}`);
// 우수양수능력 범위
if (시작2 && 종료2)
cqlFilters.push(`excln_wpmp_ablt BETWEEN ${시작2} AND ${종료2}`);
else if (시작2) cqlFilters.push(`excln_wpmp_ablt >= ${시작2}`);
else if (종료2) cqlFilters.push(`excln_wpmp_ablt <= ${종료2}`);
return cqlFilters;
};
@@ -380,24 +380,24 @@ const SearchModal: React.FC<SearchModalProps> = ({
const otflCqlFilters = () => {
const cqlFilters: string[] = [];
// 설치년도 범위
// const startDate = getDateString(
// yearFilter.시작,
// 가동개시_시작_월,
// 가동개시_시작_일,
// "19000101",
// );
// const endDate = getDateString(
// yearFilter.종료,
// 가동개시_종료_월,
// 가동개시_종료_일,
// `${todayYear}${todayMonth}${todayDate}`,
// );
// cqlFilters.push(
// `설치시작년도 >= '${startDate}' and 설치시작년도 <= '${endDate}'`,
// );
const startDate = getDateString(
yearFilter.시작,
가동개시_시작_월,
가동개시_시작_일,
"19000101",
);
const endDate = getDateString(
yearFilter.종료,
가동개시_종료_월,
가동개시_종료_일,
`${todayYear}${todayMonth}${todayDate}`,
);
cqlFilters.push(
`instl_ymd >= '${startDate}' and instl_ymd <= '${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}`);
@@ -502,7 +502,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
/>
{/* 경과년도 */}
<div className="flex items-center">
{/* <div className="flex items-center">
<Label className="mr-2 w-auto text-xl text-gray-600">
경과년도
</Label>
@@ -516,7 +516,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
setYearFilter({ ...yearFilter, 경과년도: val });
}}
/>
</div>
</div> */}
{/* 용도코드 */}
<Label className="mr-2 w-auto text-xl text-gray-600">
용도코드
@@ -729,7 +729,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
endLabel=""
/>
{/* 경과년도 */}
<Label className="mr-2 w-auto text-xl text-gray-600">
{/* <Label className="mr-2 w-auto text-xl text-gray-600">
경과년도
</Label>
<Input
@@ -741,9 +741,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setYearFilter({ ...yearFilter, 경과년도: val });
}}
/>
</div>
<div className='flex items-center mb-2'>
/> */}
{/* 용도코드 */}
<Label className="mr-2 w-auto text-xl text-gray-600">
용도코드
@@ -788,85 +786,6 @@ const SearchModal: React.FC<SearchModalProps> = ({
)}
{/* 분기처리: 하수펌프장 */}
{basicType === "tb_ms_swage_pmstn" && (
<div className="mb-3">
{/* 설치년도 */}
<div className="flex items-center mb-2">
<YearRangeSelectBox
start={yearFilter.시작}
end={yearFilter.종료}
onChange={range => setYearFilter({ ...yearFilter, 시작: range.start, 종료: range.end })}
startLabel="설치년도"
endLabel=""
/>
{/* 경과년도 */}
<Label className="w-auto text-xl text-gray-600 mr-2">경과년도</Label>
<Input
className='!text-xl w-[100px] placeholder:text-center mr-8'
placeholder="입력"
value={yearFilter.경과년도}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, '');
setYearFilter({ ...yearFilter, 경과년도: val });
}}
/>
</div>
<div className="flex items-center mb-2">
{/* 일일처리용량 - 오수맨홀 */}
<Label className="mr-2 w-auto text-xl text-gray-600">
일일처리용량
</Label>
<Input
className="w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={시작1}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
set시작1(val);
}}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
className="mr-8 w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={종료1}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
set종료1(val);
}}
/>
{/* 우수양수능력 - 우수맨홀 */}
<Label className="mr-2 w-auto text-xl text-gray-600">
우수양수능력
</Label>
<Input
className="w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={시작2}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
set시작2(val);
}}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
className="mr-8 w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={종료2}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
set종료2(val);
}}
/>
</div>
</div>
)}
{/* 분기처리: 우수토실? 토구? */}
{basicType === "tb_ms_stofcbr" && (
<div className="mb-3">
{/* 설치년도 */}
<div className="flex items-center mb-2">
@@ -878,34 +797,20 @@ const SearchModal: React.FC<SearchModalProps> = ({
endLabel=""
/>
{/* 경과년도 */}
<Label className="w-auto text-xl text-gray-600 mr-2">경과년도</Label>
<Input
className='!text-xl w-[100px] placeholder:text-center mr-8'
placeholder="입력"
value={yearFilter.경과년도}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, '');
setYearFilter({ ...yearFilter, 경과년도: val });
}}
/>
</div>
<div className="flex items-center mb-2">
{/* 하천명 */}
{/* <Label className="w-auto text-xl text-gray-600 mr-2">경과년도</Label>
<Input
className='!text-xl w-[100px] placeholder:text-center mr-8'
placeholder="입력"
value={yearFilter.경과년도}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, '');
setYearFilter({ ...yearFilter, 경과년도: val });
}}
/> */}
{/* 일일처리용량 - 오수맨홀 */}
<Label className="mr-2 w-auto text-xl text-gray-600">
하천명
</Label>
<Input
className="mr-8 w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={변수1}
onChange={(e) => {
set변수1(e.target.value);
}}
/>
{/* 계획방류량 */}
<Label className="mr-2 w-auto text-xl text-gray-600">
계획방류량
일일처리용량
</Label>
<Input
className="w-[100px] !text-xl placeholder:text-center"
@@ -928,6 +833,95 @@ const SearchModal: React.FC<SearchModalProps> = ({
set종료1(val);
}}
/>
{/* 우수양수능력 - 우수맨홀 */}
<Label className="mr-2 w-auto text-xl text-gray-600">
우수양수능력
</Label>
<Input
className="w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={시작2}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
set시작2(val);
}}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
className="mr-8 w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={종료2}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
set종료2(val);
}}
/>
</div>
</div>
)}
{/* 분기처리: 우수토실? 토구? */}
{basicType === "tb_ms_stofcbr" && (
<div className="mb-3">
{/* 설치년도 */}
<div className="flex items-center mb-2">
<YearRangeSelectBox
start={yearFilter.시작}
end={yearFilter.종료}
onChange={range => setYearFilter({ ...yearFilter, 시작: range.start, 종료: range.end })}
startLabel="설치년도"
endLabel=""
/>
{/* 경과년도 */}
{/* <Label className="w-auto text-xl text-gray-600 mr-2">경과년도</Label>
<Input
className='!text-xl w-[100px] placeholder:text-center mr-8'
placeholder="입력"
value={yearFilter.경과년도}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, '');
setYearFilter({ ...yearFilter, 경과년도: val });
}}
/> */}
{/* 하천명 */}
{/* <Label className="mr-2 w-auto text-xl text-gray-600">
하천명
</Label>
<Input
className="mr-8 w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={변수1}
onChange={(e) => {
set변수1(e.target.value);
}}
/> */}
{/* 계획방류량 */}
{/* <Label className="mr-2 w-auto text-xl text-gray-600">
계획방류량
</Label>
<Input
className="w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={시작1}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
set시작1(val);
}}
/>
<span className="mx-2 text-xl font-semibold">~</span>
<Input
className="mr-8 w-[100px] !text-xl placeholder:text-center"
placeholder="입력"
value={종료1}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
set종료1(val);
}}
/> */}
</div>
</div>
)}
@@ -970,7 +964,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
/>
<div className="flex items-center">
{/* 경과년도 */}
<Label className="mr-2 w-auto text-xl text-gray-600">
{/* <Label className="mr-2 w-auto text-xl text-gray-600">
경과년도
</Label>
<Input
@@ -982,7 +976,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
const val = e.target.value.replace(/[^0-9]/g, "");
setYearFilter({ ...yearFilter, 경과년도: val });
}}
/>
/> */}
</div>
</div>
{/* 조회 버튼 중앙 정렬 */}
@@ -1095,6 +1089,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
z-[101]
`}
body={renderBody()}
useDirectRender={true}
/>
);
};
@@ -9,6 +9,7 @@ type LayerComponentProps = {
featureData: any;
chkMainSsc?: boolean;
additionalData?: any;
onSaveClick?: () => void;
};
type LayerContentMap = {
[key: string]: {
@@ -16,7 +16,7 @@ const inputColumn = [
{ id: "place", title: "매설위치", type: "select", options: ["도로", "하상"] },
];
const MsSwagePpl = ({ featureData }: { featureData: any }) => {
const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClick?: () => void }) => {
const [repairData, setRepairData] = useState([
{ year: "2025", type: "개대체" },
{ year: "2025", type: "보수" },
@@ -40,7 +40,7 @@ const MsSwagePpl = ({ featureData }: { featureData: any }) => {
return (
<div>
<>
<VerticalTable
headName='자체 입력정보'
tableData={[]}
@@ -53,6 +53,8 @@ const MsSwagePpl = ({ featureData }: { featureData: any }) => {
onPageChange={function (page: number): void {
throw new Error("Function not implemented.");
}}
showSaveButton={true}
onSaveClick={onSaveClick}
/>
<InputSection
title="보수 및 갱신"
@@ -72,7 +74,7 @@ const MsSwagePpl = ({ featureData }: { featureData: any }) => {
sectionKey="inspection"
onInputChange={(section, index, field, value) => handleInputChange(section, index, field, value, dataMap)}
/>
</div>
</>
)
}
@@ -6,14 +6,23 @@ const inputColumn = [
{ id: "freq", title: "설계빈도", type: "input" },
]
// 하수펌프장
const sewagePump = () => {
const sewagePump = ({ featureData, onSaveClick }: { featureData: any, onSaveClick?: () => void }) => {
return (
<>
<VerticalTable headName='자체 입력정보' tableData={[]} headlist={inputColumn} pageSize={0} total={0} children={undefined} cellClick={undefined} isEditable={true} onPageChange={function (page: number): void {
<VerticalTable
headName='자체 입력정보'
tableData={[]}
headlist={inputColumn}
pageSize={0}
total={0}
children={undefined}
cellClick={undefined}
isEditable={true}
onPageChange={function (page: number): void {
throw new Error('Function not implemented.');
}}
/>
</>
showSaveButton={true}
onSaveClick={onSaveClick}
/>
)
}
@@ -8,13 +8,23 @@ const inputColumn = [
{ id: "place", title: "매설위치", type: "select", options: ["도로", "하상"] },
{ id: 'spec', title: '규격', type: 'input' },
];
const Smh = () => {
const Smh = ({ featureData, onSaveClick }: { featureData: any, onSaveClick?: () => void }) => {
return (
<div>
<VerticalTable headName='자체 입력정보' tableData={[]} headlist={inputColumn} pageSize={20} total={0} children={undefined} cellClick={undefined} isEditable={true} onPageChange={function (page: number): void {
<VerticalTable
headName='자체 입력정보'
tableData={[]}
headlist={inputColumn}
pageSize={20}
total={0}
children={undefined}
cellClick={undefined}
isEditable={true}
onPageChange={function (page: number): void {
throw new Error("Function not implemented.");
}}></VerticalTable>
</div>
}}
showSaveButton={true}
onSaveClick={onSaveClick}
/>
)
}
@@ -9,10 +9,19 @@ const StormWaterPump = ({ featureData }: { featureData: Record<string, any> }) =
const validKey = inputColumn.map((item) => item.id);
const filteredData = featureData && Object.entries(featureData).filter(([key]) => validKey.includes(key)).reduce((obj: Record<string, any>, [key, value]) => { obj[key] = value; return obj; }, {});
return (
<div><VerticalTable headName='자체 입력정보' tableData={[filteredData]} headlist={inputColumn} pageSize={0} total={0} children={undefined} cellClick={undefined} isEditable={true} onPageChange={function (page: number): void {
throw new Error('Function not implemented.');
}} />
</div>
<VerticalTable
headName='자체 입력정보'
tableData={[filteredData]}
headlist={inputColumn}
pageSize={0}
total={0}
children={undefined}
cellClick={undefined}
isEditable={true}
onPageChange={function (page: number): void {
throw new Error('Function not implemented.');
}}
/>
)
}
@@ -53,16 +53,16 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
try {
console.log(`추가 데이터 API 호출 시작: v1/onsemiro/swgRain/${adstDstrCd}/${manageNo}/mntrngs`);
// 🎯 타임아웃 설정 (10초)
const timeoutPromise = new Promise((_, reject) =>
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject(new Error('API 타임아웃')), 10000)
);
const apiPromise = getData(`v1/onsemiro/swgRain/${adstDstrCd}/${manageNo}/mntrngs`);
const response = await Promise.race([apiPromise, timeoutPromise]) as any;
console.log('추가 데이터 API 호출 성공:', response);
return response?.content || [];
} catch (error) {
@@ -207,7 +207,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
useEffect(() => {
if (layerNm === '중점우수토실' && featureData?.values_) {
const data = featureData.values_;
if (data?.adst_dstr_cd && data?.manage_no) {
// 🎯 추가 데이터를 비동기로 로딩 (UI 블로킹 없음)
fetchAdditionalData(data.adst_dstr_cd, data.manage_no)
@@ -310,14 +310,14 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
color="white"
onClick={openModalInfil}
>
Infil
침입수분석
</Button>
<Button
className="px-2 py-1 text-xl text-gray-600 border border-gray-600 rounded hover:bg-gray-700"
color="white"
onClick={openModalRdii}
>
RDII
RDII분석
</Button>
</>
)}
@@ -351,17 +351,13 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
total2={0}
isEditable2={buttonChk}
/>
<div className="w-full mx-5 flex items-center justify-end space-x-2">
{buttonChk ? <Button onClick={handleSaveClick} className="px-4 mr-5 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700">
저장
</Button> : null}
</div>
<Modal isModalOpen={isModalOpen} title="자체입력정보 저장" setIsModalOpen={setIsModalOpen} closeModal={handleModalClose} saveModal={handleModalSave}><div className="text-lg">정보를 저장하시겠습니까?</div></Modal>
{ContentComponent &&
<ContentComponent
featureData={fetchData}
chkMainSsc={chkMainSsc}
additionalData={mntrngsData}
onSaveClick={handleSaveClick}
/>
}
</div>
@@ -335,10 +335,15 @@ const IrSetting = () => {
// '.' 기호가 포함된 경우, 처음이나 끝에 오면 안 됨
if (newValue.includes('.') && newValue.startsWith('.')) return; // '.'이 처음에는 올 수 없음
// 숫자 값으로 변환하여 범위 체크 (0 이상 1 이하)
const numericValue = parseFloat(newValue);
if (isNaN(numericValue) || numericValue < 0 || numericValue > 1) return;
setInput1(newValue);
}}
className="ml-5 h-[3.2rem] text-center text-xl w-[150px]"
placeholder="예: 0.75" />
placeholder="예: 0.75"
/>
</FormSection>
<FormSection
name='analysis information'
@@ -400,7 +400,34 @@ export default function RTKForm() {
fileIdx={2} />
</div></FormSection>
<FormSection name='rate' form={form} titleNm='○ 오수전환율'>
<Input {...form.register("rate")} className="h-12 text-center text-xl w-[225px] ml-5" />
<Input
value={form.watch("rate")} // form의 rate 값을 가져옴
onChange={(e) => {
const newValue = e.target.value;
if (newValue === "") {
form.setValue("rate", newValue); // form의 rate 필드에 설정
return;
}
// 숫자와 '.'만 허용하고, '.'은 최대 하나인지 확인
const isValidChars = /^[0-9]*\.?[0-9]*$/.test(newValue);
if (!isValidChars) return; // 유효하지 않은 문자 또는 여러 개의 '.' 포함
// '.' 기호가 처음에 오면 안 됨
if (newValue.startsWith('.')) return;
// 완성된 숫자인 경우에만 범위 체크 (입력 중인 경우 허용)
if (!newValue.endsWith('.')) {
const numericValue = parseFloat(newValue);
if (isNaN(numericValue) || numericValue < 0 || numericValue > 1) return;
}
form.setValue("rate", newValue, { shouldValidate: true }); // form의 rate 필드에 설정
}}
className="h-12 text-center text-xl w-[225px] ml-5"
placeholder="예: 0.75"
/>
</FormSection>
<FormSection name='date' form={form} titleNm='○ 상수사용량 적용기간'>
{/* <DatePicker
@@ -24,12 +24,14 @@ const formSchema = z.object({
type ResultFormValues = z.infer<typeof formSchema>
const tableColumn = [
{ id: 'rainInfwtAnlsSn', title: '분석번호' },
{ id: 'enoNm', title: '환경청' },
{ id: 'ctpvNm', title: '시도' },
{ id: 'sggNm', title: '시군구' },
{ id: 'swageTmplntNm', title: '하수처리장' },
// { id: 'swtrmtZoneNm', title: '처리구역' },
{ id: 'aplcnYm', title: '상수사용연월' },
{ id: 'drtwSwtcRt', title: '오수 전환율' },
{ id: 'srcNm', title: 'RTX 계수 출처' },
{ id: 'srcNm', title: 'RTK 계수 출처' },
{ id: 'cntbArea', title: 'RDII 기여면적' },
{ id: 'anlsInfo', title: 'RDII 분석정보' },
{ id: 'regDt', title: '분석일자' },
@@ -24,8 +24,9 @@ const formSchema = z.object({
type ResultFormValues = z.infer<typeof formSchema>
const tableColumn = [
// { id: 'no', title: '번호' },
{ id: 'inftwtAnlsSn', title: '분석번호' },
{ id: 'enoNm', title: '환경청' },
{ id: 'ctpvNm', title: '시도' },
{ id: 'sggNm', title: '시군구' },
{ id: 'swageTmplntNm', title: '하수처리장' },
// { id: 'swtrmtZoneNm', title: '처리구역' },
{ id: 'aplcnYm', title: '적용연월' },
@@ -102,24 +102,6 @@ const Page = () => {
selected={toDate}
onSelect={(date: Date | undefined) => { if (date) setToDate(date) }} />
</div>
<div className='flex items-center gap-2'>
<Label className="w-20 text-xl text-gray-600">관리년도</Label>
<SelectBox
className="w-[90px] mr-3 ml-4"
selectClass="rounded-lg bg-white"
label=""
selectArray={yearOptions}
onSelectValue={(value: string | number) => setManageYear(String(value))}
/>
<span>~</span>
<SelectBox
className="w-[90px] mr-3 ml-4"
selectClass="rounded-lg bg-white"
label=""
selectArray={yearOptions}
onSelectValue={(value: string | number) => setMngQu(String(value))}
/>
</div>
<div className='flex items-center'>
<Label className="w-20 text-xl text-gray-600">등록자</Label>
<Input
@@ -103,24 +103,6 @@ const Page = () => {
<DatePicker mode={'single'}
selected={toDate}
onSelect={(date: Date | undefined) => { if (date) setToDate(date) }} />
<div className='flex items-center gap-2'>
<Label className="w-20 text-xl text-gray-600">관리년도</Label>
<SelectBox
className="w-[90px] mr-3 ml-4"
selectClass="rounded-lg bg-white"
label=""
selectArray={yearOptions}
onSelectValue={(value: string | number) => setManageYear(String(value))}
/>
<span>~</span>
<SelectBox
className="w-[90px] mr-3 ml-4"
selectClass="rounded-lg bg-white"
label=""
selectArray={yearOptions}
onSelectValue={(value: string | number) => setMngQu(String(value))}
/>
</div>
<div className='flex items-center'>
<Label className="w-20 text-xl text-gray-600">등록자</Label>
<Input
+14 -2
View File
@@ -1,5 +1,5 @@
import UiPageNations from "@common/business_components/ui/table/uiPageNations";
import { Table, TableBody, TableCell, TableRow } from "@common/components";
import { Table, TableBody, TableCell, TableRow, Button } from "@common/components";
import { useEffect, useState } from "react";
type UiTableProps = {
@@ -27,6 +27,8 @@ type UiTableProps = {
resetPageNo2?: boolean;
isEditable2?: boolean;
showSecondTable?: boolean;
showSaveButton?: boolean;
onSaveClick?: () => void;
};
type UiHeadProps = {
@@ -62,6 +64,8 @@ export function VerticalTable({
resetPageNo2 = false,
isEditable2 = false,
showSecondTable = false,
showSaveButton = false,
onSaveClick,
}: UiTableProps) {
const [cur, setCur] = useState<number>(1);
const [formData, setFormData] = useState<{ [key: string]: string | number | boolean }>({});
@@ -93,8 +97,16 @@ export function VerticalTable({
return (
<>
{headName ? (
<div className="card-header">
<div className="card-header flex items-center justify-between">
<h3 className="text-2xl mx-3 font-medium text-label">{headName}</h3>
{showSaveButton && onSaveClick && (
<Button
onClick={onSaveClick}
className="px-4 mr-3 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700"
>
저장
</Button>
)}
</div>
) : null}
<div className={`card !m-[1.2rem] !p-0r ${className}`}>
+13 -6
View File
@@ -538,6 +538,9 @@ importers:
date-fns:
specifier: ^3.6.0
version: 3.6.0
libphonenumber-js:
specifier: ^1.12.9
version: 1.12.9
lucide-react:
specifier: ^0.474.0
version: 0.474.0(react@18.3.1)
@@ -2398,7 +2401,7 @@ packages:
magic-string: 0.27.0
react-docgen-typescript: 2.2.2(typescript@5.6.3)
typescript: 5.6.3
vite: 6.2.0(@types/node@22.13.5)
vite: 6.2.0(@types/node@22.13.9)
dev: true
/@jridgewell/gen-mapping@0.3.8:
@@ -2511,7 +2514,7 @@ packages:
dnd-multi-backend: 8.1.2(dnd-core@16.0.1)
framer-motion: 11.18.2(react-dom@18.3.1)(react@18.3.1)
react: 18.3.1
react-dnd: 16.0.1(@types/node@22.13.5)(@types/react@18.3.18)(react@18.3.1)
react-dnd: 16.0.1(@types/node@22.13.9)(@types/react@18.3.18)(react@18.3.1)
react-dnd-html5-backend: 16.0.1
react-dnd-touch-backend: 16.0.1
react-dom: 18.3.1(react@18.3.1)
@@ -3991,7 +3994,7 @@ packages:
browser-assert: 1.2.1
storybook: 8.6.0(prettier@3.5.2)
ts-dedent: 2.2.0
vite: 6.2.0(@types/node@22.13.5)
vite: 6.2.0(@types/node@22.13.9)
dev: true
/@storybook/components@8.6.0(storybook@8.6.0):
@@ -4123,7 +4126,7 @@ packages:
resolve: 1.22.10
storybook: 8.6.0(prettier@3.5.2)
tsconfig-paths: 4.2.0
vite: 6.2.0(@types/node@22.13.5)
vite: 6.2.0(@types/node@22.13.9)
transitivePeerDependencies:
- rollup
- supports-color
@@ -4598,7 +4601,7 @@ packages:
'@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.9)
'@types/babel__core': 7.20.5
react-refresh: 0.14.2
vite: 6.2.0(@types/node@22.13.5)
vite: 6.2.0(@types/node@22.13.9)
transitivePeerDependencies:
- supports-color
dev: true
@@ -7314,6 +7317,10 @@ packages:
type-check: 0.4.0
dev: true
/libphonenumber-js@1.12.9:
resolution: {integrity: sha512-VWwAdNeJgN7jFOD+wN4qx83DTPMVPPAUyx9/TUkBXKLiNkuWWk6anV0439tgdtwaJDrEdqkvdN22iA6J4bUCZg==}
dev: false
/lie@3.3.0:
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
dependencies:
@@ -9780,7 +9787,7 @@ packages:
debug: 4.4.0
globrex: 0.1.2
tsconfck: 3.1.5(typescript@5.6.3)
vite: 6.2.0(@types/node@22.13.5)
vite: 6.2.0(@types/node@22.13.9)
transitivePeerDependencies:
- supports-color
- typescript