Skip to content

Commit 67dc880

Browse files
authored
Merge pull request Expensify#64670 from s77rt/unapproved-accruals
Suggested Search: Unapproved accruals
2 parents 2126290 + a562a12 commit 67dc880

56 files changed

Lines changed: 1321 additions & 676 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

assets/images/money-hourglass.svg

Lines changed: 13 additions & 0 deletions
Loading

src/CONST/index.ts

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6547,7 +6547,6 @@ const CONST = {
65476547
},
65486548

65496549
SEARCH: {
6550-
NEVER: 'never',
65516550
RESULTS_PAGE_SIZE: 50,
65526551
DATA_TYPES: {
65536552
EXPENSE: 'expense',
@@ -6586,6 +6585,7 @@ const CONST = {
65866585
},
65876586
GROUP_BY: {
65886587
REPORTS: 'reports',
6588+
MEMBERS: 'members',
65896589
},
65906590
BOOLEAN: {
65916591
YES: 'yes',
@@ -6742,6 +6742,10 @@ const CONST = {
67426742
AFTER: 'After',
67436743
ON: 'On',
67446744
},
6745+
DATE_PRESETS: {
6746+
NEVER: 'never',
6747+
LAST_MONTH: 'last-month',
6748+
},
67456749
SNAPSHOT_ONYX_KEYS: [
67466750
ONYXKEYS.COLLECTION.REPORT,
67476751
ONYXKEYS.COLLECTION.POLICY,
@@ -6753,6 +6757,131 @@ const CONST = {
67536757
],
67546758
},
67556759

6760+
/**
6761+
* SEARCH_TYPE_FILTERS_KEYS is an object keyed by the different search types.
6762+
* Each value is then an array of arrays where each inner array is a separate section in the UI.
6763+
*/
6764+
get SEARCH_TYPE_FILTERS_KEYS() {
6765+
return {
6766+
[this.SEARCH.DATA_TYPES.EXPENSE]: [
6767+
[
6768+
this.SEARCH.SYNTAX_FILTER_KEYS.TYPE,
6769+
this.SEARCH.SYNTAX_FILTER_KEYS.FROM,
6770+
this.SEARCH.SYNTAX_FILTER_KEYS.TO,
6771+
this.SEARCH.SYNTAX_FILTER_KEYS.KEYWORD,
6772+
this.SEARCH.SYNTAX_FILTER_KEYS.STATUS,
6773+
this.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID,
6774+
this.SEARCH.SYNTAX_ROOT_KEYS.GROUP_BY,
6775+
],
6776+
[
6777+
this.SEARCH.SYNTAX_FILTER_KEYS.EXPENSE_TYPE,
6778+
this.SEARCH.SYNTAX_FILTER_KEYS.MERCHANT,
6779+
this.SEARCH.SYNTAX_FILTER_KEYS.DATE,
6780+
this.SEARCH.SYNTAX_FILTER_KEYS.AMOUNT,
6781+
this.SEARCH.SYNTAX_FILTER_KEYS.CURRENCY,
6782+
this.SEARCH.SYNTAX_FILTER_KEYS.CATEGORY,
6783+
this.SEARCH.SYNTAX_FILTER_KEYS.TAG,
6784+
this.SEARCH.SYNTAX_FILTER_KEYS.DESCRIPTION,
6785+
this.SEARCH.SYNTAX_FILTER_KEYS.CARD_ID,
6786+
this.SEARCH.SYNTAX_FILTER_KEYS.POSTED,
6787+
this.SEARCH.SYNTAX_FILTER_KEYS.TAX_RATE,
6788+
this.SEARCH.SYNTAX_FILTER_KEYS.REIMBURSABLE,
6789+
this.SEARCH.SYNTAX_FILTER_KEYS.BILLABLE,
6790+
],
6791+
[
6792+
this.SEARCH.SYNTAX_FILTER_KEYS.REPORT_ID,
6793+
this.SEARCH.SYNTAX_FILTER_KEYS.SUBMITTED,
6794+
this.SEARCH.SYNTAX_FILTER_KEYS.APPROVED,
6795+
this.SEARCH.SYNTAX_FILTER_KEYS.PAID,
6796+
this.SEARCH.SYNTAX_FILTER_KEYS.EXPORTED,
6797+
],
6798+
],
6799+
[this.SEARCH.DATA_TYPES.INVOICE]: [
6800+
[
6801+
this.SEARCH.SYNTAX_FILTER_KEYS.TYPE,
6802+
this.SEARCH.SYNTAX_FILTER_KEYS.FROM,
6803+
this.SEARCH.SYNTAX_FILTER_KEYS.TO,
6804+
this.SEARCH.SYNTAX_FILTER_KEYS.KEYWORD,
6805+
this.SEARCH.SYNTAX_FILTER_KEYS.STATUS,
6806+
this.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID,
6807+
],
6808+
[
6809+
this.SEARCH.SYNTAX_FILTER_KEYS.MERCHANT,
6810+
this.SEARCH.SYNTAX_FILTER_KEYS.DATE,
6811+
this.SEARCH.SYNTAX_FILTER_KEYS.AMOUNT,
6812+
this.SEARCH.SYNTAX_FILTER_KEYS.CURRENCY,
6813+
this.SEARCH.SYNTAX_FILTER_KEYS.CATEGORY,
6814+
this.SEARCH.SYNTAX_FILTER_KEYS.TAG,
6815+
this.SEARCH.SYNTAX_FILTER_KEYS.DESCRIPTION,
6816+
this.SEARCH.SYNTAX_FILTER_KEYS.CARD_ID,
6817+
this.SEARCH.SYNTAX_FILTER_KEYS.POSTED,
6818+
this.SEARCH.SYNTAX_FILTER_KEYS.TAX_RATE,
6819+
],
6820+
[
6821+
this.SEARCH.SYNTAX_FILTER_KEYS.REPORT_ID,
6822+
this.SEARCH.SYNTAX_FILTER_KEYS.SUBMITTED,
6823+
this.SEARCH.SYNTAX_FILTER_KEYS.APPROVED,
6824+
this.SEARCH.SYNTAX_FILTER_KEYS.PAID,
6825+
this.SEARCH.SYNTAX_FILTER_KEYS.EXPORTED,
6826+
],
6827+
],
6828+
[this.SEARCH.DATA_TYPES.TRIP]: [
6829+
[
6830+
this.SEARCH.SYNTAX_FILTER_KEYS.TYPE,
6831+
this.SEARCH.SYNTAX_FILTER_KEYS.FROM,
6832+
this.SEARCH.SYNTAX_FILTER_KEYS.TO,
6833+
this.SEARCH.SYNTAX_FILTER_KEYS.KEYWORD,
6834+
this.SEARCH.SYNTAX_FILTER_KEYS.STATUS,
6835+
this.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID,
6836+
this.SEARCH.SYNTAX_ROOT_KEYS.GROUP_BY,
6837+
],
6838+
[
6839+
this.SEARCH.SYNTAX_FILTER_KEYS.MERCHANT,
6840+
this.SEARCH.SYNTAX_FILTER_KEYS.DATE,
6841+
this.SEARCH.SYNTAX_FILTER_KEYS.AMOUNT,
6842+
this.SEARCH.SYNTAX_FILTER_KEYS.CURRENCY,
6843+
this.SEARCH.SYNTAX_FILTER_KEYS.CATEGORY,
6844+
this.SEARCH.SYNTAX_FILTER_KEYS.TAG,
6845+
this.SEARCH.SYNTAX_FILTER_KEYS.DESCRIPTION,
6846+
this.SEARCH.SYNTAX_FILTER_KEYS.CARD_ID,
6847+
this.SEARCH.SYNTAX_FILTER_KEYS.POSTED,
6848+
this.SEARCH.SYNTAX_FILTER_KEYS.TAX_RATE,
6849+
],
6850+
[
6851+
this.SEARCH.SYNTAX_FILTER_KEYS.REPORT_ID,
6852+
this.SEARCH.SYNTAX_FILTER_KEYS.SUBMITTED,
6853+
this.SEARCH.SYNTAX_FILTER_KEYS.APPROVED,
6854+
this.SEARCH.SYNTAX_FILTER_KEYS.PAID,
6855+
this.SEARCH.SYNTAX_FILTER_KEYS.EXPORTED,
6856+
],
6857+
],
6858+
[this.SEARCH.DATA_TYPES.CHAT]: [
6859+
[
6860+
this.SEARCH.SYNTAX_FILTER_KEYS.TYPE,
6861+
this.SEARCH.SYNTAX_FILTER_KEYS.FROM,
6862+
this.SEARCH.SYNTAX_FILTER_KEYS.TO,
6863+
this.SEARCH.SYNTAX_FILTER_KEYS.IN,
6864+
this.SEARCH.SYNTAX_FILTER_KEYS.KEYWORD,
6865+
this.SEARCH.SYNTAX_FILTER_KEYS.STATUS,
6866+
this.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID,
6867+
this.SEARCH.SYNTAX_FILTER_KEYS.DATE,
6868+
],
6869+
],
6870+
[this.SEARCH.DATA_TYPES.TASK]: [
6871+
[
6872+
this.SEARCH.SYNTAX_FILTER_KEYS.TYPE,
6873+
this.SEARCH.SYNTAX_FILTER_KEYS.TITLE,
6874+
this.SEARCH.SYNTAX_FILTER_KEYS.DESCRIPTION,
6875+
this.SEARCH.SYNTAX_FILTER_KEYS.IN,
6876+
this.SEARCH.SYNTAX_FILTER_KEYS.FROM,
6877+
this.SEARCH.SYNTAX_FILTER_KEYS.ASSIGNEE,
6878+
this.SEARCH.SYNTAX_FILTER_KEYS.STATUS,
6879+
this.SEARCH.SYNTAX_FILTER_KEYS.DATE,
6880+
],
6881+
],
6882+
} as const;
6883+
},
6884+
67566885
EXPENSE: {
67576886
TYPE: {
67586887
CASH_CARD_NAME: 'Cash Expense',

src/ROUTES.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const ROUTES = {
5454
},
5555
SEARCH_ADVANCED_FILTERS: 'search/filters',
5656
SEARCH_ADVANCED_FILTERS_TYPE: 'search/filters/type',
57+
SEARCH_ADVANCED_FILTERS_GROUP_BY: 'search/filters/groupBy',
5758
SEARCH_ADVANCED_FILTERS_STATUS: 'search/filters/status',
5859
SEARCH_ADVANCED_FILTERS_DATE: 'search/filters/date',
5960
SEARCH_ADVANCED_FILTERS_CURRENCY: 'search/filters/currency',

src/SCREENS.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const SCREENS = {
4343
REPORT_RHP: 'Search_Report_RHP',
4444
ADVANCED_FILTERS_RHP: 'Search_Advanced_Filters_RHP',
4545
ADVANCED_FILTERS_TYPE_RHP: 'Search_Advanced_Filters_Type_RHP',
46+
ADVANCED_FILTERS_GROUP_BY_RHP: 'Search_Advanced_Filters_GroupBy_RHP',
4647
ADVANCED_FILTERS_STATUS_RHP: 'Search_Advanced_Filters_Status_RHP',
4748
ADVANCED_FILTERS_DATE_RHP: 'Search_Advanced_Filters_Date_RHP',
4849
ADVANCED_FILTERS_SUBMITTED_RHP: 'Search_Advanced_Filters_Submitted_RHP',

src/components/Icon/Expensicons.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ import Meter from '@assets/images/meter.svg';
151151
import Minus from '@assets/images/minus.svg';
152152
import MoneyBag from '@assets/images/money-bag.svg';
153153
import MoneyCircle from '@assets/images/money-circle.svg';
154+
import MoneyHourglass from '@assets/images/money-hourglass.svg';
154155
import MoneySearch from '@assets/images/money-search.svg';
155156
import MoneyWaving from '@assets/images/money-waving.svg';
156157
import Monitor from '@assets/images/monitor.svg';
@@ -361,6 +362,7 @@ export {
361362
MoneyCircle,
362363
MoneySearch,
363364
MoneyWaving,
365+
MoneyHourglass,
364366
Monitor,
365367
Mute,
366368
ExpensifyLogoNew,

src/components/Search/FilterDropdowns/SingleSelectPopup.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ function SingleSelectPopup<T extends string>({label, value, items, closeOverlay,
6161
}, [closeOverlay, onChange, selectedItem]);
6262

6363
const resetChanges = useCallback(() => {
64-
onChange(items.at(0) ?? null);
64+
onChange(null);
6565
closeOverlay();
66-
}, [closeOverlay, items, onChange]);
66+
}, [closeOverlay, onChange]);
6767

6868
return (
6969
<View style={[!isSmallScreenWidth && styles.pv4, styles.gap2]}>

src/components/Search/SearchContext.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, {useCallback, useContext, useMemo, useRef, useState} from 'react';
22
import {isMoneyRequestReport} from '@libs/ReportUtils';
3-
import {isReportListItemType, isTransactionListItemType} from '@libs/SearchUIUtils';
3+
import {isTransactionListItemType, isTransactionMemberGroupListItemType, isTransactionReportGroupListItemType} from '@libs/SearchUIUtils';
44
import CONST from '@src/CONST';
55
import type ChildrenProps from '@src/types/utils/ChildrenProps';
66
import type {SearchContext, SearchContextData} from './types';
@@ -63,12 +63,19 @@ function SearchContextProvider({children}: ChildrenProps) {
6363
// When selecting transactions, we also need to manage the reports to which these transactions belong. This is done to ensure proper exporting to CSV.
6464
let selectedReports: SearchContext['selectedReports'] = [];
6565

66-
if (data.length && data.every(isReportListItemType)) {
66+
if (data.length && data.every(isTransactionReportGroupListItemType)) {
6767
selectedReports = data
6868
.filter((item) => isMoneyRequestReport(item) && item.transactions.every(({keyForList}) => selectedTransactions[keyForList]?.isSelected))
6969
.map(({reportID, action = CONST.SEARCH.ACTION_TYPES.VIEW, total = CONST.DEFAULT_NUMBER_ID, policyID}) => ({reportID, action, total, policyID}));
7070
}
7171

72+
if (data.length && data.every(isTransactionMemberGroupListItemType)) {
73+
selectedReports = data
74+
.flatMap((item) => item.transactions)
75+
.filter(({keyForList}) => !!keyForList && selectedTransactions[keyForList]?.isSelected)
76+
.map(({reportID, action = CONST.SEARCH.ACTION_TYPES.VIEW, amount: total = CONST.DEFAULT_NUMBER_ID, policyID}) => ({reportID, action, total, policyID}));
77+
}
78+
7279
if (data.length && data.every(isTransactionListItemType)) {
7380
selectedReports = data
7481
.filter(({keyForList}) => !!keyForList && selectedTransactions[keyForList]?.isSelected)

src/components/Search/SearchDateFilterBase/CalendarView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type CalendarViewProps = {
1717
};
1818

1919
function SearchDateFilterBaseCalendarView({view, value, navigateBack, setValue}: CalendarViewProps) {
20-
const initialValue = value === CONST.SEARCH.NEVER ? null : value;
20+
const initialValue = value === CONST.SEARCH.DATE_PRESETS.NEVER ? null : value;
2121

2222
const styles = useThemeStyles();
2323
const {translate} = useLocalize();

src/components/Search/SearchDateFilterBase/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function SearchDateFilterBase({dateKey, titleKey}: SearchDateFilterBaseProps) {
3434
const setDateValue = (key: SearchDateModifier, dateValue: string | null) => {
3535
setLocalDateValues((currentValue) => {
3636
// If we are setting the 'on' to 'never', reset the other dates
37-
if (key === CONST.SEARCH.DATE_MODIFIERS.ON && dateValue === CONST.SEARCH.NEVER) {
37+
if (key === CONST.SEARCH.DATE_MODIFIERS.ON && dateValue === CONST.SEARCH.DATE_PRESETS.NEVER) {
3838
return {
3939
[CONST.SEARCH.DATE_MODIFIERS.ON]: dateValue,
4040
[CONST.SEARCH.DATE_MODIFIERS.AFTER]: null,
@@ -43,7 +43,7 @@ function SearchDateFilterBase({dateKey, titleKey}: SearchDateFilterBaseProps) {
4343
}
4444

4545
// If we are setting any other value while 'on' is set to 'never', reset 'on' to null
46-
if (key !== CONST.SEARCH.DATE_MODIFIERS.ON && currentValue?.[CONST.SEARCH.DATE_MODIFIERS.ON] === CONST.SEARCH.NEVER) {
46+
if (key !== CONST.SEARCH.DATE_MODIFIERS.ON && currentValue?.[CONST.SEARCH.DATE_MODIFIERS.ON] === CONST.SEARCH.DATE_PRESETS.NEVER) {
4747
return {
4848
...currentValue,
4949
[key]: dateValue,

0 commit comments

Comments
 (0)