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;
|