| import React, { useEffect } from 'react'; | 
| import { useForm, useWatch, Controller } from 'react-hook-form'; | 
| import { | 
|     Box, | 
|     Grid, | 
|     Typography, | 
|     TextField, | 
|     Card, | 
|     CardContent, | 
|     Button, | 
|     Select, | 
|     MenuItem, | 
|     useTheme, | 
|     FormControl, | 
|     Stack, | 
|     Divider, | 
|     Drawer, | 
|     IconButton, | 
|     Switch, | 
|     FormControlLabel, | 
|     FormLabel, | 
|     ToggleButtonGroup, | 
|     ToggleButton, | 
| } from '@mui/material'; | 
| import CloseIcon from '@mui/icons-material/Close'; | 
| import { useTranslate } from 'react-admin'; | 
| import * as Tool from '../tool'; | 
| import { PAGE_DRAWER_WIDTH } from '@/config/setting'; | 
| import { | 
|     DEVICE_TYPE, | 
| } from '../constants'; | 
| import { useNotification } from '../Notification'; | 
|   | 
| const incrementOptionsMap = { | 
|     [DEVICE_TYPE.SHELF]: [ | 
|         { value: 'row', label: 'page.map.settings.config.shelf.row' }, | 
|         { value: 'bay', label: 'page.map.settings.config.shelf.bay' }, | 
|     ], | 
|     [DEVICE_TYPE.CHARGE]: [ | 
|         { value: 'no', label: 'page.map.settings.config.base.no' }, | 
|     ], | 
|     [DEVICE_TYPE.STATION]: [ | 
|         { value: 'no', label: 'page.map.settings.config.base.no' }, | 
|     ], | 
|     [DEVICE_TYPE.POINT]: [ | 
|         { value: 'no', label: 'page.map.settings.config.base.no' }, | 
|     ], | 
| }; | 
|   | 
|   | 
| const validateIncrement = (value, deviceType, sprite, translate) => { | 
|     if (!value) { | 
|         return true; | 
|     } | 
|     switch (deviceType) { | 
|         case DEVICE_TYPE.SHELF: | 
|             if (!sprite?.data?.row || !sprite?.data?.bay) { | 
|                 return translate('page.map.settings.map.copy.valid.shelf'); | 
|             } | 
|             break; | 
|         default: | 
|             if (!sprite?.data?.no) { | 
|                 return translate('page.map.settings.map.copy.valid.common'); | 
|             } | 
|             break; | 
|     } | 
|     return true; | 
| }; | 
|   | 
| const getDefaultFormValues = (value = {}) => ({ | 
|     copyDirect: value.copyDirect || '', | 
|     copyCount: value.copyCount || '', | 
|     gap: 0.0, | 
|     autoIncrement: false, | 
|     incrementMode: 'ascending', | 
|     incrementValue: undefined, | 
| }); | 
|   | 
| const CopyDrawer = (props) => { | 
|     const { | 
|         open, | 
|         onCancel, | 
|         sprite, | 
|         value, | 
|         width = PAGE_DRAWER_WIDTH, | 
|         handleOnCopy, | 
|         setLastCopiedSprites, | 
|         setSpriteSettings, | 
|     } = props; | 
|     const notify = useNotification(); | 
|     const translate = useTranslate(); | 
|     const theme = useTheme(); | 
|     const themeMode = theme.palette.mode; | 
|   | 
|     const deviceType = sprite?.data?.type; | 
|     const incrementOptions = incrementOptionsMap[deviceType] | 
|   | 
|     const { control, handleSubmit, reset, watch, setValue, formState: { errors } } = useForm({ | 
|         defaultValues: getDefaultFormValues(value), | 
|     }); | 
|   | 
|     const autoIncrement = useWatch({ control, name: 'autoIncrement' }); | 
|     const incrementValue = useWatch({ control, name: 'incrementValue' }); | 
|   | 
|     useEffect(() => { | 
|         if (sprite && value && Object.keys(value).length > 0) { | 
|             reset(getDefaultFormValues(value)); | 
|         } | 
|     }, [sprite, value, reset, incrementOptions, setValue]); | 
|   | 
|     useEffect(() => { | 
|         if (autoIncrement && incrementOptions && incrementOptions.length > 0) { | 
|             if (!incrementValue) { | 
|                 setValue('incrementValue', incrementOptions[0].value); | 
|             } | 
|         } else { | 
|             setValue('incrementValue', undefined); | 
|         } | 
|     }, [autoIncrement, incrementOptions, setValue]); | 
|   | 
|     const handleClose = () => { | 
|         onCancel(); | 
|     } | 
|   | 
|     const onFormSubmit = (data) => { | 
|         if (!sprite || !data || Object.keys(data).length === 0) { | 
|             return; | 
|         } | 
|   | 
|         const { copyCount, copyDirect, gap, autoIncrement, incrementMode, incrementValue } = data; | 
|         const copiedSprites = []; | 
|   | 
|         const adjustPosition = (sprite, direction, gap, index) => { | 
|             const factor = index + 1; | 
|             switch (direction) { | 
|                 case 'left': | 
|                     sprite.position.x -= factor * (gap + sprite.width); | 
|                     break; | 
|                 case 'right': | 
|                     sprite.position.x += factor * (gap + sprite.width); | 
|                     break; | 
|                 case 'up': | 
|                     sprite.position.y -= factor * (gap + sprite.height); | 
|                     break; | 
|                 case 'down': | 
|                     sprite.position.y += factor * (gap + sprite.height); | 
|                     break; | 
|                 default: | 
|                     break; | 
|             } | 
|         }; | 
|   | 
|         const incrementSpriteData = (copiedSprite, index) => { | 
|             const incrementAmount = incrementMode === 'descending' ? -(index + 1) : index + 1; | 
|             switch (deviceType) { | 
|                 case DEVICE_TYPE.SHELF: | 
|                     if (incrementValue === 'row') { | 
|                         copiedSprite.data.row = sprite.data.row + incrementAmount; | 
|                     } | 
|                     if (incrementValue === 'bay') { | 
|                         copiedSprite.data.bay = sprite.data.bay + incrementAmount; | 
|                     } | 
|                     if (copiedSprite.data.row && copiedSprite.data.bay) { | 
|                         copiedSprite.data.no = `${copiedSprite.data.row}-${copiedSprite.data.bay}`; | 
|                     } | 
|                     break; | 
|                 default: | 
|                     if (incrementValue === 'no') { | 
|                         copiedSprite.data.no = Tool.incrementSpriteNo(sprite.data.no, incrementAmount); | 
|                     } | 
|                     break; | 
|             } | 
|         }; | 
|   | 
|         for (let i = 0; i < copyCount; i++) { | 
|             const copiedSprite = Tool.copySprite(sprite); | 
|   | 
|             adjustPosition(copiedSprite, copyDirect, gap, i); | 
|   | 
|             // auto-increment-value | 
|             if (autoIncrement && deviceType) { | 
|                 incrementSpriteData(copiedSprite, i); | 
|             } | 
|   | 
|             Tool.getMapContainer().addChild(copiedSprite); | 
|             Tool.beSettings(copiedSprite, setSpriteSettings); | 
|             copiedSprites.push(copiedSprite); | 
|         } | 
|   | 
|         setLastCopiedSprites(copiedSprites); | 
|         onCancel(); | 
|         handleOnCopy?.(data); | 
|         notify.info(translate('common.response.success')); | 
|     }; | 
|   | 
|     return ( | 
|         <> | 
|             <Drawer | 
|                 variant="persistent" | 
|                 open={open} | 
|                 anchor="right" | 
|                 onClose={handleClose} | 
|                 sx={{ zIndex: 100, opacity: 1 }} | 
|             > | 
|                 {(open) && ( | 
|                     <Box pt={12} width={{ xs: '100vW', sm: width }} height={'calc(100vh - 200px);'} mt={{ xs: 2, sm: 1 }} sx={{ | 
|                     }}> | 
|                         <Stack direction="row" p={2}> | 
|                             <Typography variant="h6" flex="1"> | 
|                                 {translate('page.map.settings.map.copy.title')} | 
|                             </Typography> | 
|                             <IconButton onClick={handleClose} size="small"> | 
|                                 <CloseIcon /> | 
|                             </IconButton> | 
|                         </Stack> | 
|   | 
|                         <Box p={3}> | 
|                             <Card sx={{ | 
|                                 p: 2, | 
|                                 transition: '0.3s', | 
|                                 boxShadow: themeMode === 'light' | 
|                                     ? '0px 2px 8px rgba(0, 0, 0, 0.1)' | 
|                                     : '0px 2px 2px rgba(255, 255, 255, 0.1)', | 
|                                 '&:hover': { | 
|                                     boxShadow: themeMode === 'light' | 
|                                         ? '0px 4px 16px rgba(0, 0, 0, 0.2)' | 
|                                         : '0px 4px 8px rgba(255, 255, 255, 0.2)', | 
|                                 }, | 
|                                 borderRadius: '8px', | 
|                             }}> | 
|                                 <CardContent> | 
|                                     <Box component="form" onSubmit={handleSubmit(onFormSubmit)} noValidate sx={{ mt: 0 }}> | 
|                                         <Grid container spacing={1.4}> | 
|                                             <Grid item xs={6}> | 
|                                                 <Controller | 
|                                                     name="copyDirect" | 
|                                                     control={control} | 
|                                                     render={({ field }) => ( | 
|                                                         <TextField | 
|                                                             {...field} | 
|                                                             label={translate('page.map.settings.map.copy.direction')} | 
|                                                             InputProps={{ | 
|                                                                 readOnly: true, | 
|                                                             }} | 
|                                                             fullWidth | 
|                                                         /> | 
|                                                     )} | 
|                                                 /> | 
|                                             </Grid> | 
|                                             <Grid item xs={6}> | 
|                                                 <Controller | 
|                                                     name="copyCount" | 
|                                                     control={control} | 
|                                                     render={({ field }) => ( | 
|                                                         <TextField | 
|                                                             {...field} | 
|                                                             label={translate('page.map.settings.map.copy.count')} | 
|                                                             InputProps={{ | 
|                                                                 readOnly: true, | 
|                                                             }} | 
|                                                             fullWidth | 
|                                                         /> | 
|                                                     )} | 
|                                                 /> | 
|                                             </Grid> | 
|   | 
|                                             <Grid item xs={12}> | 
|                                                 <Controller | 
|                                                     name="gap" | 
|                                                     control={control} | 
|                                                     render={({ field }) => ( | 
|                                                         <TextField | 
|                                                             {...field} | 
|                                                             label={translate('page.map.settings.map.copy.field.gap')} | 
|                                                             type="number" | 
|                                                             sx={{ width: '50%' }} | 
|                                                             fullWidth | 
|                                                             inputProps={{ | 
|                                                                 // min: 0, | 
|                                                                 step: 1, | 
|                                                             }} | 
|                                                             onChange={(e) => { | 
|                                                                 field.onChange(e.target.value === '' ? '' : Number(e.target.value)); | 
|                                                             }} | 
|                                                         /> | 
|                                                     )} | 
|                                                 /> | 
|                                             </Grid> | 
|   | 
|                                             <Grid item xs={12} mt={2} mb={1}> | 
|                                                 <Divider /> | 
|                                             </Grid> | 
|   | 
|                                             <Grid item xs={12}> | 
|                                                 <Controller | 
|                                                     name="autoIncrement" | 
|                                                     control={control} | 
|                                                     rules={{ validate: (value) => validateIncrement(value, deviceType, sprite, translate) }} | 
|                                                     render={({ field }) => ( | 
|                                                         <FormControlLabel | 
|                                                             control={ | 
|                                                                 <Switch | 
|                                                                     {...field} | 
|                                                                     checked={field.value || false} | 
|                                                                     onChange={(e) => field.onChange(e.target.checked)} | 
|                                                                 /> | 
|                                                             } | 
|                                                             label={translate('page.map.settings.map.copy.field.autoIncrement')} | 
|                                                         /> | 
|                                                     )} | 
|                                                 /> | 
|                                                 {errors.autoIncrement && ( | 
|                                                     <Typography color="error"> | 
|                                                         {errors.autoIncrement.message} | 
|                                                     </Typography> | 
|                                                 )} | 
|                                             </Grid> | 
|   | 
|                                             {(!!incrementOptions?.length && autoIncrement) && ( | 
|                                                 <Grid item xs={12}> | 
|                                                     <FormControl fullWidth> | 
|                                                         <FormLabel sx={{ mb: 1 }}> | 
|                                                             {translate('page.map.settings.map.copy.field.incrementValue')} | 
|                                                         </FormLabel> | 
|                                                         <Controller | 
|                                                             name='incrementValue' | 
|                                                             control={control} | 
|                                                             render={({ field }) => ( | 
|                                                                 <ToggleButtonGroup | 
|                                                                     {...field} | 
|                                                                     value={field.value} | 
|                                                                     exclusive | 
|                                                                     onChange={(event, value) => { | 
|                                                                         if (value !== null) { | 
|                                                                             field.onChange(value); | 
|                                                                         } | 
|                                                                     }} | 
|                                                                     fullWidth | 
|                                                                 > | 
|                                                                     {incrementOptions.map((option, idx) => ( | 
|                                                                         <ToggleButton key={idx} value={option.value}> | 
|                                                                             {translate(option.label)} | 
|                                                                         </ToggleButton> | 
|                                                                     ))} | 
|                                                                 </ToggleButtonGroup> | 
|                                                             )} | 
|                                                         /> | 
|                                                     </FormControl> | 
|                                                 </Grid> | 
|                                             )} | 
|   | 
|                                             {autoIncrement && ( | 
|                                                 <Grid item xs={12}> | 
|                                                     <FormControl fullWidth> | 
|                                                         <FormLabel sx={{ | 
|                                                             mb: 1 | 
|                                                         }}> | 
|                                                             {translate('page.map.settings.map.copy.field.incrementMode')} | 
|                                                         </FormLabel> | 
|                                                         <Controller | 
|                                                             name="incrementMode" | 
|                                                             control={control} | 
|                                                             render={({ field }) => ( | 
|                                                                 <ToggleButtonGroup | 
|                                                                     {...field} | 
|                                                                     value={field.value} | 
|                                                                     exclusive | 
|                                                                     onChange={(event, value) => { | 
|                                                                         if (value !== null) { | 
|                                                                             field.onChange(value); | 
|                                                                         } | 
|                                                                     }} | 
|                                                                     fullWidth | 
|                                                                 > | 
|                                                                     <ToggleButton value="ascending"> | 
|                                                                         {translate('page.map.settings.map.copy.field.ascend')} | 
|                                                                     </ToggleButton> | 
|                                                                     <ToggleButton value="descending"> | 
|                                                                         {translate('page.map.settings.map.copy.field.descend')} | 
|                                                                     </ToggleButton> | 
|                                                                 </ToggleButtonGroup> | 
|                                                             )} | 
|                                                         /> | 
|                                                     </FormControl> | 
|                                                 </Grid> | 
|                                             )} | 
|   | 
|                                             <Grid item xs={12} mt={2}> | 
|                                                 <Divider /> | 
|                                             </Grid> | 
|   | 
|                                             <Grid item xs={12} mt={2}> | 
|                                                 <Stack direction="row" spacing={2}> | 
|                                                     <Button variant="contained" color="primary" type="submit"> | 
|                                                         {translate('ra.action.confirm')} | 
|                                                     </Button> | 
|                                                 </Stack> | 
|                                             </Grid> | 
|   | 
|                                         </Grid> | 
|                                     </Box> | 
|                                 </CardContent> | 
|                             </Card> | 
|                         </Box> | 
|                     </Box> | 
|                 )} | 
|             </Drawer> | 
|         </> | 
|     ) | 
| } | 
|   | 
| export default CopyDrawer; |