Skip to content

Commit 9268603

Browse files
authored
Merge pull request #61844 from daledah/fix/61821
2 parents 64ff87f + 13bc508 commit 9268603

File tree

8 files changed

+96
-90
lines changed

8 files changed

+96
-90
lines changed

src/components/SelectionListWithModal/index.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ type SelectionListWithModalProps<TItem extends ListItem> = SelectionListProps<TI
1717
onTurnOnSelectionMode?: (item: TItem | null) => void;
1818
isSelected?: (item: TItem) => boolean;
1919
isScreenFocused?: boolean;
20+
selectedItemKeys?: Array<string | number>;
2021
};
2122

2223
function SelectionListWithModal<TItem extends ListItem>(
23-
{turnOnSelectionModeOnLongPress, onTurnOnSelectionMode, onLongPressRow, isScreenFocused = false, sections, isSelected, ...rest}: SelectionListWithModalProps<TItem>,
24+
{turnOnSelectionModeOnLongPress, onTurnOnSelectionMode, onLongPressRow, isScreenFocused = false, sections, isSelected, selectedItemKeys, ...rest}: SelectionListWithModalProps<TItem>,
2425
ref: ForwardedRef<SelectionListHandle>,
2526
) {
2627
const [isModalVisible, setIsModalVisible] = useState(false);
@@ -40,12 +41,14 @@ function SelectionListWithModal<TItem extends ListItem>(
4041

4142
useEffect(() => {
4243
// We can access 0 index safely as we are not displaying multiple sections in table view
43-
const selectedItems = sections[0].data.filter((item) => {
44-
if (isSelected) {
45-
return isSelected(item);
46-
}
47-
return !!item.isSelected;
48-
});
44+
const selectedItems =
45+
selectedItemKeys ??
46+
sections[0].data.filter((item) => {
47+
if (isSelected) {
48+
return isSelected(item);
49+
}
50+
return !!item.isSelected;
51+
});
4952
selectionRef.current = selectedItems.length;
5053

5154
if (!isSmallScreenWidth) {
@@ -66,7 +69,7 @@ function SelectionListWithModal<TItem extends ListItem>(
6669
turnOffMobileSelectionMode();
6770
}
6871
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
69-
}, [sections, isSmallScreenWidth, isSelected, isFocused]);
72+
}, [sections, selectedItemKeys, selectionMode, isSmallScreenWidth, isSelected, isFocused]);
7073

7174
useEffect(
7275
() => () => {

src/hooks/useSearchResults.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {useEffect, useState, useTransition} from 'react';
1+
import {useEffect, useRef, useState, useTransition} from 'react';
2+
import type {ListItem} from '@components/SelectionList/types';
23
import CONST from '@src/CONST';
34
import usePrevious from './usePrevious';
45

@@ -7,15 +8,21 @@ import usePrevious from './usePrevious';
78
* It utilizes `useTransition` to allow the searchQuery to change rapidly, while more expensive renders that occur using
89
* the result of the filtering and sorting are deprioritized, allowing them to happen in the background.
910
*/
10-
function useSearchResults<TValue>(data: TValue[], filterData: (datum: TValue, searchInput: string) => boolean, sortData: (data: TValue[]) => TValue[] = (d) => d) {
11+
function useSearchResults<TValue extends ListItem>(data: TValue[], filterData: (datum: TValue, searchInput: string) => boolean, sortData: (data: TValue[]) => TValue[] = (d) => d) {
1112
const [inputValue, setInputValue] = useState('');
1213
const [result, setResult] = useState(data);
13-
const [, startTransition] = useTransition();
1414
const prevData = usePrevious(data);
15+
const prevInputValueRef = useRef<string | undefined>(undefined);
16+
const [, startTransition] = useTransition();
1517
useEffect(() => {
18+
const normalizedSearchQuery = inputValue.trim().toLowerCase();
19+
const filtered = normalizedSearchQuery.length ? data.filter((item) => filterData(item, normalizedSearchQuery)) : data;
20+
if (prevInputValueRef.current === inputValue) {
21+
setResult(filtered);
22+
return;
23+
}
24+
prevInputValueRef.current = inputValue;
1625
startTransition(() => {
17-
const normalizedSearchQuery = inputValue.trim().toLowerCase();
18-
const filtered = normalizedSearchQuery.length ? data.filter((item) => filterData(item, normalizedSearchQuery)) : data;
1926
const sorted = sortData(filtered);
2027
setResult(sorted);
2128
});

src/pages/workspace/WorkspaceMembersPage.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,6 @@ function WorkspaceMembersPage({personalDetails, route, policy, currentUserPerson
704704

705705
const selectionModeHeader = selectionMode?.isEnabled && shouldUseNarrowLayout;
706706

707-
const sections = useMemo(() => [{data: filteredData, isDisabled: false}], [filteredData]);
708-
709707
return (
710708
<WorkspacePageWithSections
711709
headerText={selectionModeHeader ? translate('common.selectMultiple') : translate('workspace.common.members')}
@@ -774,7 +772,7 @@ function WorkspaceMembersPage({personalDetails, route, policy, currentUserPerson
774772
showsVerticalScrollIndicator={false}
775773
contentContainerStyle={[styles.flexGrow1, styles.flexShrink0]}
776774
>
777-
{shouldUseNarrowLayout && filteredData.length > 0 && <View style={[styles.pr5]}>{getHeaderContent()}</View>}
775+
{shouldUseNarrowLayout && data.length > 0 && <View style={[styles.pr5]}>{getHeaderContent()}</View>}
778776
{!shouldUseNarrowLayout && (
779777
<>
780778
{!!headerMessage && (
@@ -797,7 +795,8 @@ function WorkspaceMembersPage({personalDetails, route, policy, currentUserPerson
797795
<SelectionListWithModal
798796
ref={selectionListRef}
799797
canSelectMultiple={canSelectMultiple}
800-
sections={sections}
798+
sections={[{data: filteredData, isDisabled: false}]}
799+
selectedItemKeys={selectedEmployees}
801800
ListItem={TableListItem}
802801
turnOnSelectionModeOnLongPress={isPolicyAdmin}
803802
onTurnOnSelectionMode={(item) => item && toggleUser(item?.accountID)}

src/pages/workspace/categories/WorkspaceCategoriesPage.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
162162
}, []);
163163
const [inputValue, setInputValue, filteredCategoryList] = useSearchResults(categoryList, filterCategory, sortCategories);
164164

165-
useAutoTurnSelectionModeOffWhenHasNoActiveOption(filteredCategoryList);
166-
167-
const sections = useMemo(() => [{data: filteredCategoryList, isDisabled: false}], [filteredCategoryList]);
165+
useAutoTurnSelectionModeOffWhenHasNoActiveOption(categoryList);
168166

169167
const toggleCategory = useCallback(
170168
(category: PolicyOption) => {
@@ -466,7 +464,8 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
466464
canSelectMultiple={canSelectMultiple}
467465
turnOnSelectionModeOnLongPress={isSmallScreenWidth}
468466
onTurnOnSelectionMode={(item) => item && toggleCategory(item)}
469-
sections={sections}
467+
sections={[{data: filteredCategoryList, isDisabled: false}]}
468+
selectedItemKeys={selectedCategories}
470469
onCheckboxPress={toggleCategory}
471470
onSelectRow={navigateToCategorySettings}
472471
shouldPreventDefaultFocusOnSelectRow={!canUseTouchScreen()}

src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ function PolicyDistanceRatesPage({
187187
}, []);
188188
const sortRates = useCallback((rates: RateForList[]) => rates.sort((a, b) => (a.rate ?? 0) - (b.rate ?? 0)), []);
189189
const [inputValue, setInputValue, filteredDistanceRatesList] = useSearchResults(distanceRatesList, filterRate, sortRates);
190-
const sections = useMemo(() => [{data: filteredDistanceRatesList, key: 'distanceRatesList'}], [filteredDistanceRatesList]);
191190

192191
const addRate = () => {
193192
Navigation.navigate(ROUTES.WORKSPACE_CREATE_DISTANCE_RATE.getRoute(policyID));
@@ -411,7 +410,8 @@ function PolicyDistanceRatesPage({
411410
canSelectMultiple={canSelectMultiple}
412411
turnOnSelectionModeOnLongPress
413412
onTurnOnSelectionMode={(item) => item && toggleRate(item)}
414-
sections={sections}
413+
sections={[{data: filteredDistanceRatesList, isDisabled: false}]}
414+
selectedItemKeys={selectedDistanceRates}
415415
onCheckboxPress={toggleRate}
416416
onSelectRow={openRateDetails}
417417
onSelectAll={toggleAllRates}

src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,12 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
135135
const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, {canBeMissing: false});
136136
const {selectionMode} = useMobileSelectionMode();
137137

138-
const customUnit = getPerDiemCustomUnit(policy);
138+
const customUnit = useMemo(() => getPerDiemCustomUnit(policy), [policy]);
139139
const customUnitRates: Record<string, Rate> = useMemo(() => customUnit?.rates ?? {}, [customUnit]);
140140

141-
const allRatesArray = Object.values(customUnitRates);
141+
const allRatesArray = useMemo(() => Object.values(customUnitRates), [customUnitRates]);
142142

143-
const allSubRates = getSubRatesData(allRatesArray);
143+
const allSubRates = useMemo(() => getSubRatesData(allRatesArray), [allRatesArray]);
144144

145145
const canSelectMultiple = shouldUseNarrowLayout ? selectionMode?.isEnabled : true;
146146

@@ -203,7 +203,6 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
203203
}, []);
204204
const sortRates = useCallback((rates: PolicyOption[]) => lodashSortBy(rates, 'text', localeCompare) as PolicyOption[], []);
205205
const [inputValue, setInputValue, filteredSubRatesList] = useSearchResults(subRatesList, filterRate, sortRates);
206-
const sections = useMemo(() => [{data: filteredSubRatesList, isDisabled: false}], [filteredSubRatesList]);
207206

208207
const toggleSubRate = (subRate: PolicyOption) => {
209208
if (selectedPerDiem.find((selectedSubRate) => selectedSubRate.subRateID === subRate.subRateID) !== undefined) {
@@ -229,19 +228,25 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
229228
}
230229
};
231230

232-
const getCustomListHeader = () => (
233-
<View style={[styles.flex1, styles.flexRow, styles.justifyContentBetween, canSelectMultiple && styles.pl3, !canSelectMultiple && [styles.ph9, styles.pv3, styles.pb5]]}>
234-
<View style={styles.flex3}>
235-
<Text style={[styles.textMicroSupporting, styles.alignSelfStart]}>{translate('common.destination')}</Text>
231+
const getCustomListHeader = () => {
232+
const header = (
233+
<View style={[styles.flex1, styles.flexRow, styles.justifyContentBetween, canSelectMultiple && styles.pl3]}>
234+
<View style={styles.flex3}>
235+
<Text style={[styles.textMicroSupporting, styles.alignSelfStart]}>{translate('common.destination')}</Text>
236+
</View>
237+
<View style={styles.flex2}>
238+
<Text style={[styles.textMicroSupporting, styles.alignItemsStart, styles.pl2]}>{translate('common.subrate')}</Text>
239+
</View>
240+
<View style={styles.flex2}>
241+
<Text style={[styles.textMicroSupporting, styles.alignSelfEnd]}>{translate('workspace.perDiem.amount')}</Text>
242+
</View>
236243
</View>
237-
<View style={styles.flex2}>
238-
<Text style={[styles.textMicroSupporting, styles.alignItemsStart, styles.pl2]}>{translate('common.subrate')}</Text>
239-
</View>
240-
<View style={styles.flex2}>
241-
<Text style={[styles.textMicroSupporting, styles.alignSelfEnd]}>{translate('workspace.perDiem.amount')}</Text>
242-
</View>
243-
</View>
244-
);
244+
);
245+
if (canSelectMultiple) {
246+
return header;
247+
}
248+
return <View style={!canSelectMultiple && [styles.ph9, styles.pv3, styles.pb5]}>{header}</View>;
249+
};
245250

246251
const openSettings = () => {
247252
Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_SETTINGS.getRoute(policyID));
@@ -446,7 +451,8 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
446451
canSelectMultiple={canSelectMultiple}
447452
turnOnSelectionModeOnLongPress
448453
onTurnOnSelectionMode={(item) => item && toggleSubRate(item)}
449-
sections={sections}
454+
sections={[{data: filteredSubRatesList, isDisabled: false}]}
455+
selectedItemKeys={selectedPerDiem.map((item) => item.subRateID)}
450456
onCheckboxPress={toggleSubRate}
451457
onSelectRow={openSubRateDetails}
452458
shouldPreventDefaultFocusOnSelectRow={!canUseTouchScreen()}

0 commit comments

Comments
 (0)