refactor: 코드 정리 및 불필요한 주석 제거

- EntityJoinController에서 중복 제거 설정 관련 주석 및 코드 삭제
- screenGroupController와 tableManagementController에서 AuthenticatedRequest 타입을 일반 Request로 변경
- 불필요한 로그 및 주석 제거로 코드 가독성 향상
- tableManagementController에서 에러 메시지 개선
This commit is contained in:
DDD1542
2026-01-15 17:36:38 +09:00
parent 9dc549be09
commit efa95af4b9
15 changed files with 1650 additions and 3070 deletions

View File

@@ -129,6 +129,7 @@ interface TableSettingModalProps {
columns?: ColumnInfo[];
filterColumns?: string[];
onSaveSuccess?: () => void;
isEmbedded?: boolean; // 탭 안에 임베드 모드로 표시
}
// 검색 가능한 Select 컴포넌트
@@ -256,6 +257,7 @@ export function TableSettingModal({
columns = [],
filterColumns = [],
onSaveSuccess,
isEmbedded = false,
}: TableSettingModalProps) {
const [activeTab, setActiveTab] = useState("columns");
const [loading, setLoading] = useState(false);
@@ -304,9 +306,19 @@ export function TableSettingModal({
// 초기 편집 상태 설정
const initialEdits: Record<string, Partial<ColumnTypeInfo>> = {};
columnsData.forEach((col) => {
// referenceTable이 설정되어 있으면 inputType은 entity여야 함
let effectiveInputType = col.inputType || "direct";
if (col.referenceTable && effectiveInputType !== "entity") {
effectiveInputType = "entity";
}
// codeCategory/codeValue가 설정되어 있으면 inputType은 code여야 함
if (col.codeCategory && effectiveInputType !== "code") {
effectiveInputType = "code";
}
initialEdits[col.columnName] = {
displayName: col.displayName,
inputType: col.inputType || "direct",
inputType: effectiveInputType,
referenceTable: col.referenceTable,
referenceColumn: col.referenceColumn,
displayColumn: col.displayColumn,
@@ -343,10 +355,10 @@ export function TableSettingModal({
try {
// 모든 화면 조회
const screensResponse = await screenApi.getScreens({ size: 1000 });
if (screensResponse.items) {
if (screensResponse.data) {
const usingScreens: ScreenUsingTable[] = [];
screensResponse.items.forEach((screen: any) => {
screensResponse.data.forEach((screen: any) => {
// 메인 테이블로 사용하는 경우
if (screen.tableName === tableName) {
usingScreens.push({
@@ -418,6 +430,35 @@ export function TableSettingModal({
},
}));
// 입력 타입 변경 시 관련 필드 초기화
if (field === "inputType") {
// 엔티티가 아닌 다른 타입으로 변경하면 참조 설정 초기화
if (value !== "entity") {
setEditedColumns((prev) => ({
...prev,
[columnName]: {
...prev[columnName],
inputType: value,
referenceTable: "",
referenceColumn: "",
displayColumn: "",
},
}));
}
// 코드가 아닌 다른 타입으로 변경하면 코드 설정 초기화
if (value !== "code") {
setEditedColumns((prev) => ({
...prev,
[columnName]: {
...prev[columnName],
inputType: value,
codeCategory: "",
codeValue: "",
},
}));
}
}
// 참조 테이블 변경 시 참조 컬럼 초기화
if (field === "referenceTable") {
setEditedColumns((prev) => ({
@@ -452,8 +493,18 @@ export function TableSettingModal({
// detailSettings 처리 (Entity 타입인 경우)
let finalDetailSettings = mergedColumn.detailSettings || "";
// referenceTable이 설정되어 있으면 inputType을 entity로 자동 설정
let currentInputType = (mergedColumn.inputType || "") as string;
if (mergedColumn.referenceTable && currentInputType !== "entity") {
currentInputType = "entity";
}
// codeCategory가 설정되어 있으면 inputType을 code로 자동 설정
if (mergedColumn.codeCategory && currentInputType !== "code") {
currentInputType = "code";
}
if (mergedColumn.inputType === "entity" && mergedColumn.referenceTable) {
if (currentInputType === "entity" && mergedColumn.referenceTable) {
// 기존 detailSettings를 파싱하거나 새로 생성
let existingSettings: Record<string, unknown> = {};
if (typeof mergedColumn.detailSettings === "string" && mergedColumn.detailSettings.trim().startsWith("{")) {
@@ -479,7 +530,7 @@ export function TableSettingModal({
}
// Code 타입인 경우 hierarchyRole을 detailSettings에 포함
if (mergedColumn.inputType === "code" && (mergedColumn as any).hierarchyRole) {
if (currentInputType === "code" && (mergedColumn as any).hierarchyRole) {
let existingSettings: Record<string, unknown> = {};
if (typeof finalDetailSettings === "string" && finalDetailSettings.trim().startsWith("{")) {
try {
@@ -502,7 +553,7 @@ export function TableSettingModal({
const columnSetting: ColumnSettings = {
columnName: columnName,
columnLabel: mergedColumn.displayName || originalColumn.displayName || "",
webType: mergedColumn.inputType || originalColumn.inputType || "text",
inputType: currentInputType || "text", // referenceTable/codeCategory가 설정된 경우 자동 보정된 값 사용
detailSettings: finalDetailSettings,
codeCategory: mergedColumn.codeCategory || originalColumn.codeCategory || "",
codeValue: mergedColumn.codeValue || originalColumn.codeValue || "",
@@ -593,6 +644,158 @@ export function TableSettingModal({
];
};
// 임베드 모드
if (isEmbedded) {
return (
<>
<div className="flex h-full flex-col">
{/* 헤더 */}
<div className="flex flex-shrink-0 items-center justify-between border-b pb-2 px-3 pt-2">
<div className="flex items-center gap-2">
<Table2 className="h-4 w-4 text-green-500" />
<span className="text-sm font-medium">{tableLabel || tableName}</span>
{tableName !== tableLabel && tableName !== (tableLabel || tableName) && (
<span className="text-xs text-muted-foreground">({tableName})</span>
)}
</div>
<div className="flex items-center gap-2">
<Button
variant="outline"
size="sm"
onClick={() => setShowTableManagementModal(true)}
className="h-7 gap-1 text-xs"
>
<Settings className="h-3 w-3" />
</Button>
<Button
variant="outline"
size="sm"
onClick={handleRefresh}
className="h-7 w-7 p-0"
disabled={loading}
>
<RefreshCw className={cn("h-3 w-3", loading && "animate-spin")} />
</Button>
<Button
size="sm"
onClick={handleSaveAll}
className="h-7 gap-1 text-xs"
disabled={saving || loading}
>
{saving ? (
<Loader2 className="h-3 w-3 animate-spin" />
) : (
<Save className="h-3 w-3" />
)}
</Button>
</div>
</div>
<div className="flex min-h-0 flex-1 gap-3 p-3">
{/* 좌측: 탭 (40%) */}
<div className="flex w-[40%] min-h-0 flex-col">
<Tabs
value={activeTab}
onValueChange={setActiveTab}
className="flex min-h-0 flex-1 flex-col"
>
<TabsList className="h-8 flex-shrink-0">
<TabsTrigger value="columns" className="gap-1 text-xs">
<Columns3 className="h-3 w-3" />
</TabsTrigger>
<TabsTrigger value="screens" className="gap-1 text-xs">
<Monitor className="h-3 w-3" />
</TabsTrigger>
<TabsTrigger value="references" className="gap-1 text-xs">
<Eye className="h-3 w-3" />
</TabsTrigger>
</TabsList>
<TabsContent value="columns" className="mt-2 min-h-0 flex-1 overflow-hidden">
<ColumnListTab
columns={tableColumns.map((col) => ({
...col,
isPK: col.columnName === "id" || col.columnName.endsWith("_id"),
isFK: (col.inputType as string) === "entity",
}))}
editedColumns={editedColumns}
selectedColumn={selectedColumn}
onSelectColumn={setSelectedColumn}
loading={loading}
/>
</TabsContent>
<TabsContent value="screens" className="mt-2 min-h-0 flex-1 overflow-hidden">
<ScreensTab screensUsingTable={screensUsingTable} loading={loading} />
</TabsContent>
<TabsContent value="references" className="mt-2 min-h-0 flex-1 overflow-hidden">
<ReferenceTab
tableName={tableName}
tableLabel={tableLabel}
referencedBy={referencedBy}
joinColumnRefs={joinColumnRefs}
loading={loading}
/>
</TabsContent>
</Tabs>
</div>
{/* 우측: 상세 설정 (60%) */}
<div className="flex w-[60%] min-h-0 flex-col rounded-lg border bg-muted/30 p-3">
{selectedColumn && mergedColumns.find((c) => c.columnName === selectedColumn) ? (
<ColumnDetailPanel
columnInfo={mergedColumns.find((c) => c.columnName === selectedColumn)!}
editedColumn={editedColumns[selectedColumn] || {}}
tableOptions={tableOptions}
inputTypeOptions={inputTypeOptions}
getRefColumnOptions={getRefColumnOptions}
loadingRefColumns={loadingRefColumns}
onColumnChange={(field, value) => handleColumnChange(selectedColumn, field, value)}
/>
) : (
<div className="flex h-full items-center justify-center text-sm text-muted-foreground">
<div className="text-center">
<Columns3 className="mx-auto h-12 w-12 text-muted-foreground/30" />
<p className="mt-2"> </p>
<p> .</p>
</div>
</div>
)}
</div>
</div>
</div>
{/* 테이블 타입 관리 모달 */}
<Dialog open={showTableManagementModal} onOpenChange={setShowTableManagementModal}>
<DialogContent className="flex h-[90vh] max-h-[1000px] w-[95vw] max-w-[1400px] flex-col p-0">
<div className="flex items-center justify-between border-b p-4">
<h2 className="text-lg font-semibold"> </h2>
<Button
variant="ghost"
size="sm"
onClick={() => {
setShowTableManagementModal(false);
loadTableData();
}}
>
<X className="h-4 w-4" />
</Button>
</div>
<div className="flex-1 overflow-hidden">
<TableManagementPage />
</div>
</DialogContent>
</Dialog>
</>
);
}
// 기존 모달 모드
return (
<>
<Dialog open={isOpen} onOpenChange={onClose}>
@@ -843,6 +1046,7 @@ function ColumnListTab({
<div className="space-y-1 px-3 pb-3">
{filteredColumns.map((col) => {
const edited = editedColumns[col.columnName] || {};
// editedColumns에서 inputType을 가져옴 (초기화 시 이미 보정됨)
const inputType = (edited.inputType || col.inputType || "text") as string;
const isSelected = selectedColumn === col.columnName;
@@ -873,23 +1077,17 @@ function ColumnListTab({
PK
</Badge>
)}
{col.isFK && (
<Badge variant="outline" className="bg-green-100 text-green-700 text-[10px] px-1.5">
<Link2 className="mr-0.5 h-2.5 w-2.5" />
FK
</Badge>
)}
{(edited.referenceTable || col.referenceTable) && (
{/* 엔티티 타입이거나 referenceTable이 설정되어 있으면 조인 배지 표시 (FK와 동일 의미) */}
{(inputType === "entity" || edited.referenceTable || col.referenceTable) && (
<Badge variant="outline" className="bg-blue-100 text-blue-700 text-[10px] px-1.5">
<Link2 className="mr-0.5 h-2.5 w-2.5" />
</Badge>
)}
</div>
</div>
<div className="mt-1 flex items-center gap-2 text-xs text-muted-foreground">
<div className="mt-1 text-xs text-muted-foreground">
<span className="font-mono">{col.columnName}</span>
<span></span>
<span>{col.dataType}</span>
</div>
</div>
);
@@ -925,10 +1123,11 @@ function ColumnDetailPanel({
onColumnChange,
}: ColumnDetailPanelProps) {
const currentLabel = editedColumn.displayName ?? columnInfo.displayName ?? "";
const currentInputType = (editedColumn.inputType ?? columnInfo.inputType ?? "text") as string;
const currentRefTable = editedColumn.referenceTable ?? columnInfo.referenceTable ?? "";
const currentRefColumn = editedColumn.referenceColumn ?? columnInfo.referenceColumn ?? "";
const currentDisplayColumn = editedColumn.displayColumn ?? columnInfo.displayColumn ?? "";
// editedColumn에서 inputType을 가져옴 (초기화 시 이미 보정됨)
const currentInputType = (editedColumn.inputType ?? columnInfo.inputType ?? "text") as string;
return (
<div className="flex h-full flex-col">
@@ -948,9 +1147,10 @@ function ColumnDetailPanel({
Primary Key
</Badge>
)}
{columnInfo.isFK && (
<Badge variant="outline" className="bg-green-100 text-green-700 text-[10px]">
Foreign Key
{/* 엔티티 타입이거나 referenceTable이 있으면 조인 배지 표시 */}
{(currentInputType === "entity" || currentRefTable) && (
<Badge variant="outline" className="bg-blue-100 text-blue-700 text-[10px]">
</Badge>
)}
</div>