feat: 테이블 검색 필터 위젯 구현 완료
- TableOptionsContext 기반 테이블 자동 감지 시스템 구현 - 독립 위젯으로 드래그앤드롭 배치 가능 - 3가지 기능: 컬럼 가시성, 필터 설정, 그룹 설정 - FlowWidget, TableList, SplitPanel 등 모든 테이블 컴포넌트 지원 - 유틸리티 카테고리에 등록 (1920×80px) - 위젯 크기 제어 가이드 룰 파일에 추가
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import React, { useState, useEffect, useCallback, useRef } from "react";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
@@ -52,6 +52,8 @@ import { FileUpload } from "@/components/screen/widgets/FileUpload";
|
||||
import { AdvancedSearchFilters } from "./filters/AdvancedSearchFilters";
|
||||
import { SaveModal } from "./SaveModal";
|
||||
import { useScreenPreview } from "@/contexts/ScreenPreviewContext";
|
||||
import { useTableOptions } from "@/contexts/TableOptionsContext";
|
||||
import { TableFilter, ColumnVisibility } from "@/types/table-options";
|
||||
|
||||
// 파일 데이터 타입 정의 (AttachedFileInfo와 호환)
|
||||
interface FileInfo {
|
||||
@@ -102,6 +104,8 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
}) => {
|
||||
const { isPreviewMode } = useScreenPreview(); // 프리뷰 모드 확인
|
||||
const { user } = useAuth(); // 사용자 정보 가져오기
|
||||
const { registerTable, unregisterTable } = useTableOptions(); // Context 훅
|
||||
|
||||
const [data, setData] = useState<Record<string, any>[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [searchValues, setSearchValues] = useState<Record<string, any>>({});
|
||||
@@ -113,6 +117,11 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
const hasInitializedWidthsRef = useRef(false);
|
||||
const columnRefs = useRef<Record<string, HTMLTableCellElement | null>>({});
|
||||
const isResizingRef = useRef(false);
|
||||
|
||||
// TableOptions 상태
|
||||
const [filters, setFilters] = useState<TableFilter[]>([]);
|
||||
const [grouping, setGrouping] = useState<string[]>([]);
|
||||
const [columnVisibility, setColumnVisibility] = useState<ColumnVisibility[]>([]);
|
||||
|
||||
// SaveModal 상태 (등록/수정 통합)
|
||||
const [showSaveModal, setShowSaveModal] = useState(false);
|
||||
@@ -147,6 +156,33 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
// 카테고리 값 매핑 캐시 (컬럼명 -> {코드 -> {라벨, 색상}})
|
||||
const [categoryMappings, setCategoryMappings] = useState<Record<string, Record<string, { label: string; color?: string }>>>({});
|
||||
|
||||
// 테이블 등록 (Context에 등록)
|
||||
const tableId = `datatable-${component.id}`;
|
||||
|
||||
useEffect(() => {
|
||||
if (!component.tableName || !component.columns) return;
|
||||
|
||||
registerTable({
|
||||
tableId,
|
||||
label: component.title || "데이터 테이블",
|
||||
tableName: component.tableName,
|
||||
columns: component.columns.map((col) => ({
|
||||
columnName: col.field,
|
||||
columnLabel: col.label,
|
||||
inputType: col.inputType || "text",
|
||||
visible: col.visible !== false,
|
||||
width: col.width || 150,
|
||||
sortable: col.sortable,
|
||||
filterable: col.filterable !== false,
|
||||
})),
|
||||
onFilterChange: setFilters,
|
||||
onGroupChange: setGrouping,
|
||||
onColumnVisibilityChange: setColumnVisibility,
|
||||
});
|
||||
|
||||
return () => unregisterTable(tableId);
|
||||
}, [component.id, component.tableName, component.columns, component.title]);
|
||||
|
||||
// 공통코드 옵션 가져오기
|
||||
const loadCodeOptions = useCallback(
|
||||
async (categoryCode: string) => {
|
||||
|
||||
Reference in New Issue
Block a user