diff --git a/assets/images/columns.svg b/assets/images/columns.svg
new file mode 100644
index 000000000000..6921bb4895dd
--- /dev/null
+++ b/assets/images/columns.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index 5fa77b994f63..7f2b5f5767a3 100755
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -6699,6 +6699,21 @@ const CONST = {
CARD: 'card',
WITHDRAWAL_ID: 'withdrawal-id',
},
+ get CUSTOM_COLUMNS() {
+ return {
+ DATE: this.TABLE_COLUMNS.DATE,
+ STATUS: this.TABLE_COLUMNS.STATUS,
+ TITLE: this.TABLE_COLUMNS.TITLE,
+ FROM: this.TABLE_COLUMNS.FROM,
+ TO: this.TABLE_COLUMNS.TO,
+ ACTION: this.TABLE_COLUMNS.ACTION,
+ };
+ },
+ get DEFAULT_COLUMNS() {
+ return {
+ EXPENSE_REPORT: [this.TABLE_COLUMNS.DATE, this.TABLE_COLUMNS.STATUS, this.TABLE_COLUMNS.TITLE, this.TABLE_COLUMNS.FROM, this.TABLE_COLUMNS.TO, this.TABLE_COLUMNS.ACTION],
+ };
+ },
BOOLEAN: {
YES: 'yes',
NO: 'no',
@@ -6781,6 +6796,7 @@ const CONST = {
SORT_BY: 'sortBy',
SORT_ORDER: 'sortOrder',
GROUP_BY: 'groupBy',
+ COLUMNS: 'columns',
},
SYNTAX_FILTER_KEYS: {
TYPE: 'type',
@@ -6889,6 +6905,7 @@ const CONST = {
ATTENDEE: 'attendee',
IS: 'is',
REPORT_FIELD: 'report-field',
+ COLUMNS: 'columns',
},
get SEARCH_USER_FRIENDLY_VALUES_MAP() {
return {
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 3b7d7253be31..9cbc13be2f56 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -66,6 +66,7 @@ const ROUTES = {
route: 'search/saved-search/rename',
getRoute: ({name, jsonQuery}: {name: string; jsonQuery: SearchQueryString}) => `search/saved-search/rename?name=${name}&q=${jsonQuery}` as const,
},
+ SEARCH_COLUMNS: 'search/columns',
SEARCH_ADVANCED_FILTERS: {
route: 'search/filters/:filterKey?',
getRoute: (filterKey?: SearchFilterKey | UserFriendlyKey) => {
diff --git a/src/SCREENS.ts b/src/SCREENS.ts
index 8ac4f48c7614..da77476dd62b 100644
--- a/src/SCREENS.ts
+++ b/src/SCREENS.ts
@@ -48,6 +48,7 @@ const SCREENS = {
MONEY_REQUEST_REPORT_HOLD_TRANSACTIONS: 'Search_Money_Request_Report_Hold_Transactions',
MONEY_REQUEST_REPORT_REJECT_TRANSACTIONS: 'Search_Money_Request_Report_Reject_Transactions',
REPORT_RHP: 'Search_Report_RHP',
+ COLUMNS_RHP: 'Search_Columns_RHP',
REPORT_VERIFY_ACCOUNT: 'Search_Report_Verify_Account',
ADVANCED_FILTERS_RHP: 'Search_Advanced_Filters_RHP',
ADVANCED_FILTERS_TYPE_RHP: 'Search_Advanced_Filters_Type_RHP',
@@ -253,6 +254,7 @@ const SCREENS = {
EXPENSE_REPORT: 'ExpenseReport',
SEARCH_MONEY_REQUEST_REPORT: 'SearchMoneyRequestReport',
+ SEARCH_COLUMNS: 'SearchColumns',
SEARCH_ADVANCED_FILTERS: 'SearchAdvancedFilters',
SEARCH_SAVED_SEARCH: 'SearchSavedSearch',
SETTINGS_CATEGORIES: 'SettingsCategories',
diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts
index b66b17b32bdc..aec8abbfecec 100644
--- a/src/components/Icon/Expensicons.ts
+++ b/src/components/Icon/Expensicons.ts
@@ -47,6 +47,7 @@ import Close from '@assets/images/close.svg';
import ClosedSign from '@assets/images/closed-sign.svg';
import Coins from '@assets/images/coins.svg';
import Collapse from '@assets/images/collapse.svg';
+import Columns from '@assets/images/columns.svg';
import CommentBubbles from '@assets/images/comment-bubbles.svg';
import Concierge from '@assets/images/concierge.svg';
import Connect from '@assets/images/connect.svg';
@@ -216,6 +217,7 @@ export {
ConciergeAvatar,
Connect,
ConnectionComplete,
+ Columns,
Copy,
CreditCard,
CreditCardHourglass,
diff --git a/src/components/Icon/chunks/expensify-icons.chunk.ts b/src/components/Icon/chunks/expensify-icons.chunk.ts
index 68d8253c0977..10a0c7fada65 100644
--- a/src/components/Icon/chunks/expensify-icons.chunk.ts
+++ b/src/components/Icon/chunks/expensify-icons.chunk.ts
@@ -54,6 +54,7 @@ import Close from '@assets/images/close.svg';
import ClosedSign from '@assets/images/closed-sign.svg';
import Coins from '@assets/images/coins.svg';
import Collapse from '@assets/images/collapse.svg';
+import Columns from '@assets/images/columns.svg';
import CommentBubbles from '@assets/images/comment-bubbles.svg';
import Concierge from '@assets/images/concierge.svg';
import Connect from '@assets/images/connect.svg';
@@ -266,6 +267,7 @@ const Expensicons = {
Clock,
ClosedSign,
Collapse,
+ Columns,
CommentBubbles,
Concierge,
ConciergeAvatar,
diff --git a/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx b/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx
index 286103142f7e..01d3dc21d238 100644
--- a/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx
+++ b/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx
@@ -65,6 +65,7 @@ import NAVIGATORS from '@src/NAVIGATORS';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
+import {columnsSelector} from '@src/selectors/AdvancedSearchFiltersForm';
import type * as OnyxTypes from '@src/types/onyx';
import type {PendingAction} from '@src/types/onyx/OnyxCommon';
import MoneyRequestReportGroupHeader from './MoneyRequestReportGroupHeader';
@@ -183,6 +184,8 @@ function MoneyRequestReportTransactionList({
const shouldShowAddExpenseButton = canAddTransaction(report, isReportArchived) && isCurrentUserSubmitter(report);
const [lastDistanceExpenseType] = useOnyx(ONYXKEYS.NVP_LAST_DISTANCE_EXPENSE_TYPE, {canBeMissing: true});
const [reportLayoutGroupBy] = useOnyx(ONYXKEYS.NVP_REPORT_LAYOUT_GROUP_BY, {canBeMissing: true});
+ const [visibleColumns] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM, {canBeMissing: true, selector: columnsSelector});
+
const shouldShowGroupedTransactions = isExpenseReport(report) && !isIOUReport(report);
const addExpenseDropdownOptions = useMemo(
@@ -265,9 +268,9 @@ function MoneyRequestReportTransactionList({
}, [newTransactions, sortBy, sortOrder, transactions, localeCompare, report]);
const columnsToShow = useMemo(() => {
- const columns = getColumnsToShow(currentUserDetails?.accountID, transactions, true);
+ const columns = getColumnsToShow(currentUserDetails?.accountID, transactions, visibleColumns, true);
return (Object.keys(columns) as SearchColumnType[]).filter((column) => columns[column]);
- }, [transactions, currentUserDetails?.accountID]);
+ }, [transactions, currentUserDetails?.accountID, visibleColumns]);
const currentGroupBy = getReportLayoutGroupBy(reportLayoutGroupBy);
diff --git a/src/components/Search/SearchPageHeader/SearchFiltersBar.tsx b/src/components/Search/SearchPageHeader/SearchFiltersBar.tsx
index 2b820f11c3ce..04d602e9e8d6 100644
--- a/src/components/Search/SearchPageHeader/SearchFiltersBar.tsx
+++ b/src/components/Search/SearchPageHeader/SearchFiltersBar.tsx
@@ -99,7 +99,7 @@ function SearchFiltersBar({
const {isOffline} = useNetwork();
const personalDetails = usePersonalDetails();
- const {shouldUseNarrowLayout} = useResponsiveLayout();
+ const {shouldUseNarrowLayout, isLargeScreenWidth} = useResponsiveLayout();
const {selectedTransactions, selectAllMatchingItems, areAllMatchingItemsSelected, showSelectAllMatchingItems, shouldShowFiltersBarLoading} = useSearchContext();
const [email] = useOnyx(ONYXKEYS.SESSION, {canBeMissing: true, selector: emailSelector});
@@ -113,7 +113,7 @@ function SearchFiltersBar({
const [allFeeds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER, {canBeMissing: true});
const {isAccountLocked, showLockedAccountModal} = useContext(LockedAccountContext);
const [searchResultsErrors] = useOnyx(`${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`, {canBeMissing: true, selector: searchResultsErrorSelector});
- const expensifyIcons = useMemoizedLazyExpensifyIcons(['Filter'] as const);
+ const expensifyIcons = useMemoizedLazyExpensifyIcons(['Filter', 'Columns'] as const);
const taxRates = getAllTaxRates(allPolicies);
@@ -324,6 +324,10 @@ function SearchFiltersBar({
Navigation.navigate(ROUTES.SEARCH_ADVANCED_FILTERS.getRoute());
}, [filterFormValues]);
+ const openSearchColumns = () => {
+ Navigation.navigate(ROUTES.SEARCH_COLUMNS);
+ };
+
const isFormInitializedRef = useRef(false);
useEffect(() => {
@@ -777,6 +781,8 @@ function SearchFiltersBar({
[],
);
+ const shouldShowColumnsButton = isLargeScreenWidth && queryJSON.type === CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT;
+
const filterButtonText = useMemo(
() => translate('search.filtersHeader') + (hiddenSelectedFilters.length > 0 ? ` (${hiddenSelectedFilters.length})` : ''),
[translate, hiddenSelectedFilters.length],
@@ -784,19 +790,46 @@ function SearchFiltersBar({
const renderListFooter = useCallback(
() => (
-
+
+
+ {shouldShowColumnsButton && (
+
+ )}
+
),
- [filterButtonText, theme.link, theme.linkHover, styles.textMicroBold, openAdvancedFilters, expensifyIcons],
+ [
+ styles.flexRow,
+ styles.gap2,
+ styles.textMicroBold,
+ filterButtonText,
+ theme.link,
+ theme.linkHover,
+ expensifyIcons.Filter,
+ expensifyIcons.Columns,
+ openAdvancedFilters,
+ shouldShowColumnsButton,
+ translate,
+ ],
);
if (hasErrors) {
diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx
index 5c8482a536fb..7fd61665744f 100644
--- a/src/components/Search/index.tsx
+++ b/src/components/Search/index.tsx
@@ -66,6 +66,7 @@ import NAVIGATORS from '@src/NAVIGATORS';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import SCREENS from '@src/SCREENS';
+import {columnsSelector} from '@src/selectors/AdvancedSearchFiltersForm';
import {isActionLoadingSetSelector} from '@src/selectors/ReportMetaData';
import type {OutstandingReportsByPolicyIDDerivedValue, Transaction} from '@src/types/onyx';
import type SearchResults from '@src/types/onyx/SearchResults';
@@ -283,6 +284,8 @@ function Search({
const [violations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true});
const {accountID, email} = useCurrentUserPersonalDetails();
const [isActionLoadingSet = new Set()] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_METADATA}`, {canBeMissing: true, selector: isActionLoadingSetSelector});
+ const [visibleColumns] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM, {canBeMissing: true, selector: columnsSelector});
+
const isExpenseReportType = type === CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT;
// Filter violations based on user visibility
@@ -824,10 +827,10 @@ function Search({
if (!searchResults?.data) {
return [];
}
- const columns = getColumnsToShow(accountID, searchResults?.data, false, searchResults?.search?.type);
+ const columns = getColumnsToShow(accountID, searchResults?.data, visibleColumns, false, searchResults?.search?.type);
return (Object.keys(columns) as SearchColumnType[]).filter((col) => columns[col]);
- }, [accountID, searchResults?.data, searchResults?.search?.type]);
+ }, [accountID, searchResults?.data, searchResults?.search?.type, visibleColumns]);
const opacity = useSharedValue(1);
const animatedStyle = useAnimatedStyle(() => ({
diff --git a/src/components/Search/types.ts b/src/components/Search/types.ts
index 8f5beab5e9c6..ca6a7b532ddf 100644
--- a/src/components/Search/types.ts
+++ b/src/components/Search/types.ts
@@ -107,6 +107,7 @@ type TableColumnSize = ValueOf;
type SearchDatePreset = ValueOf;
type SearchWithdrawalType = ValueOf;
type SearchAction = ValueOf;
+type SearchCustomColumnIds = ValueOf;
type SearchContextData = {
currentSearchHash: number;
@@ -196,7 +197,8 @@ type SearchFilterKey =
| ValueOf
| typeof CONST.SEARCH.SYNTAX_ROOT_KEYS.TYPE
| typeof CONST.SEARCH.SYNTAX_ROOT_KEYS.STATUS
- | typeof CONST.SEARCH.SYNTAX_ROOT_KEYS.GROUP_BY;
+ | typeof CONST.SEARCH.SYNTAX_ROOT_KEYS.GROUP_BY
+ | typeof CONST.SEARCH.SYNTAX_ROOT_KEYS.COLUMNS;
type UserFriendlyKey = ValueOf;
type UserFriendlyValue = ValueOf;
@@ -222,6 +224,7 @@ type SearchQueryAST = {
status: SearchStatus;
sortBy: SearchColumnType;
sortOrder: SortOrder;
+ columns?: SearchCustomColumnIds[];
groupBy?: SearchGroupBy;
filters: ASTNode;
policyID?: string[];
@@ -310,4 +313,5 @@ export type {
SelectedReports,
SearchTextFilterKeys,
BankAccountMenuItem,
+ SearchCustomColumnIds,
};
diff --git a/src/components/SelectionListWithSections/Search/ExpenseReportListItem.tsx b/src/components/SelectionListWithSections/Search/ExpenseReportListItem.tsx
index ecfb4169c1a6..c599ac5c400b 100644
--- a/src/components/SelectionListWithSections/Search/ExpenseReportListItem.tsx
+++ b/src/components/SelectionListWithSections/Search/ExpenseReportListItem.tsx
@@ -25,6 +25,7 @@ function ExpenseReportListItem({
isLoading,
isFocused,
showTooltip,
+ columns,
canSelectMultiple,
onSelectRow,
onFocus,
@@ -159,6 +160,7 @@ function ExpenseReportListItem({
+
+
+ ),
+ [CONST.SEARCH.TABLE_COLUMNS.STATUS]: (
+
+
+
+ ),
+ [CONST.SEARCH.TABLE_COLUMNS.TITLE]: (
+
+
+
+ ),
+ [CONST.SEARCH.TABLE_COLUMNS.FROM]: (
+
+ {!!item.from && (
+
+ )}
+
+ ),
+ [CONST.SEARCH.TABLE_COLUMNS.TO]: (
+
+ {!!item.to && (
+
+ )}
+
+ ),
+ [CONST.SEARCH.TABLE_COLUMNS.TOTAL]: (
+
+
+
+ ),
+ [CONST.SEARCH.TABLE_COLUMNS.ACTION]: (
+
+
+
+ ),
+ };
+
const thereIsFromAndTo = !!item?.from && !!item?.to;
const showUserInfo = (item.type === CONST.REPORT.TYPE.IOU && thereIsFromAndTo) || (item.type === CONST.REPORT.TYPE.EXPENSE && !!item?.from);
@@ -151,61 +226,11 @@ function ExpenseReportListItemRow({
subscriptAvatarBorderColor={finalAvatarBorderColor}
/>
-
-
-
-
-
-
-
-
-
-
- {!!item.from && (
-
- )}
-
-
- {!!item.to && (
-
- )}
-
-
-
-
-
-
-
+
+ {columns.map((column) => {
+ const CellComponent = columnComponents[column as keyof typeof columnComponents];
+ return {CellComponent};
+ })}
({
transactionsQueryJSON,
@@ -52,6 +53,8 @@ function TransactionGroupListExpanded({
const currentUserDetails = useCurrentUserPersonalDetails();
const {translate} = useLocalize();
const [isMobileSelectionModeEnabled] = useOnyx(ONYXKEYS.MOBILE_SELECTION_MODE, {canBeMissing: true});
+ const [visibleColumns] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM, {canBeMissing: true, selector: columnsSelector});
+
const transactionsSnapshotMetadata = useMemo(() => {
return transactionsSnapshot?.search;
}, [transactionsSnapshot?.search]);
@@ -77,10 +80,10 @@ function TransactionGroupListExpanded({
if (!transactionsSnapshot?.data) {
return [];
}
- const columnsToShow = getColumnsToShow(accountID, transactionsSnapshot?.data, false, transactionsSnapshot?.search.type);
+ const columnsToShow = getColumnsToShow(accountID, transactionsSnapshot?.data, visibleColumns, false, transactionsSnapshot?.search.type);
return (Object.keys(columnsToShow) as SearchColumnType[]).filter((col) => columnsToShow[col]);
- }, [accountID, columns, isExpenseReportType, transactionsSnapshot?.data, transactionsSnapshot?.search.type]);
+ }, [accountID, columns, isExpenseReportType, transactionsSnapshot?.data, transactionsSnapshot?.search.type, visibleColumns]);
const areAllOptionalColumnsHidden = useMemo(() => {
if (isExpenseReportType) {
diff --git a/src/components/SelectionListWithSections/SearchTableHeader.tsx b/src/components/SelectionListWithSections/SearchTableHeader.tsx
index 8965f6b59c4c..498137946e8e 100644
--- a/src/components/SelectionListWithSections/SearchTableHeader.tsx
+++ b/src/components/SelectionListWithSections/SearchTableHeader.tsx
@@ -146,7 +146,7 @@ const getExpenseReportHeaders = (profileIcon?: IconAsset): SearchColumnConfig[]
},
{
columnName: CONST.SEARCH.TABLE_COLUMNS.TITLE,
- translationKey: 'common.reportName',
+ translationKey: 'common.title',
},
{
columnName: CONST.SEARCH.TABLE_COLUMNS.FROM,
diff --git a/src/components/SelectionListWithSections/types.ts b/src/components/SelectionListWithSections/types.ts
index d7d04dc9c4f5..7677b797bd0c 100644
--- a/src/components/SelectionListWithSections/types.ts
+++ b/src/components/SelectionListWithSections/types.ts
@@ -565,6 +565,9 @@ type TaskListItemProps = ListItemProps & {
};
type ExpenseReportListItemProps = ListItemProps & {
+ /** The visible columns for the report */
+ columns?: SearchColumnType[];
+
/** Whether the item's action is loading */
isLoading?: boolean;
diff --git a/src/languages/de.ts b/src/languages/de.ts
index 938a7e9b62da..30f483b71a78 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -6735,6 +6735,9 @@ Fordere Spesendetails wie Belege und Beschreibungen an, lege Limits und Standard
subtitle: 'Null Spesen. Maximale Entspannung. Gut gemacht!',
},
},
+ columns: 'Spalten',
+ resetColumns: 'Spalten zurücksetzen',
+ noColumnsError: 'Bitte wählen Sie vor dem Speichern mindestens eine Spalte aus',
statements: 'Abrechnungen',
unapprovedCash: 'Nicht genehmigtes Bargeld',
unapprovedCard: 'Nicht genehmigte Karte',
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 17356dc04704..8f20c1f98ff5 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -6590,6 +6590,9 @@ const translations = {
subtitle: 'Zero expenses. Maximum chill. Well done!',
},
},
+ columns: 'Columns',
+ resetColumns: 'Reset columns',
+ noColumnsError: 'Please select at least one column before saving',
statements: 'Statements',
unapprovedCash: 'Unapproved cash',
unapprovedCard: 'Unapproved card',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index b4b49904086c..174909a22936 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -6244,6 +6244,9 @@ ${amount} para ${merchant} - ${date}`,
subtitle: 'Cero gastos. Máxima relajación. ¡Bien hecho!',
},
},
+ columns: 'Columnas',
+ resetColumns: 'Restablecer columnas',
+ noColumnsError: 'Por favor selecciona al menos una columna antes de guardar',
statements: 'Extractos',
unapprovedCash: 'Efectivo no aprobado',
unapprovedCard: 'Tarjeta no aprobada',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index f178f271d442..ae7522060d88 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -6744,6 +6744,9 @@ Exigez des informations de dépense comme les reçus et les descriptions, défin
subtitle: 'Zéro note de frais. Détente maximale. Bien joué !',
},
},
+ columns: 'Colonnes',
+ resetColumns: 'Réinitialiser les colonnes',
+ noColumnsError: 'Veuillez sélectionner au moins une colonne avant d’enregistrer',
statements: 'Relevés',
unapprovedCash: 'Espèces non approuvées',
unapprovedCard: 'Carte non approuvée',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index cedee85ca06d..f60d9a6e83ff 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -6717,6 +6717,9 @@ Richiedi dettagli di spesa come ricevute e descrizioni, imposta limiti e valori
subtitle: 'Zero spese. Massimo relax. Ben fatto!',
},
},
+ columns: 'Colonne',
+ resetColumns: 'Reimposta colonne',
+ noColumnsError: 'Seleziona almeno una colonna prima di salvare',
statements: 'Estratti conto',
unapprovedCash: 'Contanti non approvati',
unapprovedCard: 'Carta non approvata',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 70bdceb098a3..6bcbcba270c1 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -6667,6 +6667,9 @@ ${reportName}
subtitle: '経費はゼロ。くつろぎはマックス。お見事です!',
},
},
+ columns: '列',
+ resetColumns: '列をリセット',
+ noColumnsError: '保存する前に、少なくとも 1 つの列を選択してください',
statements: 'ステートメント',
unapprovedCash: '未承認の現金',
unapprovedCard: '未承認のカード',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index ad1b67a346fd..396f75b963bd 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -6703,6 +6703,9 @@ Vraag verplichte uitgavedetails zoals bonnetjes en beschrijvingen, stel limieten
subtitle: 'Nul onkosten. Maximale ontspanning. Goed gedaan!',
},
},
+ columns: 'Kolommen',
+ resetColumns: 'Kolommen resetten',
+ noColumnsError: 'Selecteer minstens één kolom voordat je opslaat',
statements: 'Afschriften',
unapprovedCash: 'Niet-goedgekeurde contanten',
unapprovedCard: 'Niet-goedgekeurde kaart',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 9161ec5d8d91..9646789eeb38 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -6693,6 +6693,9 @@ Wymagaj szczegółów wydatków, takich jak paragony i opisy, ustawiaj limity i
subtitle: 'Zero wydatków. Maksymalny luz. Dobra robota!',
},
},
+ columns: 'Kolumny',
+ resetColumns: 'Resetuj kolumny',
+ noColumnsError: 'Proszę wybrać co najmniej jedną kolumnę przed zapisaniem',
statements: 'Wyciągi',
unapprovedCash: 'Niezaakceptowana gotówka',
unapprovedCard: 'Niezatwierdzona karta',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 83b1580c9e94..ea50d4c11e42 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -6698,6 +6698,9 @@ Exija detalhes de despesas como recibos e descrições, defina limites e padrõe
subtitle: 'Zero despesas. Máxima tranquilidade. Muito bem!',
},
},
+ columns: 'Colunas',
+ resetColumns: 'Redefinir colunas',
+ noColumnsError: 'Selecione pelo menos uma coluna antes de salvar',
statements: 'Extratos',
unapprovedCash: 'Dinheiro não aprovado',
unapprovedCard: 'Cartão não aprovado',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index eb36fda69e9b..28c1c108c05c 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -6567,6 +6567,9 @@ ${reportName}
subtitle: '报销为零,轻松满分。干得好!',
},
},
+ columns: '列',
+ resetColumns: '重置列',
+ noColumnsError: '请在保存前至少选择一列',
statements: '对账单',
unapprovedCash: '未批准的现金',
unapprovedCard: '未批准的卡片',
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
index 4d664d831c9c..c23c77a8fa73 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
@@ -44,6 +44,7 @@ import type {
RoomMembersNavigatorParamList,
ScheduleCallParamList,
SearchAdvancedFiltersParamList,
+ SearchColumnsParamList,
SearchReportActionsParamList,
SearchReportParamList,
SearchSavedSearchParamList,
@@ -976,6 +977,10 @@ const RestrictedActionModalStackNavigator = createModalStackNavigator require('../../../../pages/RestrictedAction/Workspace/WorkspaceRestrictedActionPage').default,
});
+const SearchColumnsModalStackNavigator = createModalStackNavigator({
+ [SCREENS.SEARCH.COLUMNS_RHP]: () => require('../../../../pages/Search/SearchColumnsPage').default,
+});
+
const ShareModalStackNavigator = createModalStackNavigator({
[SCREENS.SHARE.ROOT]: () => require('@pages/Share/ShareRootPage').default,
[SCREENS.SHARE.SHARE_DETAILS]: () => require('@pages/Share/ShareDetailsPage').default,
@@ -1066,4 +1071,5 @@ export {
MergeTransactionStackNavigator,
ReportCardActivateStackNavigator,
WorkspacesDomainModalStackNavigator,
+ SearchColumnsModalStackNavigator,
};
diff --git a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx
index 597293716f4b..8136743290da 100644
--- a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx
+++ b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx
@@ -337,6 +337,10 @@ function RightModalNavigator({navigation, route}: RightModalNavigatorProps) {
name={SCREENS.RIGHT_MODAL.DOMAIN}
component={ModalStackNavigators.WorkspacesDomainModalStackNavigator}
/>
+
{/* The third and second overlays are displayed here to cover RHP screens wider than the currently focused screen. */}
diff --git a/src/libs/Navigation/linkingConfig/RELATIONS/SEARCH_TO_RHP.ts b/src/libs/Navigation/linkingConfig/RELATIONS/SEARCH_TO_RHP.ts
index 05caeb60b3de..7c034c8b4b1e 100644
--- a/src/libs/Navigation/linkingConfig/RELATIONS/SEARCH_TO_RHP.ts
+++ b/src/libs/Navigation/linkingConfig/RELATIONS/SEARCH_TO_RHP.ts
@@ -13,6 +13,7 @@ const SEARCH_TO_RHP: Partial['config'] = {
[SCREENS.TRAVEL.VERIFY_ACCOUNT]: ROUTES.TRAVEL_VERIFY_ACCOUNT.route,
},
},
+ [SCREENS.RIGHT_MODAL.SEARCH_COLUMNS]: {
+ screens: {
+ [SCREENS.SEARCH.COLUMNS_RHP]: ROUTES.SEARCH_COLUMNS,
+ },
+ },
[SCREENS.RIGHT_MODAL.SEARCH_REPORT]: {
screens: {
[SCREENS.SEARCH.REPORT_RHP]: ROUTES.SEARCH_REPORT.route,
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index 1ca59f3f441a..10a0186d3db8 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -2178,6 +2178,7 @@ type RightModalNavigatorParamList = {
[SCREENS.RIGHT_MODAL.REPORT_CHANGE_APPROVER]: NavigatorScreenParams;
[SCREENS.RIGHT_MODAL.MERGE_TRANSACTION]: NavigatorScreenParams;
[SCREENS.RIGHT_MODAL.DOMAIN]: NavigatorScreenParams;
+ [SCREENS.RIGHT_MODAL.SEARCH_COLUMNS]: NavigatorScreenParams;
};
type TravelNavigatorParamList = {
@@ -2710,6 +2711,10 @@ type SearchSavedSearchParamList = {
[SCREENS.SEARCH.SAVED_SEARCH_RENAME_RHP]: SaveSearchParams;
};
+type SearchColumnsParamList = {
+ [SCREENS.SEARCH.COLUMNS_RHP]: Record;
+};
+
type RestrictedActionParamList = {
[SCREENS.RESTRICTED_ACTION_ROOT]: {
policyID: string;
@@ -2919,4 +2924,5 @@ export type {
WorkspacesDomainModalNavigatorParamList,
DomainSplitNavigatorParamList,
DomainScreenName,
+ SearchColumnsParamList,
};
diff --git a/src/libs/SearchAutocompleteUtils.ts b/src/libs/SearchAutocompleteUtils.ts
index 6786a156beb9..f4c9886caddf 100644
--- a/src/libs/SearchAutocompleteUtils.ts
+++ b/src/libs/SearchAutocompleteUtils.ts
@@ -1,6 +1,7 @@
import type {MarkdownRange} from '@expensify/react-native-live-markdown';
import type {OnyxCollection} from 'react-native-onyx';
import type {SharedValue} from 'react-native-reanimated/lib/typescript/commonTypes';
+import type {ValueOf} from 'type-fest';
import type {SubstitutionMap} from '@components/Search/SearchRouter/getQueryWithSubstitutions';
import type {SearchAutocompleteQueryRange, SearchAutocompleteResult} from '@components/Search/types';
import CONST from '@src/CONST';
@@ -227,6 +228,8 @@ function filterOutRangesWithCorrectValue(
case CONST.SEARCH.SYNTAX_FILTER_KEYS.AMOUNT:
// This uses the same regex as the AmountWithoutCurrencyInput component (allowing for 3 digit decimals as some currencies support that)
return /^-?(?!.*[.,].*[.,])\d{0,8}(?:[.,]\d{0,2})?$/.test(range.value);
+ case CONST.SEARCH.SYNTAX_ROOT_KEYS.COLUMNS:
+ return Object.values(CONST.SEARCH.CUSTOM_COLUMNS).includes(range.value as ValueOf);
case CONST.SEARCH.SYNTAX_FILTER_KEYS.IS:
return isList.includes(range.value);
default:
diff --git a/src/libs/SearchParser/autocompleteParser.js b/src/libs/SearchParser/autocompleteParser.js
index a404845a0a66..742f854ddcef 100644
--- a/src/libs/SearchParser/autocompleteParser.js
+++ b/src/libs/SearchParser/autocompleteParser.js
@@ -246,18 +246,19 @@ function peg$parse(input, options) {
var peg$c60 = "purchase-amount";
var peg$c61 = "purchasecurrency";
var peg$c62 = "purchase-currency";
- var peg$c63 = "perdiem";
- var peg$c64 = "per-diem";
- var peg$c65 = "drafts";
- var peg$c66 = "draft";
- var peg$c67 = "!=";
- var peg$c68 = ">=";
- var peg$c69 = ">";
- var peg$c70 = "<=";
- var peg$c71 = "<";
- var peg$c72 = "\u201C";
- var peg$c73 = "\u201D";
- var peg$c74 = "\"";
+ var peg$c63 = "columns";
+ var peg$c64 = "perdiem";
+ var peg$c65 = "per-diem";
+ var peg$c66 = "drafts";
+ var peg$c67 = "draft";
+ var peg$c68 = "!=";
+ var peg$c69 = ">=";
+ var peg$c70 = ">";
+ var peg$c71 = "<=";
+ var peg$c72 = "<";
+ var peg$c73 = "\u201C";
+ var peg$c74 = "\u201D";
+ var peg$c75 = "\"";
var peg$r0 = /^[ \t\r\n\xA0,:=<>!]/;
var peg$r1 = /^[:=]/;
@@ -338,33 +339,34 @@ function peg$parse(input, options) {
var peg$e63 = peg$literalExpectation("purchase-amount", true);
var peg$e64 = peg$literalExpectation("purchaseCurrency", true);
var peg$e65 = peg$literalExpectation("purchase-currency", true);
- var peg$e66 = peg$literalExpectation("perDiem", true);
- var peg$e67 = peg$literalExpectation("per-diem", true);
- var peg$e68 = peg$literalExpectation("drafts", true);
- var peg$e69 = peg$literalExpectation("draft", true);
- var peg$e70 = peg$otherExpectation("operator");
- var peg$e71 = peg$classExpectation([":", "="], false, false);
- var peg$e72 = peg$literalExpectation("!=", false);
- var peg$e73 = peg$literalExpectation(">=", false);
- var peg$e74 = peg$literalExpectation(">", false);
- var peg$e75 = peg$literalExpectation("<=", false);
- var peg$e76 = peg$literalExpectation("<", false);
- var peg$e77 = peg$otherExpectation("word");
- var peg$e78 = peg$classExpectation([" ", ",", "\t", "\n", "\r", "\xA0"], true, false);
- var peg$e79 = peg$otherExpectation("whitespace");
- var peg$e80 = peg$classExpectation([" ", "\t", "\r", "\n", "\xA0"], false, false);
- var peg$e81 = peg$otherExpectation("quote");
- var peg$e82 = peg$classExpectation([" ", ",", "\"", "\u201D", "\u201C", "\t", "\n", "\r", "\xA0"], true, false);
- var peg$e83 = peg$classExpectation(["\"", ["\u201C", "\u201D"]], false, false);
- var peg$e84 = peg$classExpectation(["\"", "\u201D", "\u201C", "\r", "\n"], true, false);
- var peg$e85 = peg$literalExpectation("\u201C", false);
- var peg$e86 = peg$literalExpectation("\u201D", false);
- var peg$e87 = peg$literalExpectation("\"", false);
- var peg$e88 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"], ["0", "9"]], false, false);
- var peg$e89 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false);
- var peg$e90 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0"], false, false);
- var peg$e91 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"]], false, false);
- var peg$e92 = peg$classExpectation([","], false, false);
+ var peg$e66 = peg$literalExpectation("columns", true);
+ var peg$e67 = peg$literalExpectation("perDiem", true);
+ var peg$e68 = peg$literalExpectation("per-diem", true);
+ var peg$e69 = peg$literalExpectation("drafts", true);
+ var peg$e70 = peg$literalExpectation("draft", true);
+ var peg$e71 = peg$otherExpectation("operator");
+ var peg$e72 = peg$classExpectation([":", "="], false, false);
+ var peg$e73 = peg$literalExpectation("!=", false);
+ var peg$e74 = peg$literalExpectation(">=", false);
+ var peg$e75 = peg$literalExpectation(">", false);
+ var peg$e76 = peg$literalExpectation("<=", false);
+ var peg$e77 = peg$literalExpectation("<", false);
+ var peg$e78 = peg$otherExpectation("word");
+ var peg$e79 = peg$classExpectation([" ", ",", "\t", "\n", "\r", "\xA0"], true, false);
+ var peg$e80 = peg$otherExpectation("whitespace");
+ var peg$e81 = peg$classExpectation([" ", "\t", "\r", "\n", "\xA0"], false, false);
+ var peg$e82 = peg$otherExpectation("quote");
+ var peg$e83 = peg$classExpectation([" ", ",", "\"", "\u201D", "\u201C", "\t", "\n", "\r", "\xA0"], true, false);
+ var peg$e84 = peg$classExpectation(["\"", ["\u201C", "\u201D"]], false, false);
+ var peg$e85 = peg$classExpectation(["\"", "\u201D", "\u201C", "\r", "\n"], true, false);
+ var peg$e86 = peg$literalExpectation("\u201C", false);
+ var peg$e87 = peg$literalExpectation("\u201D", false);
+ var peg$e88 = peg$literalExpectation("\"", false);
+ var peg$e89 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"], ["0", "9"]], false, false);
+ var peg$e90 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false);
+ var peg$e91 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0"], false, false);
+ var peg$e92 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"]], false, false);
+ var peg$e93 = peg$classExpectation([","], false, false);
var peg$f0 = function(ranges) { return { autocomplete, ranges }; };
var peg$f1 = function(filters) { return filters.filter(Boolean).flat(); };
@@ -473,30 +475,31 @@ function peg$parse(input, options) {
var peg$f49 = function() {return "is"; };
var peg$f50 = function() {return "purchaseAmount"};
var peg$f51 = function() {return "purchaseCurrency"};
- var peg$f52 = function() { return "perDiem"; };
- var peg$f53 = function() {return "drafts"; };
- var peg$f54 = function() { return "eq"; };
- var peg$f55 = function() { return "neq"; };
- var peg$f56 = function() { return "gte"; };
- var peg$f57 = function() { return "gt"; };
- var peg$f58 = function() { return "lte"; };
- var peg$f59 = function() { return "lt"; };
- var peg$f60 = function(o) {
+ var peg$f52 = function() {return "columns"};
+ var peg$f53 = function() { return "perDiem"; };
+ var peg$f54 = function() {return "drafts"; };
+ var peg$f55 = function() { return "eq"; };
+ var peg$f56 = function() { return "neq"; };
+ var peg$f57 = function() { return "gte"; };
+ var peg$f58 = function() { return "gt"; };
+ var peg$f59 = function() { return "lte"; };
+ var peg$f60 = function() { return "lt"; };
+ var peg$f61 = function(o) {
if (nameOperator) {
expectingNestedQuote = (o === "eq"); // Use simple parser if no valid operator is found
}
return o;
};
- var peg$f61 = function(chars) { return chars.join("").trim(); };
- var peg$f62 = function() { return "and"; };
- var peg$f63 = function() { return expectingNestedQuote; };
- var peg$f64 = function(start, inner, end) { //handle no-breaking space
+ var peg$f62 = function(chars) { return chars.join("").trim(); };
+ var peg$f63 = function() { return "and"; };
+ var peg$f64 = function() { return expectingNestedQuote; };
+ var peg$f65 = function(start, inner, end) { //handle no-breaking space
return [...start, '"', ...inner, '"', ...end].join("");
};
- var peg$f65 = function(start) {return "“"};
- var peg$f66 = function(start) {return "”"};
- var peg$f67 = function(start) {return "\""};
- var peg$f68 = function(start, inner, end) {
+ var peg$f66 = function(start) {return "“"};
+ var peg$f67 = function(start) {return "”"};
+ var peg$f68 = function(start) {return "\""};
+ var peg$f69 = function(start, inner, end) {
return [...start, '"', ...inner, '"'].join("");
};
var peg$currPos = options.peg$currPos | 0;
@@ -994,6 +997,9 @@ function peg$parse(input, options) {
s1 = peg$parsetitle();
if (s1 === peg$FAILED) {
s1 = peg$parsereportFieldDynamic();
+ if (s1 === peg$FAILED) {
+ s1 = peg$parsecolumns();
+ }
}
}
}
@@ -2153,6 +2159,26 @@ function peg$parse(input, options) {
return s0;
}
+ function peg$parsecolumns() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ s1 = input.substr(peg$currPos, 7);
+ if (s1.toLowerCase() === peg$c63) {
+ peg$currPos += 7;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) { peg$fail(peg$e66); }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$savedPos = s0;
+ s1 = peg$f52();
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
function peg$parsevalues() {
var s0;
@@ -2168,24 +2194,24 @@ function peg$parse(input, options) {
var s0, s1;
s0 = input.substr(peg$currPos, 7);
- if (s0.toLowerCase() === peg$c63) {
+ if (s0.toLowerCase() === peg$c64) {
peg$currPos += 7;
} else {
s0 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e66); }
+ if (peg$silentFails === 0) { peg$fail(peg$e67); }
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = input.substr(peg$currPos, 8);
- if (s1.toLowerCase() === peg$c64) {
+ if (s1.toLowerCase() === peg$c65) {
peg$currPos += 8;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e67); }
+ if (peg$silentFails === 0) { peg$fail(peg$e68); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f52();
+ s1 = peg$f53();
}
s0 = s1;
}
@@ -2197,24 +2223,24 @@ function peg$parse(input, options) {
var s0, s1;
s0 = input.substr(peg$currPos, 6);
- if (s0.toLowerCase() === peg$c65) {
+ if (s0.toLowerCase() === peg$c66) {
peg$currPos += 6;
} else {
s0 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e68); }
+ if (peg$silentFails === 0) { peg$fail(peg$e69); }
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = input.substr(peg$currPos, 5);
- if (s1.toLowerCase() === peg$c66) {
+ if (s1.toLowerCase() === peg$c67) {
peg$currPos += 5;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e69); }
+ if (peg$silentFails === 0) { peg$fail(peg$e70); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f53();
+ s1 = peg$f54();
}
s0 = s1;
}
@@ -2232,81 +2258,81 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e71); }
+ if (peg$silentFails === 0) { peg$fail(peg$e72); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f54();
+ s1 = peg$f55();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c67) {
- s1 = peg$c67;
+ if (input.substr(peg$currPos, 2) === peg$c68) {
+ s1 = peg$c68;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e72); }
+ if (peg$silentFails === 0) { peg$fail(peg$e73); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f55();
+ s1 = peg$f56();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c68) {
- s1 = peg$c68;
+ if (input.substr(peg$currPos, 2) === peg$c69) {
+ s1 = peg$c69;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e73); }
+ if (peg$silentFails === 0) { peg$fail(peg$e74); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f56();
+ s1 = peg$f57();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 62) {
- s1 = peg$c69;
+ s1 = peg$c70;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e74); }
+ if (peg$silentFails === 0) { peg$fail(peg$e75); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f57();
+ s1 = peg$f58();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c70) {
- s1 = peg$c70;
+ if (input.substr(peg$currPos, 2) === peg$c71) {
+ s1 = peg$c71;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e75); }
+ if (peg$silentFails === 0) { peg$fail(peg$e76); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f58();
+ s1 = peg$f59();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 60) {
- s1 = peg$c71;
+ s1 = peg$c72;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e76); }
+ if (peg$silentFails === 0) { peg$fail(peg$e77); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f59();
+ s1 = peg$f60();
}
s0 = s1;
}
@@ -2317,7 +2343,7 @@ function peg$parse(input, options) {
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e70); }
+ if (peg$silentFails === 0) { peg$fail(peg$e71); }
}
return s0;
@@ -2330,7 +2356,7 @@ function peg$parse(input, options) {
s1 = peg$parseoperator();
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f60(s1);
+ s1 = peg$f61(s1);
}
s0 = s1;
@@ -2348,7 +2374,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e78); }
+ if (peg$silentFails === 0) { peg$fail(peg$e79); }
}
if (s2 !== peg$FAILED) {
while (s2 !== peg$FAILED) {
@@ -2358,7 +2384,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e78); }
+ if (peg$silentFails === 0) { peg$fail(peg$e79); }
}
}
} else {
@@ -2366,13 +2392,13 @@ function peg$parse(input, options) {
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f61(s1);
+ s1 = peg$f62(s1);
}
s0 = s1;
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e77); }
+ if (peg$silentFails === 0) { peg$fail(peg$e78); }
}
return s0;
@@ -2384,7 +2410,7 @@ function peg$parse(input, options) {
s0 = peg$currPos;
s1 = peg$parse_();
peg$savedPos = s0;
- s1 = peg$f62();
+ s1 = peg$f63();
s0 = s1;
return s0;
@@ -2400,7 +2426,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e80); }
+ if (peg$silentFails === 0) { peg$fail(peg$e81); }
}
while (s1 !== peg$FAILED) {
s0.push(s1);
@@ -2409,12 +2435,12 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e80); }
+ if (peg$silentFails === 0) { peg$fail(peg$e81); }
}
}
peg$silentFails--;
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e79); }
+ if (peg$silentFails === 0) { peg$fail(peg$e80); }
return s0;
}
@@ -2424,7 +2450,7 @@ function peg$parse(input, options) {
s0 = peg$currPos;
peg$savedPos = peg$currPos;
- s1 = peg$f63();
+ s1 = peg$f64();
if (s1) {
s1 = undefined;
} else {
@@ -2461,7 +2487,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e82); }
+ if (peg$silentFails === 0) { peg$fail(peg$e83); }
}
while (s2 !== peg$FAILED) {
s1.push(s2);
@@ -2470,7 +2496,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e82); }
+ if (peg$silentFails === 0) { peg$fail(peg$e83); }
}
}
s2 = input.charAt(peg$currPos);
@@ -2478,7 +2504,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e83); }
+ if (peg$silentFails === 0) { peg$fail(peg$e84); }
}
if (s2 !== peg$FAILED) {
s3 = [];
@@ -2487,7 +2513,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e84); }
+ if (peg$silentFails === 0) { peg$fail(peg$e85); }
}
while (s4 !== peg$FAILED) {
s3.push(s4);
@@ -2496,7 +2522,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e84); }
+ if (peg$silentFails === 0) { peg$fail(peg$e85); }
}
}
s4 = input.charAt(peg$currPos);
@@ -2504,7 +2530,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e83); }
+ if (peg$silentFails === 0) { peg$fail(peg$e84); }
}
if (s4 !== peg$FAILED) {
s5 = [];
@@ -2513,7 +2539,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e78); }
+ if (peg$silentFails === 0) { peg$fail(peg$e79); }
}
while (s6 !== peg$FAILED) {
s5.push(s6);
@@ -2522,11 +2548,11 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e78); }
+ if (peg$silentFails === 0) { peg$fail(peg$e79); }
}
}
peg$savedPos = s0;
- s0 = peg$f64(s1, s3, s5);
+ s0 = peg$f65(s1, s3, s5);
} else {
peg$currPos = s0;
s0 = peg$FAILED;
@@ -2538,7 +2564,7 @@ function peg$parse(input, options) {
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e81); }
+ if (peg$silentFails === 0) { peg$fail(peg$e82); }
}
return s0;
@@ -2555,7 +2581,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e82); }
+ if (peg$silentFails === 0) { peg$fail(peg$e83); }
}
while (s2 !== peg$FAILED) {
s1.push(s2);
@@ -2564,7 +2590,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e82); }
+ if (peg$silentFails === 0) { peg$fail(peg$e83); }
}
}
s2 = input.charAt(peg$currPos);
@@ -2572,7 +2598,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e83); }
+ if (peg$silentFails === 0) { peg$fail(peg$e84); }
}
if (s2 !== peg$FAILED) {
s3 = [];
@@ -2581,7 +2607,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e84); }
+ if (peg$silentFails === 0) { peg$fail(peg$e85); }
}
if (s4 === peg$FAILED) {
s4 = peg$currPos;
@@ -2597,15 +2623,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 8220) {
- s6 = peg$c72;
+ s6 = peg$c73;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e85); }
+ if (peg$silentFails === 0) { peg$fail(peg$e86); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f65(s1);
+ s4 = peg$f66(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2628,15 +2654,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 8221) {
- s6 = peg$c73;
+ s6 = peg$c74;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e86); }
+ if (peg$silentFails === 0) { peg$fail(peg$e87); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f66(s1);
+ s4 = peg$f67(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2659,15 +2685,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 34) {
- s6 = peg$c74;
+ s6 = peg$c75;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e87); }
+ if (peg$silentFails === 0) { peg$fail(peg$e88); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f67(s1);
+ s4 = peg$f68(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2686,7 +2712,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e84); }
+ if (peg$silentFails === 0) { peg$fail(peg$e85); }
}
if (s4 === peg$FAILED) {
s4 = peg$currPos;
@@ -2702,15 +2728,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 8220) {
- s6 = peg$c72;
+ s6 = peg$c73;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e85); }
+ if (peg$silentFails === 0) { peg$fail(peg$e86); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f65(s1);
+ s4 = peg$f66(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2733,15 +2759,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 8221) {
- s6 = peg$c73;
+ s6 = peg$c74;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e86); }
+ if (peg$silentFails === 0) { peg$fail(peg$e87); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f66(s1);
+ s4 = peg$f67(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2764,15 +2790,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 34) {
- s6 = peg$c74;
+ s6 = peg$c75;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e87); }
+ if (peg$silentFails === 0) { peg$fail(peg$e88); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f67(s1);
+ s4 = peg$f68(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2788,7 +2814,7 @@ function peg$parse(input, options) {
s4 = peg$parseclosingQuote();
if (s4 !== peg$FAILED) {
peg$savedPos = s0;
- s0 = peg$f68(s1, s3, s4);
+ s0 = peg$f69(s1, s3, s4);
} else {
peg$currPos = s0;
s0 = peg$FAILED;
@@ -2800,7 +2826,7 @@ function peg$parse(input, options) {
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e81); }
+ if (peg$silentFails === 0) { peg$fail(peg$e82); }
}
return s0;
@@ -2815,7 +2841,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e83); }
+ if (peg$silentFails === 0) { peg$fail(peg$e84); }
}
if (s1 !== peg$FAILED) {
s2 = peg$currPos;
@@ -2853,7 +2879,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e88); }
+ if (peg$silentFails === 0) { peg$fail(peg$e89); }
}
while (s2 !== peg$FAILED) {
s1.push(s2);
@@ -2862,7 +2888,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e88); }
+ if (peg$silentFails === 0) { peg$fail(peg$e89); }
}
}
s2 = [];
@@ -2871,7 +2897,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s3 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e89); }
+ if (peg$silentFails === 0) { peg$fail(peg$e90); }
}
while (s3 !== peg$FAILED) {
s2.push(s3);
@@ -2880,7 +2906,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s3 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e89); }
+ if (peg$silentFails === 0) { peg$fail(peg$e90); }
}
}
s3 = [];
@@ -2889,7 +2915,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e90); }
+ if (peg$silentFails === 0) { peg$fail(peg$e91); }
}
while (s4 !== peg$FAILED) {
s3.push(s4);
@@ -2898,7 +2924,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e90); }
+ if (peg$silentFails === 0) { peg$fail(peg$e91); }
}
}
s4 = peg$parseoperator();
@@ -2917,7 +2943,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e91); }
+ if (peg$silentFails === 0) { peg$fail(peg$e92); }
}
while (s2 !== peg$FAILED) {
s1.push(s2);
@@ -2926,7 +2952,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e91); }
+ if (peg$silentFails === 0) { peg$fail(peg$e92); }
}
}
s2 = peg$currPos;
@@ -2973,7 +2999,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s0 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e92); }
+ if (peg$silentFails === 0) { peg$fail(peg$e93); }
}
}
}
@@ -2986,7 +3012,7 @@ function peg$parse(input, options) {
// List fields where you cannot prefix it with "-" to negate it
const nonNegatableKeys = new Set([
- "type", "keyword", "groupCurrency", "groupBy"
+ "type", "keyword", "groupCurrency", "groupBy", "columns"
]);
diff --git a/src/libs/SearchParser/autocompleteParser.peggy b/src/libs/SearchParser/autocompleteParser.peggy
index a07cb01c80fc..cda2b7c8c888 100644
--- a/src/libs/SearchParser/autocompleteParser.peggy
+++ b/src/libs/SearchParser/autocompleteParser.peggy
@@ -23,7 +23,7 @@
// List fields where you cannot prefix it with "-" to negate it
const nonNegatableKeys = new Set([
- "type", "keyword", "groupCurrency", "groupBy"
+ "type", "keyword", "groupCurrency", "groupBy", "columns"
]);
}
@@ -118,6 +118,7 @@ autocompleteKey "key"
/ withdrawalID
/ title
/ reportFieldDynamic
+ / columns
)
filterKey
diff --git a/src/libs/SearchParser/baseRules.peggy b/src/libs/SearchParser/baseRules.peggy
index 60fbc69ec304..d9662ad6d2d9 100644
--- a/src/libs/SearchParser/baseRules.peggy
+++ b/src/libs/SearchParser/baseRules.peggy
@@ -78,6 +78,7 @@ has = "has"i {return "has"; }
is = "is"i {return "is"; }
purchaseAmount = "purchaseAmount"i / "purchase-amount"i {return "purchaseAmount"}
purchaseCurrency = "purchaseCurrency"i / "purchase-currency"i {return "purchaseCurrency"}
+columns = "columns"i {return "columns"}
// Value transformation rules
values
diff --git a/src/libs/SearchParser/searchParser.js b/src/libs/SearchParser/searchParser.js
index 433fd21614dd..955bbae945ea 100644
--- a/src/libs/SearchParser/searchParser.js
+++ b/src/libs/SearchParser/searchParser.js
@@ -247,18 +247,19 @@ function peg$parse(input, options) {
var peg$c60 = "purchase-amount";
var peg$c61 = "purchasecurrency";
var peg$c62 = "purchase-currency";
- var peg$c63 = "perdiem";
- var peg$c64 = "per-diem";
- var peg$c65 = "drafts";
- var peg$c66 = "draft";
- var peg$c67 = "!=";
- var peg$c68 = ">=";
- var peg$c69 = ">";
- var peg$c70 = "<=";
- var peg$c71 = "<";
- var peg$c72 = "\u201C";
- var peg$c73 = "\u201D";
- var peg$c74 = "\"";
+ var peg$c63 = "columns";
+ var peg$c64 = "perdiem";
+ var peg$c65 = "per-diem";
+ var peg$c66 = "drafts";
+ var peg$c67 = "draft";
+ var peg$c68 = "!=";
+ var peg$c69 = ">=";
+ var peg$c70 = ">";
+ var peg$c71 = "<=";
+ var peg$c72 = "<";
+ var peg$c73 = "\u201C";
+ var peg$c74 = "\u201D";
+ var peg$c75 = "\"";
var peg$r0 = /^[^ \t\r\n\xA0]/;
var peg$r1 = /^[ \t\r\n\xA0,:=<>!]/;
@@ -342,33 +343,34 @@ function peg$parse(input, options) {
var peg$e65 = peg$literalExpectation("purchase-amount", true);
var peg$e66 = peg$literalExpectation("purchaseCurrency", true);
var peg$e67 = peg$literalExpectation("purchase-currency", true);
- var peg$e68 = peg$literalExpectation("perDiem", true);
- var peg$e69 = peg$literalExpectation("per-diem", true);
- var peg$e70 = peg$literalExpectation("drafts", true);
- var peg$e71 = peg$literalExpectation("draft", true);
- var peg$e72 = peg$otherExpectation("operator");
- var peg$e73 = peg$classExpectation([":", "="], false, false);
- var peg$e74 = peg$literalExpectation("!=", false);
- var peg$e75 = peg$literalExpectation(">=", false);
- var peg$e76 = peg$literalExpectation(">", false);
- var peg$e77 = peg$literalExpectation("<=", false);
- var peg$e78 = peg$literalExpectation("<", false);
- var peg$e79 = peg$otherExpectation("word");
- var peg$e80 = peg$classExpectation([" ", ",", "\t", "\n", "\r", "\xA0"], true, false);
- var peg$e81 = peg$otherExpectation("whitespace");
- var peg$e82 = peg$classExpectation([" ", "\t", "\r", "\n", "\xA0"], false, false);
- var peg$e83 = peg$otherExpectation("quote");
- var peg$e84 = peg$classExpectation([" ", ",", "\"", "\u201D", "\u201C", "\t", "\n", "\r", "\xA0"], true, false);
- var peg$e85 = peg$classExpectation(["\"", ["\u201C", "\u201D"]], false, false);
- var peg$e86 = peg$classExpectation(["\"", "\u201D", "\u201C", "\r", "\n"], true, false);
- var peg$e87 = peg$literalExpectation("\u201C", false);
- var peg$e88 = peg$literalExpectation("\u201D", false);
- var peg$e89 = peg$literalExpectation("\"", false);
- var peg$e90 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"], ["0", "9"]], false, false);
- var peg$e91 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false);
- var peg$e92 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0"], false, false);
- var peg$e93 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"]], false, false);
- var peg$e94 = peg$classExpectation([","], false, false);
+ var peg$e68 = peg$literalExpectation("columns", true);
+ var peg$e69 = peg$literalExpectation("perDiem", true);
+ var peg$e70 = peg$literalExpectation("per-diem", true);
+ var peg$e71 = peg$literalExpectation("drafts", true);
+ var peg$e72 = peg$literalExpectation("draft", true);
+ var peg$e73 = peg$otherExpectation("operator");
+ var peg$e74 = peg$classExpectation([":", "="], false, false);
+ var peg$e75 = peg$literalExpectation("!=", false);
+ var peg$e76 = peg$literalExpectation(">=", false);
+ var peg$e77 = peg$literalExpectation(">", false);
+ var peg$e78 = peg$literalExpectation("<=", false);
+ var peg$e79 = peg$literalExpectation("<", false);
+ var peg$e80 = peg$otherExpectation("word");
+ var peg$e81 = peg$classExpectation([" ", ",", "\t", "\n", "\r", "\xA0"], true, false);
+ var peg$e82 = peg$otherExpectation("whitespace");
+ var peg$e83 = peg$classExpectation([" ", "\t", "\r", "\n", "\xA0"], false, false);
+ var peg$e84 = peg$otherExpectation("quote");
+ var peg$e85 = peg$classExpectation([" ", ",", "\"", "\u201D", "\u201C", "\t", "\n", "\r", "\xA0"], true, false);
+ var peg$e86 = peg$classExpectation(["\"", ["\u201C", "\u201D"]], false, false);
+ var peg$e87 = peg$classExpectation(["\"", "\u201D", "\u201C", "\r", "\n"], true, false);
+ var peg$e88 = peg$literalExpectation("\u201C", false);
+ var peg$e89 = peg$literalExpectation("\u201D", false);
+ var peg$e90 = peg$literalExpectation("\"", false);
+ var peg$e91 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"], ["0", "9"]], false, false);
+ var peg$e92 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false);
+ var peg$e93 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0"], false, false);
+ var peg$e94 = peg$classExpectation([" ", "\t", "\n", "\r", "\xA0", ["a", "z"], ["A", "Z"]], false, false);
+ var peg$e95 = peg$classExpectation([","], false, false);
var peg$f0 = function(filters) { return applyDefaults(filters); };
var peg$f1 = function(head, tail) {
@@ -500,30 +502,31 @@ function peg$parse(input, options) {
var peg$f50 = function() {return "is"; };
var peg$f51 = function() {return "purchaseAmount"};
var peg$f52 = function() {return "purchaseCurrency"};
- var peg$f53 = function() { return "perDiem"; };
- var peg$f54 = function() {return "drafts"; };
- var peg$f55 = function() { return "eq"; };
- var peg$f56 = function() { return "neq"; };
- var peg$f57 = function() { return "gte"; };
- var peg$f58 = function() { return "gt"; };
- var peg$f59 = function() { return "lte"; };
- var peg$f60 = function() { return "lt"; };
- var peg$f61 = function(o) {
+ var peg$f53 = function() {return "columns"};
+ var peg$f54 = function() { return "perDiem"; };
+ var peg$f55 = function() {return "drafts"; };
+ var peg$f56 = function() { return "eq"; };
+ var peg$f57 = function() { return "neq"; };
+ var peg$f58 = function() { return "gte"; };
+ var peg$f59 = function() { return "gt"; };
+ var peg$f60 = function() { return "lte"; };
+ var peg$f61 = function() { return "lt"; };
+ var peg$f62 = function(o) {
if (nameOperator) {
expectingNestedQuote = (o === "eq"); // Use simple parser if no valid operator is found
}
return o;
};
- var peg$f62 = function(chars) { return chars.join("").trim(); };
- var peg$f63 = function() { return "and"; };
- var peg$f64 = function() { return expectingNestedQuote; };
- var peg$f65 = function(start, inner, end) { //handle no-breaking space
+ var peg$f63 = function(chars) { return chars.join("").trim(); };
+ var peg$f64 = function() { return "and"; };
+ var peg$f65 = function() { return expectingNestedQuote; };
+ var peg$f66 = function(start, inner, end) { //handle no-breaking space
return [...start, '"', ...inner, '"', ...end].join("");
};
- var peg$f66 = function(start) {return "“"};
- var peg$f67 = function(start) {return "”"};
- var peg$f68 = function(start) {return "\""};
- var peg$f69 = function(start, inner, end) {
+ var peg$f67 = function(start) {return "“"};
+ var peg$f68 = function(start) {return "”"};
+ var peg$f69 = function(start) {return "\""};
+ var peg$f70 = function(start, inner, end) {
return [...start, '"', ...inner, '"'].join("");
};
var peg$currPos = options.peg$currPos | 0;
@@ -1168,6 +1171,9 @@ function peg$parse(input, options) {
s1 = peg$parsepolicyID();
if (s1 === peg$FAILED) {
s1 = peg$parsegroupBy();
+ if (s1 === peg$FAILED) {
+ s1 = peg$parsecolumns();
+ }
}
}
}
@@ -2337,6 +2343,26 @@ function peg$parse(input, options) {
return s0;
}
+ function peg$parsecolumns() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ s1 = input.substr(peg$currPos, 7);
+ if (s1.toLowerCase() === peg$c63) {
+ peg$currPos += 7;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) { peg$fail(peg$e68); }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$savedPos = s0;
+ s1 = peg$f53();
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
function peg$parsevalues() {
var s0;
@@ -2352,24 +2378,24 @@ function peg$parse(input, options) {
var s0, s1;
s0 = input.substr(peg$currPos, 7);
- if (s0.toLowerCase() === peg$c63) {
+ if (s0.toLowerCase() === peg$c64) {
peg$currPos += 7;
} else {
s0 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e68); }
+ if (peg$silentFails === 0) { peg$fail(peg$e69); }
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = input.substr(peg$currPos, 8);
- if (s1.toLowerCase() === peg$c64) {
+ if (s1.toLowerCase() === peg$c65) {
peg$currPos += 8;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e69); }
+ if (peg$silentFails === 0) { peg$fail(peg$e70); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f53();
+ s1 = peg$f54();
}
s0 = s1;
}
@@ -2381,24 +2407,24 @@ function peg$parse(input, options) {
var s0, s1;
s0 = input.substr(peg$currPos, 6);
- if (s0.toLowerCase() === peg$c65) {
+ if (s0.toLowerCase() === peg$c66) {
peg$currPos += 6;
} else {
s0 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e70); }
+ if (peg$silentFails === 0) { peg$fail(peg$e71); }
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = input.substr(peg$currPos, 5);
- if (s1.toLowerCase() === peg$c66) {
+ if (s1.toLowerCase() === peg$c67) {
peg$currPos += 5;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e71); }
+ if (peg$silentFails === 0) { peg$fail(peg$e72); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f54();
+ s1 = peg$f55();
}
s0 = s1;
}
@@ -2416,81 +2442,81 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e73); }
+ if (peg$silentFails === 0) { peg$fail(peg$e74); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f55();
+ s1 = peg$f56();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c67) {
- s1 = peg$c67;
+ if (input.substr(peg$currPos, 2) === peg$c68) {
+ s1 = peg$c68;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e74); }
+ if (peg$silentFails === 0) { peg$fail(peg$e75); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f56();
+ s1 = peg$f57();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c68) {
- s1 = peg$c68;
+ if (input.substr(peg$currPos, 2) === peg$c69) {
+ s1 = peg$c69;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e75); }
+ if (peg$silentFails === 0) { peg$fail(peg$e76); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f57();
+ s1 = peg$f58();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 62) {
- s1 = peg$c69;
+ s1 = peg$c70;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e76); }
+ if (peg$silentFails === 0) { peg$fail(peg$e77); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f58();
+ s1 = peg$f59();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c70) {
- s1 = peg$c70;
+ if (input.substr(peg$currPos, 2) === peg$c71) {
+ s1 = peg$c71;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e77); }
+ if (peg$silentFails === 0) { peg$fail(peg$e78); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f59();
+ s1 = peg$f60();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 60) {
- s1 = peg$c71;
+ s1 = peg$c72;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e78); }
+ if (peg$silentFails === 0) { peg$fail(peg$e79); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f60();
+ s1 = peg$f61();
}
s0 = s1;
}
@@ -2501,7 +2527,7 @@ function peg$parse(input, options) {
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e72); }
+ if (peg$silentFails === 0) { peg$fail(peg$e73); }
}
return s0;
@@ -2514,7 +2540,7 @@ function peg$parse(input, options) {
s1 = peg$parseoperator();
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f61(s1);
+ s1 = peg$f62(s1);
}
s0 = s1;
@@ -2532,7 +2558,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e80); }
+ if (peg$silentFails === 0) { peg$fail(peg$e81); }
}
if (s2 !== peg$FAILED) {
while (s2 !== peg$FAILED) {
@@ -2542,7 +2568,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e80); }
+ if (peg$silentFails === 0) { peg$fail(peg$e81); }
}
}
} else {
@@ -2550,13 +2576,13 @@ function peg$parse(input, options) {
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
- s1 = peg$f62(s1);
+ s1 = peg$f63(s1);
}
s0 = s1;
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e79); }
+ if (peg$silentFails === 0) { peg$fail(peg$e80); }
}
return s0;
@@ -2568,7 +2594,7 @@ function peg$parse(input, options) {
s0 = peg$currPos;
s1 = peg$parse_();
peg$savedPos = s0;
- s1 = peg$f63();
+ s1 = peg$f64();
s0 = s1;
return s0;
@@ -2584,7 +2610,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e82); }
+ if (peg$silentFails === 0) { peg$fail(peg$e83); }
}
while (s1 !== peg$FAILED) {
s0.push(s1);
@@ -2593,12 +2619,12 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e82); }
+ if (peg$silentFails === 0) { peg$fail(peg$e83); }
}
}
peg$silentFails--;
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e81); }
+ if (peg$silentFails === 0) { peg$fail(peg$e82); }
return s0;
}
@@ -2608,7 +2634,7 @@ function peg$parse(input, options) {
s0 = peg$currPos;
peg$savedPos = peg$currPos;
- s1 = peg$f64();
+ s1 = peg$f65();
if (s1) {
s1 = undefined;
} else {
@@ -2645,7 +2671,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e84); }
+ if (peg$silentFails === 0) { peg$fail(peg$e85); }
}
while (s2 !== peg$FAILED) {
s1.push(s2);
@@ -2654,7 +2680,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e84); }
+ if (peg$silentFails === 0) { peg$fail(peg$e85); }
}
}
s2 = input.charAt(peg$currPos);
@@ -2662,7 +2688,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e85); }
+ if (peg$silentFails === 0) { peg$fail(peg$e86); }
}
if (s2 !== peg$FAILED) {
s3 = [];
@@ -2671,7 +2697,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e86); }
+ if (peg$silentFails === 0) { peg$fail(peg$e87); }
}
while (s4 !== peg$FAILED) {
s3.push(s4);
@@ -2680,7 +2706,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e86); }
+ if (peg$silentFails === 0) { peg$fail(peg$e87); }
}
}
s4 = input.charAt(peg$currPos);
@@ -2688,7 +2714,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e85); }
+ if (peg$silentFails === 0) { peg$fail(peg$e86); }
}
if (s4 !== peg$FAILED) {
s5 = [];
@@ -2697,7 +2723,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e80); }
+ if (peg$silentFails === 0) { peg$fail(peg$e81); }
}
while (s6 !== peg$FAILED) {
s5.push(s6);
@@ -2706,11 +2732,11 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e80); }
+ if (peg$silentFails === 0) { peg$fail(peg$e81); }
}
}
peg$savedPos = s0;
- s0 = peg$f65(s1, s3, s5);
+ s0 = peg$f66(s1, s3, s5);
} else {
peg$currPos = s0;
s0 = peg$FAILED;
@@ -2722,7 +2748,7 @@ function peg$parse(input, options) {
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e83); }
+ if (peg$silentFails === 0) { peg$fail(peg$e84); }
}
return s0;
@@ -2739,7 +2765,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e84); }
+ if (peg$silentFails === 0) { peg$fail(peg$e85); }
}
while (s2 !== peg$FAILED) {
s1.push(s2);
@@ -2748,7 +2774,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e84); }
+ if (peg$silentFails === 0) { peg$fail(peg$e85); }
}
}
s2 = input.charAt(peg$currPos);
@@ -2756,7 +2782,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e85); }
+ if (peg$silentFails === 0) { peg$fail(peg$e86); }
}
if (s2 !== peg$FAILED) {
s3 = [];
@@ -2765,7 +2791,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e86); }
+ if (peg$silentFails === 0) { peg$fail(peg$e87); }
}
if (s4 === peg$FAILED) {
s4 = peg$currPos;
@@ -2781,15 +2807,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 8220) {
- s6 = peg$c72;
+ s6 = peg$c73;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e87); }
+ if (peg$silentFails === 0) { peg$fail(peg$e88); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f66(s1);
+ s4 = peg$f67(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2812,15 +2838,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 8221) {
- s6 = peg$c73;
+ s6 = peg$c74;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e88); }
+ if (peg$silentFails === 0) { peg$fail(peg$e89); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f67(s1);
+ s4 = peg$f68(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2843,15 +2869,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 34) {
- s6 = peg$c74;
+ s6 = peg$c75;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e89); }
+ if (peg$silentFails === 0) { peg$fail(peg$e90); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f68(s1);
+ s4 = peg$f69(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2870,7 +2896,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e86); }
+ if (peg$silentFails === 0) { peg$fail(peg$e87); }
}
if (s4 === peg$FAILED) {
s4 = peg$currPos;
@@ -2886,15 +2912,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 8220) {
- s6 = peg$c72;
+ s6 = peg$c73;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e87); }
+ if (peg$silentFails === 0) { peg$fail(peg$e88); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f66(s1);
+ s4 = peg$f67(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2917,15 +2943,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 8221) {
- s6 = peg$c73;
+ s6 = peg$c74;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e88); }
+ if (peg$silentFails === 0) { peg$fail(peg$e89); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f67(s1);
+ s4 = peg$f68(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2948,15 +2974,15 @@ function peg$parse(input, options) {
}
if (s5 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 34) {
- s6 = peg$c74;
+ s6 = peg$c75;
peg$currPos++;
} else {
s6 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e89); }
+ if (peg$silentFails === 0) { peg$fail(peg$e90); }
}
if (s6 !== peg$FAILED) {
peg$savedPos = s4;
- s4 = peg$f68(s1);
+ s4 = peg$f69(s1);
} else {
peg$currPos = s4;
s4 = peg$FAILED;
@@ -2972,7 +2998,7 @@ function peg$parse(input, options) {
s4 = peg$parseclosingQuote();
if (s4 !== peg$FAILED) {
peg$savedPos = s0;
- s0 = peg$f69(s1, s3, s4);
+ s0 = peg$f70(s1, s3, s4);
} else {
peg$currPos = s0;
s0 = peg$FAILED;
@@ -2984,7 +3010,7 @@ function peg$parse(input, options) {
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e83); }
+ if (peg$silentFails === 0) { peg$fail(peg$e84); }
}
return s0;
@@ -2999,7 +3025,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e85); }
+ if (peg$silentFails === 0) { peg$fail(peg$e86); }
}
if (s1 !== peg$FAILED) {
s2 = peg$currPos;
@@ -3037,7 +3063,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e90); }
+ if (peg$silentFails === 0) { peg$fail(peg$e91); }
}
while (s2 !== peg$FAILED) {
s1.push(s2);
@@ -3046,7 +3072,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e90); }
+ if (peg$silentFails === 0) { peg$fail(peg$e91); }
}
}
s2 = [];
@@ -3055,7 +3081,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s3 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e91); }
+ if (peg$silentFails === 0) { peg$fail(peg$e92); }
}
while (s3 !== peg$FAILED) {
s2.push(s3);
@@ -3064,7 +3090,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s3 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e91); }
+ if (peg$silentFails === 0) { peg$fail(peg$e92); }
}
}
s3 = [];
@@ -3073,7 +3099,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e92); }
+ if (peg$silentFails === 0) { peg$fail(peg$e93); }
}
while (s4 !== peg$FAILED) {
s3.push(s4);
@@ -3082,7 +3108,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s4 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e92); }
+ if (peg$silentFails === 0) { peg$fail(peg$e93); }
}
}
s4 = peg$parseoperator();
@@ -3101,7 +3127,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e93); }
+ if (peg$silentFails === 0) { peg$fail(peg$e94); }
}
while (s2 !== peg$FAILED) {
s1.push(s2);
@@ -3110,7 +3136,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e93); }
+ if (peg$silentFails === 0) { peg$fail(peg$e94); }
}
}
s2 = peg$currPos;
@@ -3157,7 +3183,7 @@ function peg$parse(input, options) {
peg$currPos++;
} else {
s0 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$e94); }
+ if (peg$silentFails === 0) { peg$fail(peg$e95); }
}
}
}
@@ -3176,7 +3202,7 @@ function peg$parse(input, options) {
// List fields where you cannot prefix it with "-" to negate it
const nonNegatableKeys = new Set([
- "type", "keyword", "groupCurrency", "groupBy"
+ "type", "keyword", "groupCurrency", "groupBy", "columns"
]);
function applyDefaults(filters) {
diff --git a/src/libs/SearchParser/searchParser.peggy b/src/libs/SearchParser/searchParser.peggy
index feaebbde833d..67a8a76455a3 100644
--- a/src/libs/SearchParser/searchParser.peggy
+++ b/src/libs/SearchParser/searchParser.peggy
@@ -38,7 +38,7 @@
// List fields where you cannot prefix it with "-" to negate it
const nonNegatableKeys = new Set([
- "type", "keyword", "groupCurrency", "groupBy"
+ "type", "keyword", "groupCurrency", "groupBy", "columns"
]);
function applyDefaults(filters) {
@@ -210,7 +210,7 @@ filterKey
return k;
}
-defaultKey "default key" = @(type / status / sortBy / sortOrder / policyID / groupBy)
+defaultKey "default key" = @(type / status / sortBy / sortOrder / policyID / groupBy / columns)
identifier
= (","+)? parts:(values / quotedString / alphanumeric)|1.., ","+| empty:(","+)? {
diff --git a/src/libs/SearchQueryUtils.ts b/src/libs/SearchQueryUtils.ts
index d908a8e4fd16..65e7905174cb 100644
--- a/src/libs/SearchQueryUtils.ts
+++ b/src/libs/SearchQueryUtils.ts
@@ -31,6 +31,7 @@ import FILTER_KEYS, {ALLOWED_TYPE_FILTERS, AMOUNT_FILTER_KEYS, DATE_FILTER_KEYS}
import type {SearchAdvancedFiltersKey} from '@src/types/form/SearchAdvancedFiltersForm';
import type * as OnyxTypes from '@src/types/onyx';
import type {SearchDataTypes} from '@src/types/onyx/SearchResults';
+import arraysEqual from '@src/utils/arraysEqual';
import {getCardFeedsForDisplay} from './CardFeedUtils';
import {getCardDescription} from './CardUtils';
import {convertToBackendAmount, convertToFrontendAmountAsInteger} from './CurrencyUtils';
@@ -373,6 +374,8 @@ function getQueryHashes(query: SearchQueryJSON): {primaryHash: number; recentSea
orderedQuery += ` ${CONST.SEARCH.SYNTAX_ROOT_KEYS.SORT_BY}:${query.sortBy}`;
orderedQuery += ` ${CONST.SEARCH.SYNTAX_ROOT_KEYS.SORT_ORDER}:${query.sortOrder}`;
+ orderedQuery += ` ${CONST.SEARCH.SYNTAX_ROOT_KEYS.COLUMNS}:${Array.isArray(query.columns) ? query.columns.join(',') : query.columns}`;
+
if (query.policyID) {
orderedQuery += ` ${CONST.SEARCH.SYNTAX_FILTER_KEYS.POLICY_ID}:${Array.isArray(query.policyID) ? query.policyID.join(',') : query.policyID} `;
}
@@ -560,7 +563,7 @@ function buildQueryStringFromFilterFormValues(filterValues: Partial(columns)];
+ filtersString.push(`${CONST.SEARCH.SYNTAX_ROOT_KEYS.COLUMNS}:${filterValueArray.map(sanitizeSearchValue).join(',')}`);
+ }
+
const mappedFilters = Object.entries(otherFilters)
.map(([filterKey, filterValue]) => {
const isNegated = filterKey.endsWith(CONST.SEARCH.NOT_MODIFIER);
@@ -678,7 +686,8 @@ function buildQueryStringFromFilterFormValues(filterValues: Partial 0
) {
@@ -964,6 +973,11 @@ function buildFilterFormValuesFromQuery(
filtersForm[FILTER_KEYS.GROUP_BY] = queryJSON.groupBy;
}
+ if (queryJSON.columns) {
+ const columns = [queryJSON.columns].flat();
+ filtersForm[FILTER_KEYS.COLUMNS] = columns;
+ }
+
return filtersForm;
}
@@ -1150,6 +1164,9 @@ function formatDefaultRawFilterSegment(rawFilter: RawQueryFilter, policies: Onyx
case CONST.SEARCH.SYNTAX_ROOT_KEYS.GROUP_BY:
userFriendlyKey = getUserFriendlyKey(CONST.SEARCH.SYNTAX_ROOT_KEYS.GROUP_BY);
break;
+ case CONST.SEARCH.SYNTAX_ROOT_KEYS.COLUMNS:
+ userFriendlyKey = getUserFriendlyKey(CONST.SEARCH.SYNTAX_ROOT_KEYS.COLUMNS);
+ break;
default:
userFriendlyKey = getUserFriendlyKey(rawFilter.key as SearchFilterKey);
break;
@@ -1181,7 +1198,7 @@ function buildUserReadableQueryString(
currentUserAccountID: number,
autoCompleteWithSpace = false,
) {
- const {type, status, groupBy, policyID, rawFilterList, flatFilters: filters} = queryJSON;
+ const {type, status, groupBy, policyID, rawFilterList, flatFilters: filters = []} = queryJSON;
if (rawFilterList && rawFilterList.length > 0) {
const segments: string[] = [];
@@ -1303,7 +1320,10 @@ function buildCannedSearchQuery({
* For example: "type:trip" is a canned query.
*/
function isCannedSearchQuery(queryJSON: SearchQueryJSON) {
- return !queryJSON.filters && !queryJSON.policyID && !queryJSON.status;
+ const selectedColumns = queryJSON.columns ?? [];
+ const defaultColumns = Object.values(CONST.SEARCH.DEFAULT_COLUMNS.EXPENSE_REPORT);
+ const hasCustomColumns = !arraysEqual(defaultColumns, selectedColumns) && selectedColumns.length > 0;
+ return !queryJSON.filters && !queryJSON.policyID && !queryJSON.status && !hasCustomColumns;
}
function isDefaultExpensesQuery(queryJSON: SearchQueryJSON) {
diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts
index c56ddd227646..288907d98c7c 100644
--- a/src/libs/SearchUIUtils.ts
+++ b/src/libs/SearchUIUtils.ts
@@ -8,6 +8,7 @@ import type {SingleSelectItem} from '@components/Search/FilterDropdowns/SingleSe
import type {
SearchAction,
SearchColumnType,
+ SearchCustomColumnIds,
SearchDateFilterKeys,
SearchDatePreset,
SearchGroupBy,
@@ -2048,6 +2049,24 @@ function getExpenseTypeTranslationKey(expenseType: ValueOf): TranslationPaths {
+ // eslint-disable-next-line default-case
+ switch (columnId) {
+ case CONST.SEARCH.CUSTOM_COLUMNS.DATE:
+ return 'common.date';
+ case CONST.SEARCH.CUSTOM_COLUMNS.STATUS:
+ return 'common.status';
+ case CONST.SEARCH.CUSTOM_COLUMNS.TITLE:
+ return 'common.title';
+ case CONST.SEARCH.CUSTOM_COLUMNS.FROM:
+ return 'common.from';
+ case CONST.SEARCH.CUSTOM_COLUMNS.TO:
+ return 'common.to';
+ case CONST.SEARCH.CUSTOM_COLUMNS.ACTION:
+ return 'common.action';
+ }
+}
+
type OverflowMenuIconsType = Record<'Pencil', IconAsset>;
/**
@@ -2417,20 +2436,41 @@ function getActionOptions(translate: LocaleContextProps['translate']) {
function getColumnsToShow(
currentAccountID: number | undefined,
data: OnyxTypes.SearchResults['data'] | OnyxTypes.Transaction[],
+ visibleColumns: SearchCustomColumnIds[] = [],
isExpenseReportView = false,
type?: SearchDataTypes,
): ColumnVisibility {
if (type === CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT) {
- return {
- [CONST.SEARCH.TABLE_COLUMNS.AVATAR]: true,
- [CONST.SEARCH.TABLE_COLUMNS.DATE]: true,
- [CONST.SEARCH.TABLE_COLUMNS.STATUS]: true,
- [CONST.SEARCH.TABLE_COLUMNS.TITLE]: true,
- [CONST.SEARCH.TABLE_COLUMNS.FROM]: true,
- [CONST.SEARCH.TABLE_COLUMNS.TO]: true,
- [CONST.SEARCH.TABLE_COLUMNS.TOTAL]: true,
- [CONST.SEARCH.TABLE_COLUMNS.ACTION]: true,
- };
+ const reportColumns = [
+ CONST.SEARCH.TABLE_COLUMNS.AVATAR,
+ CONST.SEARCH.TABLE_COLUMNS.DATE,
+ CONST.SEARCH.TABLE_COLUMNS.STATUS,
+ CONST.SEARCH.TABLE_COLUMNS.TITLE,
+ CONST.SEARCH.TABLE_COLUMNS.FROM,
+ CONST.SEARCH.TABLE_COLUMNS.TO,
+ CONST.SEARCH.TABLE_COLUMNS.TOTAL,
+ CONST.SEARCH.TABLE_COLUMNS.ACTION,
+ ];
+
+ // If there are no visible columns, everything should be visible
+ if (!visibleColumns.length) {
+ return Object.fromEntries(reportColumns.map((column) => [column, true]));
+ }
+
+ // If the user has set custom columns, toggle the visible columns on, with all other
+ // columns hidden by default
+ const columns: ColumnVisibility = {};
+ const requiredColumns = new Set([CONST.SEARCH.TABLE_COLUMNS.AVATAR, CONST.SEARCH.TABLE_COLUMNS.TOTAL]);
+
+ for (const columnId of reportColumns) {
+ columns[columnId] = requiredColumns.has(columnId);
+ }
+
+ for (const column of visibleColumns) {
+ columns[column as keyof ColumnVisibility] = true;
+ }
+
+ return columns;
}
if (type === CONST.SEARCH.DATA_TYPES.TASK) {
@@ -2485,6 +2525,7 @@ function getColumnsToShow(
};
const {moneyRequestReportActionsByTransactionID} = Array.isArray(data) ? {} : createReportActionsLookupMaps(data);
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
const updateColumns = (transaction: OnyxTypes.Transaction | SearchTransaction) => {
const merchant = transaction.modifiedMerchant ? transaction.modifiedMerchant : (transaction.merchant ?? '');
@@ -2722,6 +2763,7 @@ export {
getSettlementStatus,
getSettlementStatusBadgeProps,
getTransactionFromTransactionListItem,
+ getSearchColumnTranslationKey,
getTableMinWidth,
};
export type {SavedSearchMenuItem, SearchTypeMenuSection, SearchTypeMenuItem, SearchDateModifier, SearchDateModifierLower, SearchKey, ArchivedReportsIDSet};
diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts
index 93b81c8c3400..fd1532a5053a 100644
--- a/src/libs/actions/Search.ts
+++ b/src/libs/actions/Search.ts
@@ -951,6 +951,8 @@ function clearAdvancedFilters() {
switch (key) {
case FILTER_KEYS.GROUP_BY:
continue;
+ case FILTER_KEYS.COLUMNS:
+ continue;
case FILTER_KEYS.TYPE:
values[key] = CONST.SEARCH.DATA_TYPES.EXPENSE;
continue;
diff --git a/src/pages/Search/SearchColumnsPage.tsx b/src/pages/Search/SearchColumnsPage.tsx
new file mode 100644
index 000000000000..736a2466a7eb
--- /dev/null
+++ b/src/pages/Search/SearchColumnsPage.tsx
@@ -0,0 +1,133 @@
+import React, {useState} from 'react';
+import {View} from 'react-native';
+import Button from '@components/Button';
+import DotIndicatorMessage from '@components/DotIndicatorMessage';
+import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import ScreenWrapper from '@components/ScreenWrapper';
+import type {SearchCustomColumnIds} from '@components/Search/types';
+import type {ListItem} from '@components/SelectionList/types';
+import SelectionList from '@components/SelectionListWithSections';
+import MultiSelectListItem from '@components/SelectionListWithSections/MultiSelectListItem';
+import type {SectionListDataType} from '@components/SelectionListWithSections/types';
+import TextLink from '@components/TextLink';
+import useLocalize from '@hooks/useLocalize';
+import useOnyx from '@hooks/useOnyx';
+import useThemeStyles from '@hooks/useThemeStyles';
+import {clearAllFilters} from '@libs/actions/Search';
+import Navigation from '@libs/Navigation/Navigation';
+import {buildQueryStringFromFilterFormValues} from '@libs/SearchQueryUtils';
+import {getSearchColumnTranslationKey} from '@libs/SearchUIUtils';
+import CONST from '@src/CONST';
+import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
+import type {SearchAdvancedFiltersForm} from '@src/types/form';
+import arraysEqual from '@src/utils/arraysEqual';
+
+const allCustomColumns = Object.values(CONST.SEARCH.CUSTOM_COLUMNS);
+const defaultCustomColumns = Object.values(CONST.SEARCH.DEFAULT_COLUMNS.EXPENSE_REPORT);
+
+function SearchColumnsPage() {
+ const styles = useThemeStyles();
+ const {translate} = useLocalize();
+
+ const [searchAdvancedFiltersForm] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM, {canBeMissing: true});
+
+ const [selectedColumnIds, setSelectedColumnIds] = useState(() => {
+ const columnIds = searchAdvancedFiltersForm?.columns?.filter((columnId) => Object.values(CONST.SEARCH.CUSTOM_COLUMNS).includes(columnId)) ?? [];
+
+ // We dont allow the user to unselect all columns, so we can assume that no columns = default columns
+ if (!columnIds.length) {
+ return defaultCustomColumns;
+ }
+
+ return columnIds;
+ });
+
+ const sections: Array> = [
+ {
+ title: undefined,
+ data: allCustomColumns.map((columnId) => ({
+ text: translate(getSearchColumnTranslationKey(columnId)),
+ value: columnId,
+ keyForList: columnId,
+ isSelected: selectedColumnIds?.includes(columnId),
+ })),
+ },
+ ];
+
+ const sortedDefaultColumns = [...defaultCustomColumns].sort();
+ const sortedSelectedColumnIds = [...selectedColumnIds].sort();
+ const shouldShowResetColumns = !arraysEqual(sortedSelectedColumnIds, sortedDefaultColumns);
+
+ const onSelectItem = (item: ListItem) => {
+ const updatedColumnId = item.keyForList as SearchCustomColumnIds;
+
+ if (item.isSelected) {
+ setSelectedColumnIds(selectedColumnIds.filter((columnId) => columnId !== updatedColumnId));
+ } else {
+ setSelectedColumnIds([...selectedColumnIds, updatedColumnId]);
+ }
+ };
+
+ const resetColumns = () => {
+ setSelectedColumnIds(defaultCustomColumns);
+ };
+
+ const applyChanges = () => {
+ if (!selectedColumnIds.length) {
+ return;
+ }
+
+ const updatedAdvancedFilters: Partial = {...searchAdvancedFiltersForm, columns: selectedColumnIds};
+ const queryString = buildQueryStringFromFilterFormValues(updatedAdvancedFilters);
+
+ clearAllFilters();
+ Navigation.navigate(ROUTES.SEARCH_ROOT.getRoute({query: queryString}), {forceReplace: true});
+ };
+
+ return (
+
+
+ {shouldShowResetColumns && {translate('search.resetColumns')}}
+
+
+
+ {!selectedColumnIds.length && (
+
+ )}
+
+
+
+ }
+ />
+
+
+ );
+}
+
+SearchColumnsPage.displayName = 'SearchColumnsPage';
+
+export default SearchColumnsPage;
diff --git a/src/selectors/AdvancedSearchFiltersForm.ts b/src/selectors/AdvancedSearchFiltersForm.ts
new file mode 100644
index 000000000000..6ff050d3e7b6
--- /dev/null
+++ b/src/selectors/AdvancedSearchFiltersForm.ts
@@ -0,0 +1,7 @@
+import type {OnyxEntry} from 'react-native-onyx';
+import type {SearchAdvancedFiltersForm} from '@src/types/form';
+
+const columnsSelector = (form: OnyxEntry) => form?.columns;
+
+// eslint-disable-next-line import/prefer-default-export
+export {columnsSelector};
diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts
index 710200c6c7d7..5e2e98089d5f 100644
--- a/src/styles/utils/index.ts
+++ b/src/styles/utils/index.ts
@@ -1732,9 +1732,10 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({
columnWidth = {...getWidthStyle(variables.w80), ...styles.alignItemsCenter};
break;
case CONST.SEARCH.TABLE_COLUMNS.DATE:
+ // We will remove this variable & param, but in a follow up PR. We are duplicating the logic here to "use" the variable
+ // to prevent eslint errors. This will be removed
if (isDateColumnFullWidth) {
- columnWidth = styles.flex1;
- break;
+ columnWidth = {...getWidthStyle(isDateColumnWide ? variables.w92 : variables.w52)};
}
columnWidth = {...getWidthStyle(isDateColumnWide ? variables.w92 : variables.w52)};
break;
@@ -1747,7 +1748,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({
break;
case CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT:
case CONST.SEARCH.TABLE_COLUMNS.TOTAL:
- columnWidth = {...getWidthStyle(isAmountColumnWide ? variables.w130 : variables.w96), ...styles.alignItemsEnd};
+ columnWidth = {...getWidthStyle(isAmountColumnWide ? variables.w130 : variables.w96), ...styles.flex1, ...styles.alignItemsEnd};
break;
case CONST.SEARCH.TABLE_COLUMNS.TYPE:
columnWidth = {...getWidthStyle(variables.w20), ...styles.alignItemsCenter};
diff --git a/src/types/form/SearchAdvancedFiltersForm.ts b/src/types/form/SearchAdvancedFiltersForm.ts
index 43ef6a175942..b87cc82af563 100644
--- a/src/types/form/SearchAdvancedFiltersForm.ts
+++ b/src/types/form/SearchAdvancedFiltersForm.ts
@@ -5,6 +5,7 @@ import type {
ReportFieldNegatedKey,
ReportFieldTextKey,
SearchAmountFilterKeys,
+ SearchCustomColumnIds,
SearchDateFilterKeys,
SearchGroupBy,
SearchWithdrawalType,
@@ -164,6 +165,8 @@ const FILTER_KEYS = {
ATTENDEE_NOT: 'attendeeNot',
ATTENDEE: 'attendee',
REPORT_FIELD: 'reportField',
+
+ COLUMNS: 'columns',
} as const;
const ALLOWED_TYPE_FILTERS = {
@@ -261,6 +264,7 @@ const ALLOWED_TYPE_FILTERS = {
FILTER_KEYS.ATTENDEE,
FILTER_KEYS.REPORT_FIELD,
FILTER_KEYS.ATTENDEE_NOT,
+ FILTER_KEYS.COLUMNS,
],
[CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT]: [
FILTER_KEYS.TYPE,
@@ -316,6 +320,7 @@ const ALLOWED_TYPE_FILTERS = {
FILTER_KEYS.TITLE,
FILTER_KEYS.TITLE_NOT,
FILTER_KEYS.REPORT_FIELD,
+ FILTER_KEYS.COLUMNS,
],
[CONST.SEARCH.DATA_TYPES.INVOICE]: [
FILTER_KEYS.TYPE,
@@ -399,6 +404,7 @@ const ALLOWED_TYPE_FILTERS = {
FILTER_KEYS.TITLE,
FILTER_KEYS.REPORT_FIELD,
FILTER_KEYS.TITLE_NOT,
+ FILTER_KEYS.COLUMNS,
],
[CONST.SEARCH.DATA_TYPES.TRIP]: [
@@ -476,6 +482,7 @@ const ALLOWED_TYPE_FILTERS = {
FILTER_KEYS.TITLE,
FILTER_KEYS.TITLE_NOT,
FILTER_KEYS.REPORT_FIELD,
+ FILTER_KEYS.COLUMNS,
],
[CONST.SEARCH.DATA_TYPES.CHAT]: [
@@ -524,8 +531,8 @@ type SearchAdvancedFiltersForm = Form<
SearchAdvancedFiltersKey,
{
[FILTER_KEYS.GROUP_BY]: SearchGroupBy;
-
[FILTER_KEYS.TYPE]: SearchDataTypes;
+ [FILTER_KEYS.COLUMNS]: SearchCustomColumnIds[];
[FILTER_KEYS.STATUS]: string[] | string;
diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts
index fc6bb19fe607..ae7fcb2156aa 100644
--- a/tests/unit/Search/SearchUIUtilsTest.ts
+++ b/tests/unit/Search/SearchUIUtilsTest.ts
@@ -2566,6 +2566,36 @@ describe('SearchUIUtils', () => {
});
describe('Test getColumnsToShow', () => {
+ test('Should show all columns when no custom columns are saved & viewing expense reports', () => {
+ expect(SearchUIUtils.getColumnsToShow(1, [], [], false, CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT)).toEqual({
+ [CONST.SEARCH.TABLE_COLUMNS.AVATAR]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.DATE]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.STATUS]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.TITLE]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.FROM]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.TO]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.TOTAL]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.ACTION]: true,
+ });
+ });
+
+ test('Should show specific columns when custom columns are saved & viewing expense reports', () => {
+ const visibleColumns = [CONST.SEARCH.TABLE_COLUMNS.DATE, CONST.SEARCH.TABLE_COLUMNS.STATUS, CONST.SEARCH.TABLE_COLUMNS.TITLE];
+
+ expect(SearchUIUtils.getColumnsToShow(1, [], visibleColumns, false, CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT)).toEqual({
+ // Avatar should always be visible
+ [CONST.SEARCH.TABLE_COLUMNS.AVATAR]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.DATE]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.STATUS]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.TITLE]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.FROM]: false,
+ [CONST.SEARCH.TABLE_COLUMNS.TO]: false,
+ // Total should always be visible
+ [CONST.SEARCH.TABLE_COLUMNS.TOTAL]: true,
+ [CONST.SEARCH.TABLE_COLUMNS.ACTION]: false,
+ });
+ });
+
test('Should only show columns when at least one transaction has a value for them', () => {
// Use the existing transaction as a base and modify only the fields we need to test
const baseTransaction = searchResults.data[`transactions_${transactionID}`];
@@ -2649,7 +2679,7 @@ describe('SearchUIUtils', () => {
};
// Test 1: No optional fields should be shown when all transactions are empty
- let columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [emptyTransaction, emptyTransaction], false);
+ let columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [emptyTransaction, emptyTransaction], [], false);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.MERCHANT]).toBe(false);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.CATEGORY]).toBe(false);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.TAG]).toBe(false);
@@ -2658,22 +2688,22 @@ describe('SearchUIUtils', () => {
expect(columns[CONST.SEARCH.TABLE_COLUMNS.TO]).toBe(false);
// Test 2: Merchant column should show when at least one transaction has merchant
- columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [emptyTransaction, merchantTransaction], false);
+ columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [emptyTransaction, merchantTransaction], [], false);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.MERCHANT]).toBe(true);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.CATEGORY]).toBe(false);
// Test 3: Category column should show when at least one transaction has category
- columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [emptyTransaction, categoryTransaction], false);
+ columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [emptyTransaction, categoryTransaction], [], false);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.CATEGORY]).toBe(true);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.MERCHANT]).toBe(false);
// Test 4: Tag column should show when at least one transaction has tag
- columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [emptyTransaction, tagTransaction], false);
+ columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [emptyTransaction, tagTransaction], [], false);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.TAG]).toBe(true);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.CATEGORY]).toBe(false);
// Test 5: Description column should show when at least one transaction has description
- columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [emptyTransaction, descriptionTransaction], false);
+ columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [emptyTransaction, descriptionTransaction], [], false);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.DESCRIPTION]).toBe(true);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.MERCHANT]).toBe(false);
@@ -2686,12 +2716,12 @@ describe('SearchUIUtils', () => {
[`reportActions_${reportID2}`]: {[differentUsersTransactionIOUAction.reportActionID]: differentUsersTransactionIOUAction},
personalDetailsList: searchResults.data.personalDetailsList,
};
- columns = SearchUIUtils.getColumnsToShow(submitterAccountID, data, false);
+ columns = SearchUIUtils.getColumnsToShow(submitterAccountID, data, [], false);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.FROM]).toBe(true);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.TO]).toBe(true);
// Test 7: Multiple columns should show when transactions have different fields
- columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [merchantTransaction, categoryTransaction, tagTransaction], false);
+ columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [merchantTransaction, categoryTransaction, tagTransaction], [], false);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.MERCHANT]).toBe(true);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.CATEGORY]).toBe(true);
expect(columns[CONST.SEARCH.TABLE_COLUMNS.TAG]).toBe(true);
@@ -2714,7 +2744,7 @@ describe('SearchUIUtils', () => {
};
// In expense report view, From/To columns should not be shown
- const columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [testTransaction], true);
+ const columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [testTransaction], [], true);
// These columns should be shown based on data
expect(columns[CONST.REPORT.TRANSACTION_LIST.COLUMNS.MERCHANT]).toBe(true);
@@ -2741,7 +2771,7 @@ describe('SearchUIUtils', () => {
managerID: adminAccountID,
};
- const columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [testTransaction], false);
+ const columns = SearchUIUtils.getColumnsToShow(submitterAccountID, [testTransaction], [], false);
// Should show merchant column because modifiedMerchant has value
expect(columns[CONST.SEARCH.TABLE_COLUMNS.MERCHANT]).toBe(true);