Untitled

mail@pastecode.io avatar
unknown
plain_text
5 months ago
4.8 kB
3
Indexable
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