front-fixes #33

Merged
PotapovaA merged 3 commits from front-fixes into test 2026-07-14 17:28:33 +03:00
2 changed files with 73 additions and 15 deletions

View File

@ -30,6 +30,28 @@ const LockBadge = styled.div`
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.1);
`; `;
// Функция для определения яркости цвета
const getColorBrightness = (hexColor) => {
if (!hexColor) return 255;
const color = hexColor.replace('#', '');
let r, g, b;
if (color.length === 3) {
r = parseInt(color[0] + color[0], 16);
g = parseInt(color[1] + color[1], 16);
b = parseInt(color[2] + color[2], 16);
} else if (color.length === 6) {
r = parseInt(color.substring(0, 2), 16);
g = parseInt(color.substring(2, 4), 16);
b = parseInt(color.substring(4, 6), 16);
} else {
return 255;
}
return (0.299 * r + 0.587 * g + 0.114 * b);
};
// Функция для подсветки текста // Функция для подсветки текста
const highlightText = (text, searchQueries) => { const highlightText = (text, searchQueries) => {
if (!text) return text; if (!text) return text;
@ -60,6 +82,35 @@ const highlightText = (text, searchQueries) => {
); );
}; };
const highlightWithFormatting = (originalValue, formattedValue, searchQueries) => {
if (!originalValue && originalValue !== 0) return formattedValue;
const cleanSearchQueries = searchQueries.filter(q => (q !== undefined && q !== ''));
if (cleanSearchQueries.length == 0) return formattedValue;
const originalString = String(originalValue);
const escapedQueries = cleanSearchQueries.map(query => query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
const regex = new RegExp(`(${escapedQueries.join('|')})`, 'gi');
if (!regex.test(originalString)) {
return formattedValue;
}
return (
<mark
style={{
backgroundColor: '#ffeb3b',
color: '#000',
fontWeight: 'bold',
padding: '0 2px',
borderRadius: '2px',
}}
>
{formattedValue}
</mark>
);
};
const INTEGER_COLUMN_IDS = new Set([ const INTEGER_COLUMN_IDS = new Set([
'data.header.num_group', 'data.header.num_group',
'data.nomenclature_group_id', 'data.nomenclature_group_id',
@ -97,34 +148,42 @@ const Cell = React.memo(({ cell, row, column, onClick, globalFilter, columnFilte
const isLocked = lockedCells.includes(cellKey); const isLocked = lockedCells.includes(cellKey);
const cellValue = cell.getValue(); const cellValue = cell.getValue();
let textValue = String(cellValue || ''); let originalValue = cellValue;
let displayValue = String(cellValue || '');
const isNumeric = !isNaN(Number(cellValue)) && cellValue !== null && cellValue !== undefined && cellValue !== ''; const isNumeric = !isNaN(Number(cellValue)) && cellValue !== null && cellValue !== undefined && cellValue !== '';
if (isNumeric) { if (isNumeric) {
const asInteger = INTEGER_COLUMN_IDS.has(column.id); const asInteger = INTEGER_COLUMN_IDS.has(column.id);
textValue = formatNumber(cellValue, asInteger); displayValue = formatNumber(cellValue, asInteger);
} }
const highlightedContent = useMemo(() => { const highlightedContent = useMemo(() => {
return highlightText(textValue, [globalFilter, columnFilter]); if (!isNumeric) {
}, [textValue, globalFilter]); return highlightText(displayValue, [globalFilter, columnFilter]);
}
return highlightWithFormatting(originalValue, displayValue, [globalFilter, columnFilter]);
}, [originalValue, displayValue, globalFilter, columnFilter, isNumeric]);
// Определяем цвет текста на основе яркости фона
const getTextColor = () => {
const brightness = getColorBrightness(backgroundColor);
// Если яркость меньше 128 (темный фон) - используем белый текст, иначе черный
return brightness < 128 ? '#ffffff' : '#000000';
};
// Базовые стили для заблокированной ячейки // Базовые стили для заблокированной ячейки
const lockedStyles = isLocked ? { const lockedStyles = isLocked ? {
border: '2px solid #e0e0e0', border: '2px solid #e0e0e0',
backgroundColor: '#f5f5f5', backgroundColor: '#f5f5f5',
color: '#999999',
cursor: 'not-allowed', cursor: 'not-allowed',
opacity: 0.85, opacity: 0.85,
} : {}; } : {};
// Если isEditable false, добавляем дополнительные стили
const editableStyles = !isEditable ? {
border: '2px solid #d3d3d3', // Определяем финальный цвет текста
color: backgroundColor?.toLowerCase() === '#933634' ? '#ffffff' : '#525252', const finalTextColor = isLocked ? '#999999' : getTextColor();
cursor: 'not-allowed',
} : {};
return ( return (
<div <div
@ -144,9 +203,8 @@ const Cell = React.memo(({ cell, row, column, onClick, globalFilter, columnFilte
border: '2px solid transparent', border: '2px solid transparent',
padding: '8px', padding: '8px',
backgroundColor: isLocked ? '#f5f5f5' : backgroundColor, backgroundColor: isLocked ? '#f5f5f5' : backgroundColor,
color: isLocked ? '#999999' : color, color: finalTextColor,
...lockedStyles, ...lockedStyles,
...editableStyles,
}} }}
onClick={isLocked ? undefined : onClick} onClick={isLocked ? undefined : onClick}
> >

View File

@ -360,7 +360,7 @@ const ModalEditAddVsp = ({
Региональный филиал <span style={{ color: 'red' }}>*</span> Региональный филиал <span style={{ color: 'red' }}>*</span>
</FieldLabel> </FieldLabel>
<Autocomplete <Autocomplete
options={ssps} options={ssps.filter(s => s.is_active)}
getOptionLabel={(option) => option.title || option.name || ''} getOptionLabel={(option) => option.title || option.name || ''}
value={selectedSsp} value={selectedSsp}
onChange={handleSspChange} onChange={handleSspChange}