Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9652,6 +9652,7 @@ const CONST = {
AUTH_IMAGES: 'auth-images',
},

MODAL_MAX_HEIGHT_TO_WINDOW_HEIGHT_RATIO: 0.9,
MODAL_MAX_HEIGHT_TO_WINDOW_HEIGHT_RATIO_LANDSCAPE_MODE: 0.75,

MAP_VIEW_LAYERS: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -533,8 +533,8 @@ function MoneyRequestReportTransactionList({

const groupByPopoverComponent = useCallback(
(props: {closeOverlay: () => void}) => (
<View style={[!isSmallScreenWidth && styles.pv4]}>
<View style={styles.getSelectionListPopoverHeight(groupByOptions.length || 1, windowHeight, false, isInLandscapeMode, false)}>
<View style={[styles.pv4]}>
<View style={styles.getSelectionListPopoverHeight({itemCount: groupByOptions.length || 1, windowHeight, isInLandscapeMode, hasButton: false})}>
Comment on lines +536 to +537
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary bottom padding:

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

<SelectionList
data={groupByOptions}
shouldSingleExecuteRowSelect
Expand All @@ -551,7 +551,7 @@ function MoneyRequestReportTransactionList({
</View>
</View>
),
[groupByOptions, reportLayoutGroupBy, styles, windowHeight, isSmallScreenWidth, isInLandscapeMode],
[groupByOptions, reportLayoutGroupBy, styles, windowHeight, isInLandscapeMode],
);

const transactionListContent = (
Expand Down
2 changes: 1 addition & 1 deletion src/components/Search/FilterDropdowns/BasePopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function BasePopup({children, label, applySentryLabel, resetSentryLabel, style,
const styles = useThemeStyles();

return (
<View style={[!isSmallScreenWidth && styles.pv4, style]}>
<View style={[styles.pv4, style]}>
{onBackButtonPress ? (
<HeaderWithBackButton
shouldDisplayHelpButton={false}
Expand Down
63 changes: 39 additions & 24 deletions src/components/Search/FilterDropdowns/CardSelectPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {openSearchCardFiltersPage} from '@libs/actions/Search';
import {buildCardFeedsData, buildCardsData, generateSelectedCards, getDomainFeedData, getSelectedCardsFromFeeds} from '@libs/CardFeedUtils';
import type {CardFilterItem} from '@libs/CardFeedUtils';
import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {SearchAdvancedFiltersForm} from '@src/types/form';
Expand All @@ -39,7 +40,8 @@ function CardSelectPopup({isExpanded, updateFilterForm, closeOverlay}: CardSelec
const illustrations = useThemeIllustrations();
const companyCardFeedIcons = useCompanyCardFeedIcons();
const {windowHeight} = useWindowDimensions();
const {shouldUseNarrowLayout, isInLandscapeMode} = useResponsiveLayout();
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
const {isSmallScreenWidth, isInLandscapeMode} = useResponsiveLayout();

const [areCardsLoaded] = useOnyx(ONYXKEYS.IS_SEARCH_FILTERS_CARD_DATA_LOADED);
const [userCardList, userCardListMetadata] = useOnyx(ONYXKEYS.CARD_LIST);
Expand Down Expand Up @@ -185,31 +187,44 @@ function CardSelectPopup({isExpanded, updateFilterForm, closeOverlay}: CardSelec
onApply={applyChanges}
resetSentryLabel={CONST.SENTRY_LABEL.SEARCH.FILTER_POPUP_RESET_CARD}
applySentryLabel={CONST.SENTRY_LABEL.SEARCH.FILTER_POPUP_APPLY_CARD}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- we want to fallback to 1 when it's 0
style={styles.getCardSelectionListPopoverHeight(itemCount || 1, sectionHeaderCount, windowHeight, shouldUseNarrowLayout, isInLandscapeMode, shouldShowSearchInput)}
>
{!!shouldShowLoadingState && (
<View style={[styles.flex1, styles.flexColumn, styles.justifyContentCenter, styles.alignItemsCenter]}>
<ActivityIndicator
color={theme.spinner}
size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE}
style={[styles.pl3]}
reasonAttributes={reasonAttributes}
<View
style={[
styles.getSelectionListPopoverHeight({
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- we want to fallback to 1 when it's 0
itemCount: itemCount || 1,
itemHeight: variables.optionRowHeight,
windowHeight,
isInLandscapeMode,
hasTitle: isSmallScreenWidth,
isSearchable: shouldShowSearchInput,
extraHeight: 28 * sectionHeaderCount,
}),
]}
>
{!!shouldShowLoadingState && (
<View style={[styles.flex1, styles.flexColumn, styles.justifyContentCenter, styles.alignItemsCenter]}>
<ActivityIndicator
color={theme.spinner}
size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE}
style={[styles.pl3]}
reasonAttributes={reasonAttributes}
/>
</View>
)}
{!shouldShowLoadingState && (
<SelectionListWithSections<CardFilterItem>
sections={sections}
ListItem={CardListItem}
onSelectRow={updateNewCards}
shouldPreventDefaultFocusOnSelectRow={false}
shouldShowTextInput={shouldShowSearchInput}
textInputOptions={textInputOptions}
shouldStopPropagation
canSelectMultiple
/>
</View>
)}
{!shouldShowLoadingState && (
<SelectionListWithSections<CardFilterItem>
sections={sections}
ListItem={CardListItem}
onSelectRow={updateNewCards}
shouldPreventDefaultFocusOnSelectRow={false}
shouldShowTextInput={shouldShowSearchInput}
textInputOptions={textInputOptions}
shouldStopPropagation
canSelectMultiple
/>
)}
)}
</View>
</BasePopup>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import type {SearchDateValues} from '@libs/SearchQueryUtils';
import {getDateModifierTitle, getDateRangeDisplayValueFromFormValue} from '@libs/SearchQueryUtils';
import type {SearchDateModifier} from '@libs/SearchUIUtils';
Expand Down Expand Up @@ -47,7 +46,6 @@ function DateSelectPopup({label, value, presets, style, closeOverlay, onChange,

const {translate} = useLocalize();
const styles = useThemeStyles();
const {windowHeight} = useWindowDimensions();
const searchDatePresetFilterBaseRef = useRef<SearchDatePresetFilterBaseHandle>(null);
const scrollViewRef = useRef<React.ComponentRef<typeof ScrollView>>(null);
const [selectedDateModifier, setSelectedDateModifier] = useState<SearchDateModifier | null>(null);
Expand Down Expand Up @@ -130,8 +128,6 @@ function DateSelectPopup({label, value, presets, style, closeOverlay, onChange,
closeOverlay();
}, [clearSelection, closeOverlay, onChange, selectedDateModifier]);

const maxPopupHeight = Math.round(windowHeight * 0.875);

// For non-Range modes, use original simple styles. For Range, use custom layout
const useRangeLayout = selectedDateModifier === CONST.SEARCH.DATE_MODIFIERS.RANGE;

Expand Down Expand Up @@ -186,14 +182,13 @@ function DateSelectPopup({label, value, presets, style, closeOverlay, onChange,
);
}

const topPaddingStyle = selectedDateModifier ? styles.pt3 : undefined;
const buttonRowSpacing = selectedDateModifier ? styles.mt4 : styles.mt2;
const mobileContainerStyle = useRangeLayout ? [topPaddingStyle, styles.flexGrow1, {maxHeight: maxPopupHeight}] : styles.gap2;
const mobileContainerStyle = useRangeLayout ? [styles.flexGrow1] : styles.gap2;
const mobileLabelStyle = useRangeLayout ? [styles.textLabel, styles.ph5, styles.pb3] : [styles.textLabel, styles.textSupporting, styles.ph5, styles.pv1];
const mobileButtonRowStyle = useRangeLayout ? [styles.flexRow, styles.ph5, buttonRowSpacing, styles.alignItemsCenter, styles.gap2] : [styles.flexRow, styles.gap2, styles.ph5];

return (
<View style={[mobileContainerStyle, style, isInLandscapeMode ? styles.h100 : undefined]}>
<View style={[styles.pv4, mobileContainerStyle, style, isInLandscapeMode ? styles.h100 : undefined]}>
{!selectedDateModifier && !!label && <Text style={mobileLabelStyle}>{label}</Text>}
<ScrollView
ref={scrollViewRef}
Expand Down
63 changes: 19 additions & 44 deletions src/components/Search/FilterDropdowns/DisplayPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, {useState} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import MenuItem from '@components/MenuItem';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import ScrollView from '@components/ScrollView';
import type {SearchQueryJSON} from '@components/Search/types';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
Expand Down Expand Up @@ -37,7 +36,7 @@ type DisplayPopupProps = {
function DisplayPopup({queryJSON, searchResults, closeOverlay, onSort}: DisplayPopupProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const {shouldUseNarrowLayout, isLargeScreenWidth} = useResponsiveLayout();
const {isLargeScreenWidth} = useResponsiveLayout();
const expensifyIcons = useMemoizedLazyExpensifyIcons(['Columns']);
const [searchAdvancedFilters = getEmptyObject<SearchAdvancedFiltersForm>()] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM);
const [selectedDisplayFilter, setSelectedDisplayFilter] = useState<
Expand Down Expand Up @@ -72,7 +71,7 @@ function DisplayPopup({queryJSON, searchResults, closeOverlay, onSort}: DisplayP
const viewValue = searchAdvancedFilters[CONST.SEARCH.SYNTAX_ROOT_KEYS.VIEW];

return (
<View style={[!shouldUseNarrowLayout && styles.pv4]}>
<ScrollView contentContainerStyle={[styles.pv4]}>
<MenuItemWithTopDescription
shouldShowRightIcon
description={translate('search.display.sortBy')}
Expand Down Expand Up @@ -127,7 +126,7 @@ function DisplayPopup({queryJSON, searchResults, closeOverlay, onSort}: DisplayP
sentryLabel={CONST.SENTRY_LABEL.SEARCH.COLUMNS_BUTTON}
/>
)}
</View>
</ScrollView>
);
}

Expand Down Expand Up @@ -162,46 +161,35 @@ function DisplayPopup({queryJSON, searchResults, closeOverlay, onSort}: DisplayP
setSelectedDisplayFilter(null);
};

const subtitle = {
[CONST.SEARCH.SYNTAX_ROOT_KEYS.SORT_BY]: translate('search.display.sortBy'),
[CONST.SEARCH.SYNTAX_ROOT_KEYS.SORT_ORDER]: translate('search.display.sortOrder'),
[CONST.SEARCH.SYNTAX_ROOT_KEYS.GROUP_BY]: translate('search.display.groupBy'),
[CONST.SEARCH.SYNTAX_FILTER_KEYS.GROUP_CURRENCY]: translate('common.groupCurrency'),
[CONST.SEARCH.SYNTAX_ROOT_KEYS.VIEW]: translate('search.view.label'),
[CONST.SEARCH.SYNTAX_ROOT_KEYS.LIMIT]: translate('search.display.limitResults'),
};

let subPopup: React.JSX.Element | null = null;

switch (selectedDisplayFilter) {
case CONST.SEARCH.SYNTAX_ROOT_KEYS.SORT_BY:
subPopup = (
return (
<SortByPopup
searchResults={searchResults}
queryJSON={queryJSON}
groupBy={groupBy}
onSort={onSort}
onSortOrderPress={() => setSelectedDisplayFilter(CONST.SEARCH.SYNTAX_ROOT_KEYS.SORT_ORDER)}
onBackButtonPress={goBack}
closeOverlay={closeOverlay}
/>
);
break;
case CONST.SEARCH.SYNTAX_ROOT_KEYS.SORT_ORDER:
subPopup = (
return (
<SortOrderPopup
queryJSON={queryJSON}
onSort={onSort}
onBackButtonPress={goBack}
closeOverlay={closeOverlay}
/>
);
break;
case CONST.SEARCH.SYNTAX_ROOT_KEYS.GROUP_BY:
subPopup = (
return (
<GroupByPopup
style={styles.p0}
sections={groupBySections}
value={groupBy}
closeOverlay={closeOverlay}
onBackButtonPress={goBack}
onChange={(item) => {
const newValue = item?.value;
if (!newValue) {
Expand All @@ -212,52 +200,39 @@ function DisplayPopup({queryJSON, searchResults, closeOverlay, onSort}: DisplayP
}}
/>
);
break;
case CONST.SEARCH.SYNTAX_FILTER_KEYS.GROUP_CURRENCY:
subPopup = (
return (
<GroupCurrencyPopup
onChange={(item) => updateFilterForm({groupCurrency: item?.value})}
onBackButtonPress={goBack}
closeOverlay={closeOverlay}
/>
);
break;
case CONST.SEARCH.SYNTAX_ROOT_KEYS.VIEW:
subPopup = (
return (
<SingleSelectPopup
style={styles.p0}
items={viewOptions}
value={view}
label={translate('search.view.label')}
onBackButtonPress={goBack}
closeOverlay={closeOverlay}
onChange={(item) => updateFilterForm({view: item?.value ?? CONST.SEARCH.VIEW.TABLE})}
/>
);
break;
case CONST.SEARCH.SYNTAX_ROOT_KEYS.LIMIT:
subPopup = (
return (
<TextInputPopup
style={styles.pv0}
placeholder={translate('search.filters.limit')}
defaultValue={limitValue}
label={translate('search.display.limitResults')}
onBackButtonPress={goBack}
closeOverlay={closeOverlay}
onChange={(value) => updateFilterForm({limit: value})}
/>
);
break;
default:
break;
return null;
}

return (
<View style={[!shouldUseNarrowLayout && styles.pv4]}>
<HeaderWithBackButton
shouldDisplayHelpButton={false}
style={[styles.h10, styles.pv1, styles.mb2]}
subtitle={subtitle[selectedDisplayFilter]}
onBackButtonPress={goBack}
/>
{subPopup}
</View>
);
}

export default DisplayPopup;
2 changes: 1 addition & 1 deletion src/components/Search/FilterDropdowns/DropdownButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ function DropdownButton({
// This must be false because we dont want the modal to close if we open the RHP for selections
// such as date years
shouldCloseWhenBrowserNavigationChanged={false}
innerContainerStyle={containerStyles}
innerContainerStyle={{...containerStyles, ...styles.p0}}
popoverDimensions={{
width: actualPopoverWidth,
height: CONST.POPOVER_DROPDOWN_MIN_HEIGHT,
Expand Down
21 changes: 9 additions & 12 deletions src/components/Search/FilterDropdowns/GroupByPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {SearchGroupBy} from '@components/Search/types';
import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections';
import type {ListItem} from '@components/SelectionList/types';
import useLocalize from '@hooks/useLocalize';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
Expand All @@ -18,16 +19,14 @@ type GroupByPopupItem = {
};

type GroupByPopupProps = {
/** The label to show when in an overlay on mobile */
label?: string;

/** The grouped options to show in the list */
sections: GroupBySection[];

/** The currently selected item */
value: GroupByPopupItem | null;

style?: StyleProp<ViewStyle>;
onBackButtonPress: () => void;

/** Function to call to close the overlay when changes are applied */
closeOverlay: () => void;
Expand All @@ -36,10 +35,10 @@ type GroupByPopupProps = {
onChange: (item: GroupByPopupItem | null) => void;
};

function GroupByPopup({label, value, sections, style, closeOverlay, onChange}: GroupByPopupProps) {
function GroupByPopup({value, sections, style, onBackButtonPress, closeOverlay, onChange}: GroupByPopupProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
const {isSmallScreenWidth, isInLandscapeMode} = useResponsiveLayout();
const {isInLandscapeMode} = useResponsiveLayout();
const {windowHeight} = useWindowDimensions();
const [selectedItem, setSelectedItem] = useState(value);

Expand All @@ -59,7 +58,7 @@ function GroupByPopup({label, value, sections, style, closeOverlay, onChange}: G
[sections, selectedItem?.value, styles.dividerLine],
);

const optionsCount = Math.max(
const itemCount = Math.max(
1,
listSections.reduce((count, section) => count + section.data.length + (section.data.length > 0 && !!section.customHeader ? 1 : 0), 0),
);
Expand All @@ -82,18 +81,16 @@ function GroupByPopup({label, value, sections, style, closeOverlay, onChange}: G
closeOverlay();
}, [closeOverlay, onChange]);

const shouldShowLabel = isSmallScreenWidth && !!label;

return (
<BasePopup
label={label}
onReset={resetChanges}
onApply={applyChanges}
onBackButtonPress={onBackButtonPress}
label={translate('search.display.groupBy')}
resetSentryLabel={CONST.SENTRY_LABEL.SEARCH.FILTER_POPUP_RESET_SINGLE_SELECT}
applySentryLabel={CONST.SENTRY_LABEL.SEARCH.FILTER_POPUP_APPLY_SINGLE_SELECT}
style={style}
>
<View style={[styles.getSelectionListPopoverHeight(optionsCount, windowHeight, false, isInLandscapeMode, shouldShowLabel)]}>
<View style={[style, styles.getSelectionListPopoverHeight({itemCount, windowHeight, isInLandscapeMode, hasHeader: true})]}>
<SelectionListWithSections
sections={listSections}
shouldSingleExecuteRowSelect
Expand Down
Loading
Loading