import { useContext, useMemo } from 'react' import PropTypes from 'prop-types' import { Button, Dropdown, Flex } from 'antd' import { useNavigate } from 'react-router-dom' import { ElectronContext } from '../context/ElectronContext' import { useAppUpdateContext } from '../context/AppUpdateContext' import { getSidebarMenuSections } from '../../../database/Sidebars' import FarmControlLogoSmall from '../../Logos/FarmControlLogoSmall' const runEditCommand = (command) => { try { document.execCommand(command) } catch (error) { console.warn( `[WindowAppMenu] Failed to run edit command: ${command}`, error ) } } const mapSidebarItemsToMenuItems = (items = [], navigate) => items .map((item, index) => { if (item?.type === 'divider') { return { type: 'divider', key: `divider-${index}` } } if (item?.children?.length) { return { key: item.key || `group-${item.label}-${index}`, label: item.label, children: mapSidebarItemsToMenuItems(item.children, navigate) } } if (item?.path) { return { key: item.path, label: item.label, onClick: () => navigate(item.path) } } return { key: item.key || `disabled-${item.label}-${index}`, label: item.label, disabled: true } }) .filter(Boolean) const MenuButton = ({ label, items, logo }) => ( ) MenuButton.propTypes = { label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired, items: PropTypes.array.isRequired, logo: PropTypes.bool } const WindowAppMenu = () => { const navigate = useNavigate() const { handleWindowControl } = useContext(ElectronContext) const { checkForUpdates } = useAppUpdateContext() const includeDev = import.meta.env.DEV const viewSections = useMemo( () => getSidebarMenuSections({ includeDev }), [includeDev] ) const appMenuItems = useMemo( () => [ { key: 'about', label: 'About Farm Control', onClick: () => navigate('/dashboard/management/about') }, { type: 'divider' }, { key: 'check-for-updates', label: 'Check For Updates...', onClick: () => checkForUpdates() }, { type: 'divider' }, { key: 'quit', label: 'Quit Farm Control', onClick: () => handleWindowControl('quit') } ], [checkForUpdates, handleWindowControl, navigate] ) const fileMenuItems = useMemo( () => [ { key: 'close', label: 'Close Window', onClick: () => handleWindowControl('close') } ], [handleWindowControl] ) const editMenuItems = useMemo( () => [ { key: 'undo', label: 'Undo', onClick: () => runEditCommand('undo') }, { key: 'redo', label: 'Redo', onClick: () => runEditCommand('redo') }, { type: 'divider' }, { key: 'cut', label: 'Cut', onClick: () => runEditCommand('cut') }, { key: 'copy', label: 'Copy', onClick: () => runEditCommand('copy') }, { key: 'paste', label: 'Paste', onClick: () => runEditCommand('paste') }, { key: 'pasteAndMatchStyle', label: 'Paste and Match Style', onClick: () => runEditCommand('paste') }, { key: 'delete', label: 'Delete', onClick: () => runEditCommand('delete') }, { type: 'divider' }, { key: 'selectAll', label: 'Select All', onClick: () => runEditCommand('selectAll') } ], [] ) const viewMenuItems = useMemo(() => { const sectionItems = viewSections.length > 0 ? viewSections.map((section) => ({ key: `view-section-${section.key}`, label: section.label, children: mapSidebarItemsToMenuItems(section.items || [], navigate) })) : [ { key: 'no-sidebar-items', label: 'No sidebar items available', disabled: true } ] if (!includeDev) { return sectionItems } return [ ...sectionItems, { type: 'divider' }, { key: 'toggle-devtools', label: 'Toggle Developer Tools', onClick: () => handleWindowControl('toggle-devtools') } ] }, [handleWindowControl, includeDev, navigate, viewSections]) const windowMenuItems = useMemo( () => [ { key: 'minimize', label: 'Minimize', onClick: () => handleWindowControl('minimize') }, { key: 'zoom', label: 'Zoom', onClick: () => handleWindowControl('maximize') } ], [handleWindowControl] ) const menus = useMemo( () => [ { key: 'app', label: 'Farm Control', items: appMenuItems }, { key: 'file', label: 'File', items: fileMenuItems }, { key: 'edit', label: 'Edit', items: editMenuItems }, { key: 'view', label: 'View', items: viewMenuItems }, { key: 'window', label: 'Window', items: windowMenuItems } ], [appMenuItems, editMenuItems, fileMenuItems, viewMenuItems, windowMenuItems] ) return ( {menus.map((menu) => { if (menu.key === 'app') { return ( } items={menu.items} /> ) } return ( ) })} ) } export default WindowAppMenu