NTP-59601| PR comments resolved
This commit is contained in:
63
src/assets/icons/AnimatedCircularLoaderIcon.tsx
Normal file
63
src/assets/icons/AnimatedCircularLoaderIcon.tsx
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import Animated, {
|
||||||
|
SharedValue,
|
||||||
|
useAnimatedProps,
|
||||||
|
useSharedValue,
|
||||||
|
withTiming,
|
||||||
|
} from 'react-native-reanimated';
|
||||||
|
import Svg, { Circle, NumberArray } from 'react-native-svg';
|
||||||
|
import { COLORS } from '@rn-ui-lib/colors';
|
||||||
|
|
||||||
|
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
||||||
|
|
||||||
|
interface AnimatedCircularLoaderIco {
|
||||||
|
radius: number;
|
||||||
|
circumference: number;
|
||||||
|
strokeWidth?: number;
|
||||||
|
strokeColor?: string;
|
||||||
|
centreX?: string | number;
|
||||||
|
centreY?: string | number;
|
||||||
|
origin?: NumberArray | SharedValue<NumberArray>;
|
||||||
|
progressPercent: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnimatedCircularLoaderIcon = (props: AnimatedCircularLoaderIco) => {
|
||||||
|
const {
|
||||||
|
radius,
|
||||||
|
circumference,
|
||||||
|
strokeWidth = 5,
|
||||||
|
strokeColor = '#FFEFDB',
|
||||||
|
centreX = '22',
|
||||||
|
centreY = '21',
|
||||||
|
origin = '22,21',
|
||||||
|
progressPercent,
|
||||||
|
} = props;
|
||||||
|
const progress = useSharedValue(0);
|
||||||
|
useEffect(() => {
|
||||||
|
const normalizedProgress = progressPercent / 100;
|
||||||
|
progress.value = withTiming(normalizedProgress, { duration: 400 });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const circleAnimatedProps = useAnimatedProps(() => ({
|
||||||
|
strokeDashoffset: circumference * (1 - progress.value),
|
||||||
|
}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg width="44px" height="42px" fill="none">
|
||||||
|
<Circle cx={centreX} cy={centreY} r={radius} stroke={strokeColor} strokeWidth={strokeWidth} />
|
||||||
|
<AnimatedCircle
|
||||||
|
cx={centreX}
|
||||||
|
cy={centreY}
|
||||||
|
r={radius}
|
||||||
|
stroke={COLORS.TEXT.YELLOW}
|
||||||
|
strokeWidth={strokeWidth}
|
||||||
|
strokeDasharray={circumference}
|
||||||
|
animatedProps={circleAnimatedProps}
|
||||||
|
rotation="-90"
|
||||||
|
origin={origin}
|
||||||
|
/>
|
||||||
|
</Svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AnimatedCircularLoaderIcon;
|
||||||
@@ -93,7 +93,6 @@ const AnomaliesDetailsList = ({ anomalyType }: IAnomaliesDetailsListProps) => {
|
|||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
centerAbsolute: {
|
centerAbsolute: {
|
||||||
// height: '100%',
|
|
||||||
marginTop: 160,
|
marginTop: 160,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { COLORS } from '@rn-ui-lib/colors';
|
import { COLORS } from '@rn-ui-lib/colors';
|
||||||
import Text from '@rn-ui-lib/components/Text';
|
import Text from '@rn-ui-lib/components/Text';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View, StyleSheet } from 'react-native';
|
import { View, StyleSheet } from 'react-native';
|
||||||
import Tag, { TagVariant } from '@rn-ui-lib/components/Tag';
|
|
||||||
import { AnomalyCardHeaderColor, AnomalyPriorityColor } from './constants';
|
import { AnomalyCardHeaderColor, AnomalyPriorityColor } from './constants';
|
||||||
const AnomalyCardHeader = (props: any) => {
|
import { AnomalyCardHeaderProps } from './interfaces';
|
||||||
|
|
||||||
|
const AnomalyCardHeader = (props: AnomalyCardHeaderProps) => {
|
||||||
const { item } = props;
|
const { item } = props;
|
||||||
const headerColor =
|
const headerColor =
|
||||||
AnomalyCardHeaderColor[item?.priority as keyof typeof AnomalyCardHeaderColor] ||
|
AnomalyCardHeaderColor[item?.priority as keyof typeof AnomalyCardHeaderColor] ||
|
||||||
@@ -26,7 +26,7 @@ const AnomalyCardHeader = (props: any) => {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Text style={{ fontSize: 12, color: COLORS.TEXT.WHITE }}>{item?.priority}</Text>
|
<Text style={styles.priorityText}>{item?.priority}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
@@ -55,5 +55,6 @@ const styles = StyleSheet.create({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
wordBreak: 'break-word',
|
wordBreak: 'break-word',
|
||||||
},
|
},
|
||||||
|
priorityText: { fontSize: 12, color: COLORS.TEXT.WHITE },
|
||||||
});
|
});
|
||||||
export default AnomalyCardHeader;
|
export default AnomalyCardHeader;
|
||||||
|
|||||||
@@ -1,45 +1,24 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View, StyleSheet } from 'react-native';
|
||||||
import Animated, { useAnimatedProps, useSharedValue, withTiming } from 'react-native-reanimated';
|
|
||||||
import Svg, { Circle } from 'react-native-svg';
|
|
||||||
import Text from '@rn-ui-lib/components/Text';
|
import Text from '@rn-ui-lib/components/Text';
|
||||||
import { COLORS } from '@rn-ui-lib/colors';
|
import { COLORS } from '@rn-ui-lib/colors';
|
||||||
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
import AnimatedCircularLoaderIcon from '@assets/icons/AnimatedCircularLoaderIcon';
|
||||||
|
|
||||||
const DaysTillEscalationComponent = (props: {
|
const DaysTillEscalationComponent = (props: {
|
||||||
dayTillEscalation: number;
|
dayTillEscalation: number;
|
||||||
progressPercent: number;
|
progressPercent: number;
|
||||||
}) => {
|
}) => {
|
||||||
const { dayTillEscalation, progressPercent } = props;
|
const { dayTillEscalation, progressPercent } = props;
|
||||||
const progress = useSharedValue(0);
|
|
||||||
useEffect(() => {
|
|
||||||
const normalizedProgress = progressPercent / 100;
|
|
||||||
if (dayTillEscalation > 0) {
|
|
||||||
progress.value = withTiming(normalizedProgress, { duration: 400 });
|
|
||||||
} else progress.value = withTiming(0, { duration: 0 });
|
|
||||||
}, []);
|
|
||||||
const radius = 18;
|
const radius = 18;
|
||||||
const circumference = 2 * Math.PI * radius;
|
const circumference = 2 * Math.PI * radius;
|
||||||
const circleAnimatedProps = useAnimatedProps(() => ({
|
|
||||||
strokeDashoffset: circumference * (1 - progress.value),
|
|
||||||
}));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Svg width="44px" height="42px" fill="none">
|
<AnimatedCircularLoaderIcon
|
||||||
<Circle cx="22" cy="21" r={radius} stroke="#FFEFDB" strokeWidth={5} />
|
radius={radius}
|
||||||
<AnimatedCircle
|
circumference={circumference}
|
||||||
cx="22"
|
progressPercent={dayTillEscalation > 0 ? progressPercent : 0}
|
||||||
cy="21"
|
/>
|
||||||
r={radius}
|
|
||||||
stroke={COLORS.TEXT.YELLOW}
|
|
||||||
strokeWidth={5}
|
|
||||||
strokeDasharray={circumference}
|
|
||||||
animatedProps={circleAnimatedProps}
|
|
||||||
rotation="-90"
|
|
||||||
origin="22,21"
|
|
||||||
/>
|
|
||||||
</Svg>
|
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
@@ -47,15 +26,15 @@ const DaysTillEscalationComponent = (props: {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{dayTillEscalation > 0 ? (
|
{dayTillEscalation > 0 ? (
|
||||||
<Text style={{ fontSize: 14, color: COLORS.TEXT.YELLOW, fontWeight: '700' }}>
|
<Text style={styles.textContainer}>{dayTillEscalation}</Text>
|
||||||
{dayTillEscalation}
|
|
||||||
</Text>
|
|
||||||
) : (
|
) : (
|
||||||
<Text style={{ fontSize: 14, color: COLORS.TEXT.YELLOW, fontWeight: '700' }}>0</Text>
|
<Text style={styles.textContainer}>0</Text>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
textContainer: { fontSize: 14, color: COLORS.TEXT.YELLOW, fontWeight: '700' },
|
||||||
|
});
|
||||||
export default DaysTillEscalationComponent;
|
export default DaysTillEscalationComponent;
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ interface IRcaEtaContainerProps {
|
|||||||
|
|
||||||
const RcaEtaContainer = (props: IRcaEtaContainerProps) => {
|
const RcaEtaContainer = (props: IRcaEtaContainerProps) => {
|
||||||
const { item, anomalyType } = props;
|
const { item, anomalyType } = props;
|
||||||
console.log({ item });
|
|
||||||
const [showETABottomSheet, setShowETABottomSheet] = useState(false);
|
const [showETABottomSheet, setShowETABottomSheet] = useState(false);
|
||||||
const [showRCABottomSheet, setShowRCABottomSheet] = useState(false);
|
const [showRCABottomSheet, setShowRCABottomSheet] = useState(false);
|
||||||
const [selectedAnomalyId, setSelectedAnomalyId] = useState('');
|
const [selectedAnomalyId, setSelectedAnomalyId] = useState('');
|
||||||
@@ -45,7 +44,7 @@ const RcaEtaContainer = (props: IRcaEtaContainerProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(getActivityLogs(selectedAnomalyId));
|
if(selectedAnomalyId) dispatch(getActivityLogs(selectedAnomalyId));
|
||||||
}, [selectedAnomalyId]);
|
}, [selectedAnomalyId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
21
src/screens/Dashboard/AnomalyTracker/interfaces.ts
Normal file
21
src/screens/Dashboard/AnomalyTracker/interfaces.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
export interface AnomalyItem {
|
||||||
|
escalationPercentage?: number;
|
||||||
|
daysRemaining?: number;
|
||||||
|
anomalyId?: string;
|
||||||
|
createdAt?: string;
|
||||||
|
type?: string;
|
||||||
|
subtype?: string;
|
||||||
|
priority?: string;
|
||||||
|
anomalyDetectedOn?: string;
|
||||||
|
raisedFor?: {};
|
||||||
|
anomalyReferenceId?: string;
|
||||||
|
resolution?: {};
|
||||||
|
estimatedTime?: {};
|
||||||
|
rca?: {};
|
||||||
|
resolutionTime?: string;
|
||||||
|
resolutionType?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AnomalyCardHeaderProps {
|
||||||
|
item: AnomalyItem;
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@ export const getAnomalyDetails =
|
|||||||
if (isLoading) dispatch(setAnomalyDetailsLoading(true));
|
if (isLoading) dispatch(setAnomalyDetailsLoading(true));
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.get(url, {
|
.get(url, {
|
||||||
baseURL: 'https://qa-longhorn-portal.np.navi-ppl.in/api/longhorn', //TODO: remove this
|
|
||||||
params: { status: anomalyType },
|
params: { status: anomalyType },
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@@ -41,9 +40,7 @@ export const getActivityLogs = (anomalyReferenceId: string) => (dispatch: AppDis
|
|||||||
const url = getApiUrl(ApiKeys.GET_ANOMALY_ACTIVITY_LOG, { anomalyReferenceId });
|
const url = getApiUrl(ApiKeys.GET_ANOMALY_ACTIVITY_LOG, { anomalyReferenceId });
|
||||||
dispatch(setActivityLogsLoading(true));
|
dispatch(setActivityLogsLoading(true));
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.get(url, {
|
.get(url)
|
||||||
baseURL: 'https://qa-longhorn-portal.np.navi-ppl.in/api/longhorn', //TODO: remove this
|
|
||||||
})
|
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status === API_STATUS_CODE.OK) {
|
if (response.status === API_STATUS_CODE.OK) {
|
||||||
dispatch(setActivityLogs(response?.data));
|
dispatch(setActivityLogs(response?.data));
|
||||||
|
|||||||
@@ -15,12 +15,11 @@ const InternalAgentDashboard = () => {
|
|||||||
atleastOneEmiCollected: cases?.atleastOneEmiCollected,
|
atleastOneEmiCollected: cases?.atleastOneEmiCollected,
|
||||||
totalEmi: cases?.totalEmi,
|
totalEmi: cases?.totalEmi,
|
||||||
};
|
};
|
||||||
const totalOpenAnomalies = useAppSelector(
|
const totalOpenAnomalies =
|
||||||
(state) => state?.anomalyTracker?.openAnomaliesList?.pages?.totalElements
|
useAppSelector((state) => state?.anomalyTracker?.openAnomaliesList?.pages?.totalElements) || 0;
|
||||||
);
|
const totalClosedAnomalies =
|
||||||
const totalClosedAnomalies = useAppSelector(
|
useAppSelector((state) => state?.anomalyTracker?.closedAnomaliesList?.pages?.totalElements) ||
|
||||||
(state) => state?.anomalyTracker?.closedAnomaliesList?.pages?.totalElements
|
0;
|
||||||
);
|
|
||||||
const isOpenOrClosedAnomaliesPresent = totalOpenAnomalies + totalClosedAnomalies > 0;
|
const isOpenOrClosedAnomaliesPresent = totalOpenAnomalies + totalClosedAnomalies > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -32,10 +32,11 @@ const Dashboard = () => {
|
|||||||
dispatch(
|
dispatch(
|
||||||
getPerformanceMetrics(Object.keys(caseDetailsIds ?? {}), isExternalAgent, setIsLoading)
|
getPerformanceMetrics(Object.keys(caseDetailsIds ?? {}), isExternalAgent, setIsLoading)
|
||||||
);
|
);
|
||||||
if (!isExternalAgent) {
|
// TODO: Uncomment when api is added by backend
|
||||||
dispatch(getAnomalyDetails(AnomalyType.OPEN, {}, false));
|
// if (!isExternalAgent) {
|
||||||
dispatch(getAnomalyDetails(AnomalyType.RESOLVED, {}, false));
|
// dispatch(getAnomalyDetails(AnomalyType.OPEN, {}, false));
|
||||||
}
|
// dispatch(getAnomalyDetails(AnomalyType.RESOLVED, {}, false));
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user