import { FormEvent, useEffect } from 'react'; import { useSearchParams } from 'react-router-dom'; import { Button, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerFooter, DrawerHeader, DrawerOverlay, useDisclosure, } from '@chakra-ui/react'; import ParamInput from './ParamInput'; import { isSection, ViewOption } from './types'; import style from './ViewParamsEditor.module.scss'; type ViewParamsObj = { [key: string]: string | FormDataEntryValue }; /** * Makes a new URLSearchParams object from the given params object */ const getURLSearchParamsFromObj = (paramsObj: ViewParamsObj, paramFields: ViewOption[]) => { const newSearchParams = new URLSearchParams(); // Convert paramFields to an object that contains default values const defaultValues: Record = {}; paramFields.forEach((option) => { if (!isSection(option)) { defaultValues[option.id] = String(option.defaultValue); } // extract persisted values if ('type' in option && option.type === 'persist') { newSearchParams.set(option.id, option.value); } }); // compare which values are different from the default values Object.entries(paramsObj).forEach(([id, value]) => { if (typeof value === 'string' && value.length && defaultValues[id] !== value) { newSearchParams.set(id, value); } }); return newSearchParams; }; interface EditFormDrawerProps { viewOptions: ViewOption[]; } // TODO: this is a good candidate for memoisation, but needs the paramFields to be stable export default function ViewParamsEditor({ viewOptions }: EditFormDrawerProps) { const [searchParams, setSearchParams] = useSearchParams(); const { isOpen, onClose, onOpen } = useDisclosure(); useEffect(() => { const isEditing = searchParams.get('edit'); if (isEditing === 'true') { return onOpen(); } }, [searchParams, onOpen]); const handleClose = () => { searchParams.delete('edit'); setSearchParams(searchParams); onClose(); }; const resetParams = () => { setSearchParams(); onClose(); }; const onParamsFormSubmit = (formEvent: FormEvent) => { formEvent.preventDefault(); const newParamsObject = Object.fromEntries(new FormData(formEvent.currentTarget)); const newSearchParams = getURLSearchParamsFromObj(newParamsObject, viewOptions); setSearchParams(newSearchParams); onClose(); }; return ( Customise
{viewOptions.map((option) => { if (isSection(option)) { return (
{option.section}
); } if (option.type === 'persist') { return null; } return (
); })}
); }