Skip to content

Commit 81ab58a

Browse files
authored
Merge pull request Expensify#88102 from bernhardoj/fix/revamp-actions-bar-filters-chip-regression
[CP Staging] Fix revamp actions bar filters chip regression
2 parents 146e621 + 23a7144 commit 81ab58a

4 files changed

Lines changed: 91 additions & 52 deletions

File tree

src/components/Search/FilterDropdowns/CardSelectPopup.tsx

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import ActivityIndicator from '@components/ActivityIndicator';
44
import {usePersonalDetails} from '@components/OnyxListItemProvider';
55
import CardListItem from '@components/SelectionList/ListItem/CardListItem';
66
import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections';
7+
import type {Section} from '@components/SelectionList/SelectionListWithSections/types';
78
import {useCompanyCardFeedIcons} from '@hooks/useCompanyCardIcons';
89
import useDebouncedState from '@hooks/useDebouncedState';
910
import useLocalize from '@hooks/useLocalize';
@@ -38,8 +39,7 @@ function CardSelectPopup({isExpanded, updateFilterForm, closeOverlay}: CardSelec
3839
const illustrations = useThemeIllustrations();
3940
const companyCardFeedIcons = useCompanyCardFeedIcons();
4041
const {windowHeight} = useWindowDimensions();
41-
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
42-
const {isSmallScreenWidth, isInLandscapeMode} = useResponsiveLayout();
42+
const {shouldUseNarrowLayout, isInLandscapeMode} = useResponsiveLayout();
4343

4444
const [areCardsLoaded] = useOnyx(ONYXKEYS.IS_SEARCH_FILTERS_CARD_DATA_LOADED);
4545
const [userCardList, userCardListMetadata] = useOnyx(ONYXKEYS.CARD_LIST);
@@ -100,31 +100,42 @@ function CardSelectPopup({isExpanded, updateFilterForm, closeOverlay}: CardSelec
100100
!!item.cardName?.toLocaleLowerCase().includes(debouncedSearchTerm.toLocaleLowerCase()) ||
101101
(item.isVirtual && translate('workspace.expensifyCard.virtual').toLocaleLowerCase().includes(debouncedSearchTerm.toLocaleLowerCase()));
102102

103-
const sections =
104-
searchAdvancedFiltersForm === undefined
105-
? []
106-
: [
107-
{
108-
title: undefined,
109-
data: [...cardFeedsSectionData.selected, ...individualCardsSectionData.selected, ...closedCardsSectionData.selected].filter(searchFunction),
110-
sectionIndex: 0,
111-
},
112-
{
113-
title: translate('search.filters.card.cardFeeds'),
114-
data: cardFeedsSectionData.unselected.filter(searchFunction),
115-
sectionIndex: 1,
116-
},
117-
{
118-
title: translate('search.filters.card.individualCards'),
119-
data: individualCardsSectionData.unselected.filter(searchFunction),
120-
sectionIndex: 2,
121-
},
122-
{
123-
title: translate('search.filters.card.closedCards'),
124-
data: closedCardsSectionData.unselected.filter(searchFunction),
125-
sectionIndex: 3,
126-
},
127-
];
103+
let sections: Array<Section<CardFilterItem>> = [];
104+
let itemCount;
105+
let sectionHeaderCount = 0;
106+
107+
if (searchAdvancedFiltersForm) {
108+
const selectedData = [...cardFeedsSectionData.selected, ...individualCardsSectionData.selected, ...closedCardsSectionData.selected].filter(searchFunction);
109+
const unselectedCardFeedsData = cardFeedsSectionData.unselected.filter(searchFunction);
110+
const unselectedIndividualCardsData = individualCardsSectionData.unselected.filter(searchFunction);
111+
const unselectedClosedCardsData = closedCardsSectionData.unselected.filter(searchFunction);
112+
113+
itemCount = selectedData.length + unselectedCardFeedsData.length + unselectedIndividualCardsData.length + unselectedClosedCardsData.length;
114+
sectionHeaderCount = [unselectedCardFeedsData.length, unselectedIndividualCardsData.length, unselectedClosedCardsData.length].filter(Boolean).length;
115+
116+
sections = [
117+
{
118+
title: undefined,
119+
data: selectedData,
120+
sectionIndex: 0,
121+
},
122+
{
123+
title: translate('search.filters.card.cardFeeds'),
124+
data: unselectedCardFeedsData,
125+
sectionIndex: 1,
126+
},
127+
{
128+
title: translate('search.filters.card.individualCards'),
129+
data: unselectedIndividualCardsData,
130+
sectionIndex: 2,
131+
},
132+
{
133+
title: translate('search.filters.card.closedCards'),
134+
data: unselectedClosedCardsData,
135+
sectionIndex: 3,
136+
},
137+
];
138+
}
128139

129140
const applyChanges = () => {
130141
const feeds = cardFeedsSectionData.selected.map((feed) => feed.cardFeedKey);
@@ -174,6 +185,8 @@ function CardSelectPopup({isExpanded, updateFilterForm, closeOverlay}: CardSelec
174185
onApply={applyChanges}
175186
resetSentryLabel={CONST.SENTRY_LABEL.SEARCH.FILTER_POPUP_RESET_CARD}
176187
applySentryLabel={CONST.SENTRY_LABEL.SEARCH.FILTER_POPUP_APPLY_CARD}
188+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- we want to fallback to 1 when it's 0
189+
style={styles.getCardSelectionListPopoverHeight(itemCount || 1, sectionHeaderCount, windowHeight, shouldUseNarrowLayout, isInLandscapeMode, shouldShowSearchInput)}
177190
>
178191
{!!shouldShowLoadingState && (
179192
<View style={[styles.flex1, styles.flexColumn, styles.justifyContentCenter, styles.alignItemsCenter]}>
@@ -186,28 +199,16 @@ function CardSelectPopup({isExpanded, updateFilterForm, closeOverlay}: CardSelec
186199
</View>
187200
)}
188201
{!shouldShowLoadingState && (
189-
<View
190-
style={[
191-
styles.getSelectionListPopoverHeight(
192-
sections.flatMap((section) => section.data).length || 1,
193-
windowHeight,
194-
shouldShowSearchInput,
195-
isInLandscapeMode,
196-
isSmallScreenWidth,
197-
),
198-
]}
199-
>
200-
<SelectionListWithSections<CardFilterItem>
201-
sections={sections}
202-
ListItem={CardListItem}
203-
onSelectRow={updateNewCards}
204-
shouldPreventDefaultFocusOnSelectRow={false}
205-
shouldShowTextInput={shouldShowSearchInput}
206-
textInputOptions={textInputOptions}
207-
shouldStopPropagation
208-
canSelectMultiple
209-
/>
210-
</View>
202+
<SelectionListWithSections<CardFilterItem>
203+
sections={sections}
204+
ListItem={CardListItem}
205+
onSelectRow={updateNewCards}
206+
shouldPreventDefaultFocusOnSelectRow={false}
207+
shouldShowTextInput={shouldShowSearchInput}
208+
textInputOptions={textInputOptions}
209+
shouldStopPropagation
210+
canSelectMultiple
211+
/>
211212
)}
212213
</BasePopup>
213214
);

src/components/Search/SearchPageHeader/useSearchFiltersBar.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,14 @@ function useSearchFiltersBar(queryJSON: SearchQueryJSON): UseSearchFiltersBarRes
301301
case FILTER_KEYS.IS:
302302
case FILTER_KEYS.EXPENSE_TYPE:
303303
case FILTER_KEYS.STATUS: {
304-
const formValues = searchAdvancedFiltersForm[filterKey];
305-
const formValuesAsArray = Array.isArray(formValues) ? formValues : [formValues];
304+
let formValues = searchAdvancedFiltersForm[filterKey] ?? [];
305+
306+
if (filterKey === FILTER_KEYS.STATUS) {
307+
formValues = Array.isArray(formValues) ? formValues : formValues.split(',');
308+
}
309+
306310
const items = getMultiSelectFilterOptions(filterKey, type, translate);
307-
const value = items.filter((item) => formValuesAsArray.includes(item.value));
311+
const value = items.filter((item) => formValues.includes(item.value));
308312

309313
const multiSelectComponent = ({closeOverlay}: PopoverComponentProps) => (
310314
<MultiSelectFilterPopup

src/libs/SearchUIUtils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4806,6 +4806,7 @@ const FILTER_LABEL_MAP: Partial<Record<SearchAdvancedFiltersKey, TranslationPath
48064806
[FILTER_KEYS.STATUS]: 'common.status',
48074807
[FILTER_KEYS.TAG]: 'common.tag',
48084808
[FILTER_KEYS.TAX_RATE]: 'workspace.taxes.taxRate',
4809+
[FILTER_KEYS.TYPE]: 'common.type',
48094810
[FILTER_KEYS.TO]: 'common.to',
48104811
[FILTER_KEYS.TITLE]: 'common.title',
48114812
[FILTER_KEYS.WITHDRAWAL_ID]: 'common.withdrawalID',
@@ -4915,6 +4916,14 @@ function getDisplayValue(
49154916
translate: LocalizedTranslate,
49164917
localeCompare: LocaleContextProps['localeCompare'],
49174918
) {
4919+
if (key === FILTER_KEYS.TYPE) {
4920+
const filterValue = form[key];
4921+
if (filterValue === CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT) {
4922+
return translate('common.expenseReport');
4923+
}
4924+
return filterValue ? translate(`common.${filterValue}`) : undefined;
4925+
}
4926+
49184927
if (key === FILTER_KEYS.TAG || key === FILTER_KEYS.CATEGORY) {
49194928
const mapFn =
49204929
key === FILTER_KEYS.TAG

src/styles/index.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6319,6 +6319,31 @@ const dynamicStyles = (theme: ThemeColors) =>
63196319
return {height, ...width};
63206320
},
63216321

6322+
getCardSelectionListPopoverHeight: (
6323+
itemCount: number,
6324+
sectionHeaderCount: number,
6325+
windowHeight: number,
6326+
shouldUseNarrowLayout: boolean,
6327+
isInLandscapeMode: boolean,
6328+
isSearchable = true,
6329+
) => {
6330+
const MODAL_PADDING = 32;
6331+
const BUTTON_HEIGHT = 48;
6332+
const SEARCHBAR_HEIGHT = isSearchable ? 64 : 0;
6333+
const TITLE_HEIGHT = shouldUseNarrowLayout ? 34 : 0;
6334+
const PADDING = shouldUseNarrowLayout ? 0 : MODAL_PADDING;
6335+
const ESTIMATED_LIST_HEIGHT = itemCount * variables.optionRowHeight + sectionHeaderCount * 28 + SEARCHBAR_HEIGHT + BUTTON_HEIGHT + TITLE_HEIGHT + PADDING;
6336+
6337+
const popoverHeight = isInLandscapeMode ? CONST.MODAL_MAX_HEIGHT_TO_WINDOW_HEIGHT_RATIO_LANDSCAPE_MODE * windowHeight - MODAL_PADDING : CONST.POPOVER_DROPDOWN_MAX_HEIGHT;
6338+
6339+
// Native platforms don't support maxHeight in the way thats expected, so lets manually set the height to either
6340+
// the listHeight, the max height of the popover, or 90% of the window height, such that we never overflow the screen
6341+
// and never expand over the max height
6342+
const height = Math.min(ESTIMATED_LIST_HEIGHT, popoverHeight, windowHeight * 0.9);
6343+
6344+
return {height};
6345+
},
6346+
63226347
testDriveModalContainer: (shouldUseNarrowLayout: boolean) => ({
63236348
// On small/medium screens, we need to remove the top padding
63246349
paddingTop: 0,

0 commit comments

Comments
 (0)