Merge branch 'iipbs/sn/dev' into iipbs/dm/dev
This commit is contained in:
+1
-1
@@ -27,4 +27,4 @@ settings.json
|
||||
.npmrc
|
||||
.cursor
|
||||
|
||||
apps/**/tsconfig.tsbuildinfo
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#!/bin/sh
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [ "$BRANCH" != "main" ]; then
|
||||
exit 0
|
||||
fi
|
||||
pnpm turbo run build --filter="...[origin/$BRANCH]"
|
||||
|
||||
@@ -21,7 +21,6 @@ export default function RootLayout({
|
||||
setCurrentMenuInfo(id);
|
||||
getMenuAuth(id.menuCd);
|
||||
router.push(id.urlPath);
|
||||
console.log(id);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
## Project
|
||||
This repository contains a Next.js web application.
|
||||
|
||||
Main technologies:
|
||||
- Next.js
|
||||
- TypeScript
|
||||
- pnpm workspace
|
||||
- turborepo
|
||||
|
||||
이 저장소는 pnpm workspace + Turborepo 기반 monorepo이다.
|
||||
|
||||
- 워크스페이스 범위는 `apps/*`, `apps/common/*`, `packages/*`, `packages/common/*`
|
||||
- 루트 스크립트는 `turbo run build`, `turbo run dev` 를 사용한다
|
||||
- `build` 작업은 의존 패키지의 `build` 를 먼저 수행한다 (`dependsOn: ["^build"]`)
|
||||
- `dev` 는 캐시하지 않는 지속 실행 작업이다
|
||||
- 변경 범위만 선택 실행할 수 있으므로, 전체 빌드보다 `--filter` 사용을 우선한다
|
||||
|
||||
## Encoding
|
||||
- UTF-8
|
||||
- 한글이 깨지지 않도록 주의할 것
|
||||
|
||||
## Monorepo structure
|
||||
apps/
|
||||
_template
|
||||
as
|
||||
cm
|
||||
cs
|
||||
dc
|
||||
dm
|
||||
dm_new
|
||||
fo
|
||||
sn
|
||||
st
|
||||
wr
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import MsSwagePpl from "../popupComponent/MsSwagePpl";
|
||||
import sewagePump from "../popupComponent/sewagePump";
|
||||
import MsSwagePpl from "../popupComponent/MsSwagePpl"; // 하수관로
|
||||
import sewagePump from "../popupComponent/sewagePump"; // 하수펌프
|
||||
import smh from "../popupComponent/smh";
|
||||
import Ssc from "../popupComponent/Ssc";
|
||||
import StormWaterPump from "../popupComponent/stormWaterPump";
|
||||
|
||||
@@ -28,6 +28,10 @@ import { VerticalTable } from "@/components/ui/verticalTable";
|
||||
import { useGisContext } from "@common/business_components/ui/map/Gis";
|
||||
import { Button } from "@common/components/ui";
|
||||
import { useEffect, useRef, useState, useMemo } from "react";
|
||||
import Style from "ol/style/Style.js";
|
||||
import Fill from "ol/style/Fill.js";
|
||||
import Stroke from "ol/style/Stroke.js";
|
||||
import CircleStyle from "ol/style/Circle.js";
|
||||
import { getLayerContentComponent } from "../common";
|
||||
import { SwtrmtFcltCol, SwtrmtFcltCol2, SwtrmtPrcsZoneCol, SwtrmtPrcsZoneCol2, untrtSwgRainCol1, untrtSwgRainCol2, MsSwagePplCol, MsSwagePplCol2, ExclnSewagePumpCol, ExclnSewagePumpCol2, DrtwSewagePumpCol, DrtwSewagePumpCol2, MsSwageMhlCol, MsSwageMhlCol2, stofcbrCol, stofcbrCol2, MS_SWAGE_MHL_CODES, DRTW_SEWAGE_PUMP_USE_CODES } from "../common/table";
|
||||
import InfilChart from './chart/infilChart';
|
||||
@@ -38,6 +42,27 @@ import { codeMapper } from "../common/codeMapper";
|
||||
import LoadingOverlay from '@/components/ui/LoadingBar';
|
||||
import { searchUpperPpls } from "./smh";
|
||||
|
||||
const linkedFacilityHighlightStyle = new Style({
|
||||
image: new CircleStyle({
|
||||
radius: 18,
|
||||
fill: new Fill({
|
||||
color: 'rgba(255, 235, 59, 0.35)',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: 'rgba(255, 193, 7, 0.45)',
|
||||
width: 2,
|
||||
}),
|
||||
}),
|
||||
fill: new Fill({
|
||||
color: 'rgba(255, 235, 59, 0.2)',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: 'rgba(255, 193, 7, 0.35)',
|
||||
width: 2.5,
|
||||
}),
|
||||
zIndex: 9999,
|
||||
});
|
||||
|
||||
|
||||
const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, featureData: any }) => {
|
||||
const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; };
|
||||
@@ -59,6 +84,8 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
const [isLoading, setIsLoading] = useState(false); // 로딩 상태
|
||||
const [chmbrXcnts, setChmbrXcnts] = useState<string>(''); // 로딩 상태
|
||||
const [chmbrYdnts, setChmbrYdnts] = useState<string>(''); // 로딩 상태
|
||||
const linkedFacilityFeatureRef = useRef<any>(null);
|
||||
const linkedFacilityOriginalStyleRef = useRef<any>(null);
|
||||
|
||||
// 🎯 관로관리번호 추출
|
||||
const pplMngNo = featureData?.values_?.fclt_mng_no || "";
|
||||
@@ -77,6 +104,70 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
};
|
||||
}, [featureData?.values_]);
|
||||
|
||||
const clearLinkedFacilityHighlight = () => {
|
||||
if (linkedFacilityFeatureRef.current) {
|
||||
linkedFacilityFeatureRef.current.setStyle(linkedFacilityOriginalStyleRef.current ?? undefined);
|
||||
linkedFacilityFeatureRef.current.changed?.();
|
||||
}
|
||||
|
||||
linkedFacilityFeatureRef.current = null;
|
||||
linkedFacilityOriginalStyleRef.current = null;
|
||||
};
|
||||
|
||||
// 하수처리구역에 연결된 하수처리시설 피처를 찾아 기존 아이콘 위에 노랑 하이라이트를 덧씌운다.
|
||||
const highlightLinkedFacility = (facilityCode: string | null | undefined) => {
|
||||
clearLinkedFacilityHighlight();
|
||||
|
||||
if (!gisMap || !facilityCode) return;
|
||||
|
||||
const normalizedFacilityCode = String(facilityCode).trim();
|
||||
const layers = gisMap.getLayers().getArray();
|
||||
|
||||
for (const layer of layers) {
|
||||
const source = layer?.getSource?.();
|
||||
if (!source?.getFeatures) continue;
|
||||
|
||||
const features = source.getFeatures();
|
||||
const targetFeature = features.find((feature: any) => {
|
||||
const featureId = feature?.getId?.();
|
||||
const isFacilityLayer = typeof featureId === 'string' && featureId.startsWith('tb_il_swage_prcs_fclt.');
|
||||
const featureFacilityCode = feature?.get?.('swtrmt_fclt_cd');
|
||||
|
||||
return isFacilityLayer && String(featureFacilityCode ?? '').trim() === normalizedFacilityCode;
|
||||
});
|
||||
|
||||
if (targetFeature) {
|
||||
const originalFeatureStyle = targetFeature.getStyle?.();
|
||||
const featureLayer = targetFeature.getLayer?.();
|
||||
const layerStyleFn = featureLayer?.getStyleFunction?.() ?? null;
|
||||
|
||||
linkedFacilityOriginalStyleRef.current = originalFeatureStyle;
|
||||
linkedFacilityFeatureRef.current = targetFeature;
|
||||
targetFeature.setStyle((feature: any, resolution: number) => {
|
||||
let styles: any[] = [];
|
||||
|
||||
if (typeof originalFeatureStyle === 'function') {
|
||||
const originalStyles = originalFeatureStyle(feature, resolution);
|
||||
if (Array.isArray(originalStyles)) styles.push(...originalStyles);
|
||||
else if (originalStyles) styles.push(originalStyles);
|
||||
} else if (originalFeatureStyle) {
|
||||
if (Array.isArray(originalFeatureStyle)) styles.push(...originalFeatureStyle);
|
||||
else styles.push(originalFeatureStyle);
|
||||
} else if (layerStyleFn) {
|
||||
const layerStyles = layerStyleFn(feature, resolution);
|
||||
if (Array.isArray(layerStyles)) styles.push(...layerStyles);
|
||||
else if (layerStyles) styles.push(layerStyles);
|
||||
}
|
||||
|
||||
styles.push(linkedFacilityHighlightStyle);
|
||||
return styles;
|
||||
});
|
||||
targetFeature.changed?.();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 피쳐데이터의 현재 레이어 이름 가져오는 함수
|
||||
const getSelectedLayers = () => {
|
||||
let result = null;
|
||||
@@ -348,6 +439,26 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
fetchData();
|
||||
}, [featureId, processedData]);
|
||||
|
||||
useEffect(() => {
|
||||
const layerTypeNm = featureData?.values_
|
||||
? featureData?.id_?.split('.')?.[0]
|
||||
: featureData?.lyrTypeNm;
|
||||
|
||||
if (layerTypeNm === 'tb_ms_swage_prcs_zone') {
|
||||
const facilityCode = featureData?.values_?.swtrmt_fclt_cd ?? featureData?.swtrmtFcltCd;
|
||||
highlightLinkedFacility(facilityCode);
|
||||
return () => {
|
||||
clearLinkedFacilityHighlight();
|
||||
};
|
||||
}
|
||||
|
||||
clearLinkedFacilityHighlight();
|
||||
|
||||
return () => {
|
||||
clearLinkedFacilityHighlight();
|
||||
};
|
||||
}, [featureData, gisMap]);
|
||||
|
||||
// 저장 시 모달 띄우기
|
||||
const handleSaveClick = () => {
|
||||
setIsModalOpen(true); // 모달 열기
|
||||
@@ -525,4 +636,4 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default FeatureClickEventPopup;
|
||||
export default FeatureClickEventPopup;
|
||||
|
||||
@@ -249,7 +249,7 @@ const ReportTab: React.FC<ReportTabProps> = ({ open, isSearch = true, ctpvNm, sg
|
||||
<LoadingOverlay isLoading={isLoading} />
|
||||
<UiTable
|
||||
headName={(() => {
|
||||
return (<>조회 결과 ({tableCount.toLocaleString('ko-KR')})건</>);
|
||||
return (<>조회 결과</>);
|
||||
})()
|
||||
}
|
||||
tableData={tableData}
|
||||
|
||||
@@ -130,7 +130,7 @@ const SearchModal: React.FC = () => {
|
||||
<UiTable className='w-[120%]'
|
||||
headName={(() => {
|
||||
const label = BASIC_TYPES.find((type) => type.val === basicType)?.text
|
||||
return (<>{label} 조회 결과 ({tableCount.toLocaleString('ko-KR')})건</>);
|
||||
return (<>{label} 조회 결과</>);
|
||||
})()
|
||||
}
|
||||
tableData={tableData}
|
||||
@@ -161,7 +161,7 @@ const SearchModal: React.FC = () => {
|
||||
headName={
|
||||
(() => {
|
||||
const label = WORK_TYPES.find((type) => type.val === workType)?.text
|
||||
return (<>{label} 사업 현황 ({tableCount.toLocaleString('ko-KR')})건</>);
|
||||
return (<>{label} 사업 현황</>);
|
||||
})()
|
||||
}
|
||||
tableData={tableData}
|
||||
@@ -188,7 +188,7 @@ const SearchModal: React.FC = () => {
|
||||
headName={
|
||||
(() => {
|
||||
const label = WORK_TYPES.find((type) => type.val === workType)?.text
|
||||
return (<>{label} 결과표 ({detailTableCount.toLocaleString('ko-KR')})건</>);
|
||||
return (<>{label} 결과표</>);
|
||||
})()
|
||||
}
|
||||
tableData={detailTableData}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { btnClass } from "@/app/store/common/code";
|
||||
import { excelCoSttnParsing } from "@/app/store/matDmd/coSttn/excel";
|
||||
import { fetchType, getFetch } from "@/components/lib/api";
|
||||
import {
|
||||
confirmToast,
|
||||
//confirmToast,
|
||||
excelDownload,
|
||||
formatPhoneNumber,
|
||||
getCity,
|
||||
@@ -29,8 +29,10 @@ import type { DemandCompType } from "@common/business_components/ui/sdmInsertFor
|
||||
import { Button } from "@common/components/ui";
|
||||
import moment from "moment";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import toast, { Toaster } from "react-hot-toast";
|
||||
// import toast, { Toaster } from "react-hot-toast";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAlertStore } from "@/src/shared/lib";
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
|
||||
export default function CoSttn() {
|
||||
const {
|
||||
@@ -48,7 +50,8 @@ export default function CoSttn() {
|
||||
getMyUUID
|
||||
} = useWrStore((state) => state);
|
||||
const { regAuthrtYn, mdfcnAuthrtYn } = auth;
|
||||
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
const { confirm } = useConfirm();
|
||||
const [bdstTable, setBdstTable] = useState<DemandCompType[]>();
|
||||
const [pageNation, setPageNation] = useState(1);
|
||||
const { coSttnRes, coSttnResCount } = coSttn;
|
||||
@@ -98,7 +101,7 @@ export default function CoSttn() {
|
||||
|
||||
useEffect(() => {
|
||||
if (!coSttn.isInit) {
|
||||
coSttnInit("1", "13", "0");
|
||||
coSttnInit("1", "13", "0"); // 수요처 목록 조회
|
||||
}
|
||||
}, [coSttn.isInit, coSttnInit]);
|
||||
|
||||
@@ -167,16 +170,21 @@ export default function CoSttn() {
|
||||
}
|
||||
};
|
||||
const { t } = useTranslation('base');
|
||||
const initPassword = () => {
|
||||
const initPassword = async () => {
|
||||
if (updateData) {
|
||||
const dmdInfoId = updateData.dmdInfoId;
|
||||
const dmdInfoSliceId = `${dmdInfoId.slice(0, 3)}-${dmdInfoId.slice(3, 5)}-${dmdInfoId.slice(5, 10)}-${dmdInfoId.slice(10)}`
|
||||
const handleConfirm = () => {
|
||||
coSttnPwInit(dmdInfoId);
|
||||
const handleConfirm = async () => {
|
||||
const message = await coSttnPwInit(dmdInfoId);
|
||||
alert(message);
|
||||
};
|
||||
confirmToast( t('isInitPw', { dmdInfoId: dmdInfoSliceId }), handleConfirm, 'text-2xl');
|
||||
//confirmToast( t('isInitPw', { dmdInfoId: dmdInfoSliceId }), handleConfirm, 'text-2xl');
|
||||
if (await confirm(t('isInitPw', { dmdInfoId: dmdInfoSliceId }))) {
|
||||
await handleConfirm();
|
||||
}
|
||||
} else {
|
||||
toast.error("비밀번호 초기화를 원하는 행을 선택해주세요.")
|
||||
alert("비밀번호 초기화를 원하는 행을 선택해주세요.");
|
||||
// toast.error("비밀번호 초기화를 원하는 행을 선택해주세요.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,7 +246,7 @@ export default function CoSttn() {
|
||||
onClick={() => {
|
||||
/* 저장 로직 */
|
||||
if (!updateData) {
|
||||
toast.error("수요처 변경을 원하는 행을 선택해주세요");
|
||||
alert("수요처 변경을 원하는 행을 선택해주세요");
|
||||
} else {
|
||||
setIsDmdModal({
|
||||
...isDmdModal,
|
||||
@@ -274,8 +282,8 @@ export default function CoSttn() {
|
||||
headName={[]}
|
||||
tableData={bdstTable || []}
|
||||
headlist={coSttn.coSttHeadList}
|
||||
pageSize={20}
|
||||
total={coSttnResCount + 10 || 0}
|
||||
pageSize={13}
|
||||
total={coSttnResCount || 0}
|
||||
cellClick={ async(index: number | undefined) => {
|
||||
const uuid = await getMyUUID();
|
||||
const updateData = coSttnRes[index as number];
|
||||
@@ -332,9 +340,7 @@ export default function CoSttn() {
|
||||
`/reuseFc/request/${data.dmdInfoId}`
|
||||
);
|
||||
if (dmd) {
|
||||
toast.error(
|
||||
`사업자번호 ${dmd.dmdInfoId}는 이미 등록되었습니다. 다시등록해주세요`
|
||||
);
|
||||
alert(`사업자번호 ${dmd.dmdInfoId}는 이미 등록되었습니다. 다시등록해주세요`);
|
||||
return;
|
||||
}
|
||||
await regDemandCompany(data as DemandCompType);
|
||||
@@ -352,7 +358,7 @@ export default function CoSttn() {
|
||||
}
|
||||
></UiModal>
|
||||
</ContentsDiv>
|
||||
<Toaster position="top-center" />
|
||||
{/* <Toaster position="top-center" /> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ export default function LdrmntCoSttn() {
|
||||
<div className="overflow-x-auto">
|
||||
<ListDiv className="min-w-max">
|
||||
<UiTable
|
||||
headName={undefined}
|
||||
headName={[]}
|
||||
tableData={bdstTable || []}
|
||||
headlist={ldrmntHeadListExport}
|
||||
pageSize={20}
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { CommonTableProps } from "@/app/store/common/type/header";
|
||||
import { fetchType, getFetchWithCount, putFectch } from "@/components/lib/api";
|
||||
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
|
||||
import { coSttHeadListExport, coSttNodeListExport } from "./headList";
|
||||
import toast from "react-hot-toast";
|
||||
|
||||
// 테이블 헤드 리스트
|
||||
const coSttNodeList = coSttNodeListExport;
|
||||
@@ -25,7 +24,7 @@ type coSttnActions = {
|
||||
coSttnInit: (pageNo: string, pageCnt: string, con: string) => void;
|
||||
coSttnSearch: (pageNo: string, pageCnt: string, con: string) => void;
|
||||
coSttnTxtSearch: (pageNo: string, pageCnt: string, con: string, txt: string) => void;
|
||||
coSttnPwInit: (dmdInfoId: string) => void;
|
||||
coSttnPwInit: (dmdInfoId: string) => Promise<string>;
|
||||
};
|
||||
|
||||
export type coSttnType = coSttnState & coSttnActions;
|
||||
@@ -46,6 +45,7 @@ export const coSttnActionsExport: (set: any) => coSttnActions = (
|
||||
set: any
|
||||
) => {
|
||||
return {
|
||||
// 수요처 목록 조회
|
||||
coSttnInit: async (pageNo: string, pageCnt: string, con: string) => {
|
||||
try {
|
||||
|
||||
@@ -126,10 +126,14 @@ export const coSttnActionsExport: (set: any) => coSttnActions = (
|
||||
try {
|
||||
const response = await putFectch(`/reuseFc/request/chgPassword/${dmdInfoId}`,[])
|
||||
if (response.status === 200) {
|
||||
toast.success('비밀번호가 초기화 되었습니다.')
|
||||
return "비밀번호가 초기화되었습니다.";
|
||||
} else {
|
||||
toast.error('비밀번호 초기화에 실패하였습니다')
|
||||
return "비밀번호 초기화에 실패하였습니다.";
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return "비밀번호 초기화에 실패하였습니다.";
|
||||
} finally {
|
||||
set((state: coSttnState) => {
|
||||
return {
|
||||
...state,
|
||||
@@ -139,11 +143,7 @@ export const coSttnActionsExport: (set: any) => coSttnActions = (
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
toast.error('비밀번호 초기화에 실패하였습니다.')
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,12 @@ function AlertDialog() {
|
||||
{message}
|
||||
</p>
|
||||
</div>
|
||||
<DialogFooter className="!justify-center">
|
||||
<DialogClose asChild>
|
||||
<Button>확인</Button>
|
||||
</DialogClose>
|
||||
<DialogFooter>
|
||||
<div className="flex w-full justify-center">
|
||||
<DialogClose asChild>
|
||||
<Button>확인</Button>
|
||||
</DialogClose>
|
||||
</div>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -28,17 +28,19 @@ function ConfirmDialog({
|
||||
{message}
|
||||
</p>
|
||||
</div>
|
||||
<DialogFooter className="!justify-center">
|
||||
<DialogClose asChild>
|
||||
<Button onClick={onConfirm} {...confirmButtonProps}>
|
||||
{confirmButtonProps?.label ?? "확인"}
|
||||
</Button>
|
||||
</DialogClose>
|
||||
<DialogClose asChild>
|
||||
<Button onClick={onCancel} color="white" {...cancelButtonProps}>
|
||||
{cancelButtonProps?.label ?? "취소"}
|
||||
</Button>
|
||||
</DialogClose>
|
||||
<DialogFooter>
|
||||
<div className="flex w-full justify-center gap-2">
|
||||
<DialogClose asChild>
|
||||
<Button onClick={onConfirm} {...confirmButtonProps}>
|
||||
{confirmButtonProps?.label ?? "확인"}
|
||||
</Button>
|
||||
</DialogClose>
|
||||
<DialogClose asChild>
|
||||
<Button onClick={onCancel} color="white" {...cancelButtonProps}>
|
||||
{cancelButtonProps?.label ?? "취소"}
|
||||
</Button>
|
||||
</DialogClose>
|
||||
</div>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -28,13 +28,9 @@
|
||||
"@/*": ["./*"],
|
||||
"@common/components/*": ["../../packages/common/components/src/*"],
|
||||
"@common/components": ["../../packages/common/components/src/index"],
|
||||
"@common/business_components/*": [
|
||||
"../../packages/common/business_components/src/*"
|
||||
],
|
||||
"@common/business_components": [
|
||||
"../../packages/common/business_components/src/index"
|
||||
],
|
||||
"@common/network": ["../../packages/common/network"]
|
||||
"@common/business_components/*": ["../../packages/common/business_components/src/*"],
|
||||
"@common/business_components": ["../../packages/common/business_components/src/index"],
|
||||
"@common/network": ["../../packages/common/network"],
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
|
||||
@@ -16,6 +16,7 @@ export type ChkClass = {
|
||||
chk: boolean;
|
||||
readonly: boolean;
|
||||
};
|
||||
|
||||
type UiTableProps<T extends object> = {
|
||||
headName: React.ReactNode | undefined;
|
||||
tableData: T[];
|
||||
@@ -123,17 +124,20 @@ export function UiTable<T extends object = Record<string, unknown>>({
|
||||
};
|
||||
|
||||
const leafCols = getLeafCols(headlist);
|
||||
const totalLabel = typeof total === "number" ? total.toLocaleString("ko-KR") : " ";
|
||||
const hasTotal = typeof total === "number";
|
||||
|
||||
return (
|
||||
<>
|
||||
{headName ? (
|
||||
headButton ? (
|
||||
<div className="card-header flex items-center justify-between">
|
||||
<h3 className="text-2xl font-medium text-label">{headName}</h3>
|
||||
<h3 className="text-2xl font-medium text-label">{headName} 총 {totalLabel}건</h3>
|
||||
<>{headButton}</>
|
||||
</div>
|
||||
) : (
|
||||
<div className="card-header">
|
||||
<h3 className="text-2xl font-medium text-label">{headName}</h3>
|
||||
<h3 className="text-2xl font-medium text-label">{headName} 총 {totalLabel}건</h3>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
@@ -286,7 +290,7 @@ export function UiTable<T extends object = Record<string, unknown>>({
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
{total <= 0 ? (
|
||||
{!hasTotal || total <= 0 ? (
|
||||
<></>
|
||||
) : (
|
||||
<UiPageNations
|
||||
|
||||
Reference in New Issue
Block a user