import { DrawerContent, DrawerPortal, DrawerRoot } from '@liam-hq/ui' import { err, ok, type Result } from 'neverthrow' import { createContext, type FC, type PropsWithChildren, type RefObject, useCallback, useContext, useEffect, useMemo, useRef, } from 'react' import { useSchemaOrThrow, useUserEditingOrThrow } from '../../../../../stores' import { TableDetail } from '../../ERDContent/components/TableNode/TableDetail' import styles from './TableDetailDrawer.module.css' type TableDetailDrawerContextValue = { drawerRef: RefObject } const TableDetailDrawerContext = createContext(null) const useTableDetailDrawerContext = (): Result< TableDetailDrawerContextValue, Error > => { const context = useContext(TableDetailDrawerContext) if (!context) { return err( new Error( 'useTableDetailDrawerContext must be used within TableDetailDrawerRoot', ), ) } return ok(context) } const useTableDetailDrawerContextOrThrow = (): TableDetailDrawerContextValue => { const result = useTableDetailDrawerContext() if (result.isErr()) throw result.error return result.value } export const TableDetailDrawerRoot: FC = ({ children }) => { const { activeTableName, setActiveTableName } = useUserEditingOrThrow() const drawerRef = useRef(null) const { current } = useSchemaOrThrow() const open = Object.keys(current.tables).length > 0 && activeTableName !== undefined const handleClose = useCallback(() => { setActiveTableName(null) }, [setActiveTableName]) useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (!(event.target instanceof Element)) { return } if ( drawerRef.current && !drawerRef.current.contains(event.target) && open ) { event.preventDefault() event.stopPropagation() handleClose() } } if (open) { document.addEventListener('mousedown', handleClickOutside, true) } return () => { document.removeEventListener('mousedown', handleClickOutside, true) } }, [open, handleClose]) return ( {children} ) } export const TableDetailDrawer: FC = () => { const { drawerRef } = useTableDetailDrawerContextOrThrow() const { current, merged } = useSchemaOrThrow() const { showDiff, activeTableName } = useUserEditingOrThrow() const schema = useMemo(() => { return showDiff && merged ? merged : current }, [showDiff, merged, current]) const table = schema.tables[activeTableName ?? ''] const ariaDescribedBy = table?.comment == null ? { 'aria-describedby': undefined, } : {} return ( {table !== undefined && ( )} ) }