Skip to content

Commit

Permalink
Merge pull request #47098 from Expensify/cmartins-useExpenseType
Browse files Browse the repository at this point in the history
  • Loading branch information
dangrous authored Aug 12, 2024
2 parents 0c20baf + a7efdcc commit 7481b6e
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 77 deletions.
11 changes: 7 additions & 4 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5242,6 +5242,7 @@ const CONST = {
DATA_TYPES: {
TRANSACTION: 'transaction',
REPORT: 'report',
EXPENSE: 'expense',
},
ACTION_TYPES: {
VIEW: 'view',
Expand All @@ -5265,10 +5266,12 @@ const CONST = {
DESC: 'desc',
},
STATUS: {
ALL: 'all',
SHARED: 'shared',
DRAFTS: 'drafts',
FINISHED: 'finished',
EXPENSE: {
ALL: 'all',
SHARED: 'shared',
DRAFTS: 'drafts',
FINISHED: 'finished',
},
},
TYPE: {
EXPENSE: 'expense',
Expand Down
8 changes: 4 additions & 4 deletions src/components/Search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const transactionItemMobileHeight = 100;
const reportItemTransactionHeight = 52;
const listItemPadding = 12; // this is equivalent to 'mb3' on every transaction/report list item
const searchHeaderHeight = 54;
const sortableSearchStatuses: SearchStatus[] = [CONST.SEARCH.STATUS.ALL];
const sortableSearchStatuses: SearchStatus[] = [CONST.SEARCH.STATUS.EXPENSE.ALL];

function mapTransactionItemToSelectedEntry(item: TransactionListItemType): [string, SelectedTransactionInfo] {
return [item.keyForList, {isSelected: true, canDelete: item.canDelete, canHold: item.canHold, canUnhold: item.canUnhold, action: item.action}];
Expand Down Expand Up @@ -210,9 +210,9 @@ function Search({queryJSON, policyIDs, isCustomQuery}: SearchProps) {
return null;
}

const ListItem = SearchUtils.getListItem(type);
const data = SearchUtils.getSections(searchResults.data, searchResults.search, type);
const sortedData = SearchUtils.getSortedSections(type, data, sortBy, sortOrder);
const ListItem = SearchUtils.getListItem(type, status);
const data = SearchUtils.getSections(type, status, searchResults.data, searchResults.search);
const sortedData = SearchUtils.getSortedSections(type, status, data, sortBy, sortOrder);
const sortedSelectedData = sortedData.map((item) => mapToItemWithSelectionInfo(item, selectedTransactions, canSelectMultiple));

const shouldShowEmptyState = !isDataLoaded || data.length === 0;
Expand Down
3 changes: 2 additions & 1 deletion src/components/Search/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ type SelectedTransactions = Record<string, SelectedTransactionInfo>;

type SortOrder = ValueOf<typeof CONST.SEARCH.SORT_ORDER>;
type SearchColumnType = ValueOf<typeof CONST.SEARCH.TABLE_COLUMNS>;
type SearchStatus = ValueOf<typeof CONST.SEARCH.STATUS>;
type ExpenseSearchStatus = ValueOf<typeof CONST.SEARCH.STATUS.EXPENSE>;
type SearchStatus = ExpenseSearchStatus;

type SearchContext = {
currentSearchHash: number;
Expand Down
62 changes: 31 additions & 31 deletions src/libs/SearchUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {ValueOf} from 'type-fest';
import type {ASTNode, QueryFilter, QueryFilters, SearchColumnType, SearchQueryJSON, SearchQueryString, SortOrder} from '@components/Search/types';
import type {ASTNode, QueryFilter, QueryFilters, SearchColumnType, SearchQueryJSON, SearchQueryString, SearchStatus, SortOrder} from '@components/Search/types';
import ReportListItem from '@components/SelectionList/Search/ReportListItem';
import TransactionListItem from '@components/SelectionList/Search/TransactionListItem';
import type {ListItem, ReportListItemType, TransactionListItemType} from '@components/SelectionList/types';
Expand All @@ -10,7 +10,7 @@ import type {SearchAdvancedFiltersForm} from '@src/types/form';
import INPUT_IDS from '@src/types/form/SearchAdvancedFiltersForm';
import type * as OnyxTypes from '@src/types/onyx';
import type SearchResults from '@src/types/onyx/SearchResults';
import type {SearchAccountDetails, SearchDataTypes, SearchPersonalDetails, SearchTransaction, SearchTypeToItemMap, SectionsType} from '@src/types/onyx/SearchResults';
import type {ListItemDataType, ListItemType, SearchAccountDetails, SearchDataTypes, SearchPersonalDetails, SearchTransaction} from '@src/types/onyx/SearchResults';
import DateUtils from './DateUtils';
import navigationRef from './Navigation/navigationRef';
import type {AuthScreensParamList, BottomTabNavigatorParamList, RootStackParamList, State} from './Navigation/types';
Expand Down Expand Up @@ -233,39 +233,39 @@ function getReportSections(data: OnyxTypes.SearchResults['data'], metadata: Onyx
return Object.values(reportIDToTransactions);
}

const searchTypeToItemMap: SearchTypeToItemMap = {
[CONST.SEARCH.DATA_TYPES.TRANSACTION]: {
listItem: TransactionListItem,
getSections: getTransactionsSections,
getSortedSections: getSortedTransactionData,
},
[CONST.SEARCH.DATA_TYPES.REPORT]: {
listItem: ReportListItem,
getSections: getReportSections,
// sorting for ReportItems not yet implemented
getSortedSections: getSortedReportData,
},
};

function getListItem<K extends keyof SearchTypeToItemMap>(type: K): SearchTypeToItemMap[K]['listItem'] {
return searchTypeToItemMap[type].listItem;
function getListItem(type: SearchDataTypes, status: SearchStatus): ListItemType<typeof status> {
switch (type) {
case CONST.SEARCH.DATA_TYPES.TRANSACTION:
case CONST.SEARCH.DATA_TYPES.EXPENSE:
case CONST.SEARCH.DATA_TYPES.REPORT:
return status === CONST.SEARCH.STATUS.EXPENSE.ALL ? TransactionListItem : ReportListItem;
default:
return TransactionListItem;
}
}

function getSections<K extends keyof SearchTypeToItemMap>(
data: OnyxTypes.SearchResults['data'],
metadata: OnyxTypes.SearchResults['search'],
type: K,
): ReturnType<SearchTypeToItemMap[K]['getSections']> {
return searchTypeToItemMap[type].getSections(data, metadata) as ReturnType<SearchTypeToItemMap[K]['getSections']>;
function getSections(type: SearchDataTypes, status: SearchStatus, data: OnyxTypes.SearchResults['data'], metadata: OnyxTypes.SearchResults['search']) {
switch (type) {
case CONST.SEARCH.DATA_TYPES.TRANSACTION:
case CONST.SEARCH.DATA_TYPES.EXPENSE:
case CONST.SEARCH.DATA_TYPES.REPORT:
return status === CONST.SEARCH.STATUS.EXPENSE.ALL ? getTransactionsSections(data, metadata) : getReportSections(data, metadata);
default:
return getTransactionsSections(data, metadata);
}
}

function getSortedSections<K extends keyof SearchTypeToItemMap>(
type: K,
data: SectionsType<K>,
sortBy?: SearchColumnType,
sortOrder?: SortOrder,
): ReturnType<SearchTypeToItemMap[K]['getSortedSections']> {
return searchTypeToItemMap[type].getSortedSections(data, sortBy, sortOrder) as ReturnType<SearchTypeToItemMap[K]['getSortedSections']>;
function getSortedSections(type: SearchDataTypes, status: SearchStatus, data: ListItemDataType<typeof status>, sortBy?: SearchColumnType, sortOrder?: SortOrder) {
switch (type) {
case CONST.SEARCH.DATA_TYPES.TRANSACTION:
case CONST.SEARCH.DATA_TYPES.EXPENSE:
case CONST.SEARCH.DATA_TYPES.REPORT:
return status === CONST.SEARCH.STATUS.EXPENSE.ALL
? getSortedTransactionData(data as TransactionListItemType[], sortBy, sortOrder)
: getSortedReportData(data as ReportListItemType[]);
default:
return getSortedTransactionData(data as TransactionListItemType[], sortBy, sortOrder);
}
}

function getQueryHash(query: string, policyID?: string, sortBy?: string, sortOrder?: string): number {
Expand Down
24 changes: 12 additions & 12 deletions src/pages/Search/SearchFiltersStatusPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,27 @@ function SearchFiltersStatusPage() {
() => [
{
text: translate('common.all'),
value: CONST.SEARCH.STATUS.ALL,
keyForList: CONST.SEARCH.STATUS.ALL,
isSelected: activeItem === CONST.SEARCH.STATUS.ALL,
value: CONST.SEARCH.STATUS.EXPENSE.ALL,
keyForList: CONST.SEARCH.STATUS.EXPENSE.ALL,
isSelected: activeItem === CONST.SEARCH.STATUS.EXPENSE.ALL,
},
{
text: translate('common.shared'),
value: CONST.SEARCH.STATUS.SHARED,
keyForList: CONST.SEARCH.STATUS.SHARED,
isSelected: activeItem === CONST.SEARCH.STATUS.SHARED,
value: CONST.SEARCH.STATUS.EXPENSE.SHARED,
keyForList: CONST.SEARCH.STATUS.EXPENSE.SHARED,
isSelected: activeItem === CONST.SEARCH.STATUS.EXPENSE.SHARED,
},
{
text: translate('common.drafts'),
value: CONST.SEARCH.STATUS.DRAFTS,
keyForList: CONST.SEARCH.STATUS.DRAFTS,
isSelected: activeItem === CONST.SEARCH.STATUS.DRAFTS,
value: CONST.SEARCH.STATUS.EXPENSE.DRAFTS,
keyForList: CONST.SEARCH.STATUS.EXPENSE.DRAFTS,
isSelected: activeItem === CONST.SEARCH.STATUS.EXPENSE.DRAFTS,
},
{
text: translate('common.finished'),
value: CONST.SEARCH.STATUS.FINISHED,
keyForList: CONST.SEARCH.STATUS.FINISHED,
isSelected: activeItem === CONST.SEARCH.STATUS.FINISHED,
value: CONST.SEARCH.STATUS.EXPENSE.FINISHED,
keyForList: CONST.SEARCH.STATUS.EXPENSE.FINISHED,
isSelected: activeItem === CONST.SEARCH.STATUS.EXPENSE.FINISHED,
},
],
[translate, activeItem],
Expand Down
8 changes: 4 additions & 4 deletions src/pages/Search/SearchStatusMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,25 @@ function SearchStatusMenu({queryJSON, isCustomQuery}: SearchStatusMenuProps) {
const statusMenuItems: SearchStatusMenuItem[] = [
{
title: translate('common.expenses'),
status: CONST.SEARCH.STATUS.ALL,
status: CONST.SEARCH.STATUS.EXPENSE.ALL,
icon: Expensicons.Receipt,
route: ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: normalizeQuery(CONST.SEARCH.TAB.EXPENSE.ALL)}),
},
{
title: translate('common.shared'),
status: CONST.SEARCH.STATUS.SHARED,
status: CONST.SEARCH.STATUS.EXPENSE.SHARED,
icon: Expensicons.Send,
route: ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: normalizeQuery(CONST.SEARCH.TAB.EXPENSE.SHARED)}),
},
{
title: translate('common.drafts'),
status: CONST.SEARCH.STATUS.DRAFTS,
status: CONST.SEARCH.STATUS.EXPENSE.DRAFTS,
icon: Expensicons.Pencil,
route: ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: normalizeQuery(CONST.SEARCH.TAB.EXPENSE.DRAFTS)}),
},
{
title: translate('common.finished'),
status: CONST.SEARCH.STATUS.FINISHED,
status: CONST.SEARCH.STATUS.EXPENSE.FINISHED,
icon: Expensicons.CheckCircle,
route: ROUTES.SEARCH_CENTRAL_PANE.getRoute({query: normalizeQuery(CONST.SEARCH.TAB.EXPENSE.FINISHED)}),
},
Expand Down
28 changes: 7 additions & 21 deletions src/types/onyx/SearchResults.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {ValueOf} from 'type-fest';
import type {SearchColumnType, SortOrder} from '@components/Search/types';
import type {SearchStatus} from '@components/Search/types';
import type ReportListItem from '@components/SelectionList/Search/ReportListItem';
import type TransactionListItem from '@components/SelectionList/Search/TransactionListItem';
import type {ReportListItemType, TransactionListItemType} from '@components/SelectionList/types';
Expand All @@ -9,11 +9,10 @@ import type CONST from '@src/CONST';
type SearchDataTypes = ValueOf<typeof CONST.SEARCH.DATA_TYPES>;

/** Model of search result list item */
type ListItemType<T extends SearchDataTypes> = T extends typeof CONST.SEARCH.DATA_TYPES.TRANSACTION
? typeof TransactionListItem
: T extends typeof CONST.SEARCH.DATA_TYPES.REPORT
? typeof ReportListItem
: never;
type ListItemType<T extends SearchStatus> = T extends typeof CONST.SEARCH.STATUS.EXPENSE.ALL ? typeof TransactionListItem : typeof ReportListItem;

/** Model of search list item data type */
type ListItemDataType<T extends SearchStatus> = T extends typeof CONST.SEARCH.STATUS.EXPENSE.ALL ? TransactionListItemType[] : ReportListItemType[];

/** Model of search result section */
type SectionsType<T extends SearchDataTypes> = T extends typeof CONST.SEARCH.DATA_TYPES.TRANSACTION
Expand All @@ -22,20 +21,6 @@ type SectionsType<T extends SearchDataTypes> = T extends typeof CONST.SEARCH.DAT
? ReportListItemType[]
: never;

/** Mapping of search results to list item */
type SearchTypeToItemMap = {
[K in SearchDataTypes]: {
/** Collection of search result list item */
listItem: ListItemType<K>;

/** Returns search results sections based on search results data */
getSections: (data: SearchResults['data'], metadata: SearchResults['search']) => SectionsType<K>;

/** Returns sorted search results sections based on search results data */
getSortedSections: (data: SectionsType<K>, sortBy?: SearchColumnType, sortOrder?: SortOrder) => SectionsType<K>;
};
};

/** Model of columns to show for search results */
type ColumnsToShow = {
/** Whether the category column should be shown */
Expand Down Expand Up @@ -258,14 +243,15 @@ type SearchResults = {
export default SearchResults;

export type {
ListItemType,
ListItemDataType,
SearchTransaction,
SearchTransactionType,
SearchTransactionAction,
SearchPersonalDetails,
SearchPolicyDetails,
SearchAccountDetails,
SearchDataTypes,
SearchTypeToItemMap,
SearchReport,
SectionsType,
};

0 comments on commit 7481b6e

Please sign in to comment.