From 14d6406a61a7183075abff9378168340a74c35af Mon Sep 17 00:00:00 2001 From: kjs Date: Thu, 12 Feb 2026 11:42:32 +0900 Subject: [PATCH] feat: Improve selected rows data management in TabsWidget and SplitPanelLayoutComponent - Refactored TabsWidget to manage local selected rows data, enhancing responsiveness to user interactions. - Introduced a new callback for handling selected rows changes, ensuring updates are reflected in both local and parent states. - Updated SplitPanelLayoutComponent to share selected rows data between tabs and buttons, improving data consistency across components. - Enhanced overall user experience by ensuring immediate recognition of selection changes within the tabbed interface. --- .../components/screen/widgets/TabsWidget.tsx | 38 ++++++++++++++++--- .../SplitPanelLayoutComponent.tsx | 29 ++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/frontend/components/screen/widgets/TabsWidget.tsx b/frontend/components/screen/widgets/TabsWidget.tsx index 2dd0899c..6b0d0864 100644 --- a/frontend/components/screen/widgets/TabsWidget.tsx +++ b/frontend/components/screen/widgets/TabsWidget.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useState, useEffect, useMemo } from "react"; +import React, { useState, useEffect, useCallback } from "react"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Button } from "@/components/ui/button"; import { X, Loader2 } from "lucide-react"; @@ -35,6 +35,8 @@ interface TabsWidgetProps { sortOrder?: "asc" | "desc", columnOrder?: string[], ) => void; + // 추가 props (부모에서 전달받은 나머지 props) + [key: string]: any; } export function TabsWidget({ @@ -47,8 +49,9 @@ export function TabsWidget({ isDesignMode = false, onComponentSelect, selectedComponentId, - selectedRowsData, - onSelectedRowsChange, + selectedRowsData: _externalSelectedRowsData, + onSelectedRowsChange: externalOnSelectedRowsChange, + ...restProps }: TabsWidgetProps) { const { setActiveTab, removeTabsComponent } = useActiveTab(); const { @@ -62,6 +65,30 @@ export function TabsWidget({ const storageKey = `tabs-${component.id}-selected`; + // 탭 내부 자체 selectedRowsData 상태 관리 (항상 로컬 상태 사용) + // 부모에서 빈 배열 []이 전달되어도 로컬 상태를 우선하여 탭 내부 버튼이 즉시 인식 + const [localSelectedRowsData, setLocalSelectedRowsData] = useState([]); + + // 선택 변경 핸들러: 로컬 상태 업데이트 + 부모 콜백 호출 + const handleSelectedRowsChange = useCallback( + ( + selectedRows: any[], + selectedRowsDataNew: any[], + sortBy?: string, + sortOrder?: "asc" | "desc", + columnOrder?: string[], + ) => { + // 로컬 상태 업데이트 (탭 내부 버튼이 즉시 인식) + setLocalSelectedRowsData(selectedRowsDataNew); + + // 부모 콜백 호출 (부모 상태도 업데이트) + if (externalOnSelectedRowsChange) { + externalOnSelectedRowsChange(selectedRows, selectedRowsDataNew, sortBy, sortOrder, columnOrder); + } + }, + [externalOnSelectedRowsChange], + ); + // 초기 선택 탭 결정 const getInitialTab = () => { if (persistSelection && typeof window !== "undefined") { @@ -342,6 +369,7 @@ export function TabsWidget({ }} > ); diff --git a/frontend/lib/registry/components/v2-split-panel-layout/SplitPanelLayoutComponent.tsx b/frontend/lib/registry/components/v2-split-panel-layout/SplitPanelLayoutComponent.tsx index 923c1aa3..83aabc85 100644 --- a/frontend/lib/registry/components/v2-split-panel-layout/SplitPanelLayoutComponent.tsx +++ b/frontend/lib/registry/components/v2-split-panel-layout/SplitPanelLayoutComponent.tsx @@ -194,6 +194,17 @@ export const SplitPanelLayoutComponent: React.FC const [selectedLeftItem, setSelectedLeftItem] = useState(null); const [expandedRightItems, setExpandedRightItems] = useState>(new Set()); // 확장된 우측 아이템 const [customLeftSelectedData, setCustomLeftSelectedData] = useState>({}); // 커스텀 모드: 좌측 선택 데이터 + // 커스텀 모드: 탭/버튼 간 공유할 selectedRowsData 자체 관리 (항상 로컬 상태 사용) + const [localSelectedRowsData, setLocalSelectedRowsData] = useState([]); + const handleLocalSelectedRowsChange = useCallback( + (selectedRows: any[], selectedRowsDataNew: any[], sortBy?: string, sortOrder?: "asc" | "desc", columnOrder?: string[]) => { + setLocalSelectedRowsData(selectedRowsDataNew); + if ((props as any).onSelectedRowsChange) { + (props as any).onSelectedRowsChange(selectedRows, selectedRowsDataNew, sortBy, sortOrder, columnOrder); + } + }, + [(props as any).onSelectedRowsChange], + ); const [leftSearchQuery, setLeftSearchQuery] = useState(""); const [rightSearchQuery, setRightSearchQuery] = useState(""); const [isLoadingLeft, setIsLoadingLeft] = useState(false); @@ -2757,8 +2768,17 @@ export const SplitPanelLayoutComponent: React.FC { // 커스텀 모드: 좌측 카드/테이블 선택 시 데이터 캡처 if (data?.selectedRowsData && data.selectedRowsData.length > 0) { @@ -3645,8 +3665,17 @@ export const SplitPanelLayoutComponent: React.FC );