import {Atom} from '@reatom/core'; import {useAtom} from '@reatom/react'; import {Button, Checkbox as CheckboxInput, Drawer, Input, Select as SelectInput} from 'antd'; import {CheckboxChangeEvent} from 'antd/lib/checkbox'; import {SelectValue} from 'antd/lib/select'; import React, {FC, Fragment, memo, SyntheticEvent, useCallback, useEffect, useMemo} from 'react'; import {createUseStyles} from 'react-jss'; import {queryParsers} from '../../../pages/users/utils'; import {useQuery} from '../../hooks/useQuery'; import {CrudService} from '../../services/CrudService'; import {EntityMode} from '../../types/EntityModes'; export enum FormInputType { Text = 'text', Checkbox = 'checkobx', Select = 'select', } type SelectOption = { value: string; label: string; }; type FormOption = { name: string; label: string; type?: FormInputType; options?: SelectOption[]; checkboxLabel?: string; }; type Options = { entityFormAtom: Atom; service: CrudService; formOptions: FormOption[]; entityName: string; }; const AVAILABLE_CLOSE_MODES = [EntityMode.Show]; const DISABLED_FORM_MODES = [EntityMode.Show]; const useStyles = createUseStyles({ button: { marginRight: '8px', }, input: { marginBottom: '16px', width: '100%', }, }); export const createEntitySidebar = function ({ entityFormAtom, service, formOptions, entityName, }: Options): FC { return memo(() => { const {mode, id} = useQuery(queryParsers); const form = useAtom(entityFormAtom); const classes = useStyles(); useEffect(() => { service.loadEntity(id); }, [id, mode]); const handleClose = () => { service.navigate(); }; const onChangeInput = (event: SyntheticEvent) => { const {name, value} = event.currentTarget; service.loadEntityForm({ ...form, [name]: value, }); }; const onChangeCheckbox = (event: CheckboxChangeEvent) => { const {name, checked} = event.target; service.loadEntityForm({ ...form, [name!]: checked, }); }; const onChangeSelect = (name: string) => (value: SelectValue) => { if (!Array.isArray(value)) { service.loadEntityForm({ ...form, [name]: value, }); } }; const disabled = useMemo(() => !mode || DISABLED_FORM_MODES.includes(mode), [mode]); const handleCreateUser = useCallback(() => { service.createEntity(form); }, [form]); const handleSaveUser = useCallback(() => { if (id) { service.updateEntity({ ...form, id, }); } }, [form, id]); const handleCopy = useCallback(() => { service.navigate(EntityMode.Copy, id); }, [id]); const handleEdit = useCallback(() => { service.navigate(EntityMode.Edit, id); }, [id]); const handleDelete = useCallback(() => { service.removeEntity(id); }, [id]); const handleBackdrop = useCallback(() => { if (mode && AVAILABLE_CLOSE_MODES.includes(mode)) { handleClose(); } }, [mode]); const title = useMemo(() => { switch (mode) { case EntityMode.Create: return `Creating a ${entityName}`; case EntityMode.Copy: return `Coping ${entityName} "${id}"`; case EntityMode.Edit: return `Editing ${entityName} "${id}"`; case EntityMode.Show: return `Viewing ${entityName} "${id}"`; default: return `Mode "${mode}" not supported for ${entityName} form`; } }, [mode, id]); const primaryButton = useMemo(() => { switch (mode) { case EntityMode.Create: case EntityMode.Copy: return ( ); case EntityMode.Edit: return ( ); case EntityMode.Show: return ( ); default: return null; } }, [mode, classes, handleEdit, handleCreateUser, handleSaveUser]); const renderFooter = useMemo(() => { return (
{primaryButton} {mode === EntityMode.Show && ( )}
); }, [primaryButton, mode, classes, handleCopy, handleDelete]); return (
{formOptions.map(({name, label, type = FormInputType.Text, options, checkboxLabel}) => { return (
{type === FormInputType.Checkbox && ( {checkboxLabel ?? label} )} {type === FormInputType.Select && ( {(options ?? []).map(option => ( {option.label} ))} )} {type === FormInputType.Text && ( )}
); })}
); }); };