handleReulst

mail@pastecode.io avatar
unknown
javascript
16 days ago
7.7 kB
3
Indexable
Never
import PropTypes from 'prop-types';
import { clearErrors } from 'redux-store/reducers/dispatch/actions';
import { FINISH_CODE } from 'redux-store/reducers/dispatch/reducer';
import { addComplementedEmergency } from 'redux-store/reducers/emergencyComplements/actions';
import { INITIAL_MAP_RESOURCES } from 'redux-store/reducers/mapResources/reducers';
import { FINISH_STATES } from 'redux-store/reducers/unitForces/reducers';
import React, { useEffect, useMemo } from 'react';
import { useQueryClient } from 'react-query';
import { useDispatch, useSelector } from 'react-redux';
import { MAP_IDS } from 'config/map-keys';
import { PROFILE_SUBMODULES } from 'config/profile-permissions';
import { REACT_QUERY_KEYS } from 'config/react-query-keys';
import { EMERGENCY_EVENTS, SOCKET_CHANNELS_TOPICS } from 'config/socket-channels';
import { useWebSocketContext } from 'context/webSocketContext';
import { getStaticFileUrl } from 'utils';
import { ENVS } from 'utils/constants';
import { useSdcApi } from 'hooks';
import { useAccess } from 'hooks/useAccess';
import { useNotification } from 'hooks/useNotification';

const audio = new Audio(getStaticFileUrl(ENVS.REACT_APP_EMERGENCY_ALERT_SOUND_ASSET_PATH));

/**
 *  ✅ Este componente solamente escucha los cambios en el reducer para mostrar mensajes o lanzar actualizaciones
 * @param {{children: import('react').ReactNode}} param0
 * @returns
 */
