diff options
Diffstat (limited to 'components/contextmenu.tsx')
-rw-r--r-- | components/contextmenu.tsx | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/components/contextmenu.tsx b/components/contextmenu.tsx new file mode 100644 index 0000000..755bd9d --- /dev/null +++ b/components/contextmenu.tsx @@ -0,0 +1,237 @@ +import React, { useRef } from 'react' +import { + Box, + Menu, + MenuItem, + MenuList, + MenuGroup, + MenuItemOption, + MenuOptionGroup, + Heading, + MenuDivider, + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalFooter, + ModalBody, + ModalCloseButton, + useDisclosure, + Button, + PopoverTrigger, + PopoverContent, + Popover, + Flex, + PopoverBody, + PopoverCloseButton, + PopoverArrow, + PopoverHeader, + PopoverFooter, + Portal, + Text, + VStack, +} from '@chakra-ui/react' +import { + DeleteIcon, + EditIcon, + CopyIcon, + AddIcon, + ViewIcon, + ExternalLinkIcon, + ChevronRightIcon, + PlusSquareIcon, +} from '@chakra-ui/icons' + +import { OrgRoamGraphReponse, OrgRoamLink, OrgRoamNode } from '../api' + +export default interface ContextMenuProps { + background: Boolean + node?: OrgRoamNode + nodeType?: string + coordinates: number[] + handleLocal: (node: OrgRoamNode, add: string) => void + openNodeInEmacs: (node: OrgRoamNode) => void + menuClose: () => void + scope: { nodeIds: string[] } + deleteNodeInEmacs: (node: OrgRoamNode) => void + createNodeInEmacs: (node: OrgRoamNode) => void +} + +export const ContextMenu = (props: ContextMenuProps) => { + const { + background, + node, + nodeType, + coordinates, + handleLocal, + menuClose, + scope, + openNodeInEmacs, + deleteNodeInEmacs, + createNodeInEmacs, + } = props + const { isOpen, onOpen, onClose } = useDisclosure() + const copyRef = useRef<any>() + return ( + <> + <Box + position="absolute" + zIndex="overlay" + left={coordinates[0] + 10} + top={coordinates[1] - 10} + padding={5} + > + <Menu closeOnBlur={false} defaultIsOpen onClose={() => menuClose()}> + <MenuList zIndex="overlay" bgColor="alt.100" borderColor="gray.500" maxWidth="xs"> + {node && ( + <> + <Heading size="sm" isTruncated px={3} py={1}> + {node.title} + </Heading> + <MenuDivider borderColor="gray.500" /> + </> + )} + {scope.nodeIds.length !== 0 && ( + <> + <MenuItem onClick={() => handleLocal(node!, 'add')} icon={<PlusSquareIcon />}> + Expand local graph at node + </MenuItem> + <MenuItem onClick={() => handleLocal(node!, 'replace')} icon={<ViewIcon />}> + Open local graph for this node + </MenuItem> + </> + )} + {!node?.properties.FILELESS ? ( + <MenuItem icon={<EditIcon />} onClick={() => openNodeInEmacs(node as OrgRoamNode)}> + Open in Emacs + </MenuItem> + ) : ( + <MenuItem icon={<AddIcon />} onClick={() => createNodeInEmacs(node)}> + Create node + </MenuItem> + )} + {node?.properties.ROAM_REFS && ( + <MenuItem icon={<ExternalLinkIcon />}>Open in Zotero</MenuItem> + )} + {scope.nodeIds.length === 0 && ( + <MenuItem icon={<ViewIcon />} onClick={() => handleLocal(node!, 'replace')}> + Open local graph + </MenuItem> + )} + {/* Doesn't work at the moment + <MenuItem closeOnSelect={false} closeOnBlur={false}> + <Box _hover={{ bg: 'gray.200' }} width="100%"> + <Popover + initialFocusRef={copyRef} + trigger="hover" + placement="right-start" + gutter={0} + > + <PopoverTrigger> + <MenuItem closeOnSelect={false} icon={<CopyIcon />}> + <Flex justifyContent="space-between" alignItems="center"> + Copy... + <ChevronRightIcon /> + </Flex> + </MenuItem> + </PopoverTrigger> + <PopoverContent width={100}> + <Menu defaultIsOpen closeOnBlur={false} closeOnSelect={false}> + <MenuList bg="alt.100" zIndex="popover"> + <MenuItem ref={copyRef}>ID</MenuItem> + <MenuItem>Title</MenuItem> + <MenuItem>File path</MenuItem> + </MenuList> + </Menu> + </PopoverContent> + </Popover> + </Box> + </MenuItem> */} + {node?.level === 0 && ( + <MenuItem + closeOnSelect={false} + icon={<DeleteIcon color="red.500" />} + color="red.500" + onClick={onOpen} + > + Permenantly delete note + </MenuItem> + )} + </MenuList> + </Menu> + </Box> + <Modal isCentered isOpen={isOpen} onClose={onClose}> + <ModalOverlay /> + <ModalContent zIndex="popover"> + <ModalHeader>Delete node?</ModalHeader> + <ModalCloseButton /> + <ModalBody> + <VStack spacing={4} display="flex" alignItems="flex-start"> + <Text>This will permanently delete your note:</Text> + <Text fontWeight="bold">{node?.title}</Text> + {node?.level !== 0 && ( + <Text> + This will only delete the from this heading until but not including the next node. + Your parent file and all other nodes will not be deleted. + </Text> + )} + <Text>Are you sure you want to do continue?</Text> + </VStack> + </ModalBody> + <ModalFooter> + <Button + mr={3} + onClick={() => { + console.log('closing') + onClose() + menuClose() + }} + > + Cancel + </Button> + <Button + variant="link" + colorScheme="red" + ml={3} + onClick={() => { + console.log('aaaaa') + deleteNodeInEmacs(node!) + onClose() + menuClose() + }} + > + Delete node + </Button> + </ModalFooter> + </ModalContent> + </Modal> + </> + ) +} + +/* <Box> + * <Popover> + * <PopoverTrigger> + * Permenantly delete node + * </MenuItem> + * </PopoverTrigger> + * <PopoverContent borderColor="red.500" _focus={{}}> + * <PopoverHeader fontWeight="semibold">Delete Node?</PopoverHeader> + * <PopoverArrow /> + * <PopoverCloseButton onClick={onClose} /> + * <PopoverBody> + * This will permanently delete your node! Are you sure you want to do this? + * </PopoverBody> + * <PopoverFooter> + * <Flex justifyContent="space-between" py={1}> + * <Button colorScheme="gray" bg="gray.800" color="alt.100" width={30} onClick={onClose}> + * Nah + * </Button> + * <Button colorScheme="red" variant="link" onClick={onClose}> + * Delete node + * </Button> + * </Flex> + * </PopoverFooter> + * </PopoverContent> + * </Popover> + * </Box> */ |