Untitled
import React, { useState, useEffect, useRef, useCallback, memo, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import { PROFILE_SUBMODULE, useAccess } from 'hooks/useAccess'; import EmptyContentSelect from 'components/EmptyContentSelect'; import IncidentCard from 'components/emergency-cards/DispatchDashboardMulticorporation'; import './index.scss'; const ITEM_SIZE_WIDTH = 290; const ITEM_SIZE_HEIGTH = 140; const ITEM_HORIZONTAL_SEPARATION = 5; const CardLista = ({ visible, emergenciesDispatch = [], openTabItemHandler, blinkEmergencyIds = [], loadingEmergencies, onClickEmergencyItem, filterClosedCorporationsInCard, className, onContextMenu = () => { /** */ }, emptyResultMsg = 'despacho_card.mensaje' }) => { const { assignedCorporation } = useSelector((state) => state.CadSession); const { complementedEmergencyIds } = useSelector((state) => state.emergencyComplements); const { hasAccess } = useAccess(); const isAssignedComplaintsEnabled = hasAccess(PROFILE_SUBMODULE.N089_MODULO_DENUNCIAS_ASIGNADAS); const showAssignedUnitCount = useMemo( () => hasAccess(PROFILE_SUBMODULE.CAN_SHOW_ASSIGNED_UNIT_FORCES_IDENTIFIER), [hasAccess] ); const { t } = useTranslation('translations'); const containerRef = useRef(null); const [startIndex, setStartIndex] = useState(0); const [endIndex, setEndIndex] = useState(0); const [windowWidth, setWindowWidth] = useState(window.innerWidth); const isBlink = (emergencyId) => !!blinkEmergencyIds?.includes(emergencyId); const updateWindowWidth = () => { setWindowWidth(window.innerWidth); }; useEffect(() => { window.addEventListener('resize', updateWindowWidth); return () => { window.removeEventListener('resize', updateWindowWidth); }; }, []); const itemsPerRow = useMemo(() => { return Math.floor(windowWidth / (ITEM_SIZE_WIDTH + ITEM_HORIZONTAL_SEPARATION * 2)) || 1; }, [windowWidth]); const totalRows = useMemo(() => { return Math.ceil(emergenciesDispatch.length / itemsPerRow); }, [emergenciesDispatch.length, itemsPerRow]); const calculateVisibleItems = useCallback(() => { if (!containerRef.current) return; const { scrollTop, clientHeight } = containerRef.current; const startRow = Math.floor(scrollTop / ITEM_SIZE_HEIGTH); const endRow = Math.min(totalRows, Math.ceil((scrollTop + clientHeight) / ITEM_SIZE_HEIGTH)); setStartIndex(startRow * itemsPerRow); setEndIndex(endRow * itemsPerRow); }, [totalRows, itemsPerRow]); useEffect(() => { calculateVisibleItems(); containerRef.current.addEventListener('scroll', calculateVisibleItems); return () => { containerRef.current.removeEventListener('scroll', calculateVisibleItems); }; }, [calculateVisibleItems]); if (!visible) { return null; } return ( <div className={`card-list-dispatcher ${className ?? ''}`}> {(!emergenciesDispatch || emergenciesDispatch.length === 0) && !loadingEmergencies ? ( <div className="empty"> <EmptyContentSelect fullText={t(emptyResultMsg)} customIconName="EmptyTableIcon" /> </div> ) : ( <div ref={containerRef} className="cards-container"> {emergenciesDispatch.slice(startIndex, endIndex).map((emergency, i) => { const actualIndex = startIndex + i; const isOnRightEdge = (actualIndex + 1) % itemsPerRow === 0; const isOnTopEdge = actualIndex < itemsPerRow; return ( <IncidentCard key={emergenciesDispatch[actualIndex]?.id + '-' + actualIndex} showAssignedUnitCount={showAssignedUnitCount} profileAssignedCorporations={assignedCorporation} blinkAnimation={isBlink(emergency.id)} emergency={emergency} onClickPreviewEmergency={openTabItemHandler} showAddress={isAssignedComplaintsEnabled} showChronometer={!isAssignedComplaintsEnabled} filterClosedCorporations={filterClosedCorporationsInCard} onClick={(ev, em) => onClickEmergencyItem( { ...ev, isOnRightEdge, isOnTopEdge, rowIndex: Math.floor(actualIndex / itemsPerRow), ITEM_SIZE_HEIGTH }, em ) } isComplemented={complementedEmergencyIds.indexOf(emergency.id) !== -1} onContextMenu={onContextMenu} /> ); })} </div> )} </div> ); }; export default memo(CardLista);
Leave a Comment