From 0bb16f97953a156b2a30ce309b342bc134a31003 Mon Sep 17 00:00:00 2001 From: jyha00 Date: Mon, 21 Jul 2025 15:28:42 +0900 Subject: [PATCH 1/8] =?UTF-8?q?=EB=8F=84=EB=84=9B=EC=B0=A8=ED=8A=B8=20?= =?UTF-8?q?=EB=B2=94=EB=A1=80=20=EB=86=92=EC=9D=B4=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/business_components/src/ui/chart/DoughnutChart.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/business_components/src/ui/chart/DoughnutChart.tsx b/packages/common/business_components/src/ui/chart/DoughnutChart.tsx index 6f113bee3..ec8fc2fd9 100644 --- a/packages/common/business_components/src/ui/chart/DoughnutChart.tsx +++ b/packages/common/business_components/src/ui/chart/DoughnutChart.tsx @@ -50,7 +50,7 @@ const customStyles = { fontWeight: "normal", marginTop: "16px", marginBottom: "8px", - minHeight: "32px", // 범례 영역 높이 통일 + minHeight: "60px", // 범례 영역 높이 통일 } as CSSProperties, }; const renderCustomizedLabel = ({ From ddf3a5cfa0aedbb2bb73e073ff97fa68ca2c5d9a Mon Sep 17 00:00:00 2001 From: leedj312 Date: Mon, 21 Jul 2025 19:56:57 +0900 Subject: [PATCH 2/8] =?UTF-8?q?=EC=BA=98=EB=A6=B0=EB=8D=94=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=98=A4=EB=A5=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/business_components/src/ui/date_picker/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/common/business_components/src/ui/date_picker/index.tsx b/packages/common/business_components/src/ui/date_picker/index.tsx index 2652eabd7..34760c245 100644 --- a/packages/common/business_components/src/ui/date_picker/index.tsx +++ b/packages/common/business_components/src/ui/date_picker/index.tsx @@ -108,12 +108,11 @@ export function DatePicker({ // captionLayout="dropdown-buttons" // fromYear={2000} // toYear={new Date().getFullYear()} - toDate={new Date()} // 금일까지만 표시됨 (금일 이후는 안보임) showOutsideDays={false} // 금월 까지만 표출되도록 mode="single" selected={field?.value} onSelect={handleSelect} - initialFocus + disabled={{ after: new Date() }} // 금일까지만 표시됨 (금일 이후는 안보임) 20250721 캘린더가 변경됨!! locale={ko} /> From 7d95ddf6a521f108b3b49d71760ba6e92a56d2dc Mon Sep 17 00:00:00 2001 From: truthwing Date: Tue, 22 Jul 2025 13:55:31 +0900 Subject: [PATCH 3/8] =?UTF-8?q?ChkClass=20=ED=83=80=EC=9E=85=EC=9D=98=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EB=A1=9C=20=EB=8F=99=EC=9E=91=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=EC=B2=B4=ED=81=AC=EB=B0=95=EC=8A=A4=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 --- .../business_components/src/ui/table/index.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/common/business_components/src/ui/table/index.tsx b/packages/common/business_components/src/ui/table/index.tsx index 85ffb85ea..b4a66d839 100644 --- a/packages/common/business_components/src/ui/table/index.tsx +++ b/packages/common/business_components/src/ui/table/index.tsx @@ -5,7 +5,10 @@ import { useEffect, useState, useRef } from "react"; import { HeadMakeColSpan } from "./HeadMakeColSpan"; import UiPageNations from "./uiPageNations"; import { Check } from "lucide-react"; - +export type ChkClass={ + chk:boolean + readonly:boolean +} type UiTableProps = { headName: React.ReactNode | undefined; tableData: { [key: string]: any }[]; @@ -109,7 +112,17 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr onClick={() => handleCellClick(index, head.id)} key={`cell-${head.id}-${index}`} > - {typeof el[head.id] === 'boolean' + {typeof el[head.id] === 'object' + ? { + if((el[head.id] as ChkClass).readonly == true) return + (el[head.id] as ChkClass).chk = Boolean(checked); + }} + > + + : + typeof el[head.id] === 'boolean' ? { From a028b6ae8bba8e074e82900d05925d4e5a9c6951 Mon Sep 17 00:00:00 2001 From: leedj312 Date: Tue, 22 Jul 2025 15:37:54 +0900 Subject: [PATCH 4/8] =?UTF-8?q?ui=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=EB=B0=95=EC=8A=A4=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=8B=9C=20=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=9D=84=20=EC=82=AC=EC=9A=A9=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/ui/table/index.tsx | 253 ++++++++++++------ 1 file changed, 170 insertions(+), 83 deletions(-) diff --git a/packages/common/business_components/src/ui/table/index.tsx b/packages/common/business_components/src/ui/table/index.tsx index b4a66d839..de6fed944 100644 --- a/packages/common/business_components/src/ui/table/index.tsx +++ b/packages/common/business_components/src/ui/table/index.tsx @@ -1,14 +1,21 @@ -"use client" +"use client"; -import { Checkbox, Table, TableBody, TableCell, TableHeader, TableRow } from "@common/components"; +import { + Checkbox, + Table, + TableBody, + TableCell, + TableHeader, + TableRow, +} from "@common/components"; import { useEffect, useState, useRef } from "react"; import { HeadMakeColSpan } from "./HeadMakeColSpan"; import UiPageNations from "./uiPageNations"; import { Check } from "lucide-react"; -export type ChkClass={ - chk:boolean - readonly:boolean -} +export type ChkClass = { + chk: boolean; + readonly: boolean; +}; type UiTableProps = { headName: React.ReactNode | undefined; tableData: { [key: string]: any }[]; @@ -23,22 +30,35 @@ type UiTableProps = { boldArray?: number[]; resetSelection?: boolean; index?: number; -} +}; type UiHeadProps = { id: string; title: string; align?: string; visible?: boolean; -} +}; -export function UiTable({ tableData, headlist, pageSize, total, headName, children, cellClick, onPageChange, className = '', resetPageNo = false, boldArray = [], resetSelection = false, index = -1 }: UiTableProps) { +export function UiTable({ + tableData, + headlist, + pageSize, + total, + headName, + children, + cellClick, + onPageChange, + className = "", + resetPageNo = false, + boldArray = [], + resetSelection = false, + index = -1, +}: UiTableProps) { const [cur, setCur] = useState(1); const [idx, setIdx] = useState(index); const [headerHeight, setHeaderHeight] = useState(0); const headerRef = useRef(null); - useEffect(() => { if (resetPageNo) { setCur(1); @@ -54,14 +74,14 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr useEffect(() => { if (headerRef.current) { - setHeaderHeight(headerRef.current.offsetHeight-5); + setHeaderHeight(headerRef.current.offsetHeight - 5); } }, [tableData, headlist]); const handlePageChange = (page: number) => { setCur(page); onPageChange(page); - } + }; const handleCellClick = (index: number, headId: string) => { if (cellClick) { @@ -70,91 +90,158 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr } }; - return ( <> - {headName ?
-

{headName}

-
: <>} -
+ {headName ? ( +
+

{headName}

+
+ ) : ( + <> + )} +
{children ? children : } - - {tableData.length > 0 ? tableData?.map((el: Record, index) => ( - - {headlist - .filter((item) => item.visible != false) - .map((head) => ( - head.id && head.id.length > 1 && ( - boldArray.includes(index) - ? - handleCellClick(index, head.id)} - key={`cell-${head.id}-${index}`} - > - {typeof el[head.id] !== 'number' ? String(el[head.id] ?? '') : String(el[head.id]).includes('.') - ? String(el[head.id]).split('.').map((part, index) => - index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part - ).join('.') - : String(el[head.id] ?? '').replace(/\B(?=(\d{3})+(?!\d))/g, ",")} - - : - + {tableData.length > 0 ? ( + tableData?.map((el: Record, index) => ( + + {headlist + .filter((item) => item.visible != false) + .map( + (head) => + head.id && + head.id.length > 1 && + (boldArray.includes(index) ? ( + handleCellClick(index, head.id)} + key={`cell-${head.id}-${index}`} + > + {typeof el[head.id] !== "number" + ? String(el[head.id] ?? "") + : String(el[head.id]).includes(".") + ? String(el[head.id]) + .split(".") + .map((part, index) => + index === 0 + ? part.replace( + /\B(?=(\d{3})+(?!\d))/g, + ",", + ) + : part, + ) + .join(".") + : String(el[head.id] ?? "").replace( + /\B(?=(\d{3})+(?!\d))/g, + ",", + )} + + ) : ( + handleCellClick(index, head.id)} - key={`cell-${head.id}-${index}`} - > - {typeof el[head.id] === 'object' - ? { - if((el[head.id] as ChkClass).readonly == true) return - (el[head.id] as ChkClass).chk = Boolean(checked); - }} - > - - : - typeof el[head.id] === 'boolean' - ? { - el[head.id] = checked; - }} - > - - - : - typeof el[head.id] !== 'number' ? - String(el[head.id] ?? '') : - String(el[head.id]).includes('.') - ? String(el[head.id]).split('.').map((part, index) => - index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part - ).join('.') - : - String(el[head.id] ?? '').replace(/\B(?=(\d{3})+(?!\d))/g, ",")} - - ) - ))} - - )) : ( + onClick={() => handleCellClick(index, head.id)} + key={`cell-${head.id}-${index}`} + > + { + //체크박스 유형애서 readOnly가 필요한 경우를 위해서 ChkClass 를 사용해서 readOnly 처리함. + typeof el[head.id] === "object" && + el[head.id] !== null && + "chk" in (el[head.id] as object) && + "readonly" in (el[head.id] as object) ? ( + { + { + console.log(el[head.id]); + } + if ( + (el[head.id] as ChkClass).readonly == true + ) + return; + (el[head.id] as ChkClass).chk = + Boolean(checked); + }} + > + + + ) : typeof el[head.id] === "boolean" ? ( + { + el[head.id] = checked; + }} + > + + + ) : typeof el[head.id] !== "number" ? ( + String(el[head.id] ?? "") + ) : String(el[head.id]).includes(".") ? ( + String(el[head.id]) + .split(".") + .map((part, index) => + index === 0 + ? part.replace( + /\B(?=(\d{3})+(?!\d))/g, + ",", + ) + : part, + ) + .join(".") + ) : ( + String(el[head.id] ?? "").replace( + /\B(?=(\d{3})+(?!\d))/g, + ",", + ) + ) + } + + )), + )} + + )) + ) : ( - item.visible != false).length} className="h-24 text-center text-gray-500"> + item.visible != false).length + } + className="h-24 text-center text-gray-500" + > 조회된 결과가 없습니다. )}
- {total <= 0 ? <> : } + {total <= 0 ? ( + <> + ) : ( + + )}
); -} \ No newline at end of file +} From 8435096e5a20865b8559a48e1b7b16fcafc0a471 Mon Sep 17 00:00:00 2001 From: swcho Date: Tue, 22 Jul 2025 16:16:42 +0900 Subject: [PATCH 5/8] =?UTF-8?q?remove:=20UITab2=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/ui/tab/index-2.tsx | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 packages/common/business_components/src/ui/tab/index-2.tsx diff --git a/packages/common/business_components/src/ui/tab/index-2.tsx b/packages/common/business_components/src/ui/tab/index-2.tsx deleted file mode 100644 index 71c103835..000000000 --- a/packages/common/business_components/src/ui/tab/index-2.tsx +++ /dev/null @@ -1,38 +0,0 @@ -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 }; From 804688b3c1b8875f211b87d329b7eb7267aa2a5d Mon Sep 17 00:00:00 2001 From: swcho Date: Tue, 22 Jul 2025 16:28:48 +0900 Subject: [PATCH 6/8] =?UTF-8?q?remove:=20UITable2=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/ui/table/index-2.tsx | 155 ------------------ 1 file changed, 155 deletions(-) delete mode 100644 packages/common/business_components/src/ui/table/index-2.tsx diff --git a/packages/common/business_components/src/ui/table/index-2.tsx b/packages/common/business_components/src/ui/table/index-2.tsx deleted file mode 100644 index 9756d2dfa..000000000 --- a/packages/common/business_components/src/ui/table/index-2.tsx +++ /dev/null @@ -1,155 +0,0 @@ -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components"; -import { useEffect, useState } from "react"; -import UiPageNations from "./uiPageNations"; - -type UiTableProps = { - headName: React.ReactNode | undefined; - tableData: { [key: string]: string | number | boolean | object }[]; - headlist: UiHeadProps[]; - pageSize: number; - total: number; - children: React.ReactNode | undefined; - cellClick: ((index: number | undefined, headId: string) => void) | undefined; - onPageChange: (page: number) => void; - className?: string; - resetPageNo?: boolean; - cur?: number; - height?: string; // ✅ 추가된 prop -}; - -type UiHeadProps = { - id: string; - title: string; - align?: string; -}; - -export function UiTable2({ - tableData, - headlist, - pageSize, - total, - children, - headName, - cellClick, - onPageChange, - className = '', - resetPageNo = false, - cur, - height = '45vh', // ✅ 기본값 설정 -}: UiTableProps) { - const [idx, setIdx] = useState(-1); - const [curState, setCurState] = useState(cur ?? 1); - - useEffect(() => { - setCurState(cur ?? 1); - }, [cur]); - - useEffect(() => { - if (resetPageNo) { - setCurState(1); - onPageChange(1); - } - }, [onPageChange, resetPageNo]); - - const handlePageChange = (page: number) => { - setCurState(page); - onPageChange(page); - }; - - const handleCellClick = (index: number, headId: string) => { - if (cellClick) { - cellClick(index, headId); - setIdx(index); - } - }; - - const startIdx = (curState - 1) * pageSize; - - return ( - <> - {headName && ( -
-
-

{headName}

-
-
- )} - -
- {/* ✅ 외부에서 조절 가능한 높이 적용 */} -
- - - {children ? ( - <>{children} - ) : ( - - {headlist.map((head) => ( - - {head.title} - - ))} - - )} - - - - {tableData.length > 0 ? ( - tableData.map((el, index) => ( - - {headlist.map((head) => ( - handleCellClick(startIdx + index, head.id)} - > - {typeof el[head.id] === 'number' - ? String(el[head.id]).replace(/\B(?=(\d{3})+(?!\d))/g, ",") - : String(el[head.id] ?? '')} - - ))} - - )) - ) : ( - - - {/* ✅ 높이 보장 + 가운데 정렬용 div */} -
- 🔍 검색 결과가 없습니다. -
-
-
- )} -
-
-
- - {/* 페이지네이션 하단 고정 */} - {( -
- -
- )} -
- - ); -} From d5c967e9ad47b5ab91ddf0a5e5b068d70325b386 Mon Sep 17 00:00:00 2001 From: swcho Date: Wed, 23 Jul 2025 17:45:06 +0900 Subject: [PATCH 7/8] =?UTF-8?q?feat,=20remove:=20-=20SelectBox=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=20selectContentClass=20pro?= =?UTF-8?q?ps=20=EC=B6=94=EA=B0=80=20(=EB=93=9C=EB=A1=AD=EB=8B=A4=EC=9A=B4?= =?UTF-8?q?=EC=97=90=20z=20index=20=EA=B0=92=EC=9D=84=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=A8)=20-=20SelectBox2=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/ui/select/index-2.tsx | 45 ------------------- .../src/ui/select/index.tsx | 4 +- 2 files changed, 3 insertions(+), 46 deletions(-) delete mode 100644 packages/common/business_components/src/ui/select/index-2.tsx diff --git a/packages/common/business_components/src/ui/select/index-2.tsx b/packages/common/business_components/src/ui/select/index-2.tsx deleted file mode 100644 index 8ff1f4582..000000000 --- a/packages/common/business_components/src/ui/select/index-2.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @remarks - * 이 버전은 SearchModal에서 사용하기 위해 `SelectContent`의 z-index를 `z-[101]`로 수정하였습니다. - */ -import { Label } from "@common/components"; -import React from "react"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./lib/selectBox"; - -/** 차트 기본 스타일 */ -interface SelectBox1 { - text:string, - val:string|number -} - -const SelectBox2 = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes & { - label:string, - selectClass:string|undefined, - className:string, - selectArray:SelectBox1[], - onSelectValue:(val:string|number)=>void, - value?: string|number - } ->(({ label, className, selectClass, selectArray, onSelectValue, value }, ref)=>{ - const placeHolder = selectArray?.[0]?.text ?? ""; - - return ( -
- {label && } - -
- ) -}) - -export { SelectBox2 }; diff --git a/packages/common/business_components/src/ui/select/index.tsx b/packages/common/business_components/src/ui/select/index.tsx index d09e3023a..82db6da45 100644 --- a/packages/common/business_components/src/ui/select/index.tsx +++ b/packages/common/business_components/src/ui/select/index.tsx @@ -27,6 +27,7 @@ const SelectBox = React.forwardRef< onSelectValue: (val: string | number) => void; value?: string | number; readOnly?: boolean; // readOnly 속성 추가 + selectContentClass?: string; } >( ( @@ -38,6 +39,7 @@ const SelectBox = React.forwardRef< onSelectValue, value, readOnly = false, + selectContentClass, }, ref, ) => { @@ -87,7 +89,7 @@ const SelectBox = React.forwardRef< > - + {visibleItems.map((selectArray) => ( {selectArray.text} From 523925459c6fac939f611d2ade69e73a5cd21ae7 Mon Sep 17 00:00:00 2001 From: jyha00 Date: Thu, 24 Jul 2025 19:28:20 +0900 Subject: [PATCH 8/8] =?UTF-8?q?=EB=B0=94=EC=B0=A8=ED=8A=B8=20=ED=8F=AC?= =?UTF-8?q?=EB=A7=A4=ED=84=B0=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business_components/src/ui/chart/BarChart.tsx | 2 ++ .../src/ui/chart/lib/function.tsx | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 packages/common/business_components/src/ui/chart/lib/function.tsx diff --git a/packages/common/business_components/src/ui/chart/BarChart.tsx b/packages/common/business_components/src/ui/chart/BarChart.tsx index 218ebac34..79aa61c98 100644 --- a/packages/common/business_components/src/ui/chart/BarChart.tsx +++ b/packages/common/business_components/src/ui/chart/BarChart.tsx @@ -6,6 +6,7 @@ import { type ChartConfig } from "./lib/chart"; import type { CSSProperties } from "react"; +import { formatCommaNumber } from "./lib/function"; const customStyles = { legendContainer: { @@ -119,6 +120,7 @@ export default function Chart({chartConfig=undefined, chartData=[], chartTitle=' fontWeight={500} domain={[0, globalMax]} ticks={ticks} + tickFormatter={(value) => formatCommaNumber(value)} label={yFieldText ? { value: yFieldText, className:"text-[15px] font-bold", position: 'insideLeft', angle: -90, offset: -30 } : undefined} /> }/> diff --git a/packages/common/business_components/src/ui/chart/lib/function.tsx b/packages/common/business_components/src/ui/chart/lib/function.tsx new file mode 100644 index 000000000..dc1921f0a --- /dev/null +++ b/packages/common/business_components/src/ui/chart/lib/function.tsx @@ -0,0 +1,12 @@ +// 숫자입력시 , 삽입 +export const formatCommaNumber = ( + value: number | string | undefined | null +): string => { + if (value === undefined || value === null || value === "") return ""; + const num = Number(value); + // 숫자로 변환할 수 없는 값이 들어올 경우 빈 문자열을 반환하여 예상치 못한 "NaN" 출력을 방지합니다. + if (isNaN(num)) { + return ""; + } + return num.toLocaleString(); +}; \ No newline at end of file