Files
collection-portal/src/pages/LiveLocationTracker/utils.tsx

267 lines
8.9 KiB
TypeScript
Raw Normal View History

import dayjs from 'dayjs';
import { createQueryParams, readQueryParams } from 'src/utils/QueryParamsHelper';
import { getAgentAllocations, getAgentLocationHistory } from './actions/LiveLocationTrackerActions';
import {
AgentDetailsPayload,
IAgentAllocation,
IAgentLocationHistory,
ISelectedFeedback,
LOCATION_TYPE_FILTERS,
MapPinLocation
} from './constants/LiveLocationTrackerInterfaces';
import { AGENT_LIVE_LOCATION } from './constants/LiveLocatonTrackerConstants';
import { NavigateFunction } from 'react-router-dom';
import { formatEpochTime } from 'src/utils/DateHelper';
import styles from './components/AgentMarker/agentMarker.module.scss';
import { v4 as uuidv4 } from 'uuid';
TP-42467 | External Agency Dashboards V1: AM - Overall and Field Governance (#787) * TP-42467 | Inital Commit * TP-42467 | Table CHanges * TP-42467 | Table Changes * TP-42467 | Redux Setup + Actions Added * TP-42467 | Table Changes * TP-42467 | Routing Changes + Tabs Changes + Table Changes * TP-42467 | Agent Name Options support added * TP-42467 | Code Refactored * TP-42467 | Column Def changes * TP-42467 | API Contract Changes * TP-42467 | API helper changes * TP-42467 | Css Fixes + Agent Map Location Entry point added * TP-42467 | Clickstream Added + Tab Issues Fixes + Feature Flags Added * TP-42467 | Code Refactored * TP-42467 | Mocks Added * TP-42467 | Last Updated Logic Added * TP-42467 | Polling Added * TP-42461 |removed comments| Aman Singh * TP-42467 |lint issues| Aman Singh * TP-42467 | Table UI flickering fix * TP-42467 | Filter changes for DPD Table * TP-42467 | Filter changes + Query Params Changing + Refactoring + Routing * TP-42467 | API Fix + Loading State Fix + Table changes * TP-42467 | Path Param Changes * TP-42467 | API Integration * TP-42467 | Code Refactored * TP-42467 | Minor fix * TP-42467 | Contract Changes + Code Refactored * TP-42467 | Contract Changes * TP-42467 | UAT Fixes * TP-42467 | UAT Fixes * TP-42467 | Time format fix * TP-42467 | Bug Fixes * TP-42467 | UAT Fixes * TP-42467 | Code Refactored * TP-42467 | Bug Fix * TP-42467 | PR comments reolved * TP-42467 | endpoint change * TP-42567 | UAT Fix * TP-42467 | web ui library update --------- Co-authored-by: aman.singh <aman.singh@navi.com> Co-authored-by: Varnit Goyal <varnit.goyal@navi.com>
2024-01-24 22:47:13 +05:30
import { LocalStorage } from '@cp/src/utils/StorageUtils';
enum MapPinsZIndices {
CASES = 1,
AGENT = 2,
GENUINE_FEEDBACK = 3,
SUSPICIOUS_FEEDBACK = 4
}
export const getAllocationPins = (
data: Record<string, IAgentAllocation>,
agentLocationHistory: IAgentLocationHistory[]
) => {
const casesLocation: MapPinLocation[] = [];
const feedbacksLocation = [];
const suspiciousFeedback: MapPinLocation[] = [];
const genuineFeedback: MapPinLocation[] = [];
const agentLocations: IAgentLocationHistory[] = [];
for (const lanNo in data) {
if (data?.[lanNo]?.location) {
casesLocation.push({
type: LOCATION_TYPE_FILTERS.CASES,
location: data?.[lanNo]?.location,
lanNo,
name: data?.[lanNo]?.customerName,
addressText: data?.[lanNo]?.addressText,
zIndex: MapPinsZIndices.CASES
});
}
if (data?.[lanNo]?.feedbacks) {
const feedbacks = data[lanNo].feedbacks.map(feedback => ({
...feedback,
lanNo
}));
feedbacksLocation.push(...feedbacks);
}
}
feedbacksLocation?.forEach(feedback => {
if (feedback.suspicious) {
suspiciousFeedback?.push({
type: LOCATION_TYPE_FILTERS.SUSPICIOUS_FEEDBACK,
location: feedback?.location,
interactionId: feedback?.interactionId,
lastUpdatedAt: formatEpochTime(feedback?.epochTimestamp),
interactionStatus: feedback?.interactionStatus,
lanNo: feedback?.lanNo,
zIndex: MapPinsZIndices.SUSPICIOUS_FEEDBACK
});
return;
}
genuineFeedback?.push({
type: LOCATION_TYPE_FILTERS.GENUINE_FEEDBACK,
location: feedback?.location,
interactionId: feedback?.interactionId,
lastUpdatedAt: formatEpochTime(feedback?.epochTimestamp),
interactionStatus: feedback?.interactionStatus,
lanNo: feedback?.lanNo,
zIndex: MapPinsZIndices.GENUINE_FEEDBACK
});
});
agentLocationHistory?.forEach((locationData: IAgentLocationHistory) => {
agentLocations.push({
...locationData,
zIndex: MapPinsZIndices.AGENT
});
});
return {
casesLocation,
suspiciousFeedback,
genuineFeedback,
agentLocations,
disabledFilters: {
[LOCATION_TYPE_FILTERS.AGENT]: !agentLocationHistory?.length,
[LOCATION_TYPE_FILTERS.CASES]: !casesLocation?.length,
[LOCATION_TYPE_FILTERS.GENUINE_FEEDBACK]: !genuineFeedback?.length,
[LOCATION_TYPE_FILTERS.SUSPICIOUS_FEEDBACK]: !suspiciousFeedback?.length
}
};
};
export const getAgentLocationFormattedData = (data: IAgentLocationHistory[]) => {
const agentLocationHistory: MapPinLocation[] = [];
data?.forEach((locationData: IAgentLocationHistory) => {
agentLocationHistory.push({
type: LOCATION_TYPE_FILTERS.AGENT,
location: locationData?.location,
lastUpdatedAt: formatEpochTime(locationData?.epochTimestamp),
referenceId: uuidv4()
});
});
return agentLocationHistory;
};
export const getMapLocations = (
locationFilters: Record<string, boolean>,
agentAllocations: Record<string, IAgentAllocation> | null,
agentLocationHistory: IAgentLocationHistory[]
) => {
const { casesLocation, suspiciousFeedback, genuineFeedback, agentLocations, disabledFilters } =
getAllocationPins(agentAllocations ?? {}, agentLocationHistory);
// Initialize an empty array to hold the combined data for all selected filters
let combinedData: Array<MapPinLocation | IAgentLocationHistory> = [];
// Check if the array includes specific filters and add the corresponding data
if (locationFilters?.[LOCATION_TYPE_FILTERS.CASES]) {
combinedData = [...combinedData, ...casesLocation];
}
if (locationFilters?.[LOCATION_TYPE_FILTERS.AGENT]) {
combinedData = [...combinedData, ...agentLocations];
}
if (locationFilters?.[LOCATION_TYPE_FILTERS.GENUINE_FEEDBACK]) {
combinedData = [...combinedData, ...genuineFeedback];
}
if (locationFilters?.[LOCATION_TYPE_FILTERS.SUSPICIOUS_FEEDBACK]) {
combinedData = [...combinedData, ...suspiciousFeedback];
}
// If no specific filters are selected or the ALL filter is selected, combine all data
if (locationFilters?.[LOCATION_TYPE_FILTERS.ALL]) {
combinedData = [...casesLocation, ...agentLocations, ...genuineFeedback, ...suspiciousFeedback];
}
return {
data: combinedData,
disabledFilters
};
};
export const getMaxInputDate = (format: string) => {
return dayjs().format(format);
};
// start of the month
export const getMinInputDate = (format: string) => {
return dayjs().startOf('month').format(format);
};
export const getAgentDetails =
(payload: AgentDetailsPayload, navigate: NavigateFunction) => (dispatch: any) => {
const { [AGENT_LIVE_LOCATION]: queryParams = {} } = readQueryParams();
const url = createQueryParams({
[AGENT_LIVE_LOCATION]: { ...queryParams, DATE: payload?.date, SELECTED_FEEDBACK_ID: '' }
});
navigate(url);
dispatch(getAgentLocationHistory(payload));
dispatch(getAgentAllocations(payload));
};
export const shouldZoomIn = (
selectedFeedback: ISelectedFeedback,
type: LOCATION_TYPE_FILTERS | undefined,
lanNo: string | undefined,
interactionId: string | undefined
) => {
if (!type) return false;
return (
(selectedFeedback?.lanNo === lanNo && type === LOCATION_TYPE_FILTERS.CASES) ||
(selectedFeedback?.interactionId === interactionId &&
[LOCATION_TYPE_FILTERS.SUSPICIOUS_FEEDBACK, LOCATION_TYPE_FILTERS.GENUINE_FEEDBACK].includes(
type
))
);
};
// [OVERLAY-POPUP] Reference: https://developers.google.com/maps/documentation/javascript/examples/overlay-popup
export const loadCustomPopup = (type?: string) => {
class CustomPopup extends google.maps.OverlayView {
position: google.maps.LatLng;
containerDiv: HTMLDivElement;
refId: string;
constructor(position: google.maps.LatLng, content: HTMLElement, refId: string) {
super();
this.position = position;
this.refId = refId;
content.classList.add(styles.popupBubble);
// This zero-height div is positioned at the bottom of the bubble.
const bubbleAnchor = document.createElement('div');
bubbleAnchor.classList.add(styles.popupBubbleAnchor);
if (!type) {
content.classList.add(styles.agentPopupBubble);
bubbleAnchor.classList.add(styles.agentPopupBubbleAnchor);
}
bubbleAnchor.appendChild(content);
// This zero-height div is positioned at the bottom of the tip.
this.containerDiv = document.createElement('div');
this.containerDiv.classList.add(styles.popupContainer);
this.containerDiv.appendChild(bubbleAnchor);
// Optionally stop clicks, etc., from bubbling up to the map.
CustomPopup.preventMapHitsAndGesturesFrom(this.containerDiv);
}
/** Called when the popup is added to the map. */
onAdd() {
this.getPanes()!.floatPane.appendChild(this.containerDiv);
}
/** Called when the popup is removed from the map. */
onRemove() {
if (this.containerDiv.parentElement) {
this.containerDiv.parentElement.removeChild(this.containerDiv);
}
}
/** Called each frame when the popup needs to draw itself. */
draw() {
const divPosition = this.getProjection().fromLatLngToDivPixel(this.position)!;
// Hide the popup when it is far out of view.
const display =
Math.abs(divPosition.x) < 4000 && Math.abs(divPosition.y) < 4000 ? 'block' : 'none';
if (display === 'block') {
this.containerDiv.style.left = divPosition.x + 'px';
this.containerDiv.style.top = divPosition.y + 'px';
}
if (this.containerDiv.style.display !== display) {
this.containerDiv.style.display = display;
}
}
}
return CustomPopup;
};
TP-42467 | External Agency Dashboards V1: AM - Overall and Field Governance (#787) * TP-42467 | Inital Commit * TP-42467 | Table CHanges * TP-42467 | Table Changes * TP-42467 | Redux Setup + Actions Added * TP-42467 | Table Changes * TP-42467 | Routing Changes + Tabs Changes + Table Changes * TP-42467 | Agent Name Options support added * TP-42467 | Code Refactored * TP-42467 | Column Def changes * TP-42467 | API Contract Changes * TP-42467 | API helper changes * TP-42467 | Css Fixes + Agent Map Location Entry point added * TP-42467 | Clickstream Added + Tab Issues Fixes + Feature Flags Added * TP-42467 | Code Refactored * TP-42467 | Mocks Added * TP-42467 | Last Updated Logic Added * TP-42467 | Polling Added * TP-42461 |removed comments| Aman Singh * TP-42467 |lint issues| Aman Singh * TP-42467 | Table UI flickering fix * TP-42467 | Filter changes for DPD Table * TP-42467 | Filter changes + Query Params Changing + Refactoring + Routing * TP-42467 | API Fix + Loading State Fix + Table changes * TP-42467 | Path Param Changes * TP-42467 | API Integration * TP-42467 | Code Refactored * TP-42467 | Minor fix * TP-42467 | Contract Changes + Code Refactored * TP-42467 | Contract Changes * TP-42467 | UAT Fixes * TP-42467 | UAT Fixes * TP-42467 | Time format fix * TP-42467 | Bug Fixes * TP-42467 | UAT Fixes * TP-42467 | Code Refactored * TP-42467 | Bug Fix * TP-42467 | PR comments reolved * TP-42467 | endpoint change * TP-42567 | UAT Fix * TP-42467 | web ui library update --------- Co-authored-by: aman.singh <aman.singh@navi.com> Co-authored-by: Varnit Goyal <varnit.goyal@navi.com>
2024-01-24 22:47:13 +05:30
export const getLiveLocationParams = (source: string) => {
// Get the current live-location-tracker-params from local storage
const currentParams = LocalStorage.getItem('live-location-tracker-params') || '';
const paramRegex = /SOURCE\*AGENT_LIVE_LOCATION=[^&]*/;
const hasParam = paramRegex.test(currentParams);
let updatedParams;
if (hasParam) {
updatedParams = currentParams.replace(paramRegex, `SOURCE*${AGENT_LIVE_LOCATION}=${source}`);
} else {
updatedParams =
currentParams + (currentParams ? '&' : '?') + `SOURCE*${AGENT_LIVE_LOCATION}=${source}`;
}
return updatedParams;
};