가이드 삭제
This commit is contained in:
parent
774332558b
commit
0823874ebc
|
|
@ -8,7 +8,6 @@ import { ElementConfigModal } from "./ElementConfigModal";
|
||||||
import { ListWidgetConfigModal } from "./widgets/ListWidgetConfigModal";
|
import { ListWidgetConfigModal } from "./widgets/ListWidgetConfigModal";
|
||||||
import { YardWidgetConfigModal } from "./widgets/YardWidgetConfigModal";
|
import { YardWidgetConfigModal } from "./widgets/YardWidgetConfigModal";
|
||||||
import { DashboardSaveModal } from "./DashboardSaveModal";
|
import { DashboardSaveModal } from "./DashboardSaveModal";
|
||||||
import { KeyboardShortcutsGuide } from "./KeyboardShortcutsGuide";
|
|
||||||
import { DashboardElement, ElementType, ElementSubtype } from "./types";
|
import { DashboardElement, ElementType, ElementSubtype } from "./types";
|
||||||
import { GRID_CONFIG, snapToGrid, snapSizeToGrid, calculateCellSize } from "./gridUtils";
|
import { GRID_CONFIG, snapToGrid, snapSizeToGrid, calculateCellSize } from "./gridUtils";
|
||||||
import { Resolution, RESOLUTIONS, detectScreenResolution } from "./ResolutionSelector";
|
import { Resolution, RESOLUTIONS, detectScreenResolution } from "./ResolutionSelector";
|
||||||
|
|
@ -27,7 +26,7 @@ import {
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { CheckCircle2, Keyboard } from "lucide-react";
|
import { CheckCircle2 } from "lucide-react";
|
||||||
|
|
||||||
interface DashboardDesignerProps {
|
interface DashboardDesignerProps {
|
||||||
dashboardId?: string;
|
dashboardId?: string;
|
||||||
|
|
@ -58,7 +57,6 @@ export default function DashboardDesigner({ dashboardId: initialDashboardId }: D
|
||||||
const [dashboardDescription, setDashboardDescription] = useState<string>("");
|
const [dashboardDescription, setDashboardDescription] = useState<string>("");
|
||||||
const [successModalOpen, setSuccessModalOpen] = useState(false);
|
const [successModalOpen, setSuccessModalOpen] = useState(false);
|
||||||
const [clearConfirmOpen, setClearConfirmOpen] = useState(false);
|
const [clearConfirmOpen, setClearConfirmOpen] = useState(false);
|
||||||
const [shortcutsGuideOpen, setShortcutsGuideOpen] = useState(false);
|
|
||||||
|
|
||||||
// 클립보드 (복사/붙여넣기용)
|
// 클립보드 (복사/붙여넣기용)
|
||||||
const [clipboard, setClipboard] = useState<DashboardElement | null>(null);
|
const [clipboard, setClipboard] = useState<DashboardElement | null>(null);
|
||||||
|
|
@ -337,7 +335,7 @@ export default function DashboardDesigner({ dashboardId: initialDashboardId }: D
|
||||||
onDelete: handleDeleteSelected,
|
onDelete: handleDeleteSelected,
|
||||||
onCopy: handleCopyElement,
|
onCopy: handleCopyElement,
|
||||||
onPaste: handlePasteElement,
|
onPaste: handlePasteElement,
|
||||||
enabled: !saveModalOpen && !successModalOpen && !clearConfirmOpen && !shortcutsGuideOpen,
|
enabled: !saveModalOpen && !successModalOpen && !clearConfirmOpen,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 전체 삭제 확인 모달 열기
|
// 전체 삭제 확인 모달 열기
|
||||||
|
|
@ -653,21 +651,6 @@ export default function DashboardDesigner({ dashboardId: initialDashboardId }: D
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
|
|
||||||
{/* 키보드 단축키 가이드 모달 */}
|
|
||||||
<KeyboardShortcutsGuide isOpen={shortcutsGuideOpen} onClose={() => setShortcutsGuideOpen(false)} />
|
|
||||||
|
|
||||||
{/* 키보드 단축키 도움말 플로팅 버튼 */}
|
|
||||||
<div className="fixed right-8 bottom-8 z-50">
|
|
||||||
<Button
|
|
||||||
onClick={() => setShortcutsGuideOpen(true)}
|
|
||||||
size="lg"
|
|
||||||
className="h-12 w-12 rounded-full p-0 shadow-lg"
|
|
||||||
title="키보드 단축키 (?"
|
|
||||||
>
|
|
||||||
<Keyboard className="h-5 w-5" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</DashboardProvider>
|
</DashboardProvider>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
"use client";
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog";
|
|
||||||
import { Keyboard } from "lucide-react";
|
|
||||||
|
|
||||||
interface KeyboardShortcutsGuideProps {
|
|
||||||
isOpen: boolean;
|
|
||||||
onClose: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ShortcutItem {
|
|
||||||
keys: string[];
|
|
||||||
description: string;
|
|
||||||
category: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const shortcuts: ShortcutItem[] = [
|
|
||||||
// 기본 작업
|
|
||||||
{ keys: ["Delete"], description: "선택한 요소 삭제", category: "기본 작업" },
|
|
||||||
{ keys: ["Ctrl", "C"], description: "요소 복사", category: "기본 작업" },
|
|
||||||
{ keys: ["Ctrl", "V"], description: "요소 붙여넣기", category: "기본 작업" },
|
|
||||||
|
|
||||||
// 실행 취소/재실행 (구현 예정)
|
|
||||||
{ keys: ["Ctrl", "Z"], description: "실행 취소 (구현 예정)", category: "편집" },
|
|
||||||
{ keys: ["Ctrl", "Shift", "Z"], description: "재실행 (구현 예정)", category: "편집" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const KeyBadge = ({ keyName }: { keyName: string }) => (
|
|
||||||
<kbd className="inline-flex h-6 min-w-6 items-center justify-center rounded border border-gray-300 bg-gray-100 px-2 text-xs font-semibold text-gray-800 shadow-sm">
|
|
||||||
{keyName}
|
|
||||||
</kbd>
|
|
||||||
);
|
|
||||||
|
|
||||||
export function KeyboardShortcutsGuide({ isOpen, onClose }: KeyboardShortcutsGuideProps) {
|
|
||||||
// 카테고리별로 그룹화
|
|
||||||
const groupedShortcuts = shortcuts.reduce(
|
|
||||||
(acc, shortcut) => {
|
|
||||||
if (!acc[shortcut.category]) {
|
|
||||||
acc[shortcut.category] = [];
|
|
||||||
}
|
|
||||||
acc[shortcut.category].push(shortcut);
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{} as Record<string, ShortcutItem[]>,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Mac OS 감지
|
|
||||||
const isMac = typeof navigator !== "undefined" && navigator.platform.toUpperCase().indexOf("MAC") >= 0;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog open={isOpen} onOpenChange={onClose}>
|
|
||||||
<DialogContent className="max-w-[95vw] sm:max-w-[600px]">
|
|
||||||
<DialogHeader>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Keyboard className="h-5 w-5" />
|
|
||||||
<DialogTitle className="text-base sm:text-lg">키보드 단축키</DialogTitle>
|
|
||||||
</div>
|
|
||||||
<DialogDescription className="text-xs sm:text-sm">
|
|
||||||
대시보드 편집을 더 빠르게 할 수 있는 단축키 목록입니다
|
|
||||||
{isMac && " (Mac에서는 Ctrl 대신 Cmd 키를 사용하세요)"}
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
|
|
||||||
<div className="max-h-[60vh] space-y-6 overflow-y-auto pr-2">
|
|
||||||
{Object.entries(groupedShortcuts).map(([category, categoryShortcuts]) => (
|
|
||||||
<div key={category}>
|
|
||||||
<h3 className="mb-3 text-sm font-semibold text-gray-900">{category}</h3>
|
|
||||||
<div className="space-y-2">
|
|
||||||
{categoryShortcuts.map((shortcut, index) => (
|
|
||||||
<div
|
|
||||||
key={`${category}-${index}`}
|
|
||||||
className="flex items-center justify-between rounded-lg border border-gray-200 bg-gray-50 p-3"
|
|
||||||
>
|
|
||||||
<span className="text-sm text-gray-700">{shortcut.description}</span>
|
|
||||||
<div className="flex items-center gap-1">
|
|
||||||
{shortcut.keys.map((key, keyIndex) => (
|
|
||||||
<React.Fragment key={keyIndex}>
|
|
||||||
<KeyBadge keyName={isMac && key === "Ctrl" ? "⌘" : key} />
|
|
||||||
{keyIndex < shortcut.keys.length - 1 && <span className="text-xs text-gray-400">+</span>}
|
|
||||||
</React.Fragment>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt-4 rounded-lg bg-blue-50 p-3 text-xs text-blue-800">
|
|
||||||
<p className="font-medium">💡 팁</p>
|
|
||||||
<p className="mt-1">입력 필드나 모달에서는 단축키가 자동으로 비활성화됩니다.</p>
|
|
||||||
</div>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue