167 lines
5.7 KiB
TypeScript
167 lines
5.7 KiB
TypeScript
/**
|
|
* 화면명: 하수관로 편집 도구
|
|
* 관로 추가·이동·꼭지점 편집·삭제 도구를 선택하고 제어한다.
|
|
*/
|
|
"use client";
|
|
|
|
import { Check, Move, PenTool, Plus, Trash2, X } from "lucide-react";
|
|
import { Button } from "@common/components/ui";
|
|
|
|
import type { GisEditTool } from "./gisEditTypes";
|
|
import { useGisEditOperationLabels } from "./useGisEditCommonCodes";
|
|
|
|
type Props = {
|
|
isEditMode: boolean;
|
|
activeTool: GisEditTool | null;
|
|
isSnapEnabled: boolean;
|
|
canUseTools: boolean;
|
|
canSave: boolean;
|
|
isSaving?: boolean;
|
|
statusMessage: string;
|
|
allowedTools?: GisEditTool[];
|
|
onClose?: () => void;
|
|
onToggleSnap: () => void;
|
|
onSelectTool: (tool: GisEditTool) => void;
|
|
onSave: () => void;
|
|
};
|
|
|
|
const TOOL_BUTTONS: Array<{
|
|
tool: GisEditTool;
|
|
icon: typeof Plus;
|
|
}> = [
|
|
{ tool: "ADD", icon: Plus },
|
|
{ tool: "MOVE", icon: Move },
|
|
{ tool: "VERTEX_EDIT", icon: PenTool },
|
|
{ tool: "DELETE", icon: Trash2 },
|
|
];
|
|
|
|
export default function GisEditToolbar({
|
|
isEditMode,
|
|
activeTool,
|
|
isSnapEnabled,
|
|
canUseTools,
|
|
canSave,
|
|
isSaving = false,
|
|
statusMessage,
|
|
allowedTools = [],
|
|
onClose,
|
|
onToggleSnap,
|
|
onSelectTool,
|
|
onSave,
|
|
}: Props) {
|
|
// 버튼의 업무 코드값은 그대로 유지하고 CMS 공통코드명만 화면 라벨로 사용한다.
|
|
const operationLabels = useGisEditOperationLabels();
|
|
|
|
if (!isEditMode) return null;
|
|
|
|
return (
|
|
<div
|
|
data-testid="gis-edit-toolbar"
|
|
className="absolute bottom-4 left-1/2 z-[60] flex w-[min(980px,calc(100%-2rem))] -translate-x-1/2 flex-col"
|
|
>
|
|
<div className="card !m-0 flex !border-0 !bg-background !p-[0.8rem] shadow-[0_1px_2px_rgba(60,64,67,0.3),0_1px_3px_1px_rgba(60,64,67,0.15)]">
|
|
<div className="flex w-full items-center gap-3 overflow-hidden">
|
|
<div className="flex w-[168px] shrink-0 flex-col justify-center border-r border-border pr-3">
|
|
<span className="whitespace-nowrap text-[1.3rem] font-semibold leading-5 text-label">
|
|
하수관로 편집
|
|
</span>
|
|
<span
|
|
className="mt-0.5 truncate text-[1.05rem] text-muted-foreground"
|
|
title={statusMessage}
|
|
>
|
|
{statusMessage || "편집 도구를 선택하세요."}
|
|
</span>
|
|
</div>
|
|
<div className="flex min-w-0 flex-1 items-center justify-center gap-3">
|
|
<div className="flex items-center gap-1 rounded-md bg-container p-1">
|
|
{TOOL_BUTTONS.map(({ tool, icon: Icon }) => {
|
|
const isActive = activeTool === tool;
|
|
const isToolEnabled =
|
|
canUseTools && allowedTools.includes(tool);
|
|
const label = operationLabels[tool];
|
|
if (tool === "VERTEX_EDIT") {
|
|
return (
|
|
<div
|
|
key="vertex-edit-with-snap"
|
|
className="flex shrink-0 items-center"
|
|
>
|
|
<Button
|
|
type="button"
|
|
color={
|
|
activeTool === "VERTEX_EDIT" ? "primary" : "white"
|
|
}
|
|
className="min-w-[98px] px-2"
|
|
disabled={!isToolEnabled}
|
|
onClick={() => onSelectTool("VERTEX_EDIT")}
|
|
>
|
|
<span className="flex items-center justify-center gap-2 whitespace-nowrap">
|
|
<Icon className="h-4 w-4" />
|
|
<span>{label}</span>
|
|
</span>
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|
|
return (
|
|
<Button
|
|
key={tool}
|
|
type="button"
|
|
color={isActive ? "primary" : "white"}
|
|
className="min-w-[74px] shrink-0 px-2"
|
|
disabled={!isToolEnabled}
|
|
onClick={() => onSelectTool(tool)}
|
|
>
|
|
<span className="flex items-center justify-center gap-2 whitespace-nowrap">
|
|
<Icon className="h-4 w-4" />
|
|
<span>{label}</span>
|
|
</span>
|
|
</Button>
|
|
);
|
|
})}
|
|
</div>
|
|
<div className="h-8 w-px shrink-0 bg-border" />
|
|
<Button
|
|
type="button"
|
|
color={isSnapEnabled ? "primary" : "white"}
|
|
className="min-w-[82px] shrink-0 px-2"
|
|
disabled={!canUseTools}
|
|
onClick={onToggleSnap}
|
|
title="이동과 꼭지점편집에 스냅핑 적용"
|
|
>
|
|
<span className="flex items-center justify-center gap-2 whitespace-nowrap">
|
|
<Check className="h-4 w-4" />
|
|
<span>스냅핑</span>
|
|
</span>
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="flex w-[140px] shrink-0 items-center justify-end gap-2 border-l border-border pl-3">
|
|
<Button
|
|
type="button"
|
|
color="primary"
|
|
className="min-w-[64px] shrink-0 px-2"
|
|
disabled={!canSave || isSaving}
|
|
onClick={onSave}
|
|
>
|
|
{isSaving ? "저장 중" : "저장"}
|
|
</Button>
|
|
|
|
<Button
|
|
type="button"
|
|
color="white"
|
|
className="min-w-[64px] shrink-0 px-2"
|
|
onClick={onClose}
|
|
title="하수관로 편집 취소"
|
|
>
|
|
<span className="flex items-center justify-center gap-2 whitespace-nowrap">
|
|
<X className="h-4 w-4" />
|
|
<span>취소</span>
|
|
</span>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|