카테고리 라벨 보이지 않는 문제 수정

This commit is contained in:
kjs
2026-01-12 10:32:41 +09:00
parent 6732e7d969
commit 9e7253a293
3 changed files with 79 additions and 64 deletions

View File

@@ -187,71 +187,68 @@ class TableCategoryValueService {
logger.info("형제 메뉴 OBJID 목록", { menuObjid, siblingObjids });
}
// 2. 카테고리 값 조회 (형제 메뉴 포함)
// 2. 카테고리 값 조회 (메뉴 스코프 또는 형제 메뉴 포함)
let query: string;
let params: any[];
const baseSelect = `
SELECT
value_id AS "valueId",
table_name AS "tableName",
column_name AS "columnName",
value_code AS "valueCode",
value_label AS "valueLabel",
value_order AS "valueOrder",
parent_value_id AS "parentValueId",
depth,
description,
color,
icon,
is_active AS "isActive",
is_default AS "isDefault",
company_code AS "companyCode",
menu_objid AS "menuObjid",
created_at AS "createdAt",
updated_at AS "updatedAt",
created_by AS "createdBy",
updated_by AS "updatedBy"
FROM table_column_category_values
WHERE table_name = $1
AND column_name = $2
`;
if (companyCode === "*") {
// 최고 관리자: 모든 카테고리 값 조회
// 메뉴 스코프 제거: 같은 테이블.컬럼 조합은 모든 메뉴에서 공유
query = `
SELECT
value_id AS "valueId",
table_name AS "tableName",
column_name AS "columnName",
value_code AS "valueCode",
value_label AS "valueLabel",
value_order AS "valueOrder",
parent_value_id AS "parentValueId",
depth,
description,
color,
icon,
is_active AS "isActive",
is_default AS "isDefault",
company_code AS "companyCode",
menu_objid AS "menuObjid",
created_at AS "createdAt",
updated_at AS "updatedAt",
created_by AS "createdBy",
updated_by AS "updatedBy"
FROM table_column_category_values
WHERE table_name = $1
AND column_name = $2
`;
params = [tableName, columnName];
logger.info("최고 관리자 카테고리 값 조회");
// 최고 관리자: menuObjid가 있으면 해당 메뉴(및 형제 메뉴)의 조회
if (menuObjid && siblingObjids.length > 0) {
query = baseSelect + ` AND menu_objid = ANY($3::numeric[])`;
params = [tableName, columnName, siblingObjids];
logger.info("최고 관리자 메뉴 스코프 카테고리 값 조회", { menuObjid, siblingObjids });
} else if (menuObjid) {
query = baseSelect + ` AND menu_objid = $3`;
params = [tableName, columnName, menuObjid];
logger.info("최고 관리자 단일 메뉴 카테고리 값 조회", { menuObjid });
} else {
// menuObjid 없으면 모든 값 조회 (중복 가능)
query = baseSelect;
params = [tableName, columnName];
logger.info("최고 관리자 전체 카테고리 값 조회 (menuObjid 없음)");
}
} else {
// 일반 회사: 자신의 카테고리 값만 조회
// 메뉴 스코프 제거: 같은 테이블.컬럼 조합은 모든 메뉴에서 공유
query = `
SELECT
value_id AS "valueId",
table_name AS "tableName",
column_name AS "columnName",
value_code AS "valueCode",
value_label AS "valueLabel",
value_order AS "valueOrder",
parent_value_id AS "parentValueId",
depth,
description,
color,
icon,
is_active AS "isActive",
is_default AS "isDefault",
company_code AS "companyCode",
menu_objid AS "menuObjid",
created_at AS "createdAt",
updated_at AS "updatedAt",
created_by AS "createdBy",
updated_by AS "updatedBy"
FROM table_column_category_values
WHERE table_name = $1
AND column_name = $2
AND company_code = $3
`;
params = [tableName, columnName, companyCode];
logger.info("회사별 카테고리 값 조회", { companyCode });
// 일반 회사: 자신의 회사 + menuObjid로 필터링
if (menuObjid && siblingObjids.length > 0) {
query = baseSelect + ` AND company_code = $3 AND menu_objid = ANY($4::numeric[])`;
params = [tableName, columnName, companyCode, siblingObjids];
logger.info("회사별 메뉴 스코프 카테고리 값 조회", { companyCode, menuObjid, siblingObjids });
} else if (menuObjid) {
query = baseSelect + ` AND company_code = $3 AND menu_objid = $4`;
params = [tableName, columnName, companyCode, menuObjid];
logger.info("회사별 단일 메뉴 카테고리 값 조회", { companyCode, menuObjid });
} else {
// menuObjid 없으면 회사 전체 조회 (중복 가능하지만 회사별로 제한)
query = baseSelect + ` AND company_code = $3`;
params = [tableName, columnName, companyCode];
logger.info("회사별 카테고리 값 조회 (menuObjid 없음)", { companyCode });
}
}
if (!includeInactive) {

View File

@@ -1,6 +1,7 @@
"use client";
import React, { useState, useEffect, useCallback, useRef } from "react";
import React, { useState, useEffect, useCallback, useRef, useMemo } from "react";
import { useSearchParams } from "next/navigation";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
@@ -188,6 +189,16 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
const screenContext = useScreenContextOptional(); // 화면 컨텍스트 (좌측/우측 위치 확인용)
const splitPanelPosition = screenContext?.splitPanelPosition; // 분할 패널 내 위치
// URL에서 menuObjid 가져오기 (카테고리 값 조회 시 필요)
const searchParams = useSearchParams();
const menuObjid = useMemo(() => {
// 1. ScreenContext에서 가져오기
if (screenContext?.menuObjid) return screenContext.menuObjid;
// 2. URL 쿼리에서 가져오기
const urlMenuObjid = searchParams.get("menuObjid");
return urlMenuObjid ? parseInt(urlMenuObjid) : undefined;
}, [screenContext?.menuObjid, searchParams]);
const [data, setData] = useState<Record<string, any>[]>([]);
const [loading, setLoading] = useState(false);
const [searchValues, setSearchValues] = useState<Record<string, any>>({});
@@ -365,8 +376,10 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
for (const col of categoryColumns) {
try {
// menuObjid가 있으면 쿼리 파라미터로 전달 (메뉴별 카테고리 색상 적용)
const queryParams = menuObjid ? `?menuObjid=${menuObjid}` : "";
const response = await apiClient.get(
`/table-categories/${component.tableName}/${col.columnName}/values`
`/table-categories/${component.tableName}/${col.columnName}/values${queryParams}`
);
if (response.data.success && response.data.data) {
@@ -379,7 +392,7 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
};
});
mappings[col.columnName] = mapping;
console.log(`✅ 카테고리 매핑 로드 성공 [${col.columnName}]:`, mapping);
console.log(`✅ 카테고리 매핑 로드 성공 [${col.columnName}]:`, mapping, { menuObjid });
}
} catch (error) {
console.error(`❌ 카테고리 값 로드 실패 [${col.columnName}]:`, error);
@@ -394,7 +407,7 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
};
loadCategoryMappings();
}, [component.tableName, component.columns, getColumnWebType]);
}, [component.tableName, component.columns, getColumnWebType, menuObjid]);
// 파일 상태 확인 함수
const checkFileStatus = useCallback(

View File

@@ -13,6 +13,7 @@ import type { SplitPanelPosition } from "@/contexts/SplitPanelContext";
interface ScreenContextValue {
screenId?: number;
tableName?: string;
menuObjid?: number; // 메뉴 OBJID (카테고리 값 조회 시 필요)
splitPanelPosition?: SplitPanelPosition; // 🆕 분할 패널 위치 (left/right)
// 🆕 폼 데이터 (RepeaterFieldGroup 등 컴포넌트 데이터 저장)
@@ -39,6 +40,7 @@ const ScreenContext = createContext<ScreenContextValue | null>(null);
interface ScreenContextProviderProps {
screenId?: number;
tableName?: string;
menuObjid?: number; // 메뉴 OBJID
splitPanelPosition?: SplitPanelPosition; // 🆕 분할 패널 위치
children: React.ReactNode;
}
@@ -49,6 +51,7 @@ interface ScreenContextProviderProps {
export function ScreenContextProvider({
screenId,
tableName,
menuObjid,
splitPanelPosition,
children,
}: ScreenContextProviderProps) {
@@ -112,6 +115,7 @@ export function ScreenContextProvider({
() => ({
screenId,
tableName,
menuObjid,
splitPanelPosition,
formData,
updateFormData,
@@ -127,6 +131,7 @@ export function ScreenContextProvider({
[
screenId,
tableName,
menuObjid,
splitPanelPosition,
formData,
updateFormData,