ui 테이블 체크박스 사용시 클래스 타입을 사용 체크
This commit is contained in:
@@ -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<number>(1);
|
||||
const [idx, setIdx] = useState<number>(index);
|
||||
const [headerHeight, setHeaderHeight] = useState<number>(0);
|
||||
const headerRef = useRef<HTMLTableSectionElement>(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 ? <div className="card-header">
|
||||
<h3 className="text-2xl font-medium text-label">{headName}</h3>
|
||||
</div> : <></>}
|
||||
<div className={`card !m-[1.2rem] !p-0r ${className}`}>
|
||||
{headName ? (
|
||||
<div className="card-header">
|
||||
<h3 className="text-2xl font-medium text-label">{headName}</h3>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<div className={`card !p-0r !m-[1.2rem] ${className}`}>
|
||||
<Table variant="secondary">
|
||||
<TableHeader ref={headerRef} className="font-bold">
|
||||
{children ? children : <HeadMakeColSpan upHeadList={headlist} />}
|
||||
</TableHeader>
|
||||
<TableBody className='text-center'>
|
||||
{tableData.length > 0 ? tableData?.map((el: Record<string, unknown>, index) => (
|
||||
<TableRow key={`row-${index}`}>
|
||||
{headlist
|
||||
.filter((item) => item.visible != false)
|
||||
.map((head) => (
|
||||
head.id && head.id.length > 1 && (
|
||||
boldArray.includes(index)
|
||||
?
|
||||
<TableCell
|
||||
className={`${head.align === 'right' ? 'text-right' : head.align === 'center' ? 'text-center' : 'text-center'} ${cellClick && idx === index ? '!font-[1000] cursor-pointer' :
|
||||
cellClick ? 'cursor-pointer' : ''
|
||||
} !font-bold sticky bg-secondary z-40`}
|
||||
style={{ top: `${headerHeight + (index * 39)}px` }}
|
||||
onClick={() => 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, ",")}
|
||||
</TableCell>
|
||||
:
|
||||
<TableCell
|
||||
className={`${head.align === 'right' ? 'text-right' : head.align === 'center' ? 'text-center' : 'text-center'} ${cellClick && idx === index ? '!font-[1000] cursor-pointer' :
|
||||
cellClick ? 'cursor-pointer' : ''
|
||||
<TableBody className="text-center">
|
||||
{tableData.length > 0 ? (
|
||||
tableData?.map((el: Record<string, unknown>, index) => (
|
||||
<TableRow key={`row-${index}`}>
|
||||
{headlist
|
||||
.filter((item) => item.visible != false)
|
||||
.map(
|
||||
(head) =>
|
||||
head.id &&
|
||||
head.id.length > 1 &&
|
||||
(boldArray.includes(index) ? (
|
||||
<TableCell
|
||||
className={`${head.align === "right" ? "text-right" : head.align === "center" ? "text-center" : "text-center"} ${
|
||||
cellClick && idx === index
|
||||
? "cursor-pointer !font-[1000]"
|
||||
: cellClick
|
||||
? "cursor-pointer"
|
||||
: ""
|
||||
} sticky z-40 bg-secondary !font-bold`}
|
||||
style={{ top: `${headerHeight + index * 39}px` }}
|
||||
onClick={() => 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,
|
||||
",",
|
||||
)}
|
||||
</TableCell>
|
||||
) : (
|
||||
<TableCell
|
||||
className={`${head.align === "right" ? "text-right" : head.align === "center" ? "text-center" : "text-center"} ${
|
||||
cellClick && idx === index
|
||||
? "cursor-pointer !font-[1000]"
|
||||
: cellClick
|
||||
? "cursor-pointer"
|
||||
: ""
|
||||
} mt-[${boldArray.length * 40}px]`}
|
||||
onClick={() => handleCellClick(index, head.id)}
|
||||
key={`cell-${head.id}-${index}`}
|
||||
>
|
||||
{typeof el[head.id] === 'object'
|
||||
? <Checkbox
|
||||
checked={(el[head.id] as ChkClass).chk === true}
|
||||
onCheckedChange={(checked) => {
|
||||
if((el[head.id] as ChkClass).readonly == true) return
|
||||
(el[head.id] as ChkClass).chk = Boolean(checked);
|
||||
}}
|
||||
>
|
||||
<Check className="h-6 w-6 text-primary" />
|
||||
</Checkbox>:
|
||||
typeof el[head.id] === 'boolean'
|
||||
? <Checkbox
|
||||
checked={el[head.id] === true}
|
||||
onCheckedChange={(checked) => {
|
||||
el[head.id] = checked;
|
||||
}}
|
||||
>
|
||||
<Check className="h-6 w-6 text-primary" />
|
||||
</Checkbox>
|
||||
:
|
||||
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, ",")}
|
||||
</TableCell>
|
||||
)
|
||||
))}
|
||||
</TableRow>
|
||||
)) : (
|
||||
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) ? (
|
||||
<Checkbox
|
||||
checked={
|
||||
(el[head.id] as ChkClass)?.chk === true
|
||||
}
|
||||
onCheckedChange={(checked) => {
|
||||
{
|
||||
console.log(el[head.id]);
|
||||
}
|
||||
if (
|
||||
(el[head.id] as ChkClass).readonly == true
|
||||
)
|
||||
return;
|
||||
(el[head.id] as ChkClass).chk =
|
||||
Boolean(checked);
|
||||
}}
|
||||
>
|
||||
<Check className="h-6 w-6 text-primary" />
|
||||
</Checkbox>
|
||||
) : typeof el[head.id] === "boolean" ? (
|
||||
<Checkbox
|
||||
checked={el[head.id] === true}
|
||||
onCheckedChange={(checked) => {
|
||||
el[head.id] = checked;
|
||||
}}
|
||||
>
|
||||
<Check className="h-6 w-6 text-primary" />
|
||||
</Checkbox>
|
||||
) : 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,
|
||||
",",
|
||||
)
|
||||
)
|
||||
}
|
||||
</TableCell>
|
||||
)),
|
||||
)}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={headlist.filter((item) => item.visible != false).length} className="h-24 text-center text-gray-500">
|
||||
<TableCell
|
||||
colSpan={
|
||||
headlist.filter((item) => item.visible != false).length
|
||||
}
|
||||
className="h-24 text-center text-gray-500"
|
||||
>
|
||||
조회된 결과가 없습니다.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
{total <= 0 ? <></> : <UiPageNations total={total} cur={cur} pageSize={pageSize} onPageChange={handlePageChange} />}
|
||||
{total <= 0 ? (
|
||||
<></>
|
||||
) : (
|
||||
<UiPageNations
|
||||
total={total}
|
||||
cur={cur}
|
||||
pageSize={pageSize}
|
||||
onPageChange={handlePageChange}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user