배포다시 되게 고쳐놓음

This commit is contained in:
leeheejin 2026-01-16 17:39:35 +09:00
parent 50a25cb9de
commit 2a3cc7ba00
1 changed files with 48 additions and 53 deletions

View File

@ -384,20 +384,36 @@ export const PivotGridComponent: React.FC<PivotGridProps> = ({
localStorage.setItem(stateStorageKey, JSON.stringify(stateToSave)); localStorage.setItem(stateStorageKey, JSON.stringify(stateToSave));
}, [fields, pivotState, sortConfig, columnWidths, stateStorageKey]); }, [fields, pivotState, sortConfig, columnWidths, stateStorageKey]);
// 상태 복원 (localStorage) // 상태 복원 (localStorage) - 프로덕션 안전성 강화
useEffect(() => { useEffect(() => {
if (typeof window === "undefined") return; if (typeof window === "undefined") return;
const savedState = localStorage.getItem(stateStorageKey);
if (savedState) { try {
try { const savedState = localStorage.getItem(stateStorageKey);
const parsed = JSON.parse(savedState); if (!savedState) return;
if (parsed.fields) setFields(parsed.fields);
if (parsed.pivotState) setPivotState(parsed.pivotState); const parsed = JSON.parse(savedState);
if (parsed.sortConfig) setSortConfig(parsed.sortConfig);
if (parsed.columnWidths) setColumnWidths(parsed.columnWidths); // 필드 복원 시 유효성 검사 (중요!)
} catch (e) { if (parsed.fields && Array.isArray(parsed.fields) && parsed.fields.length > 0) {
console.warn("피벗 상태 복원 실패:", e); // 저장된 필드가 현재 데이터와 호환되는지 확인
const validFields = parsed.fields.filter((f: PivotFieldConfig) =>
f && typeof f.field === "string" && typeof f.area === "string"
);
if (validFields.length > 0) {
setFields(validFields);
}
} }
// 나머지 상태 복원
if (parsed.pivotState) setPivotState(parsed.pivotState);
if (parsed.sortConfig) setSortConfig(parsed.sortConfig);
if (parsed.columnWidths) setColumnWidths(parsed.columnWidths);
} catch (e) {
console.warn("피벗 상태 복원 실패, localStorage 초기화:", e);
// 손상된 상태는 제거
localStorage.removeItem(stateStorageKey);
} }
}, [stateStorageKey]); }, [stateStorageKey]);
@ -512,15 +528,15 @@ export const PivotGridComponent: React.FC<PivotGridProps> = ({
return null; return null;
} }
const visibleFields = fields.filter((f) => f.visible !== false); // FieldChooser에서 이미 필드를 완전히 제거하므로 visible 필터링 불필요
// 행, 열, 데이터 영역에 필드가 하나도 없으면 null 반환 (필터는 제외) // 행, 열, 데이터 영역에 필드가 하나도 없으면 null 반환 (필터는 제외)
if (visibleFields.filter((f) => ["row", "column", "data"].includes(f.area)).length === 0) { if (fields.filter((f) => ["row", "column", "data"].includes(f.area)).length === 0) {
return null; return null;
} }
const result = processPivotData( const result = processPivotData(
filteredData, filteredData,
visibleFields, fields,
pivotState.expandedRowPaths, pivotState.expandedRowPaths,
pivotState.expandedColumnPaths pivotState.expandedColumnPaths
); );
@ -536,32 +552,18 @@ export const PivotGridComponent: React.FC<PivotGridProps> = ({
}); });
return result; return result;
}, [ }, [filteredData, fields, pivotState.expandedRowPaths, pivotState.expandedColumnPaths]);
filteredData,
fields,
JSON.stringify(pivotState.expandedRowPaths),
JSON.stringify(pivotState.expandedColumnPaths)
]);
// 🆕 초기 로드 시 첫 레벨 자동 확장 // 초기 로드 시 첫 레벨 자동 확장
useEffect(() => { useEffect(() => {
if (pivotResult && pivotResult.flatRows.length > 0 && !isInitialExpanded) { if (pivotResult && pivotResult.flatRows.length > 0 && !isInitialExpanded) {
console.log("🔶 피벗 결과 생성됨:", {
flatRowsCount: pivotResult.flatRows.length,
expandedRowPaths: pivotState.expandedRowPaths.length,
isInitialExpanded,
});
// 첫 레벨 행들의 경로 수집 (level 0인 행들) // 첫 레벨 행들의 경로 수집 (level 0인 행들)
const firstLevelRows = pivotResult.flatRows.filter(row => row.level === 0 && row.hasChildren); const firstLevelRows = pivotResult.flatRows.filter((row) => row.level === 0 && row.hasChildren);
console.log("🔶 첫 레벨 행 (level 0, hasChildren):", firstLevelRows.map(r => ({ path: r.path, caption: r.caption })));
// 첫 레벨 행이 있으면 자동 확장 // 첫 레벨 행이 있으면 자동 확장
if (firstLevelRows.length > 0) { if (firstLevelRows.length > 0) {
const firstLevelPaths = firstLevelRows.map(row => row.path); const firstLevelPaths = firstLevelRows.map((row) => row.path);
console.log("🔶 초기 자동 확장 실행 (한 번만):", firstLevelPaths); setPivotState((prev) => ({
setPivotState(prev => ({
...prev, ...prev,
expandedRowPaths: firstLevelPaths, expandedRowPaths: firstLevelPaths,
})); }));
@ -725,19 +727,16 @@ export const PivotGridComponent: React.FC<PivotGridProps> = ({
// 필드 변경 // 필드 변경
const handleFieldsChange = useCallback( const handleFieldsChange = useCallback(
(newFields: PivotFieldConfig[]) => { (newFields: PivotFieldConfig[]) => {
// 🆕 visible: false 필드 제거 (FieldChooser에서 "사용 안함"으로 설정한 필드) // FieldChooser에서 이미 필드를 완전히 제거하므로 추가 필터링 불필요
const visibleFields = newFields.filter(f => f.visible !== false);
console.log("🔷 [handleFieldsChange] 필드 변경:", { console.log("🔷 [handleFieldsChange] 필드 변경:", {
totalFields: newFields.length, totalFields: newFields.length,
visibleFields: visibleFields.length, filterFields: newFields.filter(f => f.area === "filter").length,
removedFields: newFields.length - visibleFields.length, filterFieldNames: newFields.filter(f => f.area === "filter").map(f => f.field),
filterFields: visibleFields.filter(f => f.area === "filter").length, rowFields: newFields.filter(f => f.area === "row").length,
filterFieldNames: visibleFields.filter(f => f.area === "filter").map(f => f.field), columnFields: newFields.filter(f => f.area === "column").length,
dataFields: newFields.filter(f => f.area === "data").length,
}); });
console.log("🔷 [handleFieldsChange] setFields 호출 전"); setFields(newFields);
setFields(visibleFields);
console.log("🔷 [handleFieldsChange] setFields 호출 후");
}, },
[] []
); );
@ -945,6 +944,8 @@ export const PivotGridComponent: React.FC<PivotGridProps> = ({
// 인쇄 기능 (PDF 내보내기보다 먼저 정의해야 함) // 인쇄 기능 (PDF 내보내기보다 먼저 정의해야 함)
const handlePrint = useCallback(() => { const handlePrint = useCallback(() => {
if (typeof window === "undefined") return;
const printContent = tableRef.current; const printContent = tableRef.current;
if (!printContent) return; if (!printContent) return;
@ -1047,8 +1048,10 @@ export const PivotGridComponent: React.FC<PivotGridProps> = ({
// 상태 초기화 (확장/축소, 정렬, 필터만 초기화, 필드 설정은 유지) // 상태 초기화 (확장/축소, 정렬, 필터만 초기화, 필드 설정은 유지)
const handleResetState = useCallback(() => { const handleResetState = useCallback(() => {
// 로컬 스토리지에서 상태 제거 // 로컬 스토리지에서 상태 제거 (SSR 보호)
localStorage.removeItem(stateStorageKey); if (typeof window !== "undefined") {
localStorage.removeItem(stateStorageKey);
}
// 확장/축소, 정렬, 필터 상태만 초기화 // 확장/축소, 정렬, 필터 상태만 초기화
setPivotState({ setPivotState({
@ -1061,9 +1064,6 @@ export const PivotGridComponent: React.FC<PivotGridProps> = ({
setColumnWidths({}); setColumnWidths({});
setSelectedCell(null); setSelectedCell(null);
setSelectionRange(null); setSelectionRange(null);
// 🆕 필드 설정은 유지 (initialFields로 되돌리지 않음)
console.log("🔷 피벗 상태가 초기화되었습니다 (필드 설정은 유지)");
}, [stateStorageKey]); }, [stateStorageKey]);
// 필드 숨기기/표시 상태 // 필드 숨기기/표시 상태
@ -1081,11 +1081,6 @@ export const PivotGridComponent: React.FC<PivotGridProps> = ({
}); });
}, []); }, []);
// 숨겨진 필드 제외한 활성 필드들
const visibleFields = useMemo(() => {
return fields.filter((f) => !hiddenFields.has(f.field));
}, [fields, hiddenFields]);
// 숨겨진 필드 목록 // 숨겨진 필드 목록
const hiddenFieldsList = useMemo(() => { const hiddenFieldsList = useMemo(() => {
return fields.filter((f) => hiddenFields.has(f.field)); return fields.filter((f) => hiddenFields.has(f.field));