From 8603fddbcb8d41e56443295d140978ccad5dc246 Mon Sep 17 00:00:00 2001 From: leeheejin Date: Mon, 19 Jan 2026 09:50:25 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B0=B0=ED=8F=AC=20=EB=8B=A4=EC=8B=9C..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pivot-grid/PivotGridComponent.tsx | 46 ++++++++++++++----- .../pivot-grid/hooks/useVirtualScroll.ts | 8 +++- .../pivot-grid/utils/pivotEngine.ts | 20 ++------ 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/frontend/lib/registry/components/pivot-grid/PivotGridComponent.tsx b/frontend/lib/registry/components/pivot-grid/PivotGridComponent.tsx index feda2167..57bc2e8a 100644 --- a/frontend/lib/registry/components/pivot-grid/PivotGridComponent.tsx +++ b/frontend/lib/registry/components/pivot-grid/PivotGridComponent.tsx @@ -376,6 +376,12 @@ export const PivotGridComponent: React.FC = ({ const parsed = JSON.parse(savedState); + // 버전 체크 - 버전이 다르면 이전 상태 무시 + if (parsed.version !== PIVOT_STATE_VERSION) { + localStorage.removeItem(stateStorageKey); + return; + } + // 필드 복원 시 유효성 검사 (중요!) if (parsed.fields && Array.isArray(parsed.fields) && parsed.fields.length > 0) { // 저장된 필드가 현재 데이터와 호환되는지 확인 @@ -501,19 +507,31 @@ export const PivotGridComponent: React.FC = ({ if (activeFilters.length === 0) return data; - return data.filter((row) => { + const result = data.filter((row) => { return activeFilters.every((filter) => { - const value = row[filter.field]; + const rawValue = row[filter.field]; const filterValues = filter.filterValues || []; const filterType = filter.filterType || "include"; + // 타입 안전한 비교: 값을 문자열로 변환하여 비교 + const value = rawValue === null || rawValue === undefined + ? "(빈 값)" + : String(rawValue); + if (filterType === "include") { - return filterValues.includes(value); + return filterValues.some((fv) => String(fv) === value); } else { - return !filterValues.includes(value); + return filterValues.every((fv) => String(fv) !== value); } }); }); + + // 모든 데이터가 필터링되면 경고 (디버깅용) + if (result.length === 0 && data.length > 0) { + console.warn("⚠️ [PivotGrid] 필터로 인해 모든 데이터가 제거됨"); + } + + return result; }, [data, fields]); // ==================== 피벗 처리 ==================== @@ -1654,7 +1672,10 @@ export const PivotGridComponent: React.FC = ({
0 ? containerHeight : undefined, + minHeight: 100 // 최소 높이 보장 - 블라인드 효과 방지 + }} tabIndex={0} onKeyDown={handleKeyDown} > @@ -1929,12 +1950,15 @@ export const PivotGridComponent: React.FC = ({ }); })()} - {/* 가상 스크롤 하단 여백 */} - {enableVirtualScroll && ( - - - - )} + {/* 가상 스크롤 하단 여백 - 음수 방지 */} + {enableVirtualScroll && (() => { + const bottomPadding = Math.max(0, virtualScroll.totalHeight - virtualScroll.offsetTop - (visibleFlatRows.length * ROW_HEIGHT)); + return bottomPadding > 0 ? ( + + + + ) : null; + })()} {/* 열 총계 행 (하단 위치 - 기본값) */} {totals?.showColumnGrandTotals && totals?.rowGrandTotalPosition !== "top" && ( diff --git a/frontend/lib/registry/components/pivot-grid/hooks/useVirtualScroll.ts b/frontend/lib/registry/components/pivot-grid/hooks/useVirtualScroll.ts index 152cb2df..6557dee3 100644 --- a/frontend/lib/registry/components/pivot-grid/hooks/useVirtualScroll.ts +++ b/frontend/lib/registry/components/pivot-grid/hooks/useVirtualScroll.ts @@ -51,14 +51,18 @@ export function useVirtualScroll(options: VirtualScrollOptions): VirtualScrollRe // 보이는 아이템 수 const visibleCount = Math.ceil(containerHeight / itemHeight); - // 시작/끝 인덱스 계산 + // 시작/끝 인덱스 계산 (음수 방지) const { startIndex, endIndex } = useMemo(() => { + // itemCount가 0이면 빈 배열 + if (itemCount === 0) { + return { startIndex: 0, endIndex: -1 }; + } const start = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan); const end = Math.min( itemCount - 1, Math.ceil((scrollTop + containerHeight) / itemHeight) + overscan ); - return { startIndex: start, endIndex: end }; + return { startIndex: start, endIndex: Math.max(start, end) }; // end가 start보다 작지 않도록 }, [scrollTop, itemHeight, containerHeight, itemCount, overscan]); // 전체 높이 diff --git a/frontend/lib/registry/components/pivot-grid/utils/pivotEngine.ts b/frontend/lib/registry/components/pivot-grid/utils/pivotEngine.ts index 702a13e5..02dd4608 100644 --- a/frontend/lib/registry/components/pivot-grid/utils/pivotEngine.ts +++ b/frontend/lib/registry/components/pivot-grid/utils/pivotEngine.ts @@ -710,23 +710,9 @@ export function processPivotData( .filter((f) => f.area === "data" && f.visible !== false) .sort((a, b) => (a.areaIndex || 0) - (b.areaIndex || 0)); - const filterFields = fields.filter( - (f) => f.area === "filter" && f.visible !== false - ); - - // 필터 적용 - let filteredData = data; - for (const filterField of filterFields) { - if (filterField.filterValues && filterField.filterValues.length > 0) { - filteredData = filteredData.filter((row) => { - const value = getFieldValue(row, filterField); - if (filterField.filterType === "exclude") { - return !filterField.filterValues!.includes(value); - } - return filterField.filterValues!.includes(value); - }); - } - } + // 참고: 필터링은 PivotGridComponent에서 이미 처리됨 + // 여기서는 추가 필터링 없이 전달받은 데이터 사용 + const filteredData = data; // 확장 경로 Set 변환 (잘못된 형식 필터링) const validRowPaths = (expandedRowPaths || []).filter( -- 2.43.0