분할 패널 테이블에서 셀 클릭 시 행 선택 및 자동 필터링 구현
This commit is contained in:
parent
d21c4acf0f
commit
23a1dd6321
|
|
@ -1506,6 +1506,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
tableName: tableConfig.selectedTable,
|
||||
selectedLeftData: splitPanelContext?.selectedLeftData,
|
||||
linkedFilters: splitPanelContext?.linkedFilters,
|
||||
splitPanelPosition: splitPanelPosition,
|
||||
});
|
||||
|
||||
if (splitPanelContext) {
|
||||
|
|
@ -1537,6 +1538,39 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
linkedFilterValues[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// 🆕 자동 컬럼 매칭: linkedFilters가 설정되어 있지 않아도
|
||||
// 우측 화면(splitPanelPosition === "right")이고 좌측 데이터가 선택되어 있으면
|
||||
// 동일한 컬럼명이 있는 경우 자동으로 필터링 적용
|
||||
if (
|
||||
splitPanelPosition === "right" &&
|
||||
hasSelectedLeftData &&
|
||||
Object.keys(linkedFilterValues).length === 0 &&
|
||||
!hasLinkedFiltersConfigured
|
||||
) {
|
||||
const leftData = splitPanelContext.selectedLeftData!;
|
||||
const tableColumns = (tableConfig.columns || []).map((col) => col.columnName);
|
||||
|
||||
// 좌측 데이터의 컬럼 중 현재 테이블에 동일한 컬럼이 있는지 확인
|
||||
for (const [colName, colValue] of Object.entries(leftData)) {
|
||||
// null, undefined, 빈 문자열 제외
|
||||
if (colValue === null || colValue === undefined || colValue === "") continue;
|
||||
// id, objid 등 기본 키는 제외 (너무 일반적인 컬럼명)
|
||||
if (colName === "id" || colName === "objid" || colName === "company_code") continue;
|
||||
|
||||
// 현재 테이블에 동일한 컬럼이 있는지 확인
|
||||
if (tableColumns.includes(colName)) {
|
||||
linkedFilterValues[colName] = colValue;
|
||||
hasLinkedFiltersConfigured = true;
|
||||
console.log(`🔗 [TableList] 자동 컬럼 매칭: ${colName} = ${colValue}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(linkedFilterValues).length > 0) {
|
||||
console.log("🔗 [TableList] 자동 컬럼 매칭 필터 적용:", linkedFilterValues);
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(linkedFilterValues).length > 0) {
|
||||
console.log("🔗 [TableList] 연결 필터 적용:", linkedFilterValues);
|
||||
}
|
||||
|
|
@ -1749,7 +1783,10 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
searchTerm,
|
||||
searchValues,
|
||||
isDesignMode,
|
||||
splitPanelContext?.selectedLeftData, // 🆕 연결 필터 변경 시 재조회
|
||||
// 🆕 우측 화면일 때만 selectedLeftData 변경에 반응 (좌측 테이블은 재조회 불필요)
|
||||
splitPanelPosition,
|
||||
currentSplitPosition,
|
||||
splitPanelContext?.selectedLeftData,
|
||||
]);
|
||||
|
||||
const fetchTableDataDebounced = useCallback(
|
||||
|
|
@ -2059,7 +2096,18 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
|
||||
// 🆕 분할 패널 컨텍스트에 선택된 데이터 저장 (좌측 화면인 경우)
|
||||
// disableAutoDataTransfer가 true이면 자동 전달 비활성화 (버튼 클릭으로만 전달)
|
||||
if (splitPanelContext && splitPanelPosition === "left" && !splitPanelContext.disableAutoDataTransfer) {
|
||||
// currentSplitPosition을 사용하여 정확한 위치 확인 (splitPanelPosition이 없을 수 있음)
|
||||
const effectiveSplitPosition = splitPanelPosition || currentSplitPosition;
|
||||
|
||||
console.log("🔗 [TableList] 행 클릭 - 분할 패널 위치 확인:", {
|
||||
splitPanelPosition,
|
||||
currentSplitPosition,
|
||||
effectiveSplitPosition,
|
||||
hasSplitPanelContext: !!splitPanelContext,
|
||||
disableAutoDataTransfer: splitPanelContext?.disableAutoDataTransfer,
|
||||
});
|
||||
|
||||
if (splitPanelContext && effectiveSplitPosition === "left" && !splitPanelContext.disableAutoDataTransfer) {
|
||||
if (!isCurrentlySelected) {
|
||||
// 선택된 경우: 데이터 저장
|
||||
splitPanelContext.setSelectedLeftData(row);
|
||||
|
|
@ -2077,12 +2125,57 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
console.log("행 클릭:", { row, index, isSelected: !isCurrentlySelected });
|
||||
};
|
||||
|
||||
// 🆕 셀 클릭 핸들러 (포커스 설정)
|
||||
// 🆕 셀 클릭 핸들러 (포커스 설정 + 행 선택)
|
||||
const handleCellClick = (rowIndex: number, colIndex: number, e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
setFocusedCell({ rowIndex, colIndex });
|
||||
// 테이블 컨테이너에 포커스 설정 (키보드 이벤트 수신용)
|
||||
tableContainerRef.current?.focus();
|
||||
|
||||
// 🆕 분할 패널 내에서 셀 클릭 시에도 해당 행 선택 처리
|
||||
// filteredData에서 해당 행의 데이터 가져오기
|
||||
const row = filteredData[rowIndex];
|
||||
if (!row) return;
|
||||
|
||||
const rowKey = getRowKey(row, rowIndex);
|
||||
const isCurrentlySelected = selectedRows.has(rowKey);
|
||||
|
||||
// 분할 패널 컨텍스트가 있고, 좌측 화면인 경우에만 행 선택 및 데이터 전달
|
||||
const effectiveSplitPosition = splitPanelPosition || currentSplitPosition;
|
||||
|
||||
console.log("🔗 [TableList] 셀 클릭 - 분할 패널 위치 확인:", {
|
||||
rowIndex,
|
||||
colIndex,
|
||||
splitPanelPosition,
|
||||
currentSplitPosition,
|
||||
effectiveSplitPosition,
|
||||
hasSplitPanelContext: !!splitPanelContext,
|
||||
isCurrentlySelected,
|
||||
});
|
||||
|
||||
if (splitPanelContext && effectiveSplitPosition === "left" && !splitPanelContext.disableAutoDataTransfer) {
|
||||
// 이미 선택된 행과 다른 행을 클릭한 경우에만 처리
|
||||
if (!isCurrentlySelected) {
|
||||
// 기존 선택 해제하고 새 행 선택
|
||||
setSelectedRows(new Set([rowKey]));
|
||||
setIsAllSelected(false);
|
||||
|
||||
// 분할 패널 컨텍스트에 데이터 저장
|
||||
splitPanelContext.setSelectedLeftData(row);
|
||||
console.log("🔗 [TableList] 셀 클릭으로 분할 패널 좌측 데이터 저장:", {
|
||||
row,
|
||||
parentDataMapping: splitPanelContext.parentDataMapping,
|
||||
});
|
||||
|
||||
// onSelectedRowsChange 콜백 호출
|
||||
if (onSelectedRowsChange) {
|
||||
onSelectedRowsChange([rowKey], [row], sortColumn || undefined, sortDirection);
|
||||
}
|
||||
if (onFormDataChange) {
|
||||
onFormDataChange({ selectedRows: [rowKey], selectedRowsData: [row] });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 🆕 셀 더블클릭 핸들러 (편집 모드 진입) - visibleColumns 정의 후 사용
|
||||
|
|
@ -4066,13 +4159,13 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
|
||||
// 📎 첨부파일 타입: 파일 아이콘과 개수 표시
|
||||
// 컬럼명이 'attachments'를 포함하거나, inputType이 file/attachment인 경우
|
||||
const isAttachmentColumn =
|
||||
inputType === "file" ||
|
||||
inputType === "attachment" ||
|
||||
const isAttachmentColumn =
|
||||
inputType === "file" ||
|
||||
inputType === "attachment" ||
|
||||
column.columnName === "attachments" ||
|
||||
column.columnName?.toLowerCase().includes("attachment") ||
|
||||
column.columnName?.toLowerCase().includes("file");
|
||||
|
||||
|
||||
if (isAttachmentColumn) {
|
||||
// JSONB 배열 또는 JSON 문자열 파싱
|
||||
let files: any[] = [];
|
||||
|
|
@ -4098,21 +4191,14 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
// 파일 이름 표시 (여러 개면 쉼표로 구분)
|
||||
const { Paperclip } = require("lucide-react");
|
||||
const fileNames = files.map((f: any) => f.realFileName || f.real_file_name || f.name || "파일").join(", ");
|
||||
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-1.5 text-sm max-w-full">
|
||||
<Paperclip className="h-4 w-4 text-gray-500 flex-shrink-0" />
|
||||
<span
|
||||
className="text-blue-600 truncate"
|
||||
title={fileNames}
|
||||
>
|
||||
<div className="flex max-w-full items-center gap-1.5 text-sm">
|
||||
<Paperclip className="h-4 w-4 flex-shrink-0 text-gray-500" />
|
||||
<span className="truncate text-blue-600" title={fileNames}>
|
||||
{fileNames}
|
||||
</span>
|
||||
{files.length > 1 && (
|
||||
<span className="text-muted-foreground text-xs flex-shrink-0">
|
||||
({files.length})
|
||||
</span>
|
||||
)}
|
||||
{files.length > 1 && <span className="text-muted-foreground flex-shrink-0 text-xs">({files.length})</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -4677,6 +4763,10 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
fetchTableLabel();
|
||||
}, [tableConfig.selectedTable, fetchColumnLabels, fetchTableLabel]);
|
||||
|
||||
// 🆕 우측 화면일 때만 selectedLeftData 변경에 반응하도록 변수 생성
|
||||
const isRightPanel = splitPanelPosition === "right" || currentSplitPosition === "right";
|
||||
const selectedLeftDataForRightPanel = isRightPanel ? splitPanelContext?.selectedLeftData : null;
|
||||
|
||||
useEffect(() => {
|
||||
// console.log("🔍 [TableList] useEffect 실행 - 데이터 조회 트리거", {
|
||||
// isDesignMode,
|
||||
|
|
@ -4700,7 +4790,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
refreshKey,
|
||||
refreshTrigger, // 강제 새로고침 트리거
|
||||
isDesignMode,
|
||||
splitPanelContext?.selectedLeftData, // 🆕 좌측 데이터 선택 변경 시 데이터 새로고침
|
||||
selectedLeftDataForRightPanel, // 🆕 우측 화면일 때만 좌측 데이터 선택 변경 시 데이터 새로고침
|
||||
// fetchTableDataDebounced 제거: useCallback 재생성으로 인한 무한 루프 방지
|
||||
]);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue