Merge branch 'master' into feature/TP-30224-glitchtip-fix
This commit is contained in:
20
.github/workflows/newBuild.yml
vendored
20
.github/workflows/newBuild.yml
vendored
@@ -10,6 +10,13 @@ on:
|
||||
options:
|
||||
- qa
|
||||
- dev
|
||||
type:
|
||||
description: Choose build type
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- debug
|
||||
- release
|
||||
version_code:
|
||||
description: Enter app version code (example, 292)
|
||||
required: false
|
||||
@@ -27,6 +34,9 @@ jobs:
|
||||
with:
|
||||
token: ${{ secrets.MY_REPO_PAT }}
|
||||
submodules: recursive
|
||||
- name: Generate keystore
|
||||
if: (github.event.inputs.type == 'release' || inputs.type == 'release')
|
||||
run: echo "${{ secrets.KEY_STORE }}" > keystore.asc && gpg -d --passphrase "${{ secrets.PASSPHARASE }}" --batch keystore.asc > android/app/my-upload-key.keystore
|
||||
- name: Set Node.js 16.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
@@ -60,11 +70,17 @@ jobs:
|
||||
- name: Create local.properties
|
||||
run: cd android && touch local.properties && echo "sdk.dir = /home/USERNAME/Android/Sdk" > local.properties
|
||||
- name: Assemble with Stacktrace - QA debug
|
||||
if: (github.event.inputs.environment == 'qa' || inputs.environment == 'qa')
|
||||
if: ((github.event.inputs.environment == 'qa' || inputs.environment == 'qa') && (github.event.inputs.type == 'debug' || inputs.type == 'debug'))
|
||||
run: yarn move:qa && yarn debug && cd android && ./gradlew assembleDebug
|
||||
- name: Assemble with Stacktrace - Dev debug
|
||||
if: (github.event.inputs.environment == 'dev' || inputs.environment == 'dev')
|
||||
if: ((github.event.inputs.environment == 'dev' || inputs.environment == 'dev') && (github.event.inputs.type == 'debug' || inputs.type == 'debug'))
|
||||
run: yarn move:dev && yarn debug && cd android && ./gradlew assembleDebug
|
||||
- name: Assemble with Stacktrace - QA release
|
||||
if: ((github.event.inputs.environment == 'qa' || inputs.environment == 'qa') && (github.event.inputs.type == 'release' || inputs.type == 'release'))
|
||||
run: yarn move:qa && cd android && ./gradlew assembleRelease
|
||||
- name: Assemble with Stacktrace - Dev release
|
||||
if: ((github.event.inputs.environment == 'dev' || inputs.environment == 'dev') && (github.event.inputs.type == 'debug' || inputs.type == 'release'))
|
||||
run: yarn move:dev && cd android && ./gradlew assembleRelease
|
||||
- name: Upload APK as Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"@react-navigation/native-stack": "6.9.4",
|
||||
"@reduxjs/toolkit": "1.9.1",
|
||||
"@sentry/react-native": "5.5.0",
|
||||
"@shopify/flash-list": "1.4.3",
|
||||
"@supersami/rn-foreground-service": "^2.1.0",
|
||||
"appcenter": "^4.4.5",
|
||||
"appcenter-analytics": "^4.4.5",
|
||||
@@ -51,6 +52,7 @@
|
||||
"react": "18.1.0",
|
||||
"react-hook-form": "7.40.0",
|
||||
"react-native": "0.70.6",
|
||||
"react-native-blob-util": "0.17.3",
|
||||
"react-native-call-log": "2.1.2",
|
||||
"react-native-code-push": "7.1.0",
|
||||
"react-native-contacts": "7.0.5",
|
||||
@@ -72,11 +74,10 @@
|
||||
"react-native-toast-message": "2.1.5",
|
||||
"react-native-vector-icons": "9.2.0",
|
||||
"react-native-version-number": "0.3.6",
|
||||
"react-native-webview": "12.0.2",
|
||||
"react-redux": "8.0.5",
|
||||
"redux": "4.2.0",
|
||||
"redux-persist": "6.0.0",
|
||||
"react-native-webview": "12.0.2",
|
||||
"react-native-blob-util": "0.17.3"
|
||||
"redux-persist": "6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.12.9",
|
||||
@@ -100,6 +101,7 @@
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-config-airbnb-typescript": "17.0.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-prettier-react": "0.0.24",
|
||||
"eslint-config-standard-with-typescript": "^34.0.1",
|
||||
"eslint-plugin-import": "^2.25.2",
|
||||
"eslint-plugin-jsx-a11y": "6.6.1",
|
||||
@@ -115,7 +117,6 @@
|
||||
"miragejs": "0.1.47",
|
||||
"prettier": "^2.8.7",
|
||||
"react-test-renderer": "18.1.0",
|
||||
"eslint-config-prettier-react": "0.0.24",
|
||||
"typescript": "4.8.3"
|
||||
},
|
||||
"jest": {
|
||||
|
||||
30
src/action/caseListAction.ts
Normal file
30
src/action/caseListAction.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { MILLISECONDS_IN_A_SECOND } from '../../RN-UI-LIB/src/utlis/common';
|
||||
import { setCasesImageUri } from '../reducer/allCasesSlice';
|
||||
import { AppDispatch } from '../store/store';
|
||||
|
||||
export interface IAvatarUri {
|
||||
caseId: string;
|
||||
imageUri: string;
|
||||
}
|
||||
|
||||
let avatarUris: IAvatarUri[] = [];
|
||||
let avatarUrisDispatchTimer: number = 0;
|
||||
const AVATAR_URIS_DISPATCH_TIMEOUT = 2 * MILLISECONDS_IN_A_SECOND;
|
||||
const AVATAR_URIS_BATCH_SIZE = 5;
|
||||
|
||||
const dispatchBulkAvatarUris = () => (dispatch: AppDispatch) => {
|
||||
dispatch(setCasesImageUri(avatarUris));
|
||||
avatarUris = [];
|
||||
avatarUrisDispatchTimer = 0;
|
||||
};
|
||||
|
||||
export const setCasesAvatarImageUri = (avatarUri: IAvatarUri) => (dispatch: AppDispatch) => {
|
||||
avatarUris.push(avatarUri);
|
||||
if (avatarUris.length > AVATAR_URIS_BATCH_SIZE) {
|
||||
dispatch(dispatchBulkAvatarUris());
|
||||
} else if (!avatarUrisDispatchTimer) {
|
||||
avatarUrisDispatchTimer = setTimeout(() => {
|
||||
dispatch(dispatchBulkAvatarUris());
|
||||
}, AVATAR_URIS_DISPATCH_TIMEOUT);
|
||||
}
|
||||
};
|
||||
@@ -5,6 +5,10 @@ import { addClickstreamEvent } from '../services/clickstreamEventService';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from './Constants';
|
||||
import ErrorImage from '../assets/images/Error';
|
||||
import Heading from '../../RN-UI-LIB/src/components/Heading';
|
||||
import VersionNumber from 'react-native-version-number';
|
||||
import Text from '../../RN-UI-LIB/src/components/Text';
|
||||
import { getAppVersion } from '../components/utlis/commonFunctions';
|
||||
import { COLORS } from '../../RN-UI-LIB/src/styles/colors';
|
||||
|
||||
interface IErrorBoundary {
|
||||
children?: ReactNode;
|
||||
@@ -38,6 +42,10 @@ class ErrorBoundary extends Component<IErrorBoundary, IErrorBoundaryState> {
|
||||
<Heading type={'h4'} style={styles.errorHeading} bold dark>
|
||||
Uh-Oh! Something went wrong Try to re-open the app
|
||||
</Heading>
|
||||
<Text bold dark style={styles.version}>
|
||||
App Version: {getAppVersion()} Gradle Version: {VersionNumber.appVersion} Gradle Build
|
||||
No: {VersionNumber.buildVersion}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -57,6 +65,13 @@ const styles = StyleSheet.create({
|
||||
maxWidth: 280,
|
||||
textAlign: 'center',
|
||||
},
|
||||
version: {
|
||||
fontSize: 10,
|
||||
color: COLORS.TEXT.GREY,
|
||||
paddingBottom: 10,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
},
|
||||
});
|
||||
|
||||
export default ErrorBoundary;
|
||||
|
||||
@@ -37,7 +37,7 @@ interface ITrackingComponent {
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
let MAX_BG_TRACKING_WINDOW = 1000 * 60 * 10; //10 mins;
|
||||
let MAX_BG_TRACKING_WINDOW = 1000 * 60 * 30; //30 mins;
|
||||
let LAST_SYNC_STATUS = 'SKIP';
|
||||
|
||||
const TrackingComponent: React.FC<ITrackingComponent> = ({ children }) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import { toast } from '../../RN-UI-LIB/src/components/toast';
|
||||
import { _map } from '../../RN-UI-LIB/src/utlis/common';
|
||||
import { findDocumentByDocumentType } from '../components/utlis/commonFunctions';
|
||||
import { CLICKSTREAM_EVENT_NAMES, FirestoreUpdateTypes } from '../common/Constants';
|
||||
import { getCurrentScreen, navigateToScreen } from '../components/utlis/navigationUtlis';
|
||||
import { CaseUpdates } from '../hooks/useFirestoreUpdates';
|
||||
@@ -12,11 +13,17 @@ import {
|
||||
caseVerdict,
|
||||
ICaseItem,
|
||||
} from '../screens/allCases/interface';
|
||||
import { CaseDetail, CONTEXT_TASK_STATUSES } from '../screens/caseDetails/interface';
|
||||
import {
|
||||
CaseDetail,
|
||||
CONTEXT_TASK_STATUSES,
|
||||
DOCUMENT_TYPE,
|
||||
IDocument,
|
||||
} from '../screens/caseDetails/interface';
|
||||
import { addClickstreamEvent } from '../services/clickstreamEventService';
|
||||
import { getLoanAccountNumber } from '../components/utlis/commonFunctions';
|
||||
import { getVisitedWidgetsNodeList } from '../components/form/services/forms.service';
|
||||
import { CollectionCaseWidgetId, CommonCaseWidgetId } from '../types/template.types';
|
||||
import { IAvatarUri } from '../action/caseListAction';
|
||||
|
||||
export type ICasesMap = { [key: string]: ICaseItem };
|
||||
|
||||
@@ -290,6 +297,7 @@ const allCasesSlice = createSlice({
|
||||
...updatedCaseDetail,
|
||||
currentTask,
|
||||
isSynced: true,
|
||||
imageUri: state.caseDetails[caseId].imageUri,
|
||||
};
|
||||
break;
|
||||
}
|
||||
@@ -309,11 +317,17 @@ const allCasesSlice = createSlice({
|
||||
(task) => task?.taskType === (updatedCurrentTask as string)
|
||||
);
|
||||
}
|
||||
const imageUri =
|
||||
findDocumentByDocumentType(
|
||||
updatedCaseDetail.documents,
|
||||
DOCUMENT_TYPE.OPTIMIZED_SELFIE
|
||||
)?.uri || '';
|
||||
state.caseDetails[caseId] = {
|
||||
...updatedCaseDetail,
|
||||
currentTask,
|
||||
isSynced: true,
|
||||
isNewlyAdded: !isInitialLoad,
|
||||
imageUri,
|
||||
};
|
||||
break;
|
||||
}
|
||||
@@ -528,13 +542,18 @@ const allCasesSlice = createSlice({
|
||||
return;
|
||||
}
|
||||
const { caseViewCreatedAt, caseReferenceId, isSynced, pinRank } = caseItem;
|
||||
const isCaseAlreadyPresent = state.caseDetails[caseReferenceId];
|
||||
if (
|
||||
!state.caseDetails[caseReferenceId] ||
|
||||
!isCaseAlreadyPresent ||
|
||||
(isSynced && caseViewCreatedAt && caseViewCreatedAt < payloadCreatedAt)
|
||||
) {
|
||||
const caseListItem = getCaseListItem(caseReferenceId, pinRank, caseViewCreatedAt);
|
||||
state.casesList.unshift(caseListItem);
|
||||
state.caseDetails[caseReferenceId] = { ...caseItem, isSynced: true };
|
||||
const imageUri = isCaseAlreadyPresent
|
||||
? state.caseDetails[caseReferenceId].imageUri
|
||||
: findDocumentByDocumentType(caseItem.documents, DOCUMENT_TYPE.OPTIMIZED_SELFIE)?.uri ||
|
||||
'';
|
||||
state.caseDetails[caseReferenceId] = { ...caseItem, isSynced: true, imageUri };
|
||||
}
|
||||
});
|
||||
const { pendingList, completedList, pinnedList } = getCaseListComponents(
|
||||
@@ -551,6 +570,14 @@ const allCasesSlice = createSlice({
|
||||
}
|
||||
});
|
||||
},
|
||||
setCasesImageUri: (state, action) => {
|
||||
const imageUris: IAvatarUri[] = action.payload;
|
||||
imageUris.forEach(({ caseId, imageUri }) => {
|
||||
if (state.caseDetails[caseId]) {
|
||||
state.caseDetails[caseId].imageUri = imageUri;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -571,6 +598,7 @@ export const {
|
||||
setVisitPlansUpdating,
|
||||
resetNewVisitedCases,
|
||||
syncCasesByFallback,
|
||||
setCasesImageUri,
|
||||
} = allCasesSlice.actions;
|
||||
|
||||
export default allCasesSlice.reducer;
|
||||
|
||||
@@ -49,6 +49,7 @@ const CaseItem: React.FC<ICaseItemProps> = ({
|
||||
caseDetailObj?.isSynced,
|
||||
caseDetailObj?.interactionStatus,
|
||||
caseDetailObj?.caseVerdict,
|
||||
caseDetailObj?.imageUri,
|
||||
JSON.stringify(caseDetailObj?.currentTask),
|
||||
caseDetailObj?.addressString,
|
||||
]);
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import React, { memo } from 'react';
|
||||
import React, { memo, useRef } from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import Avatar from '../../../RN-UI-LIB/src/components/Avatar';
|
||||
import UnsyncedIcon from '../../../RN-UI-LIB/src/Icons/UnsyncedIcon';
|
||||
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
|
||||
import useFetchDocument from '../../hooks/useFetchDocument';
|
||||
import { DOCUMENT_TYPE } from '../caseDetails/interface';
|
||||
import { DOCUMENT_TYPE, IDocument, TDocumentObj } from '../caseDetails/interface';
|
||||
import { ICaseItemAvatarCaseDetailObj } from './interface';
|
||||
import {
|
||||
RELATIVE_PATH_PREFIX,
|
||||
findDocumentByDocumentType,
|
||||
storeImageLocallyReturnRelativePath,
|
||||
} from '../../components/utlis/commonFunctions';
|
||||
import { ISignedRequest, getSignedApi } from '../../action/dataActions';
|
||||
import { useAppDispatch } from '../../hooks';
|
||||
import { setCasesAvatarImageUri } from '../../action/caseListAction';
|
||||
|
||||
interface ICaseItemAvatar {
|
||||
caseDetailObj: ICaseItemAvatarCaseDetailObj;
|
||||
@@ -24,39 +31,74 @@ const CaseItemAvatar: React.FC<ICaseItemAvatar> = ({
|
||||
size = AVATAR_SIZE,
|
||||
showBorder = false,
|
||||
enableRetry = true,
|
||||
shouldBatchAvatar = false,
|
||||
}) => {
|
||||
const { isPinned, customerName, isCaseSynced } = caseDetailObj;
|
||||
const { isPinned, customerName, isCaseSynced, imageUri } = caseDetailObj;
|
||||
const apiInProgressReferenceIds = useRef<string[]>([]);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const requiredDocumentTypeList = [DOCUMENT_TYPE.OPTIMIZED_SELFIE];
|
||||
|
||||
if (isPinned) {
|
||||
requiredDocumentTypeList.push(DOCUMENT_TYPE.SELFIE);
|
||||
}
|
||||
|
||||
const { documentObj, setRetryForUnsignedDocuments, loading } = useFetchDocument(
|
||||
caseDetailObj,
|
||||
requiredDocumentTypeList,
|
||||
true,
|
||||
shouldBatchAvatar
|
||||
);
|
||||
//TODO: Need to add SELFIE image Uri for pinned cases also
|
||||
// if (isPinned) {
|
||||
// requiredDocumentTypeList.push(DOCUMENT_TYPE.SELFIE);
|
||||
// }
|
||||
|
||||
const onError = async () => {
|
||||
if (enableRetry) {
|
||||
setRetryForUnsignedDocuments(requiredDocumentTypeList);
|
||||
if (imageUri.startsWith(RELATIVE_PATH_PREFIX)) {
|
||||
return;
|
||||
}
|
||||
for (let retryForDocumentsItem of requiredDocumentTypeList) {
|
||||
// Doc referenceId => needed to get a signed url of the expired s3 url.
|
||||
const imageReferenceId = findDocumentByDocumentType(
|
||||
caseDetailObj?.documentList,
|
||||
retryForDocumentsItem
|
||||
)?.referenceId;
|
||||
|
||||
if (!imageReferenceId) {
|
||||
return;
|
||||
}
|
||||
|
||||
(async (caseDetail) => {
|
||||
if (apiInProgressReferenceIds.current.includes(imageReferenceId)) return;
|
||||
|
||||
apiInProgressReferenceIds.current.push(imageReferenceId);
|
||||
|
||||
const signedRequestPayload: ISignedRequest = [
|
||||
{
|
||||
documentReferenceId: imageReferenceId,
|
||||
caseId: '' + caseDetail.caseId,
|
||||
caseType: caseDetail.caseType,
|
||||
},
|
||||
];
|
||||
const response = await getSignedApi(signedRequestPayload, enableRetry);
|
||||
const url = response?.imageUrl;
|
||||
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
const localImagePath = await storeImageLocallyReturnRelativePath(url);
|
||||
|
||||
if (localImagePath) {
|
||||
dispatch(setCasesAvatarImageUri({ caseId: caseDetail.caseId, imageUri: localImagePath }));
|
||||
}
|
||||
})(caseDetailObj);
|
||||
}
|
||||
};
|
||||
|
||||
const avatarUri = caseDetailObj.imageUri || '';
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View>
|
||||
<Avatar
|
||||
size={size}
|
||||
name={customerName}
|
||||
dataURI={documentObj[DOCUMENT_TYPE.OPTIMIZED_SELFIE] || ''}
|
||||
dataURI={avatarUri}
|
||||
onErrorFallback={onError}
|
||||
style={[showBorder && styles.border]}
|
||||
loading={loading}
|
||||
// loading={loading}
|
||||
/>
|
||||
{!isCaseSynced ? (
|
||||
<View style={styles.unsyncedIcon}>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
Animated,
|
||||
ListRenderItem,
|
||||
ListRenderItemInfo,
|
||||
Modal,
|
||||
NativeScrollEvent,
|
||||
@@ -8,9 +9,8 @@ import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
VirtualizedList,
|
||||
} from 'react-native';
|
||||
import { GenericStyles } from '../../../RN-UI-LIB/src/styles';
|
||||
import { GenericStyles, SCREEN_HEIGHT, SCREEN_WIDTH } from '../../../RN-UI-LIB/src/styles';
|
||||
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
|
||||
import { RootState } from '../../store/store';
|
||||
import { CaseTypes, ICaseItem, ICaseItemCaseDetailObj } from './interface';
|
||||
@@ -40,11 +40,14 @@ import { evaluateFilterForCases } from '../../components/screens/allCases/allCas
|
||||
import { debounce } from '../../components/utlis/commonFunctions';
|
||||
import { getCurrentScreen } from '../../components/utlis/navigationUtlis';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
import { FlashList } from '@shopify/flash-list';
|
||||
import { VisitPlanStatus } from '../../reducer/userSlice';
|
||||
import { dateFormat, DAY_MONTH_DATE_FORMAT } from '../../../RN-UI-LIB/src/utlis/dates';
|
||||
import { getAttemptedList, getNonAttemptedList } from './utils';
|
||||
|
||||
export const getItem = (item: Array<ICaseItem>, index: number) => item[index];
|
||||
export const ESTIMATED_ITEM_SIZE = 250; // Average height of List item
|
||||
export const ESTIMATED_LIST_SIZE = { height: SCREEN_HEIGHT - 192, width: SCREEN_WIDTH };
|
||||
|
||||
interface ICasesList {
|
||||
casesList: ICaseItem[];
|
||||
@@ -183,7 +186,7 @@ const CasesList: React.FC<ICasesList> = ({ casesList = [], isVisitPlan }) => {
|
||||
|
||||
const filteredCasesListWithCTA = useMemo(() => {
|
||||
if (!isVisitPlan) {
|
||||
return filteredCasesList;
|
||||
return [...filteredCasesList];
|
||||
}
|
||||
if (isLockedVisitPlanStatus) {
|
||||
return [];
|
||||
@@ -206,7 +209,13 @@ const CasesList: React.FC<ICasesList> = ({ casesList = [], isVisitPlan }) => {
|
||||
}
|
||||
}
|
||||
return visitPlanList;
|
||||
}, [filteredCasesList, isVisitPlan, selectedTodoListCount, isLockedVisitPlanStatus]);
|
||||
}, [
|
||||
filteredCasesList,
|
||||
isVisitPlan,
|
||||
selectedTodoListCount,
|
||||
isLockedVisitPlanStatus,
|
||||
intermediateTodoListMap,
|
||||
]);
|
||||
|
||||
const handleSearchChange = useCallback(
|
||||
debounce((query: string) => {
|
||||
@@ -260,6 +269,22 @@ const CasesList: React.FC<ICasesList> = ({ casesList = [], isVisitPlan }) => {
|
||||
return `My Cases (${filteredCasesList.length})`;
|
||||
};
|
||||
|
||||
let listStyle = {};
|
||||
|
||||
if (isVisitPlan) {
|
||||
if (quickFiltersPresent) {
|
||||
listStyle = styles.visitPlanListWithQuickFilters;
|
||||
} else {
|
||||
listStyle = styles.visitPlanList;
|
||||
}
|
||||
} else {
|
||||
if (quickFiltersPresent) {
|
||||
listStyle = styles.listWithQuickFilters;
|
||||
} else {
|
||||
listStyle = styles.list;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[GenericStyles.fill, styles.container]}>
|
||||
<CaseListHeader
|
||||
@@ -280,27 +305,22 @@ const CasesList: React.FC<ICasesList> = ({ casesList = [], isVisitPlan }) => {
|
||||
]}
|
||||
></Animated.View>
|
||||
) : null}
|
||||
<VirtualizedList
|
||||
data={filteredCasesListWithCTA}
|
||||
scrollEventThrottle={16}
|
||||
onScroll={handleListScroll}
|
||||
contentContainerStyle={[
|
||||
filteredCasesListWithCTA.length ? null : GenericStyles.fill,
|
||||
!isVisitPlan
|
||||
? quickFiltersPresent
|
||||
? styles.listWithQuickFilters
|
||||
: styles.list
|
||||
: quickFiltersPresent
|
||||
? styles.visitPlanListWithQuickFilters
|
||||
: styles.visitPlanList,
|
||||
]}
|
||||
initialNumToRender={4}
|
||||
renderItem={renderListItem}
|
||||
keyExtractor={(item) => item.caseReferenceId}
|
||||
getItemCount={(item) => item.length}
|
||||
getItem={getItem}
|
||||
ListEmptyComponent={listEmptyComponent}
|
||||
/>
|
||||
<View style={GenericStyles.fill}>
|
||||
{filteredCasesListWithCTA.length ? (
|
||||
<FlashList
|
||||
data={filteredCasesListWithCTA}
|
||||
scrollEventThrottle={16}
|
||||
contentContainerStyle={listStyle}
|
||||
onScroll={handleListScroll}
|
||||
renderItem={renderListItem}
|
||||
ListEmptyComponent={listEmptyComponent}
|
||||
estimatedItemSize={ESTIMATED_ITEM_SIZE}
|
||||
estimatedListSize={ESTIMATED_LIST_SIZE}
|
||||
/>
|
||||
) : (
|
||||
<View style={GenericStyles.ph12}>{listEmptyComponent}</View>
|
||||
)}
|
||||
</View>
|
||||
<Modal
|
||||
animationType="slide"
|
||||
animated
|
||||
@@ -341,24 +361,24 @@ const styles = StyleSheet.create({
|
||||
opacity: 0.6,
|
||||
},
|
||||
list: {
|
||||
marginHorizontal: 12,
|
||||
marginTop: HEADER_HEIGHT_MAX,
|
||||
paddingBottom: HEADER_HEIGHT_MAX + 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingTop: HEADER_HEIGHT_MAX,
|
||||
paddingBottom: 5,
|
||||
},
|
||||
visitPlanList: {
|
||||
marginHorizontal: 12,
|
||||
marginTop: VISIT_PLAN_HEADER_HEIGHT_MAX,
|
||||
paddingBottom: VISIT_PLAN_HEADER_HEIGHT_MAX + 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingTop: VISIT_PLAN_HEADER_HEIGHT_MAX,
|
||||
paddingBottom: 10,
|
||||
},
|
||||
listWithQuickFilters: {
|
||||
marginHorizontal: 12,
|
||||
marginTop: HEADER_HEIGHT_MAX_WITH_QUICK_FILTERS,
|
||||
paddingBottom: HEADER_HEIGHT_MAX_WITH_QUICK_FILTERS + 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingTop: HEADER_HEIGHT_MAX_WITH_QUICK_FILTERS,
|
||||
paddingBottom: 5,
|
||||
},
|
||||
visitPlanListWithQuickFilters: {
|
||||
marginHorizontal: 12,
|
||||
marginTop: VISIT_PLAN_HEADER_HEIGHT_MAX_WITH_QUICK_FILTERS,
|
||||
paddingBottom: VISIT_PLAN_HEADER_HEIGHT_MAX_WITH_QUICK_FILTERS + 10,
|
||||
paddingHorizontal: 12,
|
||||
paddingTop: VISIT_PLAN_HEADER_HEIGHT_MAX_WITH_QUICK_FILTERS,
|
||||
paddingBottom: 10,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -143,6 +143,7 @@ const ListItem: React.FC<IListItem> = (props) => {
|
||||
caseId,
|
||||
documentList: getDocumentList(caseListItemDetailObj) || [],
|
||||
caseType: caseType,
|
||||
imageUri: caseListItemDetailObj?.imageUri || '',
|
||||
}),
|
||||
[
|
||||
caseType,
|
||||
@@ -150,6 +151,7 @@ const ListItem: React.FC<IListItem> = (props) => {
|
||||
pinRank,
|
||||
caseListItemDetailObj?.customerInfo?.documents,
|
||||
caseListItemDetailObj?.documents,
|
||||
caseListItemDetailObj?.imageUri,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -314,6 +314,7 @@ export interface ICaseItemAvatarCaseDetailObj extends IFetchDocumentCaseDetailOb
|
||||
isPinned: boolean;
|
||||
isCaseSynced: boolean;
|
||||
customerName: string;
|
||||
imageUri: string;
|
||||
}
|
||||
|
||||
export interface ICaseItemCaseDetailObj extends CaseDetail {
|
||||
|
||||
@@ -74,6 +74,7 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = (props) => {
|
||||
caseId: caseDetail?.id,
|
||||
documentList: getDocumentList(caseDetail) || [],
|
||||
caseType: caseDetail?.caseType,
|
||||
imageUri: caseDetail?.imageUri || '',
|
||||
}),
|
||||
[
|
||||
caseDetail?.caseType,
|
||||
@@ -81,6 +82,7 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = (props) => {
|
||||
caseDetail?.pinRank,
|
||||
caseDetail?.customerInfo?.documents,
|
||||
caseDetail?.documents,
|
||||
caseDetail?.imageUri,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -200,6 +200,7 @@ export interface CaseDetail {
|
||||
imageReferenceId?: string;
|
||||
collectionTag?: 'Fresh' | 'Stab';
|
||||
disbursementAmount?: number;
|
||||
imageUri?: string;
|
||||
feedbackStatus?: FeedbackStatus;
|
||||
attemptedAt?: number;
|
||||
}
|
||||
|
||||
31
yarn.lock
31
yarn.lock
@@ -1838,6 +1838,14 @@
|
||||
"@sentry/types" "7.52.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@shopify/flash-list@1.4.3":
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@shopify/flash-list/-/flash-list-1.4.3.tgz#b7a4fe03d64f3c5ce9646859b49b9d95307f203d"
|
||||
integrity sha512-jtIReAbwWzYBV0dQ6Io9wBX+pD0C4qQFMrb5/fkEvX8PYDgBl5KRYvpfr9WLLj8CV2Jsn1X0mYOsB+ysWrI/8g==
|
||||
dependencies:
|
||||
recyclerlistview "4.2.0"
|
||||
tslib "2.4.0"
|
||||
|
||||
"@sideway/address@^4.1.3":
|
||||
version "4.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
|
||||
@@ -6148,7 +6156,7 @@ lodash.compact@^3.0.1:
|
||||
resolved "https://registry.yarnpkg.com/lodash.compact/-/lodash.compact-3.0.1.tgz#540ce3837745975807471e16b4a2ba21e7256ca5"
|
||||
integrity sha512-2ozeiPi+5eBXW1CLtzjk8XQFhQOEMwwfxblqeq6EGyTxZJ1bPATqilY0e6g2SLQpP4KuMeuioBhEnWz5Pr7ICQ==
|
||||
|
||||
lodash.debounce@^4.0.8:
|
||||
lodash.debounce@4.0.8, lodash.debounce@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
|
||||
@@ -7505,7 +7513,7 @@ prompts@^2.0.1, prompts@^2.4.0:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.5"
|
||||
|
||||
prop-types@^15.7.2, prop-types@^15.8.0, prop-types@^15.8.1:
|
||||
prop-types@15.8.1, prop-types@^15.7.2, prop-types@^15.8.0, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
@@ -7970,6 +7978,15 @@ recursive-fs@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/recursive-fs/-/recursive-fs-2.1.0.tgz#1e20cf7836b292ed81208c4817550a58ad0e15ff"
|
||||
integrity sha512-oed3YruYsD52Mi16s/07eYblQOLi5dTtxpIJNdfCEJ7S5v8dDgVcycar0pRWf4IBuPMIkoctC8RTqGJzIKMNAQ==
|
||||
|
||||
recyclerlistview@4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/recyclerlistview/-/recyclerlistview-4.2.0.tgz#a140149aaa470c9787a1426452651934240d69ef"
|
||||
integrity sha512-uuBCi0c+ggqHKwrzPX4Z/mJOzsBbjZEAwGGmlwpD/sD7raXixdAbdJ6BTcAmuWG50Cg4ru9p12M94Njwhr/27A==
|
||||
dependencies:
|
||||
lodash.debounce "4.0.8"
|
||||
prop-types "15.8.1"
|
||||
ts-object-utils "0.0.5"
|
||||
|
||||
redux-persist@6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8"
|
||||
@@ -9102,6 +9119,11 @@ tr46@~0.0.3:
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
||||
|
||||
ts-object-utils@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/ts-object-utils/-/ts-object-utils-0.0.5.tgz#95361cdecd7e52167cfc5e634c76345e90a26077"
|
||||
integrity sha512-iV0GvHqOmilbIKJsfyfJY9/dNHCs969z3so90dQWsO1eMMozvTpnB1MEaUbb3FYtZTGjv5sIy/xmslEz0Rg2TA==
|
||||
|
||||
tsconfig-paths@^3.14.1:
|
||||
version "3.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"
|
||||
@@ -9112,6 +9134,11 @@ tsconfig-paths@^3.14.1:
|
||||
minimist "^1.2.6"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
tslib@2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
|
||||
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
|
||||
|
||||
tslib@^1.8.1, tslib@^1.9.3:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
|
||||
Reference in New Issue
Block a user