연쇄관계 자식 라벨표시
This commit is contained in:
@@ -209,7 +209,7 @@ export interface TableListComponentProps {
|
||||
onConfigChange?: (config: any) => void;
|
||||
refreshKey?: number;
|
||||
// 탭 관련 정보 (탭 내부의 테이블에서 사용)
|
||||
parentTabId?: string; // 부모 탭 ID
|
||||
parentTabId?: string; // 부모 탭 ID
|
||||
parentTabsComponentId?: string; // 부모 탭 컴포넌트 ID
|
||||
}
|
||||
|
||||
@@ -689,7 +689,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
const [viewMode, setViewMode] = useState<"table" | "card" | "grouped-card">("table");
|
||||
// 체크박스 컬럼은 항상 기본 틀고정
|
||||
const [frozenColumns, setFrozenColumns] = useState<string[]>(
|
||||
(tableConfig.checkbox?.enabled ?? true) ? ["__checkbox__"] : []
|
||||
(tableConfig.checkbox?.enabled ?? true) ? ["__checkbox__"] : [],
|
||||
);
|
||||
const [frozenColumnCount, setFrozenColumnCount] = useState<number>(0);
|
||||
|
||||
@@ -1311,17 +1311,15 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
const parts = columnName.split(".");
|
||||
targetTable = parts[0]; // 조인된 테이블명 (예: item_info)
|
||||
targetColumn = parts[1]; // 실제 컬럼명 (예: material)
|
||||
console.log(`🔗 [TableList] 엔티티 조인 컬럼 감지:`, {
|
||||
console.log("🔗 [TableList] 엔티티 조인 컬럼 감지:", {
|
||||
originalColumn: columnName,
|
||||
targetTable,
|
||||
targetColumn,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const response = await apiClient.get(`/table-categories/${targetTable}/${targetColumn}/values`);
|
||||
|
||||
|
||||
if (response.data.success && response.data.data && Array.isArray(response.data.data)) {
|
||||
const mapping: Record<string, { label: string; color?: string }> = {};
|
||||
|
||||
@@ -1376,7 +1374,6 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
col.columnName,
|
||||
})) || [];
|
||||
|
||||
|
||||
// 조인 테이블별로 그룹화
|
||||
const joinedTableColumns: Record<string, { columnName: string; actualColumn: string }[]> = {};
|
||||
|
||||
@@ -1408,7 +1405,6 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 조인된 테이블별로 inputType 정보 가져오기
|
||||
const newJoinedColumnMeta: Record<string, { webType?: string; codeCategory?: string; inputType?: string }> = {};
|
||||
|
||||
@@ -1471,6 +1467,41 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
console.log("✅ [TableList] 조인 컬럼 메타데이터 설정:", newJoinedColumnMeta);
|
||||
}
|
||||
|
||||
// 🆕 카테고리 연쇄관계 매핑 로드 (category_value_cascading_mapping)
|
||||
try {
|
||||
const cascadingResponse = await apiClient.get(
|
||||
`/category-value-cascading/table/${tableConfig.selectedTable}/mappings`,
|
||||
);
|
||||
if (cascadingResponse.data.success && cascadingResponse.data.data) {
|
||||
const cascadingMappings = cascadingResponse.data.data;
|
||||
|
||||
// 각 자식 컬럼에 대한 매핑 추가
|
||||
for (const [columnName, columnMappings] of Object.entries(
|
||||
cascadingMappings as Record<string, Array<{ code: string; label: string }>>,
|
||||
)) {
|
||||
if (!mappings[columnName]) {
|
||||
mappings[columnName] = {};
|
||||
}
|
||||
// 연쇄관계 매핑 추가
|
||||
for (const item of columnMappings) {
|
||||
mappings[columnName][item.code] = {
|
||||
label: item.label,
|
||||
color: undefined, // 연쇄관계는 색상 없음
|
||||
};
|
||||
}
|
||||
}
|
||||
console.log("✅ [TableList] 카테고리 연쇄관계 매핑 로드 완료:", {
|
||||
tableName: tableConfig.selectedTable,
|
||||
cascadingColumns: Object.keys(cascadingMappings),
|
||||
});
|
||||
}
|
||||
} catch (cascadingError: any) {
|
||||
// 연쇄관계 매핑이 없는 경우 무시 (404 등)
|
||||
if (cascadingError?.response?.status !== 404) {
|
||||
console.warn("⚠️ [TableList] 카테고리 연쇄관계 매핑 로드 실패:", cascadingError?.message);
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(mappings).length > 0) {
|
||||
setCategoryMappings(mappings);
|
||||
setCategoryMappingsKey((prev) => prev + 1);
|
||||
@@ -1495,7 +1526,6 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
// ========================================
|
||||
|
||||
const fetchTableDataInternal = useCallback(async () => {
|
||||
|
||||
if (!tableConfig.selectedTable || isDesignMode) {
|
||||
setData([]);
|
||||
setTotalPages(0);
|
||||
@@ -1514,11 +1544,10 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
const search = searchTerm || undefined;
|
||||
|
||||
// 🆕 연결 필터 값 가져오기 (분할 패널 내부일 때)
|
||||
let linkedFilterValues: Record<string, any> = {};
|
||||
const linkedFilterValues: Record<string, any> = {};
|
||||
let hasLinkedFiltersConfigured = false; // 연결 필터가 설정되어 있는지 여부
|
||||
let hasSelectedLeftData = false; // 좌측에서 데이터가 선택되었는지 여부
|
||||
|
||||
|
||||
if (splitPanelContext) {
|
||||
// 연결 필터 설정 여부 확인 (현재 테이블에 해당하는 필터가 있는지)
|
||||
const linkedFiltersConfig = splitPanelContext.linkedFilters || [];
|
||||
@@ -1609,7 +1638,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
}
|
||||
|
||||
// 🆕 RelatedDataButtons 필터 값 준비
|
||||
let relatedButtonFilterValues: Record<string, any> = {};
|
||||
const relatedButtonFilterValues: Record<string, any> = {};
|
||||
if (relatedButtonFilter) {
|
||||
relatedButtonFilterValues[relatedButtonFilter.filterColumn] = {
|
||||
value: relatedButtonFilter.filterValue,
|
||||
@@ -1685,7 +1714,6 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
// 🆕 제외 필터 처리 (다른 테이블에 이미 존재하는 데이터 제외)
|
||||
let excludeFilterParam: any = undefined;
|
||||
if (tableConfig.excludeFilter?.enabled) {
|
||||
@@ -2427,7 +2455,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
try {
|
||||
const { apiClient } = await import("@/lib/api/client");
|
||||
|
||||
await apiClient.put(`/dynamic-form/update-field`, {
|
||||
await apiClient.put("/dynamic-form/update-field", {
|
||||
tableName: tableConfig.selectedTable,
|
||||
keyField: primaryKeyField,
|
||||
keyValue: primaryKeyValue,
|
||||
@@ -2468,7 +2496,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
|
||||
// 모든 변경사항 저장
|
||||
const savePromises = Array.from(pendingChanges.values()).map((change) =>
|
||||
apiClient.put(`/dynamic-form/update-field`, {
|
||||
apiClient.put("/dynamic-form/update-field", {
|
||||
tableName: tableConfig.selectedTable,
|
||||
keyField: primaryKeyField,
|
||||
keyValue: change.primaryKeyValue,
|
||||
@@ -2942,9 +2970,10 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
if (state.frozenColumns) {
|
||||
// 체크박스 컬럼이 항상 포함되도록 보장
|
||||
const checkboxColumn = (tableConfig.checkbox?.enabled ?? true) ? "__checkbox__" : null;
|
||||
const restoredFrozenColumns = checkboxColumn && !state.frozenColumns.includes(checkboxColumn)
|
||||
? [checkboxColumn, ...state.frozenColumns]
|
||||
: state.frozenColumns;
|
||||
const restoredFrozenColumns =
|
||||
checkboxColumn && !state.frozenColumns.includes(checkboxColumn)
|
||||
? [checkboxColumn, ...state.frozenColumns]
|
||||
: state.frozenColumns;
|
||||
setFrozenColumns(restoredFrozenColumns);
|
||||
}
|
||||
if (state.frozenColumnCount !== undefined) setFrozenColumnCount(state.frozenColumnCount); // 틀고정 컬럼 수 복원
|
||||
@@ -2956,7 +2985,6 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
});
|
||||
setHeaderFilters(filters);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("❌ 테이블 상태 복원 실패:", error);
|
||||
}
|
||||
@@ -3576,7 +3604,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
}));
|
||||
|
||||
// 배치 업데이트
|
||||
await Promise.all(updates.map((update) => apiClient.put(`/dynamic-form/update-field`, update)));
|
||||
await Promise.all(updates.map((update) => apiClient.put("/dynamic-form/update-field", update)));
|
||||
|
||||
toast.success("순서가 변경되었습니다.");
|
||||
setRefreshTrigger((prev) => prev + 1);
|
||||
@@ -4894,7 +4922,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
useEffect(() => {
|
||||
const handleRelatedButtonSelect = (event: CustomEvent) => {
|
||||
const { targetTable, filterColumn, filterValue } = event.detail || {};
|
||||
|
||||
|
||||
// 이 테이블이 대상 테이블인지 확인
|
||||
if (targetTable === tableConfig.selectedTable) {
|
||||
// filterValue가 null이면 선택 해제 (빈 상태)
|
||||
@@ -4925,9 +4953,9 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
useEffect(() => {
|
||||
if (!isDesignMode) {
|
||||
// relatedButtonFilter가 있으면 데이터 로드, null이면 빈 상태 (setRefreshTrigger로 트리거)
|
||||
console.log("🔄 [TableList] RelatedDataButtons 상태 변경:", {
|
||||
relatedButtonFilter,
|
||||
isRelatedButtonTarget
|
||||
console.log("🔄 [TableList] RelatedDataButtons 상태 변경:", {
|
||||
relatedButtonFilter,
|
||||
isRelatedButtonTarget,
|
||||
});
|
||||
setRefreshTrigger((prev) => prev + 1);
|
||||
}
|
||||
@@ -5618,7 +5646,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
for (let i = 0; i < frozenIndex; i++) {
|
||||
const frozenCol = frozenColumns[i];
|
||||
// 체크박스 컬럼은 48px 고정
|
||||
const frozenColWidth = frozenCol === "__checkbox__" ? 48 : (columnWidths[frozenCol] || 150);
|
||||
const frozenColWidth = frozenCol === "__checkbox__" ? 48 : columnWidths[frozenCol] || 150;
|
||||
leftPosition += frozenColWidth;
|
||||
}
|
||||
}
|
||||
@@ -5930,7 +5958,8 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
for (let i = 0; i < frozenIndex; i++) {
|
||||
const frozenCol = frozenColumns[i];
|
||||
// 체크박스 컬럼은 48px 고정
|
||||
const frozenColWidth = frozenCol === "__checkbox__" ? 48 : (columnWidths[frozenCol] || 150);
|
||||
const frozenColWidth =
|
||||
frozenCol === "__checkbox__" ? 48 : columnWidths[frozenCol] || 150;
|
||||
leftPosition += frozenColWidth;
|
||||
}
|
||||
}
|
||||
@@ -5958,7 +5987,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
: `${100 / visibleColumns.length}%`,
|
||||
minWidth: column.columnName === "__checkbox__" ? "48px" : undefined,
|
||||
maxWidth: column.columnName === "__checkbox__" ? "48px" : undefined,
|
||||
...(isFrozen && {
|
||||
...(isFrozen && {
|
||||
left: `${leftPosition}px`,
|
||||
backgroundColor: "hsl(var(--background))",
|
||||
}),
|
||||
@@ -6094,7 +6123,8 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
for (let i = 0; i < frozenIndex; i++) {
|
||||
const frozenCol = frozenColumns[i];
|
||||
// 체크박스 컬럼은 48px 고정
|
||||
const frozenColWidth = frozenCol === "__checkbox__" ? 48 : (columnWidths[frozenCol] || 150);
|
||||
const frozenColWidth =
|
||||
frozenCol === "__checkbox__" ? 48 : columnWidths[frozenCol] || 150;
|
||||
leftPosition += frozenColWidth;
|
||||
}
|
||||
}
|
||||
@@ -6134,7 +6164,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
column.columnName === "__checkbox__" ? "48px" : `${100 / visibleColumns.length}%`,
|
||||
minWidth: column.columnName === "__checkbox__" ? "48px" : undefined,
|
||||
maxWidth: column.columnName === "__checkbox__" ? "48px" : undefined,
|
||||
...(isFrozen && {
|
||||
...(isFrozen && {
|
||||
left: `${leftPosition}px`,
|
||||
backgroundColor: "hsl(var(--background))",
|
||||
}),
|
||||
@@ -6259,7 +6289,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
for (let i = 0; i < frozenIndex; i++) {
|
||||
const frozenCol = frozenColumns[i];
|
||||
// 체크박스 컬럼은 48px 고정
|
||||
const frozenColWidth = frozenCol === "__checkbox__" ? 48 : (columnWidths[frozenCol] || 150);
|
||||
const frozenColWidth = frozenCol === "__checkbox__" ? 48 : columnWidths[frozenCol] || 150;
|
||||
leftPosition += frozenColWidth;
|
||||
}
|
||||
}
|
||||
@@ -6284,7 +6314,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
: columnWidth
|
||||
? `${columnWidth}px`
|
||||
: undefined,
|
||||
...(isFrozen && {
|
||||
...(isFrozen && {
|
||||
left: `${leftPosition}px`,
|
||||
backgroundColor: "hsl(var(--muted) / 0.8)",
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user