diff --git a/src/languages/en.ts b/src/languages/en.ts index 855854c58dba..fdd67cb5393e 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -4593,6 +4593,12 @@ const translations = { greaterThan: ({amount}: OptionalParam = {}) => `Greater than ${amount ?? ''}`, between: ({greaterThan, lessThan}: FiltersAmountBetweenParams) => `Between ${greaterThan} and ${lessThan}`, }, + card: { + expensify: 'Expensify', + individualCards: 'Individual cards', + cardFeeds: 'Card feeds', + cardFeedName: (cardFeedBankName: string, cardFeedName?: string) => `All ${cardFeedBankName}${cardFeedName ? ` - ${cardFeedName}` : ''}`, + }, current: 'Current', past: 'Past', }, diff --git a/src/languages/es.ts b/src/languages/es.ts index 57ff99f80b6b..26f59e36fc41 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -4637,6 +4637,12 @@ const translations = { link: 'Enlace', pinned: 'Fijado', unread: 'No leído', + card: { + expensify: 'Expensify', + individualCards: 'Tarjetas individuales', + cardFeeds: 'Flujos de tarjetas', + cardFeedName: (cardFeedBankName: string, cardFeedName?: string) => `Todo ${cardFeedBankName}${cardFeedName ? ` - ${cardFeedName}` : ''}`, + }, amount: { lessThan: ({amount}: OptionalParam = {}) => `Menos de ${amount ?? ''}`, greaterThan: ({amount}: OptionalParam = {}) => `Más que ${amount ?? ''}`, diff --git a/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersCardPage.tsx b/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersCardPage.tsx index 9a6863f478f7..b229fe5dd460 100644 --- a/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersCardPage.tsx +++ b/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersCardPage.tsx @@ -9,7 +9,6 @@ import CardListItem from '@components/SelectionList/CardListItem'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as CardUtils from '@libs/CardUtils'; -import type {Section} from '@libs/OptionsListUtils'; import type {OptionData} from '@libs/ReportUtils'; import Navigation from '@navigation/Navigation'; import variables from '@styles/variables'; @@ -18,19 +17,62 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {CompanyCardFeed} from '@src/types/onyx'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; + +type SearchCardItemProps = Partial & {isCardFeed?: boolean; correspondingCards?: string[]}; function SearchFiltersCardPage() { const styles = useThemeStyles(); const {translate} = useLocalize(); - const [cardList] = useOnyx(ONYXKEYS.CARD_LIST); + const [userCardList] = useOnyx(ONYXKEYS.CARD_LIST); + const userCardListArray = Object.values(userCardList ?? {}); + + const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY); + const policyList = Object.values(policies ?? {}); + const [workspaceCardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); + const [searchAdvancedFiltersForm] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM); const currentCards = searchAdvancedFiltersForm?.cardID; const [newCards, setNewCards] = useState(currentCards ?? []); const sections = useMemo(() => { - const newSections: Section[] = []; - const cards = Object.values(cardList ?? {}) + const newSections = []; + + const cardFeedsSection = Object.entries(workspaceCardFeeds ?? {}) + .filter(([, expensifyCards]) => !isEmptyObject(expensifyCards)) + .map(([expensifyCardListKey, expensifyCards]) => { + const [, workspaceAccountID, bank] = expensifyCardListKey.split('_'); + const correspondingPolicy = policyList.find((policy) => policy?.workspaceAccountID?.toString() === workspaceAccountID); + const cardFeedBankName = bank === CONST.EXPENSIFY_CARD.BANK ? translate('search.filters.card.expensify') : CardUtils.getCardFeedName(bank as CompanyCardFeed); + const text = translate('search.filters.card.cardFeedName', cardFeedBankName, correspondingPolicy?.name); + const correspondingCards = Object.keys(expensifyCards ?? {}).filter((expensifyCardKey) => userCardListArray.some((card) => card.cardID.toString() === expensifyCardKey)); + let isSelected = true; + correspondingCards.forEach((card) => { + if (newCards.includes(card)) { + return; + } + isSelected = false; + }); + + const icon = CardUtils.getCardFeedIcon(bank as CompanyCardFeed | typeof CONST.EXPENSIFY_CARD.BANK); + return { + text, + keyForList: workspaceAccountID, + isSelected, + bankIcon: { + icon, + iconWidth: variables.cardIconWidth, + iconHeight: variables.cardIconHeight, + iconStyles: [styles.cardIcon], + }, + isCardFeed: true, + correspondingCards, + }; + }); + newSections.push({title: translate('search.filters.card.cardFeeds'), data: cardFeedsSection, shouldShow: cardFeedsSection.length > 0}); + + const cards = userCardListArray .sort((a, b) => a.bank.localeCompare(b.bank)) .map((card) => { const icon = CardUtils.getCardFeedIcon(card?.bank as CompanyCardFeed); @@ -49,15 +91,16 @@ function SearchFiltersCardPage() { iconHeight: variables.cardIconHeight, iconStyles: [styles.cardIcon], }, + isCardFeed: false, }; }); newSections.push({ - title: undefined, + title: translate('search.filters.card.individualCards'), data: cards, shouldShow: cards.length > 0, }); return newSections; - }, [cardList, styles, newCards]); + }, [workspaceCardFeeds, translate, userCardListArray, policyList, styles.cardIcon, newCards]); const handleConfirmSelection = useCallback(() => { SearchActions.updateAdvancedFilters({ @@ -68,14 +111,19 @@ function SearchFiltersCardPage() { }, [newCards]); const updateNewCards = useCallback( - (item: Partial) => { + (item: SearchCardItemProps) => { if (!item.keyForList) { return; } + + const isCardFeed = item?.isCardFeed && item?.correspondingCards; + if (item.isSelected) { - setNewCards(newCards.filter((card) => card !== item.keyForList)); + const newCardsObject = newCards.filter((card) => (isCardFeed ? !item.correspondingCards?.includes(card) : card !== item.keyForList)); + setNewCards(newCardsObject); } else { - setNewCards([...newCards, item.keyForList]); + const newCardsObject = isCardFeed ? [...newCards, ...(item?.correspondingCards ?? [])] : [...newCards, item.keyForList]; + setNewCards(newCardsObject); } }, [newCards], @@ -108,7 +156,7 @@ function SearchFiltersCardPage() { }} /> - sections={sections} onSelectRow={updateNewCards} footerContent={footerContent}