From aa300ac57644ee9723bdba8fa08754a4468c7091 Mon Sep 17 00:00:00 2001 From: Vishnu Date: Tue, 13 May 2025 17:21:17 +0530 Subject: [PATCH] Refactor Tools and Menu components for improved state management and UI responsiveness --- app/src/components/ui/Tools.tsx | 16 +- app/src/components/ui/menu/menu.tsx | 671 ++++++----------------- app/src/styles/components/menu/menu.scss | 1 + 3 files changed, 181 insertions(+), 507 deletions(-) diff --git a/app/src/components/ui/Tools.tsx b/app/src/components/ui/Tools.tsx index 69d7651..ac5f58a 100644 --- a/app/src/components/ui/Tools.tsx +++ b/app/src/components/ui/Tools.tsx @@ -160,15 +160,21 @@ const Tools: React.FC = () => { }; const toggle2D3D = () => { - setToggleThreeD(!toggleThreeD); + const toggleTo2D = toggleView; + setToggleView(!toggleTo2D); + setToggleThreeD(toggleTo2D); + setToggleUI(toggleTo2D, toggleTo2D); + if (toggleTo2D) { + setSelectedWallItem(null); + setDeleteTool(false); + setAddAction(null); + } + setActiveTool("cursor"); + setActiveSubTool("cursor"); setToggleUI( localStorage.getItem("navBarUiLeft") !== "false", localStorage.getItem("navBarUiRight") !== "false" ); - setSelectedWallItem(null); - setActiveSubTool("cursor"); - setActiveTool("cursor"); - setToggleView(!toggleThreeD); }; if (isPlaying && activeModule !== "simulation") { diff --git a/app/src/components/ui/menu/menu.tsx b/app/src/components/ui/menu/menu.tsx index 5fc0959..f1975b8 100644 --- a/app/src/components/ui/menu/menu.tsx +++ b/app/src/components/ui/menu/menu.tsx @@ -1,385 +1,198 @@ import React, { useState } from "react"; +import { useNavigate } from "react-router-dom"; import { ArrowIcon } from "../../icons/ExportCommonIcons"; import { toggleTheme } from "../../../utils/theme"; -import { useNavigate } from "react-router-dom"; -import useVersionHistoryStore from "../../../store/store"; +import useVersionHistoryStore, { useShortcutStore } from "../../../store/store"; import { useSubModuleStore } from "../../../store/useModuleStore"; interface MenuBarProps { - setOpenMenu: (isOpen: boolean) => void; // Function to update menu state + setOpenMenu: (isOpen: boolean) => void; +} + +interface MenuItem { + label: string; + onClick?: string; + shortcut?: string; + submenu?: MenuItem[]; + action?: () => void; } const MenuBar: React.FC = ({ setOpenMenu }) => { const navigate = useNavigate(); const [activeMenu, setActiveMenu] = useState(null); const [activeSubMenu, setActiveSubMenu] = useState(null); - - const { setVersionHistory } = useVersionHistoryStore(); - const { setSubModule } = useSubModuleStore(); - - // State to track selection for all menu items const [selectedItems, setSelectedItems] = useState>( {} ); - // Function to toggle selection for a specific item + const { setVersionHistory } = useVersionHistoryStore(); + const { setSubModule } = useSubModuleStore(); + const { showShortcuts, setShowShortcuts } = useShortcutStore(); + + const savedTheme = localStorage.getItem("theme") ?? "light"; + const toggleSelection = (itemName: string) => { setSelectedItems((prev) => ({ ...prev, - [itemName]: !prev[itemName], // Toggle the selection state + [itemName]: !prev[itemName], })); }; - function handleThemeChange() { + // functions + const handleThemeChange = () => { toggleTheme(); window.location.reload(); - } - - const savedTheme: string | null = localStorage.getItem("theme") ?? "light"; - - - const handleLogout = () => { - localStorage.clear(); // 1. Clear all localStorage - navigate('/'); // 2. Redirect to homepage }; - return ( -
{ - setOpenMenu(false); + const handleLogout = () => { + localStorage.clear(); + navigate("/"); + }; + + function handleShotcutsHelper() { + setShowShortcuts(!showShortcuts); + } + + const menus: Record = { + File: [ + { label: "New File", shortcut: "Ctrl + N" }, + { label: "Open Local File", shortcut: "Ctrl + O" }, + { label: "Save Version" }, + { label: "Make a Copy" }, + { label: "Share" }, + { label: "Rename" }, + { label: "Import" }, + { label: "Close File" }, + ], + Edit: [ + { label: "Undo", shortcut: "Ctrl + Z" }, + { label: "Redo", shortcut: "Ctrl + Shift + Z" }, + { label: "Undo History" }, + { label: "Redo History" }, + { label: "Find", shortcut: "Ctrl + F" }, + { label: "Delete" }, + { label: "Select by..." }, + { label: "Keymap" }, + ], + View: [ + { label: "Grid" }, + { + label: "Gizmo", + submenu: [ + { label: "Visibility" }, + { label: "Cube view" }, + { label: "Sphere view" }, + ], + }, + { label: "Zoom" }, + { label: "Full Screen", shortcut: "F11" }, + ], + Help: [ + { + label: "Shortcuts", + shortcut: "Ctrl + Shift + ?", + action: handleShotcutsHelper, + }, + { label: "Manual" }, + { label: "Video Tutorials" }, + { label: "Report a bug" }, + ], + }; + + // render menu item and sub menu item component + const renderMenuItem = ({ label, shortcut, action }: MenuItem) => ( + + ); + + const renderSubMenu = (submenu: MenuItem[], parentLabel: string) => ( +
+ {submenu.map((item) => ( + + ))} +
+ ); + + return ( +
setOpenMenu(false)}>
- {/* File Menu */} -
setActiveMenu("File")} - onMouseLeave={() => { - setActiveMenu(null); - setActiveSubMenu(null); - }} - > -
- File - - - -
- - {/* File Dropdown */} - {activeMenu === "File" && ( -
- {/* New File */} -
toggleSelection("New File")} - > -
- New File -
- Ctrl + N -
-
-
- - {/* Open Local File */} -
toggleSelection("Open Local File")} - > -
- Open Local File -
- Ctrl + O -
-
-
- - {/* Save Version */} -
toggleSelection("Save Version")} - > -
- Save Version -
-
-
- - {/* Make a Copy */} -
toggleSelection("Make a Copy")} - > -
- Make a Copy -
-
- - {/* Share */} -
toggleSelection("Share")} - > -
- Share -
-
- - {/* Rename */} -
toggleSelection("Rename")} - > -
- Rename -
-
-
- - {/* Import */} -
toggleSelection("Import")} - > -
- Import -
-
- - {/* Close File */} -
toggleSelection("Close File")} - > -
- Close File -
-
+ {Object.entries(menus).map(([menu, items]) => ( +
- {/* Edit Menu */} -
setActiveMenu("Edit")} - onMouseLeave={() => { - setActiveMenu(null); - setActiveSubMenu(null); - }} - > -
- Edit - - - -
- - {/* Edit Dropdown */} - {activeMenu === "Edit" && ( -
- {/* Undo */} -
toggleSelection("Undo")} - > -
- Undo -
- Ctrl + Z -
-
-
- - {/* Redo */} -
toggleSelection("Redo")} - > -
- Redo -
- Ctrl + Shift + Z -
-
-
-
- - {/* Undo History */} -
toggleSelection("Undo History")} - > -
- Undo History -
-
- - {/* Redo History */} -
toggleSelection("Redo History")} - > -
- Redo History -
-
-
- - {/* Find */} -
toggleSelection("Find")} - > -
- Find -
- Ctrl + F -
-
-
- - {/* Delete */} -
toggleSelection("Delete")} - > -
- Delete -
-
- - {/* Select by... */} -
toggleSelection("Select by...")} - > -
- Select by... -
-
- - {/* Keymap */} -
toggleSelection("Keymap")} - > -
- Keymap -
-
-
- )} -
- - {/* View Menu */} -
setActiveMenu("View")} - onMouseLeave={() => { - setActiveMenu(null); - setActiveSubMenu(null); - }} - > -
- View - - - -
- - {/* View Dropdown */} - {activeMenu === "View" && ( -
- {/* Grid */} -
toggleSelection("Grid")} - > -
- Grid -
-
- - {/* Gizmo */} -
setActiveSubMenu("View-Gizmo")} - onMouseLeave={() => setActiveSubMenu(null)} - > -
- Gizmo - - - -
-
- - {/* Gizmo Submenu */} - {activeSubMenu === "View-Gizmo" && ( -
- {/* Visibility */} -
toggleSelection("Visibility")} + {activeMenu === menu && ( +
+ {items.map((item) => + item.submenu ? ( +
-
- - {/* Cube view */} -
toggleSelection("Cube view")} - > - Cube view -
- - {/* Sphere view */} -
toggleSelection("Sphere view")} - > - Sphere view -
-
+
+ {item.label} + + + +
+ {activeSubMenu === item.label && + renderSubMenu(item.submenu, item.label)} + + ) : ( + renderMenuItem(item) + ) )}
+ )} + + ))} - {/* Zoom */} -
toggleSelection("Zoom")} - > -
- Zoom -
-
- - {/* Full Screen */} -
toggleSelection("Full Screen")} - > -
- Full Screen -
- F11 -
-
-
-
- )} -
- - {/* Version History Menu */} -
setActiveMenu("Version history")} onMouseLeave={() => { @@ -392,173 +205,27 @@ const MenuBar: React.FC = ({ setOpenMenu }) => { }} >
Version history
-
+ - {/* Export As Menu */} -
setActiveMenu("Export as...")} + onMouseEnter={() => setActiveMenu("Theme")} onMouseLeave={() => { setActiveMenu(null); setActiveSubMenu(null); }} - > -
Export as...
-
- -
setActiveMenu("theme")} - onMouseLeave={() => { - setActiveMenu(null); - setActiveSubMenu(null); - }} - onClick={() => { - handleThemeChange(); - }} + onClick={handleThemeChange} >
Theme
{savedTheme}
-
+ - {/* Apps Menu */} - {/*
setActiveMenu("Apps")} - onMouseLeave={() => { - setActiveMenu(null); - setActiveSubMenu(null); - }} - > -
- Apps - - - -
- - {activeMenu === "Apps" && ( -
-
toggleSelection("New App")} - > -
- - - New App - -
-
-
- -
toggleSelection("Work-flow Monitor")} - > -
- - - Work-flow Monitor - -
-
- -
toggleSelection("Temperature Visualizer")} - > -
- - - Temperature Visualizer - -
-
- -
toggleSelection("View all")} - > -
- - - View all - -
-
-
- )} -
*/} - - {/* Help Menu */} -
setActiveMenu("Help")} - onMouseLeave={() => { - setActiveMenu(null); - setActiveSubMenu(null); - }} - > -
- Help - - - -
- - {/* Help Dropdown */} - {activeMenu === "Help" && ( -
- {/* Shortcuts */} -
toggleSelection("Shortcuts")} - > -
- Shortcuts -
- Ctrl + Shift + ? -
-
-
- - {/* Manual */} -
toggleSelection("Manual")} - > -
- Manual -
-
- - {/* Video Tutorials */} -
toggleSelection("Video Tutorials")} - > -
- Video Tutorials -
-
- - {/* Report a bug */} -
toggleSelection("Report a bug")} - > -
- Report a bug -
-
-
- )} -
-
+ {/* Log out */} +
+
); diff --git a/app/src/styles/components/menu/menu.scss b/app/src/styles/components/menu/menu.scss index d25173c..4a27f4f 100644 --- a/app/src/styles/components/menu/menu.scss +++ b/app/src/styles/components/menu/menu.scss @@ -102,6 +102,7 @@ padding: 4px; .menu-item-container { position: relative; + width: 100%; .menu-item { padding: 4px 8px 4px 12px; border-radius: #{$border-radius-medium};