114 lines
3.2 KiB
JavaScript
114 lines
3.2 KiB
JavaScript
import React, { memo, useEffect, useRef, useLayoutEffect, useState, useCallback, useMemo } from 'react';
|
|
import { FormControl, Select, MenuItem } from '@mui/material';
|
|
import { useRealtime } from '../../contexts/RealtimeContext';
|
|
|
|
const EDITOR_STYLES = {
|
|
position: 'absolute',
|
|
zIndex: 12,
|
|
top: 0,
|
|
};
|
|
|
|
const VspDropdownEditCell = memo(({ refCell, onChange, disabled, value, table }) => {
|
|
const { endEditing: contextEndEditing, vspOptions } = useRealtime();
|
|
|
|
const [selectedValue, setSelectedValue] = useState(() => value ?? '');
|
|
const [position, setPosition] = useState();
|
|
const [open, setOpen] = useState(false);
|
|
|
|
const refFinished = useRef(false);
|
|
|
|
useEffect(() => {
|
|
const timer = setTimeout(() => {
|
|
setOpen(true);
|
|
}, 80);
|
|
return () => clearTimeout(timer);
|
|
}, []);
|
|
|
|
useLayoutEffect(() => {
|
|
if (!refCell?.current) return;
|
|
|
|
const td = refCell.current.offsetParent;
|
|
const tr = td?.offsetParent;
|
|
|
|
if (td && tr) {
|
|
setPosition({
|
|
left: td.offsetLeft,
|
|
width: td.offsetWidth,
|
|
translateY: tr.style.transform || '',
|
|
});
|
|
}
|
|
}, [refCell]);
|
|
|
|
const finishEditing = useCallback(() => {
|
|
if (refFinished.current) return;
|
|
refFinished.current = true;
|
|
table.setEditingCell(null);
|
|
const editingCell = table.getState().editingCell;
|
|
if (editingCell) {
|
|
contextEndEditing?.(editingCell.row, editingCell.column);
|
|
}
|
|
}, [table, contextEndEditing]);
|
|
|
|
const handleSelectChange = useCallback((e) => {
|
|
const val = e.target.value;
|
|
if (val == null || val === '') return;
|
|
refFinished.current = true;
|
|
setSelectedValue(val);
|
|
onChange?.(val);
|
|
const editingCell = table.getState().editingCell;
|
|
if (editingCell) {
|
|
contextEndEditing?.(editingCell.row, editingCell.column);
|
|
}
|
|
}, [onChange, table, contextEndEditing]);
|
|
|
|
const handleSelectClose = useCallback((_event, reason) => {
|
|
if (reason === 'selectOption') return;
|
|
finishEditing();
|
|
}, [finishEditing]);
|
|
|
|
const editorStyles = useMemo(() => ({
|
|
...EDITOR_STYLES,
|
|
left: position?.left || 0,
|
|
width: position?.width || 0,
|
|
transform: position?.translateY || 0,
|
|
}), [position]);
|
|
|
|
return (
|
|
<tr>
|
|
<td>
|
|
{position &&
|
|
<div style={editorStyles}>
|
|
<FormControl fullWidth size="small">
|
|
<Select
|
|
value={selectedValue}
|
|
onChange={handleSelectChange}
|
|
open={open}
|
|
onClose={handleSelectClose}
|
|
displayEmpty
|
|
disabled={disabled}
|
|
MenuProps={{
|
|
anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
|
|
transformOrigin: { vertical: 'top', horizontal: 'left' },
|
|
}}
|
|
>
|
|
<MenuItem value="" disabled>
|
|
Выберите ВСП
|
|
</MenuItem>
|
|
{vspOptions.map((option) => (
|
|
<MenuItem key={option.id} value={option.id}>
|
|
{option.registration_number}
|
|
</MenuItem>
|
|
))}
|
|
</Select>
|
|
</FormControl>
|
|
</div>
|
|
}
|
|
</td>
|
|
</tr>
|
|
);
|
|
});
|
|
|
|
VspDropdownEditCell.displayName = 'VspDropdownEditCell';
|
|
|
|
export default VspDropdownEditCell;
|