This commit is contained in:
kjs 2025-11-25 09:34:44 +09:00
parent 3f60f9ca3e
commit 9fda390c55
3 changed files with 84 additions and 29 deletions

View File

@ -148,11 +148,11 @@ export const updateScreenInfo = async (
try {
const { id } = req.params;
const { companyCode } = req.user as any;
const { screenName, description, isActive } = req.body;
const { screenName, tableName, description, isActive } = req.body;
await screenManagementService.updateScreenInfo(
parseInt(id),
{ screenName, description, isActive },
{ screenName, tableName, description, isActive },
companyCode
);
res.json({ success: true, message: "화면 정보가 수정되었습니다." });

View File

@ -321,7 +321,7 @@ export class ScreenManagementService {
*/
async updateScreenInfo(
screenId: number,
updateData: { screenName: string; description?: string; isActive: string },
updateData: { screenName: string; tableName?: string; description?: string; isActive: string },
userCompanyCode: string
): Promise<void> {
// 권한 확인
@ -343,16 +343,18 @@ export class ScreenManagementService {
throw new Error("이 화면을 수정할 권한이 없습니다.");
}
// 화면 정보 업데이트
// 화면 정보 업데이트 (tableName 포함)
await query(
`UPDATE screen_definitions
SET screen_name = $1,
description = $2,
is_active = $3,
updated_date = $4
WHERE screen_id = $5`,
table_name = $2,
description = $3,
is_active = $4,
updated_date = $5
WHERE screen_id = $6`,
[
updateData.screenName,
updateData.tableName || null,
updateData.description || null,
updateData.isActive,
new Date(),

View File

@ -35,7 +35,10 @@ import {
DialogDescription,
} from "@/components/ui/dialog";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { MoreHorizontal, Edit, Trash2, Copy, Eye, Plus, Search, Palette, RotateCcw, Trash } from "lucide-react";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { cn } from "@/lib/utils";
import { MoreHorizontal, Edit, Trash2, Copy, Eye, Plus, Search, Palette, RotateCcw, Trash, Check, ChevronsUpDown } from "lucide-react";
import { ScreenDefinition } from "@/types/screen";
import { screenApi } from "@/lib/api/screen";
import CreateScreenModal from "./CreateScreenModal";
@ -127,8 +130,9 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr
isActive: "Y",
tableName: "",
});
const [tables, setTables] = useState<string[]>([]);
const [tables, setTables] = useState<Array<{ tableName: string; tableLabel: string }>>([]);
const [loadingTables, setLoadingTables] = useState(false);
const [tableComboboxOpen, setTableComboboxOpen] = useState(false);
// 미리보기 관련 상태
const [previewDialogOpen, setPreviewDialogOpen] = useState(false);
@ -279,9 +283,12 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr
const { tableManagementApi } = await import("@/lib/api/tableManagement");
const response = await tableManagementApi.getTableList();
if (response.success && response.data) {
// tableName만 추출 (camelCase)
const tableNames = response.data.map((table: any) => table.tableName);
setTables(tableNames);
// tableName과 displayName 매핑 (백엔드에서 displayName으로 라벨을 반환함)
const tableList = response.data.map((table: any) => ({
tableName: table.tableName,
tableLabel: table.displayName || table.tableName,
}));
setTables(tableList);
}
} catch (error) {
console.error("테이블 목록 조회 실패:", error);
@ -297,6 +304,10 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr
// 화면 정보 업데이트 API 호출
await screenApi.updateScreenInfo(screenToEdit.screenId, editFormData);
// 선택된 테이블의 라벨 찾기
const selectedTable = tables.find((t) => t.tableName === editFormData.tableName);
const tableLabel = selectedTable?.tableLabel || editFormData.tableName;
// 목록에서 해당 화면 정보 업데이트
setScreens((prev) =>
prev.map((s) =>
@ -304,6 +315,8 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr
? {
...s,
screenName: editFormData.screenName,
tableName: editFormData.tableName,
tableLabel: tableLabel,
description: editFormData.description,
isActive: editFormData.isActive,
}
@ -1202,22 +1215,62 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr
</div>
<div className="space-y-2">
<Label htmlFor="edit-tableName"> *</Label>
<Select
value={editFormData.tableName}
onValueChange={(value) => setEditFormData({ ...editFormData, tableName: value })}
<Popover open={tableComboboxOpen} onOpenChange={setTableComboboxOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
aria-expanded={tableComboboxOpen}
className="h-8 w-full justify-between text-xs sm:h-10 sm:text-sm"
disabled={loadingTables}
>
<SelectTrigger id="edit-tableName">
<SelectValue placeholder={loadingTables ? "로딩 중..." : "테이블을 선택하세요"} />
</SelectTrigger>
<SelectContent>
{tables.map((tableName) => (
<SelectItem key={tableName} value={tableName}>
{tableName}
</SelectItem>
{loadingTables
? "로딩 중..."
: editFormData.tableName
? tables.find((table) => table.tableName === editFormData.tableName)?.tableLabel || editFormData.tableName
: "테이블을 선택하세요"}
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent
className="p-0"
style={{ width: "var(--radix-popover-trigger-width)" }}
align="start"
>
<Command>
<CommandInput placeholder="테이블 검색..." className="text-xs sm:text-sm" />
<CommandList>
<CommandEmpty className="text-xs sm:text-sm">
.
</CommandEmpty>
<CommandGroup>
{tables.map((table) => (
<CommandItem
key={table.tableName}
value={`${table.tableName} ${table.tableLabel}`}
onSelect={() => {
setEditFormData({ ...editFormData, tableName: table.tableName });
setTableComboboxOpen(false);
}}
className="text-xs sm:text-sm"
>
<Check
className={cn(
"mr-2 h-4 w-4",
editFormData.tableName === table.tableName ? "opacity-100" : "opacity-0"
)}
/>
<div className="flex flex-col">
<span className="font-medium">{table.tableLabel}</span>
<span className="text-[10px] text-gray-500">{table.tableName}</span>
</div>
</CommandItem>
))}
</SelectContent>
</Select>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</div>
<div className="space-y-2">
<Label htmlFor="edit-description"></Label>