NTP-42556 | Escalation count (#1394)

* NTP-42556 | Escalation count

* NTP-42556 | Escalation count

* NTP-42556 | Escalation count

* NTP-42556 | Escalation count

* NTP-42556 | Escalation count

* NTP-42556 | Escalation count

* NTP-42556 | Escalation count

* NTP-39150 | Retrigger Allocation

* NTP-42556 | Escalation count

* NTP-42556 | Escalation count

* NTP-42556 | Escalation count

* NTP-42556 | Escalation count

* NTP-42556 | Escalation count
This commit is contained in:
Ashish Deo
2025-03-21 17:41:59 +05:30
committed by GitHub
parent 0c489ce440
commit d657a86fe7
11 changed files with 203 additions and 66 deletions

View File

@@ -0,0 +1,25 @@
import React from 'react';
import { IconProps } from './types';
const EscalationUserIcon: React.FC<IconProps> = props => {
const { width = 24, height = 24 } = props;
return (
<svg
width={width}
height={height}
viewBox="0 0 28 28"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="28" height="28" rx="14" fill="#FFEBEB" />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M14 6.125C15.9367 6.125 17.5 7.68833 17.5 9.625C17.5 11.5617 15.9367 13.125 14 13.125C12.0633 13.125 10.5 11.5617 10.5 9.625C10.5 7.68833 12.0633 6.125 14 6.125ZM14 22.6917C11.0833 22.6917 8.505 21.1983 7 18.935C7.035 16.6133 11.6667 15.3417 14 15.3417C16.3217 15.3417 20.965 16.6133 21 18.935C19.495 21.1983 16.9167 22.6917 14 22.6917Z"
fill="#E92C2C"
/>
</svg>
);
};
export default EscalationUserIcon;

View File

@@ -0,0 +1,19 @@
const EscalationNotifIcon = () => {
return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24" height="24" rx="12" fill="#FFEBEB" />
<mask id="mask0_7834_69205" maskUnits="userSpaceOnUse" x="4" y="4" width="16" height="16">
<rect x="4" y="4" width="16" height="16" fill="#D9D9D9" />
</mask>
<g mask="url(#mask0_7834_69205)">
<rect x="9" y="8" width="6" height="8" fill="white" />
<path
d="M12 18.6792C11.8223 18.6792 11.6528 18.6458 11.4917 18.5792C11.3306 18.5125 11.1834 18.4181 11.05 18.2958L5.70004 12.9458C5.57782 12.8125 5.48338 12.6653 5.41671 12.5042C5.35004 12.3431 5.31671 12.1736 5.31671 11.9958C5.31671 11.8181 5.35004 11.6458 5.41671 11.4792C5.48338 11.3125 5.57782 11.1681 5.70004 11.0458L11.05 5.69583C11.1834 5.5625 11.3306 5.46528 11.4917 5.40417C11.6528 5.34306 11.8223 5.3125 12 5.3125C12.1778 5.3125 12.35 5.34306 12.5167 5.40417C12.6834 5.46528 12.8278 5.5625 12.95 5.69583L18.3 11.0458C18.4334 11.1681 18.5306 11.3125 18.5917 11.4792C18.6528 11.6458 18.6834 11.8181 18.6834 11.9958C18.6834 12.1736 18.6528 12.3431 18.5917 12.5042C18.5306 12.6653 18.4334 12.8125 18.3 12.9458L12.95 18.2958C12.8278 18.4181 12.6834 18.5125 12.5167 18.5792C12.35 18.6458 12.1778 18.6792 12 18.6792ZM12 12.6625C12.1889 12.6625 12.3473 12.5986 12.475 12.4708C12.6028 12.3431 12.6667 12.1847 12.6667 11.9958V9.32917C12.6667 9.14028 12.6028 8.98194 12.475 8.85417C12.3473 8.72639 12.1889 8.6625 12 8.6625C11.8112 8.6625 11.6528 8.72639 11.525 8.85417C11.3973 8.98194 11.3334 9.14028 11.3334 9.32917V11.9958C11.3334 12.1847 11.3973 12.3431 11.525 12.4708C11.6528 12.5986 11.8112 12.6625 12 12.6625ZM12 14.6625C12.1889 14.6625 12.3473 14.5986 12.475 14.4708C12.6028 14.3431 12.6667 14.1847 12.6667 13.9958C12.6667 13.8069 12.6028 13.6486 12.475 13.5208C12.3473 13.3931 12.1889 13.3292 12 13.3292C11.8112 13.3292 11.6528 13.3931 11.525 13.5208C11.3973 13.6486 11.3334 13.8069 11.3334 13.9958C11.3334 14.1847 11.3973 14.3431 11.525 14.4708C11.6528 14.5986 11.8112 14.6625 12 14.6625Z"
fill="#E92C2C"
/>
</g>
</svg>
);
};
export default EscalationNotifIcon;

View File

@@ -11,6 +11,8 @@ import { RootState } from '../../store';
import NotificationBell from '../../assets/images/icons/NotificationBell';
import Typography from '@primitives/Typography';
import cx from 'classnames';
import { getReporteesWithAllocation } from '../sidebar/actions/escalationsAction';
import { setShowLogoutModal } from '@cp/src/reducers/commonSlice';
interface FcmNotificationProps {
notification: any;
@@ -22,6 +24,10 @@ const FcmNotification = ({ notification }: FcmNotificationProps) => {
const navigate = useNavigate();
const widget = notificationTemplate?.widgets?.[0];
const phoneNumber = useSelector((state: RootState) => state.common.userData?.phoneNumber);
const agentReferenceId = useSelector((state: RootState) => state.common.userData?.referenceId);
const countOfEscalationEnabled = useSelector(
(state: RootState) => state?.common?.featureFlags?.countOfEscalationEnabled
);
const handleNotificationClick = () => {
const { params } = notification;
if (
@@ -31,6 +37,9 @@ const FcmNotification = ({ notification }: FcmNotificationProps) => {
].includes(notificationTemplate?.templateName)
) {
navigate(APP_ROUTES.CASES.path);
} else if (TemplateTypes.COLLECTION_ESCALATION_RAISED === notificationTemplate?.templateName) {
dispatch(getReporteesWithAllocation(agentReferenceId || '', countOfEscalationEnabled));
dispatch(setShowLogoutModal(true));
} else {
navigateToCaseDetails(
params?.customerReferenceId,

View File

@@ -26,6 +26,8 @@ import { interpolatePathParams } from '@cp/src/utils/interpolate';
import { TAB_KEYS as RIGHT_SIDE_TABS } from '@cp/src/pages/CaseDetails/constants/RightSidebar.constant';
import { TAB_KEYS } from '@cp/src/pages/CaseDetails/constants';
import { AnomalyStatus, AnomalyTableKeys } from '@cp/src/pages/AnomalyTracker/types';
import { getReporteesWithAllocation } from '../sidebar/actions/escalationsAction';
import { setShowLogoutModal } from '@cp/src/reducers/commonSlice';
const NotificationList: React.FC<NotificationListProps> = ({
toggleNotifications,
@@ -39,6 +41,10 @@ const NotificationList: React.FC<NotificationListProps> = ({
const templatesMap = useSelector((state: RootState) => state?.notification.templatesMap);
const phoneNumber = useSelector((state: RootState) => state.common.userData?.phoneNumber);
const agentReferenceId = useSelector((state: RootState) => state.common.userData?.referenceId);
const countOfEscalationEnabled = useSelector(
(state: RootState) => state?.common?.featureFlags?.countOfEscalationEnabled
);
const handleNotificationClick = (
notification: NotificationsData,
@@ -91,6 +97,9 @@ const NotificationList: React.FC<NotificationListProps> = ({
}
});
navigate(`${APP_ROUTES_PATHS_WITH_PATH_PARAM.ANOMALY_TRACKER.open}${queryParams}`);
} else if (templateName === TemplateTypes.COLLECTION_ESCALATION_RAISED) {
dispatch(getReporteesWithAllocation(agentReferenceId || '', countOfEscalationEnabled));
dispatch(setShowLogoutModal(true));
} else {
navigateToCaseDetails(
params?.customerReferenceId,

View File

@@ -16,6 +16,7 @@ import FeeReappliedIcon from '@cp/src/assets/icons/FeeReappliedIcon';
import InfoNotification from '@cp/src/assets/images/icons/InfoNotification';
import AnomalyResolvedIcon from '@cp/src/assets/images/icons/AnomalyResolvedIcon';
import AnomalyDetectedIcon from '@cp/src/assets/images/icons/AnomalyDetectedIcon';
import EscalationNotifIcon from '@cp/src/assets/images/icons/EscalationNotifIcon';
export enum NotificationTypes {
LONGHORN_NOTIFICATION = 'LONGHORN_NOTIFICATION',
@@ -68,7 +69,8 @@ export const TemplateTypes = {
ANOMALY_TRACKER_DETECTION: 'ANOMALY_TRACKER_DETECTION_V2',
ANOMALY_TRACKER_RESOLUTION: 'ANOMALY_TRACKER_RESOLUTION',
COLLECTION_PAUSE_EFFORTS_CASE_PAUSED: 'COLLECTION_PAUSE_EFFORTS_CASE_PAUSED',
COLLECTION_UNPAUSE_EFFORT_EVENT: 'COLLECTION_UNPAUSE_EFFORT_EVENT'
COLLECTION_UNPAUSE_EFFORT_EVENT: 'COLLECTION_UNPAUSE_EFFORT_EVENT',
COLLECTION_ESCALATION_RAISED: 'COLLECTION_ESCALATION_RAISED'
};
export const PaymentSuccessTemplateTypes = [
@@ -123,7 +125,8 @@ export const NotificationTabTemplateMap = {
TemplateTypes.FIELD_BOT_REVISIT_SCHEDULED_NOTIFICATION_TEMPLATE,
TemplateTypes.MESSAGE_WAIVE_UNHOLD_NOTIFICATION_TEMPLATE,
TemplateTypes.COLLECTION_PAUSE_EFFORTS_CASE_PAUSED,
TemplateTypes.COLLECTION_UNPAUSE_EFFORT_EVENT
TemplateTypes.COLLECTION_UNPAUSE_EFFORT_EVENT,
TemplateTypes.COLLECTION_ESCALATION_RAISED
],
[NotificationTabTypes.All]: [
TemplateTypes.PAYMENT_MADE_TEMPLATE,
@@ -156,7 +159,8 @@ export const NotificationTabTemplateMap = {
TemplateTypes.ANOMALY_TRACKER_DETECTION,
TemplateTypes.ANOMALY_TRACKER_RESOLUTION,
TemplateTypes.COLLECTION_PAUSE_EFFORTS_CASE_PAUSED,
TemplateTypes.COLLECTION_UNPAUSE_EFFORT_EVENT
TemplateTypes.COLLECTION_UNPAUSE_EFFORT_EVENT,
TemplateTypes.COLLECTION_ESCALATION_RAISED
],
[NotificationTabTypes.Tasks]: [
TemplateTypes.SUPPORT_REQUEST_RECEIVED,
@@ -310,6 +314,10 @@ export const TemplateInfoMap = {
[TemplateTypes.ANOMALY_TRACKER_RESOLUTION]: {
label: 'Anomaly resolved',
icon: <AnomalyResolvedIcon />
},
[TemplateTypes.COLLECTION_ESCALATION_RAISED]: {
label: 'Collection Escalation Raised',
icon: <EscalationNotifIcon />
}
};

View File

@@ -173,7 +173,7 @@
.logoutContainer {
position: absolute;
display: flex;
width: 220px;
width: 260px;
padding: 16px;
flex-direction: column;
align-items: flex-start;
@@ -304,3 +304,9 @@
cursor: pointer;
text-align: center;
}
.horizontalLine {
width: 100%;
height: 1px;
background: var(--navi-color-gray-border);
}

View File

@@ -1,13 +1,10 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import Typography from '@navi/web-ui/lib/primitives/Typography/index';
import cx from 'classnames';
import { Link, useLocation } from 'react-router-dom';
// styles
import styles from './SideNavBar.module.scss';
// functions, components and utlis
import cx from 'classnames';
import NaviNewLogoIcon from '@navi/web-ui/lib/icons/NaviLogoIcon/NaviNewLogoIcon';
import SideBarItems, { DASHBOARD_URL, HideSideBar } from './SideBarItems';
import SideBarItems, { HideSideBar } from './SideBarItems';
import SidebarLinks, { clearParamsMap } from './SidebarLinks';
import AgentIcon from '../../assets/images/icons/AgentIcon';
import { useDispatch, useSelector } from 'react-redux';
@@ -15,7 +12,8 @@ import { RootState } from '../../store';
import {
CosmosSyncBlockStatus,
resetHumanReminderCustomerDetails,
setAuthData
setAuthData,
setShowLogoutModal
} from '../../reducers/commonSlice';
import { setShowOTPScreen } from '../../pages/auth/reducers/authSlice';
import { logOut } from 'src/pages/auth/AuthActions';
@@ -25,12 +23,7 @@ import CircularProgress from '../ProgressBars/circularProgress/CircularProgress'
import Tooltip, { directions } from '../Tooltip';
import { AmeyoCollapsibleToolbarV3 } from '@cp/components/Ameyo/AmeyoCollapsibleToolbarV3';
import Switch from '@navi/web-ui/lib/primitives/Switch/Switch';
import {
refreshCallData,
setCallId,
setIsAgentOnline,
setManualLoginCreds
} from 'src/reducers/humanReminderSlice';
import { refreshCallData, setManualLoginCreds } from 'src/reducers/humanReminderSlice';
import { ExtensionHandler } from 'src/utils/extension.utils';
import { AMEYO_STATUS_CODES } from 'src/service/naviExtension.service';
import APP_ROUTES, { APP_ROUTES_PATHS_WITH_PATH_PARAM } from 'src/layout/Routes';
@@ -50,7 +43,6 @@ import { LOCAL_STORAGE_KEYS } from '../../constants/StorageKeys';
import useLocalStorageObserver from '../../hooks/useLocalStorageObserver';
import { Roles } from 'src/pages/auth/constants/AuthConstants';
import GenerateAmeyoPasswordIcon from '../../assets/icons/GenerateAmeyoPasswordIcon';
import AgencyPincodeMappingIcon from '../../assets/icons/AgencyPincodeMappingIcon';
import WhatsappChatIcon from '../../assets/icons/WhatsappChatIcon';
import { agentOnlineToggleHandler } from '../../pages/WhatsappChatbot/actions';
import {
@@ -73,22 +65,24 @@ import AllocationNavbarIcon from '@cp/src/assets/images/icons/AllocationNavbarIc
import EnachIcon from '@cp/src/assets/icons/EnachIcon';
import { getAgentDocuments } from './actions/downloadDRA';
import { downloadDocumentFromS3WithoughtPreview } from '@cp/src/utils/DocumentDownloadFromS3';
import { AGENT_DOCUMENT_TYPE } from './constants/constants';
import { DOCUMENTS_MAP } from './constants/constants';
import CustomLogoutIcon from '@cp/src/assets/icons/CustomLogoutIcon';
import CustomUserIcon from '@cp/src/assets/icons/CustomUserIcon';
import AgencyIcon from '@cp/src/assets/icons/AgencyIcon';
import RefreshIcon from '@icons/RefreshIcon';
import AgencyOperationsIcon from '@cp/assets/icons/AgencyOperationsIcon';
import { noop } from '@utils/common';
import { AmeyoCollapsibleToolbarV4 } from '@cp/components/Ameyo/AmeyoCollapsibleToolbarV4';
import logoutFromAmeyo from '@cp/utils/logoutFromAmeyo';
import AnomalyTrackerIcon from '@cp/src/assets/icons/AnomalyTrackerIcon';
import axiosInstance, { ApiKeys, getApiUrl, logError } from '@cp/src/utils/ApiHelper';
import { logError } from '@cp/src/utils/ApiHelper';
import sdkHelper from '@cp/src/pages/DashboardV3/utils/sdkHelper';
import { setAgentAvailability } from '@cp/src/pages/DashboardV2/dc-97/HumanReminderAction';
import { AGENT_AVAILABILITY } from '@cp/src/pages/DashboardV2/dc-97/dc97Constant';
import isNaviAgency from '@cp/src/utils/isNaviAgency';
import UserDocuments from './UserDocuments';
import EscalationUserIcon from '@cp/src/assets/icons/EscalationUserIcon';
import { Tag } from '@navi/web-ui/lib/primitives';
import { getReporteesWithAllocation } from './actions/escalationsAction';
interface ISideNavbarProps {
isDc97User?: boolean;
@@ -159,6 +153,7 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
(state: RootState) => state?.idCardApprovals?.totalPendingApprovalsNotificationCount
);
const agencyCode = useSelector((state: RootState) => state?.common?.userData?.agencyCode);
const agentReferenceId = useSelector((state: RootState) => state?.common?.userData?.referenceId);
const percentCompletedCases = useSelector(
(state: RootState) => state.leaderboard.percentCompletedRecords
)?.reduce(
@@ -178,13 +173,10 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
const isTeleInhouseTeamLead = userData?.roles?.includes(Roles.ROLE_NAVI_TELE_INHOUSE_TEAM_LEAD);
const disableAmeyoToolbarFlag = window?.config?.DISABLE_AMEYO_TOOLBAR === 'true' || isDc97User;
const [showLogout, setShowLogout] = useState<boolean>(false);
const [disableLogout, setDisableLogout] = useState<boolean>(false);
const [showNotifications, setShowNotifications] = useState(false);
const dispatch = useDispatch();
const isTeleChatAgent = userData?.roles?.includes(Roles.ROLE_TELE_CHAT_AGENT);
// const percentage = 30;
const unsubscribe = React.useRef<() => void>();
const agentId = userData?.referenceId;
const agentsData = useSelector((state: RootState) => state?.agentDocumentSlice?.documentsData);
const isAgentWithInOperativeHours = useSelector(
@@ -196,6 +188,13 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
const isAgencyCappingEnabled = useSelector(
(store: RootState) => store?.common?.featureFlags?.agencyCappingEnabled
);
const agentEscalationCount = useSelector(
(state: RootState) => state?.common?.agentEscalationCount
);
const countOfEscalationEnabled = useSelector(
(state: RootState) => state?.common?.featureFlags?.countOfEscalationEnabled
);
const showLogoutModal = useSelector((state: RootState) => state?.common?.showLogoutModal);
const [isAmeyoNewIntegrationEnabled, setIsAmeyoNewIntegrationEnabled] = useState(false);
const [isHRCNewIntegration, setIsHRCNewIntegration] = useState(false);
@@ -245,7 +244,6 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
localStorage.removeItem(LOCAL_STORAGE_KEYS.LONGHORN_FIREBASE_TOKEN);
localStorage.removeItem(CURRENT_CHAT_REF_ID_KEY);
localStorage.removeItem(HRC_CHAT_AGENT_ONLINE_STATUS);
// localStorage.removeItem(chatMessageContentKey);
logOut();
};
@@ -345,14 +343,16 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
addClickstreamEvent(clickStreamEvent);
};
const handleDashboardClick = () => {
toggleNotifications(false);
};
const openFeedbackForm = () => {
window.open(feedbackFormUrl, '_blank');
};
const notifications = useSelector((store: RootState) => store?.notification.notifications);
useEffect(() => {
dispatch(getReporteesWithAllocation(agentReferenceId || '', countOfEscalationEnabled));
}, [notifications]);
const TooltipContent = () => (
<div className={styles.tooltipContentContainer}>
<div className={styles.labelText}>Cases Completed</div>
@@ -397,17 +397,16 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
dispatch(getAgentDocuments());
}, [agentId]);
const documentDra = agentsData?.find(
doc => doc.documentType === AGENT_DOCUMENT_TYPE.DRA_CERTIFICATE
const documents = agentsData?.filter(
doc => DOCUMENTS_MAP[doc.documentType as keyof typeof DOCUMENTS_MAP]
);
const handleDownloadDraClick = (url: string, name: string) => {
addClickstreamEvent(AGENT_LOGOUT_CLICK.LH_DOCUMENT_DOWNLOAD_CLICKED, {
documentType: agentsData?.map(item => item.docContentType),
documentName: agentsData?.map(item => item.documentName)
});
downloadDocumentFromS3WithoughtPreview(url, name, `Cannot Download the document`);
};
const isDraCertificatePresent = documents?.length;
const showHorizontalLine =
countOfEscalationEnabled && isDraCertificatePresent && agentEscalationCount > 0;
const showEscalationCount = countOfEscalationEnabled && agentEscalationCount > 0;
// TODO:: REMOVE THIS CODE AFTER ONCE THINGS ARE STABLE
const isUserManagementRole =
@@ -421,7 +420,7 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
className={cx(styles.sideNavBarMain, {
[styles.sideNavBarMain__hovered]: showNotifications
})}
onMouseLeave={() => setShowLogout(false)}
onMouseLeave={() => dispatch(setShowLogoutModal(false))}
>
<div className={styles.logoContainer}>
<Link
@@ -446,7 +445,7 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
clickStreamEvent={CLICKSTREAM_EVENT_NAMES.LH_ALL_AGENTS_SIDE_PANEL_CLICK}
/>
<div className={styles.alignBotton}>
{showLogout ? (
{showLogoutModal ? (
<div className={styles.logoutContainer}>
<div className="flex flex-col gap-y-3 w-full">
<div className={styles.agentDetails}>
@@ -484,7 +483,7 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
<div
className={cx(styles.sideNavBarLinks, styles.logoutLink)}
onClick={() => {
setShowLogout(prev => !prev);
dispatch(setShowLogoutModal(!showLogoutModal));
dispatch(getAgentDocuments());
}}
>
@@ -506,7 +505,7 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
className={cx(styles.sideNavBarMain, {
[styles.sideNavBarMain__hovered]: showNotifications
})}
onMouseLeave={() => setShowLogout(false)}
onMouseLeave={() => dispatch(setShowLogoutModal(false))}
>
<div className={styles.logoContainer}>
<Link
@@ -762,7 +761,6 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
clickStreamEvent={CLICKSTREAM_EVENT_NAMES.LH_ALL_AGENTS_SIDE_PANEL_CLICK}
/>
) : null}
{/* {isTeleInhouseTeamLead ? (
<>
<SidebarLinks
@@ -778,6 +776,7 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
/>
</>
) : null} */}
{enachProcessingEnabled ? (
<>
<SidebarLinks
@@ -803,6 +802,7 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
linkClickHandler={linkClickHandler}
currentPathname={pathname}
currentSearch={search}
clickStreamEvent={CLICKSTREAM_EVENT_NAMES.LH_AMEYO_CALL_DISABLED_DISCONNECT_CLICKED}
/>
) : null}
{showParamount ? (
@@ -862,26 +862,50 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
/>
) : null}
<div className={styles.alignBotton}>
{showLogout ? (
{showLogoutModal ? (
<div className={styles.logoutContainer}>
<div className="flex flex-col gap-y-4 w-full">
<div className={styles.agentDetails}>
<CustomUserIcon width={40} height={40} fillColor="var(--greyscale-light)" />
<div className={styles.agentNameContainer}>
<Typography
variant={'h6'}
className="max-w-[138px] text-ellipsis whitespace-nowrap overflow-hidden"
>
{user?.name}
</Typography>
<Typography
variant={'p5'}
className="max-w-[138px] text-ellipsis whitespace-nowrap overflow-hidden mt-1"
>
{user?.email}
</Typography>
{showEscalationCount ? (
<EscalationUserIcon
width={40}
height={40}
fillColor="var(--greyscale-light)"
/>
) : (
<CustomUserIcon width={40} height={40} fillColor="var(--greyscale-light)" />
)}
<div className="flex flex-col">
<div className={styles.agentNameContainer}>
<Typography
variant={'h6'}
className="max-w-[138px] text-ellipsis whitespace-nowrap overflow-hidden"
>
{user?.name}
</Typography>
<Typography
variant={'p5'}
className="max-w-[138px] text-ellipsis whitespace-nowrap overflow-hidden mt-1"
>
{user?.email}
</Typography>
</div>
{showEscalationCount ? (
<>
<div className={'mt-2'}>
<Tag
color="red"
label={`${agentEscalationCount} escalation in last 60 days`}
size="sm"
variant="transparent"
/>
</div>
</>
) : null}
</div>
</div>
{showHorizontalLine ? <div className={styles.horizontalLine} /> : null}
<UserDocuments />
</div>
@@ -940,11 +964,14 @@ function SideNavBar({ isDc97User, isHRCChatUser }: ISideNavbarProps) {
<div
className={cx(styles.sideNavBarLinks, styles.logoutLink)}
onClick={() => {
setShowLogout(prev => !prev);
dispatch(setShowLogoutModal(!showLogoutModal));
dispatch(getAgentDocuments());
dispatch(
getReporteesWithAllocation(agentReferenceId || '', countOfEscalationEnabled)
);
}}
>
<AgentIcon />
{showEscalationCount ? <EscalationUserIcon /> : <AgentIcon />}
<Typography variant="h3" className={cx([styles.sideNavBarItems, styles.text])}>
<span title={user?.name}>{user?.name}</span>
</Typography>

View File

@@ -29,12 +29,11 @@ const UserDocument = (props: IUserDocument) => {
onClick={handleDownloadDraClick}
>
<div className="flex flex-row justify-between gap-1">
<FileIcon fillColor="var(--blue-base)" width={20} height={20} />
<DownloadIcon width={20} height={20} color="var(--blue-base)" />
<div className="flex items-center text-grayscale-content-2 text-xs font-medium leading-5">
{document?.documentName}
{`Download ${document?.documentName}`}
</div>
</div>
<DownloadIcon width={20} height={20} color="var(--blue-base)" />
</div>
);
};

View File

@@ -0,0 +1,21 @@
import { Dispatch } from '@reduxjs/toolkit';
import axiosInstance, { ApiKeys, getApiUrl, logError } from '../../../utils/ApiHelper';
import { setAgentEscalationCount } from '@cp/src/reducers/commonSlice';
export const getReporteesWithAllocation =
(agentReferenceId: string, countOfEscalationEnabled?: boolean) => (dispatch: Dispatch) => {
if (!countOfEscalationEnabled) {
return;
}
const url = getApiUrl(ApiKeys.ESCALATION_COUNT, { agentReferenceId });
axiosInstance
.get(url)
.then(res => {
if (res?.data) {
dispatch(setAgentEscalationCount(res?.data?.count));
}
})
.catch(err => {
logError(err);
});
};

View File

@@ -358,6 +358,8 @@ export interface CommonState {
callingWindow?: CallingWindow;
lastSyncPermissionStatus?: boolean;
shouldNotHidePauseCasesTab: boolean;
agentEscalationCount: number;
showLogoutModal?: boolean;
}
export const CHECK_LOGIN = 'CHECK_LOGIN';
@@ -430,7 +432,9 @@ const initialState = {
shouldNotHidePauseCasesTab: false,
isTeamLead: false,
isCiuAgent: false,
lastSyncPermissionStatus: false
lastSyncPermissionStatus: false,
agentEscalationCount: 0,
showLogoutModal: false
} as CommonState;
setGlobalUserData({ token: initialState.userData.token });
@@ -632,6 +636,12 @@ export const commonSlice = createSlice({
},
setCallingWindow(state, action) {
state.callingWindow = action.payload;
},
setAgentEscalationCount(state, action) {
state.agentEscalationCount = action.payload;
},
setShowLogoutModal(state, action) {
state.showLogoutModal = action.payload;
}
}
});
@@ -679,7 +689,9 @@ export const {
setSlashCallStatusFromExtension,
setAgentBusinessVertical,
setCallingWindow,
setLastSyncPermissionStatus
setLastSyncPermissionStatus,
setAgentEscalationCount,
setShowLogoutModal
} = commonSlice.actions;
export default commonSlice.reducer;

View File

@@ -313,7 +313,8 @@ export enum ApiKeys {
UPLOAD_MEDIA,
CUSTOMER_CONFIDENCE,
GET_PIN_CODES_DETAILS,
ADD_NEW_ADDRESS
ADD_NEW_ADDRESS,
ESCALATION_COUNT
}
// TODO: try to get rid of `as`
@@ -622,6 +623,7 @@ API_URLS[ApiKeys.UPLOAD_MEDIA] = 'v2/interactions/upload/media';
API_URLS[ApiKeys.CUSTOMER_CONFIDENCE] = '/telephone-configurations';
API_URLS[ApiKeys.GET_PIN_CODES_DETAILS] = '/v1/pincodes/{pinCode}';
API_URLS[ApiKeys.ADD_NEW_ADDRESS] = '/address';
API_URLS[ApiKeys.ESCALATION_COUNT] = '/agent-escalation/{agentReferenceId}/count';
// TODO: try to get rid of `as`
const MOCK_API_URLS: Record<ApiKeys, string> = {} as Record<ApiKeys, string>;
MOCK_API_URLS[ApiKeys.PEOPLE] = 'people.json';