summaryrefslogtreecommitdiff
path: root/components/client-table-v2/GUIDE.md
diff options
context:
space:
mode:
Diffstat (limited to 'components/client-table-v2/GUIDE.md')
-rw-r--r--components/client-table-v2/GUIDE.md178
1 files changed, 178 insertions, 0 deletions
diff --git a/components/client-table-v2/GUIDE.md b/components/client-table-v2/GUIDE.md
new file mode 100644
index 00000000..4ccadfc7
--- /dev/null
+++ b/components/client-table-v2/GUIDE.md
@@ -0,0 +1,178 @@
+# Table Component & Data Fetching Guide
+
+이 가이드는 `ClientVirtualTable`을 사용하여 테이블을 구현하고, 데이터를 페칭하는 3가지 주요 패턴을 설명합니다.
+
+## 개요
+
+프로젝트의 복잡도와 요구사항에 따라 아래 3가지 패턴 중 하나를 선택하여 사용할 수 있습니다.
+
+| 모드 | 패턴 | 적합한 상황 | 특징 |
+|---|---|---|---|
+| **Client** | 1. Client-Side | 데이터가 적을 때 (< 1000건), 빠른 인터랙션 필요 | 전체 데이터 로드 후 브라우저에서 처리 |
+| **Server** | 2. Factory Service | 단순 CRUD, 마스터 테이블 | 코드 1줄로 서버 액션 생성, 빠른 개발 |
+| **Server** | 3. Custom Service | 복잡한 조인, 비즈니스 로직 | 완전한 쿼리 제어, Adapter를 도구로 사용 |
+
+---
+
+## 1. Client-Side (기본 모드)
+
+데이터가 많지 않을 때 가장 간단한 방법입니다. 모든 데이터를 한 번에 받아와 `data` prop으로 넘깁니다.
+
+### 사용법
+
+```tsx
+// page.tsx
+import { getAllUsers } from "@/lib/api/users";
+import { ClientVirtualTable } from "@/components/client-table-v2/client-virtual-table";
+import { columns } from "./columns";
+
+export default async function UsersPage() {
+ const users = await getAllUsers(); // 전체 목록 조회
+
+ return (
+ <ClientVirtualTable
+ fetchMode="client"
+ data={users}
+ columns={columns}
+ enablePagination
+ enableSorting
+ enableFiltering
+ />
+ );
+}
+```
+
+---
+
+## 2. Factory Service (추천 - 단순 조회용)
+
+`createTableService`를 사용하여 서버 사이드 페칭을 위한 액션을 자동으로 생성합니다.
+
+### 1) Server Action 생성
+
+```typescript
+// app/actions/user-table.ts
+"use server"
+
+import { db } from "@/lib/db";
+import { users } from "@/lib/db/schema";
+import { columns } from "@/components/users/columns";
+import { createTableService } from "@/components/client-table-v2/adapter/create-table-service";
+
+// 팩토리 함수로 액션 생성 (한 줄로 끝!)
+export const getUserTableData = createTableService({
+ db,
+ schema: users,
+ columns: columns
+});
+```
+
+### 2) 클라이언트 컴포넌트 연결
+
+```tsx
+// components/users/user-table.tsx
+"use client"
+
+import { getUserTableData } from "@/app/actions/user-table";
+import { ClientVirtualTable } from "@/components/client-table-v2/client-virtual-table";
+import { columns } from "./columns";
+import { useState, useEffect } from "react";
+
+export function UserTable() {
+ const [data, setData] = useState([]);
+ const [totalRows, setTotalRows] = useState(0);
+ const [loading, setLoading] = useState(false);
+
+ // 테이블 상태 관리
+ const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
+ const [sorting, setSorting] = useState([]);
+ const [columnFilters, setColumnFilters] = useState([]);
+ const [globalFilter, setGlobalFilter] = useState("");
+
+ // 데이터 페칭
+ useEffect(() => {
+ const fetchData = async () => {
+ setLoading(true);
+ const result = await getUserTableData({
+ pagination,
+ sorting,
+ columnFilters,
+ globalFilter
+ });
+ setData(result.data);
+ setTotalRows(result.totalRows);
+ setLoading(false);
+ };
+
+ fetchData();
+ }, [pagination, sorting, columnFilters, globalFilter]);
+
+ return (
+ <ClientVirtualTable
+ fetchMode="server"
+ data={data}
+ rowCount={totalRows}
+ columns={columns}
+ isLoading={loading}
+ // 상태 연결
+ pagination={pagination} onPaginationChange={setPagination}
+ sorting={sorting} onSortingChange={setSorting}
+ columnFilters={columnFilters} onColumnFiltersChange={setColumnFilters}
+ globalFilter={globalFilter} onGlobalFilterChange={setGlobalFilter}
+ />
+ );
+}
+```
+
+---
+
+## 3. Custom Service (복잡한 로직용)
+
+여러 테이블을 조인하거나, 특정 권한 체크 등 복잡한 로직이 필요할 때는 `DrizzleTableAdapter`를 직접 사용합니다.
+
+### 1) Custom Server Action 작성
+
+```typescript
+// app/actions/order-table.ts
+"use server"
+
+import { db } from "@/lib/db";
+import { orders, users } from "@/lib/db/schema";
+import { DrizzleTableAdapter } from "@/components/client-table-v2/adapter/drizzle-table-adapter";
+import { count, eq } from "drizzle-orm";
+
+export async function getOrderTableData(tableState) {
+ // 1. 어댑터로 조건절 생성
+ const adapter = new DrizzleTableAdapter(orders, columns);
+ const { where, orderBy, limit, offset } = adapter.getQueryParts(tableState);
+
+ // 2. 커스텀 쿼리 작성 (예: 유저 조인)
+ const data = await db
+ .select({
+ orderId: orders.id,
+ amount: orders.amount,
+ userName: users.name // 조인된 컬럼
+ })
+ .from(orders)
+ .leftJoin(users, eq(orders.userId, users.id))
+ .where(where)
+ .orderBy(...orderBy)
+ .limit(limit)
+ .offset(offset);
+
+ // 3. 카운트 쿼리
+ const total = await db
+ .select({ count: count() })
+ .from(orders)
+ .where(where);
+
+ return {
+ data,
+ totalRows: total[0]?.count ?? 0
+ };
+}
+```
+
+### 2) 클라이언트 연결
+
+Factory Service 방식과 동일하게 `useEffect`에서 `getOrderTableData`를 호출하면 됩니다.