diff --git a/src/Components/Layout/SettingsComponents/RangeEditor.jsx b/src/Components/Layout/SettingsComponents/RangeEditor.jsx new file mode 100644 index 0000000..d0c3d65 --- /dev/null +++ b/src/Components/Layout/SettingsComponents/RangeEditor.jsx @@ -0,0 +1,153 @@ +import React, { useState, useEffect } from 'react'; +import { + Box, + Button, + TextField, + IconButton, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Paper, + Typography, + Divider, + Select, + MenuItem, + FormControl, + InputLabel +} from '@mui/material'; +import AddIcon from '@mui/icons-material/Add'; +import DeleteIcon from '@mui/icons-material/Delete'; + +const RangeEditor = ({ metric, onSave, onCancel }) => { + const [ranges, setRanges] = useState([...metric.ranges]); + const [newRange, setNewRange] = useState({ min: 0, max: 0, status: 1 }); + + const handleAddRange = () => { + if (newRange.min >= newRange.max) { + alert('Минимальное значение должно быть меньше максимального'); + return; + } + + // Проверка на пересечение с существующими диапазонами + const overlaps = ranges.some(range => + (newRange.min >= range.min && newRange.min <= range.max) || + (newRange.max >= range.min && newRange.max <= range.max) + ); + + if (overlaps) { + alert('Диапазон пересекается с существующим'); + return; + } + + setRanges([...ranges, newRange].sort((a, b) => a.min - b.min)); + setNewRange({ min: 0, max: 0, status: 1 }); + }; + + const handleDeleteRange = (index) => { + const newRanges = [...ranges]; + newRanges.splice(index, 1); + setRanges(newRanges); + }; + + const handleSave = () => { + onSave({ + ...metric, + ranges + }); + }; + + return ( + + + Редактирование диапазонов для: {metric.name} + + + + + + + Минимум + Максимум + Статус + Действия + + + + {ranges.map((range, index) => ( + + {range.min} + {range.max} + {range.status} + + handleDeleteRange(index)}> + + + + + ))} + +
+
+ + + + + Добавить новый диапазон + + + + setNewRange({ ...newRange, min: parseInt(e.target.value) || 0 })} + size="small" + /> + + setNewRange({ ...newRange, max: parseInt(e.target.value) || 0 })} + size="small" + /> + + + Статус + + + + + + + + + + +
+ ); +}; + +export default RangeEditor; \ No newline at end of file diff --git a/src/Components/Layout/SettingsModal.jsx b/src/Components/Layout/SettingsModal.jsx new file mode 100644 index 0000000..f9f7b6f --- /dev/null +++ b/src/Components/Layout/SettingsModal.jsx @@ -0,0 +1,196 @@ +// components/SettingsModal.jsx +import React, { useState, useEffect } from 'react'; +import { + Dialog, + DialogTitle, + DialogContent, + DialogActions, + Button, + Tabs, + Tab, + Box, + Typography, + IconButton, + styled, + CircularProgress, + Slide, + Snackbar, + Alert +} from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; +import SaveIcon from '@mui/icons-material/Save'; + +const Transition = React.forwardRef(function Transition(props, ref) { + return ; +}); + +const StyledDialog = styled(Dialog)(({ theme }) => ({ + '& .MuiDialog-paper': { + minWidth: 600, + maxHeight: '80vh', + backgroundColor: theme.palette.background.paper, + }, +})); + +const TabPanel = (props) => { + const { children, value, index, ...other } = props; + + return ( + + ); +}; + +const SettingsModal = ({ open, onClose }) => { + const [tabValue, setTabValue] = useState(0); + const [isSaving, setIsSaving] = useState(false); + const [showSuccess, setShowSuccess] = useState(false); + const [hasChanges, setHasChanges] = useState(false); + const [showConfirmClose, setShowConfirmClose] = useState(false); + + const handleTabChange = (event, newValue) => { + if (hasChanges) { + setShowConfirmClose(true); + } else { + setTabValue(newValue); + } + }; + + const handleSave = () => { + setIsSaving(true); + // Имитация асинхронного сохранения + setTimeout(() => { + setIsSaving(false); + setShowSuccess(true); + setHasChanges(false); + }, 1500); + }; + + const handleClose = () => { + if (hasChanges) { + setShowConfirmClose(true); + } else { + onClose(); + } + }; + + const handleConfirmClose = (shouldClose) => { + setShowConfirmClose(false); + if (shouldClose) { + onClose(); + } + }; + + // Пример обработчика изменений + const handleSettingChange = () => { + setHasChanges(true); + }; + + return ( + <> + + + Настройки + theme.palette.grey[500], + }} + > + + + + + + + + + {/* Добавляйте новые вкладки здесь */} + + + + + + Настройки меню + {/* Добавьте содержимое для вкладки меню */} + + + + Настройки внешнего вида + {/* Добавьте содержимое для вкладки внешнего вида */} + + + {/* Добавляйте новые TabPanel для новых вкладок */} + + + + + + + + + {/* Уведомление об успешном сохранении */} + setShowSuccess(false)} + anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} + > + setShowSuccess(false)} severity="success" sx={{ width: '100%' }}> + Настройки успешно сохранены! + + + + {/* Диалог подтверждения закрытия */} + handleConfirmClose(false)} + aria-labelledby="alert-dialog-title" + aria-describedby="alert-dialog-description" + > + Есть несохраненные изменения + + Вы уверены, что хотите закрыть без сохранения изменений? + + + + + + + + ); +}; + +export default SettingsModal; \ No newline at end of file diff --git a/src/Components/Layout/SidebarMenu.jsx b/src/Components/Layout/SidebarMenu.jsx index e37f326..2617bda 100644 --- a/src/Components/Layout/SidebarMenu.jsx +++ b/src/Components/Layout/SidebarMenu.jsx @@ -3,17 +3,10 @@ import React, { useState, useEffect } from "react"; import { Drawer, List, - Typography, styled, IconButton, Tooltip, Box, - Dialog, - DialogTitle, - DialogContent, - DialogActions, - Button, - TextField } from "@mui/material"; import MenuItem from "./SidebarMenuComponents/MenuItem"; import SidebarFooter from "./SidebarMenuComponents/SidebarFooter"; @@ -27,12 +20,7 @@ const SidebarMenu = ({ data, isDarkMode, setIsDarkMode, - onEditItem, - onSelectItem, - editModalOpen, - editingItem, - onCloseEditModal, - onSaveChanges + onSelectItem }) => { const [collapsed, setCollapsed] = useState(false); const { sidebarWidth, startResizing } = useSidebarResize(290); @@ -148,7 +136,7 @@ const SidebarMenu = ({ item={data} collapsed={collapsed} level={0} - onEdit={onEditItem} + onSelectItem={onSelectItem} /> )} @@ -160,74 +148,12 @@ const SidebarMenu = ({ setIsDarkMode={setIsDarkMode} /> - {!collapsed && ( )} - - {/* Модальное окно редактирования */} - ); }; -const EditMenuItemDialog = ({ open, item, onClose, onSave }) => { - const [formData, setFormData] = useState(item || {}); - - useEffect(() => { - setFormData(item || {}); - }, [item]); - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData(prev => ({ ...prev, [name]: value })); - }; - - const handleSubmit = () => { - onSave(formData); - }; - - if (!item) return null; - - return ( - - Редактирование элемента меню - - - - - {/* Дополнительные поля для редактирования */} - - - - - - - - ); -}; - export default SidebarMenu; \ No newline at end of file diff --git a/src/Components/Layout/SidebarMenuComponents/MenuItem.jsx b/src/Components/Layout/SidebarMenuComponents/MenuItem.jsx index 6fd6607..afb8801 100644 --- a/src/Components/Layout/SidebarMenuComponents/MenuItem.jsx +++ b/src/Components/Layout/SidebarMenuComponents/MenuItem.jsx @@ -7,11 +7,10 @@ import { Collapse, List, styled, - IconButton, Menu, MenuItem as MuiMenuItem } from "@mui/material"; -import { ExpandLess, ExpandMore, Folder, FolderOpen, Edit } from "@mui/icons-material"; +import { ExpandLess, ExpandMore, Folder, FolderOpen } from "@mui/icons-material"; import StatusIndicator from "./StatusIndicator"; const StyledListItem = styled(ListItem)(({ theme, level }) => ({ @@ -44,11 +43,6 @@ const MenuItem = ({ item, onSelectItem, level = 0, collapsed, onEdit }) => { setContextMenu(null); }; - const handleEditClick = () => { - onEdit(item); - handleCloseContextMenu(); - }; - const handleToggle = (e) => { e.stopPropagation(); setIsOpen(!isOpen); @@ -87,19 +81,6 @@ const MenuItem = ({ item, onSelectItem, level = 0, collapsed, onEdit }) => { }} /> {hasChildren && (isOpen ? : )} - - {level > 0 && ( - { - e.stopPropagation(); - handleEditClick(); - }} - sx={{ ml: 1 }} - > - - - )} )} @@ -114,9 +95,7 @@ const MenuItem = ({ item, onSelectItem, level = 0, collapsed, onEdit }) => { : undefined } > - - Редактировать - + {hasChildren && !collapsed && ( diff --git a/src/Components/Layout/SidebarMenuComponents/SidebarFooter.jsx b/src/Components/Layout/SidebarMenuComponents/SidebarFooter.jsx index 54a2b7b..66a37e7 100644 --- a/src/Components/Layout/SidebarMenuComponents/SidebarFooter.jsx +++ b/src/Components/Layout/SidebarMenuComponents/SidebarFooter.jsx @@ -1,4 +1,5 @@ -import React from "react"; +// components/SidebarMenuComponents/SidebarFooter.jsx +import React, { useState } from "react"; import { Brightness4, Brightness7 } from "@mui/icons-material"; import { IconButton, Tooltip } from "@mui/material"; import { @@ -7,8 +8,10 @@ import { ListItemText, styled, Switch, - Box + Box, + Button } from "@mui/material"; +import SettingsModal from "../SettingsModal"; const FooterList = styled(List)(({ theme }) => ({ backgroundColor: theme.palette.custom.sidebar, @@ -28,51 +31,76 @@ const FooterListItem = styled(ListItem)(({ theme }) => ({ })); const SidebarFooter = ({ collapsed, isDarkMode, setIsDarkMode }) => { - return ( - - {!collapsed && ( - - - - )} - - {!collapsed && ( - - )} + const [settingsOpen, setSettingsOpen] = useState(false); - - - setIsDarkMode(!isDarkMode)} - sx={{ color: 'custom.sidebarText' }} - > - {isDarkMode ? : } - - - {!collapsed && ( - setIsDarkMode(!isDarkMode)} - size="small" + const handleSettingsOpen = () => { + setSettingsOpen(true); + }; + + const handleSettingsClose = () => { + setSettingsOpen(false); + }; + + return ( + <> + + {!collapsed && ( + + + + )} + + {!collapsed && ( + )} - - - + + + + setIsDarkMode(!isDarkMode)} + sx={{ color: 'custom.sidebarText' }} + > + {isDarkMode ? : } + + + {!collapsed && ( + setIsDarkMode(!isDarkMode)} + size="small" + /> + )} + + + + + + ); }; -export default SidebarFooter; +export default SidebarFooter; \ No newline at end of file