st: fix & refactor: TabDataGrid에서 텝 전환시 컬럼 포맷 및 footer 사라지는 오류 수정, 통계 검토 - 하수 관로 검색 로직 추가
This commit is contained in:
@@ -656,22 +656,115 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
}, [rowDataMap, columnInfo]);
|
||||
|
||||
|
||||
// 활성 탭이 변경될 때마다 fitStyle 재적용 (그리드가 보일 때)
|
||||
// 탭 전환 시 그리드 레이아웃·푸터·포맷 재적용 (여러 시점 + ResizeObserver)
|
||||
const appliedTabRef = useRef<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const gridRef = gridRefs.current.get(activeTab);
|
||||
if (!gridRef?.gridView) return;
|
||||
appliedTabRef.current = null;
|
||||
const currentInfo = columnInfo.find(info => info.tabKey === activeTab);
|
||||
const columns = currentInfo?.columns;
|
||||
const columnLayout = currentInfo?.columnLayout;
|
||||
if (!columns?.length || !columnLayout) return;
|
||||
|
||||
const gridView = gridRef.gridView;
|
||||
// 약간의 지연을 두고 설정 (그리드 렌더링 완료 후)
|
||||
const timer = setTimeout(() => {
|
||||
gridView.setDisplayOptions({
|
||||
fitStyle: GridFitStyle.EVEN
|
||||
const tryApply = () => {
|
||||
if (appliedTabRef.current === activeTab) return;
|
||||
const gridRef = gridRefs.current.get(activeTab);
|
||||
if (!gridRef?.gridView || !gridRef?.dataProvider) return;
|
||||
|
||||
const gridView = gridRef.gridView;
|
||||
const dp = gridRef.dataProvider as { setFields?: (fields: unknown[]) => void; setRows?: (rows: Record<string, string | number>[]) => void } | undefined;
|
||||
const tabRowData = rowDataMap.get(activeTab) || [];
|
||||
|
||||
try {
|
||||
if (dp?.setFields) dp.setFields(buildFieldsFromColumns(columns));
|
||||
|
||||
gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN });
|
||||
gridView.setColumnLayout?.(columnLayout as ColumnLayoutItem[]);
|
||||
|
||||
const hasFooter = columns.some(col => col.footer);
|
||||
if (hasFooter) {
|
||||
const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer));
|
||||
const hasMultiRowFooter = columns.some(col => {
|
||||
const f = col.footer;
|
||||
return f && !Array.isArray(f) && 'multiRow' in f && (f as { multiRow?: boolean }).multiRow === true;
|
||||
});
|
||||
if (hasArrayFooter || hasMultiRowFooter) {
|
||||
const lengths = columns.filter(col => col.footer && Array.isArray(col.footer)).map(col => (col.footer as unknown[]).length);
|
||||
const maxLen = lengths.length ? Math.max(...lengths) : 2;
|
||||
gridView.setFooters?.(Array.from({ length: maxLen }, () => ({ height: 40 })));
|
||||
} else {
|
||||
gridView.footer.height = 40;
|
||||
}
|
||||
}
|
||||
gridView.setOptions?.({ summaryMode: "aggregate" });
|
||||
|
||||
if (columns.some(col => col.footer && Array.isArray(col.footer))) {
|
||||
const columnsWithFooter: RealGridColumnInfo[] = columns.map(col => {
|
||||
const c: RealGridColumnInfo = {
|
||||
name: col.name,
|
||||
fieldName: col.fieldName,
|
||||
header: col.header,
|
||||
editable: col.editable,
|
||||
valueType: col.valueType,
|
||||
dataFormat: col.dataFormat,
|
||||
...(col.styleName != null && { styleName: col.styleName }),
|
||||
...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }),
|
||||
};
|
||||
if (col.footer) {
|
||||
if (Array.isArray(col.footer)) c.footer = col.footer;
|
||||
else c.footer = { text: col.footer.text, expression: col.footer.expression, numberFormat: col.footer.numberFormat };
|
||||
}
|
||||
return c;
|
||||
});
|
||||
(gridView as GridViewWithSetColumns).setColumns?.(columnsWithFooter);
|
||||
columns.forEach(col => {
|
||||
if (!col.footer || !Array.isArray(col.footer)) return;
|
||||
try {
|
||||
const column = gridView.columnByName(col.name);
|
||||
const footerArr = column?.footer as unknown[] | undefined;
|
||||
if (footerArr && Array.isArray(footerArr))
|
||||
col.footer.forEach((item, i) => {
|
||||
if (item.valueCallback && footerArr[i])
|
||||
(footerArr[i] as FooterItemWithCallback).valueCallback = item.valueCallback;
|
||||
});
|
||||
} catch (_) {}
|
||||
});
|
||||
}
|
||||
columns.forEach(col => {
|
||||
if (!col.footer || Array.isArray(col.footer)) return;
|
||||
try {
|
||||
const column = gridView.columnByName(col.name);
|
||||
const fo = col.footer as { valueCallback?: (g: unknown, col: unknown, fi: number, cf: unknown, v: unknown) => unknown };
|
||||
if (column?.footer && fo.valueCallback)
|
||||
(column.footer as { valueCallback?: typeof fo.valueCallback }).valueCallback = fo.valueCallback;
|
||||
} catch (_) {}
|
||||
});
|
||||
|
||||
if (dp?.setRows && tabRowData.length) dp.setRows(tabRowData);
|
||||
gridView.refresh();
|
||||
appliedTabRef.current = activeTab;
|
||||
} catch (e) {
|
||||
console.warn('TabDataGrid activeTab layout re-apply:', e);
|
||||
}
|
||||
};
|
||||
|
||||
const delays = [200, 500, 1000, 1500];
|
||||
const timers = delays.map(d => setTimeout(tryApply, d));
|
||||
|
||||
const container = document.querySelector(`[data-tab-key="${activeTab}"]`);
|
||||
let observer: ResizeObserver | null = null;
|
||||
if (container && typeof ResizeObserver !== 'undefined') {
|
||||
observer = new ResizeObserver(() => {
|
||||
if ((container as HTMLElement).offsetWidth > 0) tryApply();
|
||||
});
|
||||
gridView.refresh();
|
||||
}, 50);
|
||||
observer.observe(container);
|
||||
}
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [activeTab]);
|
||||
return () => {
|
||||
timers.forEach(t => clearTimeout(t));
|
||||
observer?.disconnect();
|
||||
};
|
||||
}, [activeTab, columnInfo, rowDataMap]);
|
||||
|
||||
if (columnInfo.length === 0) {
|
||||
return <div>컬럼 정보가 없습니다.</div>;
|
||||
@@ -791,7 +884,9 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
}
|
||||
</div>
|
||||
<div className="h-[60vh]" data-tab-key={tabKey}>
|
||||
{activeTab === tabKey ? (
|
||||
<RealGridReact
|
||||
key={tabKey}
|
||||
ref={(el) => {
|
||||
if (el) {
|
||||
gridRefs.current.set(tabKey, el);
|
||||
@@ -1026,7 +1121,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
|
||||
const onSortingHandler = createOnSortingHandler(columns, setRowData, sortDirRef, originalRowsRef, findGridElement);
|
||||
(gridView as { onSorting?: (g: unknown, f: unknown[], d: unknown[]) => boolean }).onSorting = onSortingHandler;
|
||||
}, 0);
|
||||
}, 150);
|
||||
}
|
||||
} else {
|
||||
gridRefs.current.delete(tabKey);
|
||||
@@ -1061,6 +1156,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
/>
|
||||
))}
|
||||
</RealGridReact>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
Reference in New Issue
Block a user