function HandlerResults({ children }) {
  const { openErrorNotification, openSuccessNotification, openEmergencyNotification, operReverVehicleNotification } =
    useNotification();
  const dispatch = useDispatch();
  const { hasAccess } = useAccess();
  const { subscribeToChannel, unsubscribeChannelById } = useWebSocketContext();
  const { finishStatus, updateDescriptionError, emergenciesDispatch } = useSelector((state) => state.dispatch);
  const { assignedCorporation, incidentReceptionSoundActive } = useSelector((state) => state.CadSession);

  const {
    emergencies: { selected: selectedEmergency }
  } = useSelector((store) => store?.mapResources?.[MAP_IDS.DISPATCHER] ?? INITIAL_MAP_RESOURCES);
  const { FINISH: FINISH_CREATE } = useSelector((state) => state.createIndicent);
  const { FINISH } = useSelector((state) => state.unitForces);
  const queryClient = useQueryClient();
  const {
    microservices: {
      dispatch: {
        corporationEmergencies: { getEmergenciesByFiltersAdvance }
      }
    }
  } = useSdcApi();

  const permissions = useMemo(
    () => ({
      showNotification: hasAccess(PROFILE_SUBMODULES.SDCW_MODULO_NOTIFICACIONES_EMERGENCIA),
      canSoundAlertTypeHigh: hasAccess(PROFILE_SUBMODULES.CAN_SOUND_ALERT_TYPE_HIGH)
    }),
    [hasAccess]
  );

  const updateDispatchEmergencies = () => {
    queryClient.invalidateQueries([getEmergenciesByFiltersAdvance.queryKeyFunction('DASHBOARD-DISPATCH')]);
  };

  useEffect(() => {
    const socketId = subscribeToChannel({
      topic: SOCKET_CHANNELS_TOPICS.emergenciesUpdate(),
      eventHandler: (data) => {
        if (
          [
            EMERGENCY_EVENTS.INCIDENT_DISPATCHING,
            EMERGENCY_EVENTS.CORPORATION_ASSIGNED,
            EMERGENCY_EVENTS.INCIDENT_ASSOCIATE,
            EMERGENCY_EVENTS.INCIDENT_DISASSOCIATE,
            EMERGENCY_EVENTS.INCIDENT_OPERATIVE_CORPORATION_ASIGNED,
            EMERGENCY_EVENTS.CORPORATION_UNASSIGNED
          ].includes(data.jsonBody.typeEvent)
        ) {
          updateDispatchEmergencies({ keepState: true });

          /* Cuando se asigna una corporación a un incidente mostrará una notificación */
          if (data.jsonBody.typeEvent === EMERGENCY_EVENTS.CORPORATION_ASSIGNED) {
            const playSound =
              data?.jsonBody?.playSound || (data?.jsonBody?.playSoundHigh && permissions?.canSoundAlertTypeHigh);
            if (incidentReceptionSoundActive && playSound) audio.play();
          }

          if (
            data.jsonBody.typeEvent === EMERGENCY_EVENTS.INCIDENT_OPERATIVE_CORPORATION_ASIGNED &&
            permissions?.showNotification
          ) {
            const existGroup = assignedCorporation
              ?.map((ac) => ac?.operativeGroups?.some((c) => data.jsonBody.listCorporationOperativeId.includes(c.id)))
              .filter((ac) => ac === true);
            if (existGroup?.includes(true)) openEmergencyNotification(data?.jsonBody, { threshold: 3 });
          }
        }
      }
    });
    return () => {
      unsubscribeChannelById(socketId);
    };
  }, [
    permissions?.showNotification,
    permissions?.canSoundAlertTypeHigh,
    incidentReceptionSoundActive,
    assignedCorporation
  ]);

  useEffect(() => {
    const socketId = subscribeToChannel({
      topic: SOCKET_CHANNELS_TOPICS.emergenciesUpdate(),
      eventHandler: (data) => {
        const socketEmergencyId = data.jsonBody.incidentId;
        if (
          [
            EMERGENCY_EVENTS.LOCATION_CHANGED,
            EMERGENCY_EVENTS.CLOSED,
            EMERGENCY_EVENTS.CORPORATION_OPERATIVE_CLOSED,
            EMERGENCY_EVENTS.CORPORATION_OPERATIVE_CANCEL,
            EMERGENCY_EVENTS.INCIDENT_PRIORITY_CHANGED,
            EMERGENCY_EVENTS.INCIDENT_ASSIGNED_TO_FORCE_UNIT,
            EMERGENCY_EVENTS.INCIDENT_ADDITIONAL_CLASSIFIED
          ].includes(data.jsonBody.typeEvent)
        ) {
          // Sólo refresca si la emergencia actualizada se encuentra en el listado actual
          const em = (emergenciesDispatch ?? []).find((e) => e.id === socketEmergencyId);
          if (!em) {
            return;
          }
          updateDispatchEmergencies({ keepState: true });
        }
      }
    });
    return () => {
      unsubscribeChannelById(socketId);
    };
  }, [emergenciesDispatch]);

  useEffect(() => {
    const socketIdForRecoveredCars = subscribeToChannel({
      topic: SOCKET_CHANNELS_TOPICS.recoveredVehicleChannel(),
      eventHandler: (data) => {
        operReverVehicleNotification(data?.jsonBody);
      }
    });
    return () => {
      unsubscribeChannelById(socketIdForRecoveredCars);
    };
  }, []);

  useEffect(() => {
    switch (finishStatus) {
      case FINISH_CODE.SUCCESS_DESCRIPTION_UPDATE:
        openSuccessNotification();
        break;
      case FINISH_CODE.ERROR_DESCRIPTION_UPDATE:
        if (updateDescriptionError) {
          openErrorNotification();
          dispatch(clearErrors());
        }
        break;
      default:
        break;
    }
  }, [finishStatus]);

  /* Finish unites */
  useEffect(() => {
    switch (FINISH) {
      case FINISH_STATES.SUCCESS_ASSIGN:
        if (selectedEmergency?.id) {
          queryClient.invalidateQueries([REACT_QUERY_KEYS.dispatch.dispatch.byId(selectedEmergency?.id)]);
        }
        updateDispatchEmergencies();
        break;
      default:
        break;
    }
  }, [FINISH]);

  useEffect(() => {
    switch (FINISH_CREATE) {
      case 'SUCCESS_CORPORATION':
        updateDispatchEmergencies();
        break;
      default:
        break;
    }
  }, [FINISH_CREATE]);

  useEffect(() => {
    const socketId = subscribeToChannel({
      topic: SOCKET_CHANNELS_TOPICS.emergencyInformationChanged(),
      eventHandler: ({ jsonBody }) => {
        dispatch(addComplementedEmergency({ emergencyId: jsonBody?.incidentId, complementType: jsonBody?.typeEvent }));
      }
    });
    return () => {
      unsubscribeChannelById(socketId);
    };
  }, []);

  return <>{children}</>;
}

HandlerResults.propTypes = {
  children: PropTypes.node
};

export default HandlerResults;
Leave a Comment