This commit is contained in:
parent
3f60f9ca3e
commit
9fda390c55
|
|
@ -148,11 +148,11 @@ export const updateScreenInfo = async (
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const { companyCode } = req.user as any;
|
const { companyCode } = req.user as any;
|
||||||
const { screenName, description, isActive } = req.body;
|
const { screenName, tableName, description, isActive } = req.body;
|
||||||
|
|
||||||
await screenManagementService.updateScreenInfo(
|
await screenManagementService.updateScreenInfo(
|
||||||
parseInt(id),
|
parseInt(id),
|
||||||
{ screenName, description, isActive },
|
{ screenName, tableName, description, isActive },
|
||||||
companyCode
|
companyCode
|
||||||
);
|
);
|
||||||
res.json({ success: true, message: "화면 정보가 수정되었습니다." });
|
res.json({ success: true, message: "화면 정보가 수정되었습니다." });
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,7 @@ export class ScreenManagementService {
|
||||||
*/
|
*/
|
||||||
async updateScreenInfo(
|
async updateScreenInfo(
|
||||||
screenId: number,
|
screenId: number,
|
||||||
updateData: { screenName: string; description?: string; isActive: string },
|
updateData: { screenName: string; tableName?: string; description?: string; isActive: string },
|
||||||
userCompanyCode: string
|
userCompanyCode: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// 권한 확인
|
// 권한 확인
|
||||||
|
|
@ -343,16 +343,18 @@ export class ScreenManagementService {
|
||||||
throw new Error("이 화면을 수정할 권한이 없습니다.");
|
throw new Error("이 화면을 수정할 권한이 없습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 화면 정보 업데이트
|
// 화면 정보 업데이트 (tableName 포함)
|
||||||
await query(
|
await query(
|
||||||
`UPDATE screen_definitions
|
`UPDATE screen_definitions
|
||||||
SET screen_name = $1,
|
SET screen_name = $1,
|
||||||
description = $2,
|
table_name = $2,
|
||||||
is_active = $3,
|
description = $3,
|
||||||
updated_date = $4
|
is_active = $4,
|
||||||
WHERE screen_id = $5`,
|
updated_date = $5
|
||||||
|
WHERE screen_id = $6`,
|
||||||
[
|
[
|
||||||
updateData.screenName,
|
updateData.screenName,
|
||||||
|
updateData.tableName || null,
|
||||||
updateData.description || null,
|
updateData.description || null,
|
||||||
updateData.isActive,
|
updateData.isActive,
|
||||||
new Date(),
|
new Date(),
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,10 @@ import {
|
||||||
DialogDescription,
|
DialogDescription,
|
||||||
} from "@/components/ui/dialog";
|
} from "@/components/ui/dialog";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
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 { ScreenDefinition } from "@/types/screen";
|
||||||
import { screenApi } from "@/lib/api/screen";
|
import { screenApi } from "@/lib/api/screen";
|
||||||
import CreateScreenModal from "./CreateScreenModal";
|
import CreateScreenModal from "./CreateScreenModal";
|
||||||
|
|
@ -127,8 +130,9 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr
|
||||||
isActive: "Y",
|
isActive: "Y",
|
||||||
tableName: "",
|
tableName: "",
|
||||||
});
|
});
|
||||||
const [tables, setTables] = useState<string[]>([]);
|
const [tables, setTables] = useState<Array<{ tableName: string; tableLabel: string }>>([]);
|
||||||
const [loadingTables, setLoadingTables] = useState(false);
|
const [loadingTables, setLoadingTables] = useState(false);
|
||||||
|
const [tableComboboxOpen, setTableComboboxOpen] = useState(false);
|
||||||
|
|
||||||
// 미리보기 관련 상태
|
// 미리보기 관련 상태
|
||||||
const [previewDialogOpen, setPreviewDialogOpen] = 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 { tableManagementApi } = await import("@/lib/api/tableManagement");
|
||||||
const response = await tableManagementApi.getTableList();
|
const response = await tableManagementApi.getTableList();
|
||||||
if (response.success && response.data) {
|
if (response.success && response.data) {
|
||||||
// tableName만 추출 (camelCase)
|
// tableName과 displayName 매핑 (백엔드에서 displayName으로 라벨을 반환함)
|
||||||
const tableNames = response.data.map((table: any) => table.tableName);
|
const tableList = response.data.map((table: any) => ({
|
||||||
setTables(tableNames);
|
tableName: table.tableName,
|
||||||
|
tableLabel: table.displayName || table.tableName,
|
||||||
|
}));
|
||||||
|
setTables(tableList);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("테이블 목록 조회 실패:", error);
|
console.error("테이블 목록 조회 실패:", error);
|
||||||
|
|
@ -297,6 +304,10 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr
|
||||||
// 화면 정보 업데이트 API 호출
|
// 화면 정보 업데이트 API 호출
|
||||||
await screenApi.updateScreenInfo(screenToEdit.screenId, editFormData);
|
await screenApi.updateScreenInfo(screenToEdit.screenId, editFormData);
|
||||||
|
|
||||||
|
// 선택된 테이블의 라벨 찾기
|
||||||
|
const selectedTable = tables.find((t) => t.tableName === editFormData.tableName);
|
||||||
|
const tableLabel = selectedTable?.tableLabel || editFormData.tableName;
|
||||||
|
|
||||||
// 목록에서 해당 화면 정보 업데이트
|
// 목록에서 해당 화면 정보 업데이트
|
||||||
setScreens((prev) =>
|
setScreens((prev) =>
|
||||||
prev.map((s) =>
|
prev.map((s) =>
|
||||||
|
|
@ -304,6 +315,8 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr
|
||||||
? {
|
? {
|
||||||
...s,
|
...s,
|
||||||
screenName: editFormData.screenName,
|
screenName: editFormData.screenName,
|
||||||
|
tableName: editFormData.tableName,
|
||||||
|
tableLabel: tableLabel,
|
||||||
description: editFormData.description,
|
description: editFormData.description,
|
||||||
isActive: editFormData.isActive,
|
isActive: editFormData.isActive,
|
||||||
}
|
}
|
||||||
|
|
@ -1202,22 +1215,62 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="edit-tableName">테이블 *</Label>
|
<Label htmlFor="edit-tableName">테이블 *</Label>
|
||||||
<Select
|
<Popover open={tableComboboxOpen} onOpenChange={setTableComboboxOpen}>
|
||||||
value={editFormData.tableName}
|
<PopoverTrigger asChild>
|
||||||
onValueChange={(value) => setEditFormData({ ...editFormData, tableName: value })}
|
<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}
|
disabled={loadingTables}
|
||||||
>
|
>
|
||||||
<SelectTrigger id="edit-tableName">
|
{loadingTables
|
||||||
<SelectValue placeholder={loadingTables ? "로딩 중..." : "테이블을 선택하세요"} />
|
? "로딩 중..."
|
||||||
</SelectTrigger>
|
: editFormData.tableName
|
||||||
<SelectContent>
|
? tables.find((table) => table.tableName === editFormData.tableName)?.tableLabel || editFormData.tableName
|
||||||
{tables.map((tableName) => (
|
: "테이블을 선택하세요"}
|
||||||
<SelectItem key={tableName} value={tableName}>
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
{tableName}
|
</Button>
|
||||||
</SelectItem>
|
</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>
|
</CommandGroup>
|
||||||
</Select>
|
</CommandList>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="edit-description">설명</Label>
|
<Label htmlFor="edit-description">설명</Label>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue