diff --git a/src/assets/icons/AnomalyIcon.tsx b/src/assets/icons/AnomalyIcon.tsx
new file mode 100644
index 00000000..9cf73a97
--- /dev/null
+++ b/src/assets/icons/AnomalyIcon.tsx
@@ -0,0 +1,34 @@
+import * as React from 'react';
+import Svg, { Path, Rect } from 'react-native-svg';
+
+const AnomalyTrackerIcon = () => (
+
+);
+
+export default AnomalyTrackerIcon;
diff --git a/src/assets/icons/NoAnomaliesFoundIcon.tsx b/src/assets/icons/NoAnomaliesFoundIcon.tsx
new file mode 100644
index 00000000..d73f442f
--- /dev/null
+++ b/src/assets/icons/NoAnomaliesFoundIcon.tsx
@@ -0,0 +1,112 @@
+import * as React from 'react';
+import Svg, { Path } from 'react-native-svg';
+const NoAnomaliesFoundIcon = () => (
+
+);
+export default NoAnomaliesFoundIcon;
diff --git a/src/assets/icons/UpdateIcon.tsx b/src/assets/icons/UpdateIcon.tsx
new file mode 100644
index 00000000..115362ef
--- /dev/null
+++ b/src/assets/icons/UpdateIcon.tsx
@@ -0,0 +1,18 @@
+import * as React from 'react';
+import Svg, { G, Mask, Path, Rect } from 'react-native-svg';
+
+const UpdateIcon = () => (
+
+);
+
+export default UpdateIcon;
diff --git a/src/components/utlis/apiHelper.ts b/src/components/utlis/apiHelper.ts
index f508e4b4..9ef2f121 100644
--- a/src/components/utlis/apiHelper.ts
+++ b/src/components/utlis/apiHelper.ts
@@ -119,8 +119,10 @@ export enum ApiKeys {
GET_FEEDBACK_ADDRESSES = 'GET_FEEDBACK_ADDRESSES',
GET_TRAINING_MATERIAL_LIST = 'GET_TRAINING_MATERIAL_LIST',
GET_TRAINING_MATERIAL_DETAILS = 'GET_TRAINING_MATERIAL_DETAILS',
- SELF_CALL_ACK= '/api/v1/self-call',
- GET_CASES_GEOLOCATION_DISTANCE_FROM_AGENT_LOCATION = "GET_CASES_GEOLOCATION_DISTANCE_FROM_AGENT_LOCATION"
+ SELF_CALL_ACK = '/api/v1/self-call',
+ GET_CASES_GEOLOCATION_DISTANCE_FROM_AGENT_LOCATION = 'GET_CASES_GEOLOCATION_DISTANCE_FROM_AGENT_LOCATION',
+ GET_ANOMALY_DETAILS = 'GET_ANOMALY_DETAILS',
+ GET_ANOMALY_ACTIVITY_LOG = 'GET_ANOMALY_ACTIVITY_LOG',
}
export const API_URLS: Record = {} as Record;
@@ -229,7 +231,10 @@ API_URLS[ApiKeys.GET_TRAINING_MATERIAL_DETAILS] = '/training-page/{docRefId}';
API_URLS[ApiKeys.SELF_CALL_ACK] = '/sync-data/self-call-metadata';
API_URLS[ApiKeys.GET_TOP_ADDRESSES] = '/collection-cases/unified-locations';
API_URLS[ApiKeys.GET_FEEDBACK_ADDRESSES] = '/collection-cases/unified-locations/lite';
-API_URLS[ApiKeys.GET_CASES_GEOLOCATION_DISTANCE_FROM_AGENT_LOCATION] = '/geolocation-distance/single-source'
+API_URLS[ApiKeys.GET_ANOMALY_DETAILS] = '/anomaly-tracker';
+API_URLS[ApiKeys.GET_ANOMALY_ACTIVITY_LOG] = '/anomaly-tracker/activity-logs/{anomalyReferenceId}';
+API_URLS[ApiKeys.GET_CASES_GEOLOCATION_DISTANCE_FROM_AGENT_LOCATION] =
+ '/geolocation-distance/single-source';
export const API_STATUS_CODE = {
OK: 200,
@@ -360,7 +365,7 @@ axiosInstance.interceptors.response.use(
const url = response?.config?.url;
const apiKey = getKeyByValue(url, API_URLS);
sendApiToClickstreamEvent(response, milliseconds, false);
- if(apiKey) {
+ if (apiKey) {
logger({
msg: 'api response error',
extras: {
@@ -370,7 +375,7 @@ axiosInstance.interceptors.response.use(
endpoint: API_URLS[apiKey as keyof typeof API_URLS],
method: response?.config?.method || '',
},
- type: 'error'
+ type: 'error',
});
}
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_API_FAILED, {
diff --git a/src/reducer/anomalyTrackerSlice.ts b/src/reducer/anomalyTrackerSlice.ts
new file mode 100644
index 00000000..341c0c99
--- /dev/null
+++ b/src/reducer/anomalyTrackerSlice.ts
@@ -0,0 +1,49 @@
+import { createSlice } from '@reduxjs/toolkit';
+
+const initialState: any = {
+ openAnomaliesList: {},
+ closedAnomaliesList: {},
+ anomalyDetailsLoading: false,
+ anomalyDetails: {
+ data: {},
+ loading: false,
+ },
+ actionLoading: false,
+ acitvityLogs: {
+ data: [],
+ loading: false,
+ },
+};
+
+const anomalyTrackerSlice = createSlice({
+ name: 'anomalyTracker',
+ initialState,
+ reducers: {
+ setOpenAnomalyList: (state, action) => {
+ state.openAnomaliesList = action.payload;
+ },
+ setClosedAnomalyList: (state, action) => {
+ state.closedAnomaliesList = action.payload;
+ },
+ setAnomalyDetailsLoading: (state, action) => {
+ state.anomalyDetailsLoading = action.payload;
+ },
+ setActivityLogs: (state, action) => {
+ state.acitvityLogs.data = action.payload;
+ },
+ setActivityLogsLoading: (state, action) => {
+ state.acitvityLogs.loading = action.payload;
+ },
+ },
+});
+
+export const {
+ setOpenAnomalyList,
+ setClosedAnomalyList,
+ setAnomalyDetailsLoading,
+ setRcaReasons,
+ setActivityLogs,
+ setActivityLogsLoading,
+} = anomalyTrackerSlice.actions;
+
+export default anomalyTrackerSlice.reducer;
diff --git a/src/screens/Dashboard/AnomalyTracker/AnomaliesDetailsList.tsx b/src/screens/Dashboard/AnomalyTracker/AnomaliesDetailsList.tsx
new file mode 100644
index 00000000..e1c33eb7
--- /dev/null
+++ b/src/screens/Dashboard/AnomalyTracker/AnomaliesDetailsList.tsx
@@ -0,0 +1,106 @@
+import React from 'react';
+import { View, StyleSheet, ActivityIndicator, FlatList } from 'react-native';
+import AnomalyDetailsItem from './AnomalyDetailsItem';
+import { useAppSelector } from '@hooks';
+import { AnomalyType } from './constants';
+import { GenericStyles } from '@rn-ui-lib/styles';
+import { COLORS } from '@rn-ui-lib/colors';
+import Text from '@rn-ui-lib/components/Text';
+import NoAnomaliesFoundIcon from '@assets/icons/NoAnomaliesFoundIcon';
+import Heading from '@rn-ui-lib/components/Heading';
+
+interface IAnomaliesDetailsListProps {
+ anomalyType: string;
+}
+
+const AnomaliesDetailsList = ({ anomalyType }: IAnomaliesDetailsListProps) => {
+ const openAnomaliesData = useAppSelector(
+ (state) => state?.anomalyTracker?.openAnomaliesList?.data || []
+ );
+ const closedAnomaliesData = useAppSelector(
+ (state) => state?.anomalyTracker?.closedAnomaliesList?.data || []
+ );
+
+ const isLoading = useAppSelector((state) => state?.anomalyTracker?.anomalyDetailsLoading);
+ if (isLoading) {
+ return (
+
+
+
+ );
+ }
+ if (anomalyType === AnomalyType.OPEN) {
+ return (
+ <>
+ {openAnomaliesData?.length > 0 ? (
+ item?.anomalyId}
+ renderItem={({ item }) => }
+ contentContainerStyle={[GenericStyles.pb16]}
+ />
+ ) : (
+
+
+
+
+ No open issues
+
+
+ You have closed all the issues
+
+
+
+ )}
+ >
+ );
+ }
+ return (
+ <>
+ {closedAnomaliesData?.length > 0 ? (
+ item?.anomalyId}
+ renderItem={({ item }) => }
+ contentContainerStyle={[GenericStyles.pb16]}
+ />
+ ) : (
+
+
+
+
+ No closed issues
+
+
+ Closed issues are shown here
+
+
+
+ )}
+ >
+ );
+};
+
+const styles = StyleSheet.create({
+ centerAbsolute: {
+ // height: '100%',
+ marginTop: 160,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ text: {
+ width: '100%',
+ },
+});
+
+export default AnomaliesDetailsList;
diff --git a/src/screens/Dashboard/AnomalyTracker/AnomalyCardBody.tsx b/src/screens/Dashboard/AnomalyTracker/AnomalyCardBody.tsx
new file mode 100644
index 00000000..74caaa4f
--- /dev/null
+++ b/src/screens/Dashboard/AnomalyTracker/AnomalyCardBody.tsx
@@ -0,0 +1,29 @@
+import React from 'react';
+
+import { View, StyleSheet } from 'react-native';
+import SingleAnomalyDetails from './SingleAnomalyDetails';
+import RcaEtaContainer from './RcaEtaContainer';
+
+interface IAnomalyCardBodyProps {
+ item: any;
+ anomalyType: string;
+}
+const AnomalyCardBody = (props: IAnomalyCardBodyProps) => {
+ const { item, anomalyType } = props;
+ return (
+
+
+
+
+ );
+};
+const styles = StyleSheet.create({
+ container: {
+ borderBottomRightRadius: 6,
+ borderBottomLeftRadius: 6,
+ paddingHorizontal: 16,
+ paddingTop: 20,
+ paddingBottom: 16,
+ },
+});
+export default AnomalyCardBody;
diff --git a/src/screens/Dashboard/AnomalyTracker/AnomalyCardHeader.tsx b/src/screens/Dashboard/AnomalyTracker/AnomalyCardHeader.tsx
new file mode 100644
index 00000000..699b568c
--- /dev/null
+++ b/src/screens/Dashboard/AnomalyTracker/AnomalyCardHeader.tsx
@@ -0,0 +1,40 @@
+import { COLORS } from '@rn-ui-lib/colors';
+import { GenericStyles, getShadowStyle } from '@rn-ui-lib/styles';
+import Text from '@rn-ui-lib/components/Text';
+
+import React from 'react';
+import { View, StyleSheet } from 'react-native';
+const AnomalyCardHeader = (props: any) => {
+ const { item } = props;
+
+ return (
+
+
+ {item?.type}
+
+
+ {item?.priority}
+
+
+ );
+};
+const styles = StyleSheet.create({
+ container: {
+ display: 'flex',
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ backgroundColor: COLORS.BACKGROUND.RED,
+ borderTopRadius: 6,
+ paddingHorizontal: 16,
+ paddingVertical: 12,
+ alignItems: 'center',
+ },
+ priorityLabel: {
+ borderRadius: 4,
+ backgroundColor: COLORS.TEXT.RED,
+ paddingHorizontal: 8,
+ paddingVertical: 1,
+ },
+ text: { fontSize: 14, fontWeight: '700', color: COLORS.TEXT.DARK },
+});
+export default AnomalyCardHeader;
diff --git a/src/screens/Dashboard/AnomalyTracker/AnomalyDetailsItem.tsx b/src/screens/Dashboard/AnomalyTracker/AnomalyDetailsItem.tsx
new file mode 100644
index 00000000..503e4ff9
--- /dev/null
+++ b/src/screens/Dashboard/AnomalyTracker/AnomalyDetailsItem.tsx
@@ -0,0 +1,30 @@
+import { COLORS } from '@rn-ui-lib/colors';
+import { GenericStyles, getShadowStyle } from '@rn-ui-lib/styles';
+import React from 'react';
+import { View, StyleSheet } from 'react-native';
+import AnomalyCardBody from './AnomalyCardBody';
+import AnomalyCardHeader from './AnomalyCardHeader';
+
+interface IAnomalyDetailsItemProps {
+ anomalyType: string;
+ item: any;
+}
+const AnomalyDetailsItem = (props: IAnomalyDetailsItemProps) => {
+ const { anomalyType, item } = props;
+ return (
+
+
+
+
+ );
+};
+const styles = StyleSheet.create({
+ container: {
+ backgroundColor: COLORS.BACKGROUND.PRIMARY,
+ borderRadius: 8,
+ marginHorizontal: 16,
+ marginTop: 16,
+ ...getShadowStyle(2),
+ },
+});
+export default AnomalyDetailsItem;
diff --git a/src/screens/Dashboard/AnomalyTracker/AnomalyOverviewCard.tsx b/src/screens/Dashboard/AnomalyTracker/AnomalyOverviewCard.tsx
new file mode 100644
index 00000000..080dad06
--- /dev/null
+++ b/src/screens/Dashboard/AnomalyTracker/AnomalyOverviewCard.tsx
@@ -0,0 +1,65 @@
+import React from 'react';
+import { Pressable, View, StyleSheet } from 'react-native';
+import Text from '@rn-ui-lib/components/Text';
+import AnomalyIcon from '@assets/icons/AnomalyIcon';
+import { navigateToScreen } from '@components/utlis/navigationUtlis';
+import { PageRouteEnum } from '@screens/auth/ProtectedRouter';
+import { CaseDetailStackEnum } from '@screens/caseDetails/CaseDetailStack';
+import { GenericStyles, getShadowStyle } from '@rn-ui-lib/styles';
+import { COLORS } from '@rn-ui-lib/colors';
+import Chevron from '@rn-ui-lib/icons/Chevron';
+import { useAppSelector } from '@hooks';
+
+const AnomalyOverviewCard = () => {
+ const totalOpenAnomalies =
+ useAppSelector((state) => state?.anomalyTracker?.openAnomaliesList?.pages?.totalElements);
+
+ const onClick = () => {
+ navigateToScreen(PageRouteEnum.CASE_DETAIL_STACK, {
+ screen: CaseDetailStackEnum.ANOMALY_TRACKER,
+ });
+ };
+
+ return (
+
+
+
+ {totalOpenAnomalies} Open issues
+
+
+ View
+
+
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ display: 'flex',
+ flexDirection: 'row',
+ borderRadius: 4,
+ marginHorizontal: 16,
+ ...getShadowStyle(2),
+ backgroundColor: COLORS.BACKGROUND.ORANGE,
+ borderWidth: 1,
+ borderColor: COLORS.BORDER.ORANGE,
+ marginBottom: 16,
+ padding: 12,
+ justifyContent: 'space-between',
+ },
+ textContainer: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ gap: 6,
+ },
+ rightIcon: {
+ marginTop: 3,
+ },
+ text: { fontSize: 13, fontWeight: '600' },
+ buttonText: { color: COLORS.TEXT.BLUE, fontWeight: '600', fontSize: 13 },
+});
+export default AnomalyOverviewCard;
diff --git a/src/screens/Dashboard/AnomalyTracker/AnomlayTracker.tsx b/src/screens/Dashboard/AnomalyTracker/AnomlayTracker.tsx
new file mode 100644
index 00000000..e56070cb
--- /dev/null
+++ b/src/screens/Dashboard/AnomalyTracker/AnomlayTracker.tsx
@@ -0,0 +1,43 @@
+import React, { useEffect, useState } from 'react';
+import { anomalyPageTitle, AnomalyType, TABS } from './constants';
+import { GenericStyles, getShadowStyle } from '@rn-ui-lib/styles';
+import NavigationHeader from '@rn-ui-lib/components/NavigationHeader';
+import CustomTabs from '@rn-ui-lib/components/customTabs/CustomTabs';
+import { goBack } from '@components/utlis/navigationUtlis';
+import AnomaliesDetailsList from './AnomaliesDetailsList';
+import { useAppDispatch } from '@hooks';
+import { getAnomalyDetails } from './utils';
+
+interface IAnomalyTracker {}
+
+const AnomalyTracker: React.FC = (props: IAnomalyTracker) => {
+ const [currentTab, setCurrentTab] = useState(AnomalyType.OPEN);
+ const dispatch = useAppDispatch();
+ useEffect(() => {
+ dispatch(getAnomalyDetails(AnomalyType.OPEN, {}, true));
+ });
+ const handleTabChange = (tab: string) => {
+ if (tab === currentTab) return;
+ if (tab === AnomalyType.OPEN) {
+ dispatch(getAnomalyDetails(AnomalyType.OPEN, {}, true));
+ } else {
+ dispatch(getAnomalyDetails(AnomalyType.RESOLVED, {}, true));
+ }
+ setCurrentTab(tab);
+ };
+
+ return (
+ <>
+
+
+
+ >
+ );
+};
+
+export default AnomalyTracker;
diff --git a/src/screens/Dashboard/AnomalyTracker/SingleAnomalyDetails.tsx b/src/screens/Dashboard/AnomalyTracker/SingleAnomalyDetails.tsx
new file mode 100644
index 00000000..16ed2b48
--- /dev/null
+++ b/src/screens/Dashboard/AnomalyTracker/SingleAnomalyDetails.tsx
@@ -0,0 +1,66 @@
+import { COLORS } from '@rn-ui-lib/colors';
+import Text from '@rn-ui-lib/components/Text';
+
+import React from 'react';
+import { View, StyleSheet } from 'react-native';
+import { sanitizeString } from '@components/utlis/commonFunctions';
+import { BUSINESS_DATE_FORMAT, dateFormat } from '@rn-ui-lib/utils/dates';
+import { AnomalyType } from './constants';
+import DaysTillEscalationComponent from './DaysTillEscalationComponent';
+
+interface ISingleAnomalyDetailsProps {
+ item: any;
+ anomalyType: string;
+}
+
+const SingleAnomalyDetails = (props: ISingleAnomalyDetailsProps) => {
+ const { item, anomalyType } = props;
+
+ return (
+
+
+ Created on
+
+ {sanitizeString(dateFormat(new Date(item?.createdAt), BUSINESS_DATE_FORMAT))}
+
+
+ {anomalyType === AnomalyType.OPEN ? (
+
+ Days till Escalation
+
+
+ ) : (
+
+ Resolved on
+
+ {sanitizeString(dateFormat(new Date(item?.resolution?.at), BUSINESS_DATE_FORMAT))}
+
+
+ )}
+
+ );
+};
+const styles = StyleSheet.create({
+ container: {
+ display: 'flex',
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ paddingBottom: 16,
+ alignItems: 'center',
+ },
+ priorityLabel: {
+ borderRadius: 4,
+ backgroundColor: COLORS.TEXT.RED,
+ paddingHorizontal: 6,
+ paddingVertical: 1,
+ },
+ textLabel: { fontSize: 12, color: COLORS.TEXT.LIGHT },
+ date: { fontSize: 14, color: COLORS.TEXT.BLACK, fontWeight: '600' },
+ daysTillEscalationText: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 8 },
+ textAlign: { textAlign: 'right' },
+ w60: { width: 60 },
+});
+export default SingleAnomalyDetails;
diff --git a/src/screens/Dashboard/AnomalyTracker/constants.ts b/src/screens/Dashboard/AnomalyTracker/constants.ts
new file mode 100644
index 00000000..a0d74ef4
--- /dev/null
+++ b/src/screens/Dashboard/AnomalyTracker/constants.ts
@@ -0,0 +1,17 @@
+export enum AnomalyType {
+ OPEN = 'OPEN',
+ RESOLVED = 'RESOLVED',
+}
+
+export const TABS = [
+ {
+ key: AnomalyType.OPEN,
+ label: 'Open',
+ },
+ {
+ key: AnomalyType.RESOLVED,
+ label: 'Closed',
+ },
+];
+
+export const anomalyPageTitle = 'Your issues';
diff --git a/src/screens/Dashboard/AnomalyTracker/utils.ts b/src/screens/Dashboard/AnomalyTracker/utils.ts
new file mode 100644
index 00000000..0b6d5e2c
--- /dev/null
+++ b/src/screens/Dashboard/AnomalyTracker/utils.ts
@@ -0,0 +1,56 @@
+import axiosInstance, { API_STATUS_CODE, ApiKeys, getApiUrl } from '@components/utlis/apiHelper';
+import { AnomalyType } from './constants';
+import { logError } from '@components/utlis/errorUtils';
+
+import { AppDispatch } from '@store';
+import {
+ setActivityLogs,
+ setActivityLogsLoading,
+ setAnomalyDetailsLoading,
+ setClosedAnomalyList,
+ setOpenAnomalyList,
+} from '@reducers/anomalyTrackerSlice';
+
+export const getAnomalyDetails =
+ (anomalyType: string, payload: {}, isLoading: boolean) => (dispatch: AppDispatch) => {
+ const url = getApiUrl(ApiKeys.GET_ANOMALY_DETAILS);
+ if (isLoading) dispatch(setAnomalyDetailsLoading(true));
+ axiosInstance
+ .get(url, {
+ baseURL: 'https://qa-longhorn-portal.np.navi-ppl.in/api/longhorn', //TODO: remove this
+ params: { status: anomalyType },
+ })
+ .then((res) => {
+ if (res?.status === API_STATUS_CODE.OK) {
+ if (anomalyType === AnomalyType.OPEN) {
+ dispatch(setOpenAnomalyList(res?.data));
+ return;
+ }
+ dispatch(setClosedAnomalyList(res?.data));
+ }
+ })
+ .catch((err) => {
+ logError(err);
+ })
+ .finally(() => {
+ dispatch(setAnomalyDetailsLoading(false));
+ });
+ };
+
+export const getActivityLogs = (anomalyReferenceId: string) => (dispatch: AppDispatch) => {
+ const url = getApiUrl(ApiKeys.GET_ANOMALY_ACTIVITY_LOG, { anomalyReferenceId });
+ dispatch(setActivityLogsLoading(true));
+ axiosInstance
+ .get(url, {
+ baseURL: 'https://qa-longhorn-portal.np.navi-ppl.in/api/longhorn', //TODO: remove this
+ })
+ .then((response) => {
+ if (response.status === API_STATUS_CODE.OK) {
+ dispatch(setActivityLogs(response?.data));
+ }
+ })
+ .catch((err) => {
+ logError(err);
+ })
+ .finally(() => dispatch(setActivityLogsLoading(false)));
+};
diff --git a/src/screens/Dashboard/InternalAgentDashboard.tsx b/src/screens/Dashboard/InternalAgentDashboard.tsx
index 184a5d6c..edc57d10 100644
--- a/src/screens/Dashboard/InternalAgentDashboard.tsx
+++ b/src/screens/Dashboard/InternalAgentDashboard.tsx
@@ -3,6 +3,7 @@ import React from 'react';
import InternalAgentPerformanceCard from './InternalAgentPerformanceCard';
import PerformanceMeter from './PerformanceMeter';
import PerformanceOverview from './PerformanceOverview';
+import AnomalyOverviewCard from './AnomalyTracker/AnomalyOverviewCard';
const InternalAgentDashboard = () => {
const performanceData = useAppSelector((state) => state.agentPerformance.performanceData);
@@ -14,9 +15,17 @@ const InternalAgentDashboard = () => {
atleastOneEmiCollected: cases?.atleastOneEmiCollected,
totalEmi: cases?.totalEmi,
};
+ const totalOpenAnomalies = useAppSelector(
+ (state) => state?.anomalyTracker?.openAnomaliesList?.pages?.totalElements
+ );
+ const totalClosedAnomalies = useAppSelector(
+ (state) => state?.anomalyTracker?.closedAnomaliesList?.pages?.totalElements
+ );
+ const isOpenOrClosedAnomaliesPresent = totalOpenAnomalies + totalClosedAnomalies > 0;
return (
<>
+ {isOpenOrClosedAnomaliesPresent ? : null}
diff --git a/src/screens/Dashboard/index.tsx b/src/screens/Dashboard/index.tsx
index daedd8f3..9e6eae1b 100644
--- a/src/screens/Dashboard/index.tsx
+++ b/src/screens/Dashboard/index.tsx
@@ -16,6 +16,8 @@ import { addClickstreamEvent } from '../../services/clickstreamEventService';
import DashboardHeader from './DashboardHeader';
import ExternalAgentDashboard from './ExternalAgentDashboard';
import InternalAgentDashboard from './InternalAgentDashboard';
+import { getAnomalyDetails } from './AnomalyTracker/utils';
+import { AnomalyType } from './AnomalyTracker/constants';
const Dashboard = () => {
const [refreshing, setRefreshing] = React.useState(false);
@@ -27,7 +29,13 @@ const Dashboard = () => {
const fetchAgentPerformanceMetrics = () => {
setIsLoading(true);
- dispatch(getPerformanceMetrics(Object.keys(caseDetailsIds ?? {}), isExternalAgent, setIsLoading));
+ dispatch(
+ getPerformanceMetrics(Object.keys(caseDetailsIds ?? {}), isExternalAgent, setIsLoading)
+ );
+ if (!isExternalAgent) {
+ dispatch(getAnomalyDetails(AnomalyType.OPEN, {}, false));
+ dispatch(getAnomalyDetails(AnomalyType.RESOLVED, {}, false));
+ }
};
useEffect(() => {
diff --git a/src/screens/caseDetails/CaseDetailStack.tsx b/src/screens/caseDetails/CaseDetailStack.tsx
index a1871169..044a9192 100644
--- a/src/screens/caseDetails/CaseDetailStack.tsx
+++ b/src/screens/caseDetails/CaseDetailStack.tsx
@@ -31,6 +31,7 @@ import CallCustomer from './CallCustomer';
import TopAddresses from '@screens/addresses/topAddresses/TopAddresses';
import OtherAddresses from '@screens/addresses/otherAddresses/OtherAddresses';
import Escalations from '@screens/escalations/Escalations';
+import AnomalyTracker from '@screens/Dashboard/AnomalyTracker/AnomlayTracker';
const Stack = createNativeStackNavigator();
@@ -59,6 +60,7 @@ export enum CaseDetailStackEnum {
TOP_ADDRESSES = 'TopAddresses',
OTHER_ADDRESSES = 'OtherAddresses',
ESCALATIONS = 'Escalations',
+ ANOMALY_TRACKER = "ANOMALY_TRACKER",
}
const CaseDetailStack = () => {
@@ -124,6 +126,7 @@ const CaseDetailStack = () => {
))}
+
);
};
diff --git a/src/store/store.ts b/src/store/store.ts
index 0a540170..20304340 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -40,6 +40,7 @@ import skipTracingAddressesSlice from '@reducers/skipTracingAddressesSlice';
import trainingMaterialSlice from '@reducers/trainingMaterialSlice';
import feedbackFormSlice from '@reducers/feedbackFormSlice';
import topAddressesSlice from '@reducers/topAddressesSlice';
+import anomalyTrackerSlice from '@reducers/anomalyTrackerSlice';
const rootReducer = combineReducers({
case: caseReducer,
@@ -79,7 +80,8 @@ const rootReducer = combineReducers({
postOperationalHourRestrictionsSlice: postOperationalHourRestrictionsSlice,
trainingMaterial: trainingMaterialSlice,
feedbackForm: feedbackFormSlice,
- topAddresses: topAddressesSlice
+ topAddresses: topAddressesSlice,
+ anomalyTracker: anomalyTrackerSlice,
});
const persistConfig = {