/* Парус 8 - Панели мониторинга - Заголовок Хуки для заголовка */ //--------------------- //Подключение библиотек //--------------------- import { useState, useEffect, useCallback, useRef, useMemo } from "react"; //Классы React import { P8P_HEADER_MIN_FILTER_WIDTH } from "./p8p_header_constants"; //Константы заголовка //----------- //Тело модуля //----------- //Кастомный хук для определения информации об отображении const useP8PHeaderVisibleInfo = (containerRef, maxDisplay, totalFilters) => { //Отображаемое количество const [visibleCount, setVisibleCount] = useState(maxDisplay > 0 ? maxDisplay : 0); //Признак переполненности const [isOverflowed, setIsOverflowed] = useState(false); //Признак уменьшения меньше минимального значения const [isLessMinWidth, setIsLessMinWidth] = useState(false); //Пересчет количество отображаемых const recalcVisibleCount = useCallback(container => { //Определяем дочерние элементы const items = container.children; //Определяем параметры контейнера const containerRect = container.getBoundingClientRect(); //Если блок меньше минимального значения if (containerRect.width < P8P_HEADER_MIN_FILTER_WIDTH && items.length > 0) { //Информируем, что невозможно показать setVisibleCount(0); setIsOverflowed(true); setIsLessMinWidth(true); return; } //Обнуляем счетчик видимых let visible = 0; //Обходим дочерние элменты for (let i = 0; i < items.length; i++) { //Определяем параметры элемента const itemRect = items[i].getBoundingClientRect(); //Проверяем, полностью ли элемент виден в контейнере if (itemRect.bottom <= containerRect.bottom) { visible++; } else { //Если один элемент скрыт, то и все последующие скрыты (при row-direction) break; } } //Устанавливаем отображаемых setVisibleCount(visible); setIsOverflowed(visible < items.length); setIsLessMinWidth(false); }, []); //При открытии страницы useEffect(() => { //Определяем контейнер const container = containerRef.current; //Если контейнер не определен или установлено максимально отображение - не отслеживаем if (!container || maxDisplay > 0) { setIsOverflowed(maxDisplay < totalFilters); return; } //Пересчет количество отображаемых recalcVisibleCount(container); //Определяем отслеживание const observer = new ResizeObserver(() => { //Пересчет количество отображаемых recalcVisibleCount(container); }); //Подключаем отслеживание observer.observe(container); //При закрытии компонента return () => observer.disconnect(); }, [containerRef, maxDisplay, recalcVisibleCount, totalFilters]); //Возвращаем данные return { visibleCount, isOverflowed, isLessMinWidth }; }; //Хук состояния фильтра const useP8PHeaderFilter = ({ filters, maxDisplay }) => { //Собственное состояние - контейнер элементов const gridRef = useRef(null); //Собственное состояние - элемент выпадающего списка const [anchorEl, setAnchorEl] = useState(null); //Собственное состояние - информация об отображении const { visibleCount, isOverflowed, isLessMinWidth } = useP8PHeaderVisibleInfo(gridRef, maxDisplay, filters.length); //Отображаемые фильтры const allowedFilters = useMemo(() => { if (Array.isArray(filters) && filters.length > 0) { return filters.slice(0, maxDisplay || filters.length); } else { return []; } }, [filters, maxDisplay]); //По нажатию на меню скрытых элементов const handleFilterMoreOpen = event => { setAnchorEl(event.currentTarget); }; //При закрытии меню скрытых элементов const handleFilterMoreClose = () => { setAnchorEl(null); }; return { gridRef, anchorEl, allowedFilters, visibleCount, isOverflowed, isLessMinWidth, handleFilterMoreOpen, handleFilterMoreClose }; }; //---------------- //Интерфейс модуля //---------------- export { useP8PHeaderFilter };