From 14d2f3eb68477604d7f465bb6b9019cb540ce893 Mon Sep 17 00:00:00 2001 From: DmitriyA Date: Tue, 2 Dec 2025 04:34:56 -0500 Subject: [PATCH] version update --- .gitignore | 8 +- .../SettingsComponents/FormulaEditor.jsx | 412 +++++++++--------- 2 files changed, 208 insertions(+), 212 deletions(-) diff --git a/.gitignore b/.gitignore index e7fea06..0afc875 100755 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,10 @@ node_modules .env.local .env.development .env.production -.env.test \ No newline at end of file +.env.test + +# Local configs +vite.config.js +vite.config.local.js +.env.local +*.local.* \ No newline at end of file diff --git a/src/Components/Layout/SettingsComponents/FormulaEditor.jsx b/src/Components/Layout/SettingsComponents/FormulaEditor.jsx index 206a843..830863d 100644 --- a/src/Components/Layout/SettingsComponents/FormulaEditor.jsx +++ b/src/Components/Layout/SettingsComponents/FormulaEditor.jsx @@ -3,117 +3,168 @@ import { TextField, Box, Typography, IconButton, Divider, CircularProgress, Alert, Collapse, Tooltip, Button, Card, CardContent, Chip, Dialog, DialogTitle, - DialogContent, DialogActions, Snackbar + DialogContent, DialogActions, Snackbar, Table, + TableBody, TableCell, TableContainer, TableHead, + TableRow, Paper, Badge } from '@mui/material'; import RefreshIcon from '@mui/icons-material/Refresh'; import SearchIcon from '@mui/icons-material/Search'; import EditIcon from '@mui/icons-material/Edit'; import SaveIcon from '@mui/icons-material/Save'; +import WarningIcon from '@mui/icons-material/Warning'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import axios from 'axios'; -const FormulaItem = React.memo(({ data, onEdit }) => { - const formatValue = (value) => { - if (typeof value === 'object' && value !== null) { - return JSON.stringify(value, null, 2); - } - return String(value); +const FormulaItem = React.memo(({ formula, onEdit }) => { + const getMetricStatusColor = (found) => { + return found ? 'success' : 'error'; }; - const getValueColor = (value) => { - if (typeof value === 'boolean') return 'primary'; - if (typeof value === 'number') return 'secondary'; - if (value === null) return 'default'; - return 'info'; + const formatValue = (value) => { + if (value === undefined) return 'N/A'; + return value.toFixed(2); }; return ( + {/* Заголовок с ID и статусом метрик */} - - ID: {data.id || 'Без ID'} - - + + + {formula.name} + + + ID: {formula.id} + + + + + + + + - - {data.data.name} - - + {/* Описание */} - {data.data.desription} + {formula.description} + {/* Метрики */} + + + Метрики в формуле: + {formula.metadata?.missingMetrics > 0 && ( + + )} + + + + + + + Метрика + Описание + Значение + Статус + + + + {formula.enrichedMetrics?.map((metric, index) => ( + + + + + {metric.originalName} + + + {metric.prometheusName} + + + + + + {metric.description} + + + + + {formatValue(metric.currentValue)} + + + + : } + label={metric.found ? 'Найдена' : 'Не найдена'} + color={getMetricStatusColor(metric.found)} + size="small" + variant={metric.found ? "filled" : "outlined"} + /> + + + ))} + +
+
+
+ + {/* Формула */} - Параметры: + Формула с описанием метрик: - + - - - {JSON.stringify(data.data.values?.statusarr, null, 2)} - - - - - - - {JSON.stringify(data.data.values?.warr, null, 2)} - - - - - - - {data.data.formula} + {formula.humanReadableFormula} - - - + {/* Веса */} + + + Веса (warr): + + + {formula.values?.warr?.map((weight, index) => ( + + ))} +
@@ -125,7 +176,7 @@ const EditFormulaDialog = ({ open, formula, onClose, onSave }) => { useEffect(() => { if (formula) { - setEditedFormula(formula.data.formula || ''); + setEditedFormula(formula.formula || ''); } }, [formula]); @@ -138,11 +189,11 @@ const EditFormulaDialog = ({ open, formula, onClose, onSave }) => { return ( - Редактирование формулы: {formula?.data.name} + Редактирование формулы: {formula?.name} - {formula?.data.desription} + {formula?.description} @@ -185,7 +236,6 @@ const EditFormulaDialog = ({ open, formula, onClose, onSave }) => { const FormulaEditor = () => { const [formulas, setFormulas] = useState([]); const [filter, setFilter] = useState(''); - const [formulaId, setFormulaId] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [refreshing, setRefreshing] = useState(false); @@ -197,46 +247,32 @@ const FormulaEditor = () => { setSnackbar({ open: true, message, severity }); }; - const loadFormulas = useCallback(async (id = null) => { + const loadFormulas = useCallback(async () => { try { setLoading(true); setError(null); - const targetId = id || formulaId; - const res = await axios.get(`http://192.168.2.39:3000/api/formula/7777/options`); - - console.log('Полученные данные:', res.data); - - let formattedData; - - if (Array.isArray(res.data)) { - formattedData = res.data.map((item, index) => ({ - id: item.id || `formula_${index + 1}`, - data: item - })); - } else if (typeof res.data === 'object' && res.data !== null) { - formattedData = [{ - id: targetId, - data: res.data - }]; + const response = await axios.get('http://192.168.2.39:3000/api/enriched-formulas'); + + if (Array.isArray(response.data)) { + setFormulas(response.data); + showSnackbar(`Загружено ${response.data.length} формул`); } else { - formattedData = [{ - id: targetId, - data: { value: res.data } - }]; + throw new Error('Некорректный формат данных'); } - console.log('Форматированные данные:', formattedData); - setFormulas(formattedData); - } catch (err) { console.error('Ошибка при загрузке формул:', err); - setError(`Ошибка загрузки: ${err.message}`); + const errorMessage = axios.isAxiosError(err) + ? `Ошибка сервера: ${err.response?.status} - ${err.response?.data?.message || err.message}` + : `Ошибка загрузки: ${err.message}`; + setError(errorMessage); + showSnackbar(errorMessage, 'error'); } finally { setLoading(false); setRefreshing(false); } - }, [formulaId]); + }, []); const handleEditFormula = (formula) => { setEditingFormula(formula); @@ -246,16 +282,17 @@ const FormulaEditor = () => { try { setSaveLoading(true); - // Обновляем формулу в локальном состоянии - const updatedFormulas = formulas.map(formula => + await axios.post(`http://192.168.2.39:3000/api/formula/${formulaId}/update`, { + formula: newFormula + }); + + setFormulas(prev => prev.map(formula => formula.id === formulaId - ? { ...formula, data: { ...formula.data, formula: newFormula } } + ? { ...formula, formula: newFormula } : formula - ); + )); - setFormulas(updatedFormulas); setEditingFormula(null); - showSnackbar('Формула успешно обновлена!'); } catch (err) { @@ -266,65 +303,25 @@ const FormulaEditor = () => { } }; - const handleSendAllFormulas = async () => { - try { - setSaveLoading(true); - - // Преобразуем данные обратно в исходный формат для отправки - const dataToSend = formulas.map(formula => ({ - id: formula.data.id, - name: formula.data.name, - desription: formula.data.desription, - values: formula.data.values, - formula: formula.data.formula - })); - - console.log('Отправляемые данные:', dataToSend); - - const response = await axios.post( - 'http://192.168.2.39:9999/api/integration/3333', - dataToSend, - { - headers: { - 'Content-Type': 'application/json' - } - } - ); - - console.log('Ответ сервера:', response.data); - showSnackbar('Данные успешно отправлены на сервер!'); - - } catch (err) { - console.error('Ошибка при отправке данных:', err); - showSnackbar(`Ошибка отправки: ${err.message}`, 'error'); - } finally { - setSaveLoading(false); - } - }; - const refreshData = useCallback(() => { setRefreshing(true); loadFormulas(); }, [loadFormulas]); - const handleFormulaIdChange = (e) => { - setFormulaId(e.target.value); - }; - - const handleLoadClick = () => { - if (formulaId.trim()) { - loadFormulas(formulaId); - } - }; - const filteredFormulas = formulas.filter(formula => formula.id.toLowerCase().includes(filter.toLowerCase()) || - JSON.stringify(formula.data).toLowerCase().includes(filter.toLowerCase()) + formula.name.toLowerCase().includes(filter.toLowerCase()) || + formula.description.toLowerCase().includes(filter.toLowerCase()) || + formula.formula.toLowerCase().includes(filter.toLowerCase()) ); + const totalMetrics = formulas.reduce((sum, formula) => sum + (formula.metadata?.totalMetrics || 0), 0); + const foundMetrics = formulas.reduce((sum, formula) => sum + (formula.metadata?.foundMetrics || 0), 0); + const missingMetrics = formulas.reduce((sum, formula) => sum + (formula.metadata?.missingMetrics || 0), 0); + useEffect(() => { loadFormulas(); - }, []); + }, [loadFormulas]); return ( @@ -353,55 +350,53 @@ const FormulaEditor = () => { {/* Панель управления */} - - Редактор формул + + Редактор формул с метриками - - - - - - - + {/* Статистика */} + + + + {missingMetrics > 0 && ( + + )} + + + {/* Поиск */} + setFilter(e.target.value)} - variant="standard" - placeholder="Введите текст для поиска..." + variant="outlined" + placeholder="Введите ID, название или описание..." + size="small" /> - + @@ -409,10 +404,10 @@ const FormulaEditor = () => { {/* Список формул */} - {filteredFormulas.map((formula, index) => ( + {filteredFormulas.map((formula) => ( ))} @@ -424,7 +419,7 @@ const FormulaEditor = () => { py={3} variant="h6" > - {filter ? 'Формулы не найдены' : 'Загрузите формулы по ID'} + {filter ? 'Формулы не найдены' : 'Нет загруженных формул'} )} @@ -444,14 +439,9 @@ const FormulaEditor = () => { Всего формул: {formulas.length} • Отфильтровано: {filteredFormulas.length} - + + Метрики: {foundMetrics}/{totalMetrics} найдено + {/* Диалог редактирования */}