Skip to content
36 changes: 19 additions & 17 deletions src/components/ReportActionItem/ActionableItemButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import Button from '@components/Button';
import Button from '@components/ButtonComposed';
import type {ButtonTextProps} from '@components/ButtonComposed/primitives/ButtonText';
import type {ButtonStyleProps} from '@components/ButtonComposed/types';

import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';

import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';

import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
import type {StyleProp, ViewStyle} from 'react-native';

import React from 'react';
import {View} from 'react-native';
Expand All @@ -14,19 +17,19 @@ type ActionableItem = {
isPrimary?: boolean;
key: string;
onPress: () => void;
text: string;
shouldUseLocalization?: boolean;
};
} & ({translationKey: TranslationPaths; text?: never} | {text: string; translationKey?: never});

type ActionableItemButtonsProps = {
items: ActionableItem[];
layout?: 'horizontal' | 'vertical';
shouldUseLocalization?: boolean;
primaryTextNumberOfLines?: number;
styles?: {
text?: StyleProp<TextStyle>;
button?: StyleProp<ViewStyle>;
};

/** Props forwarded to the `Button` rendered for each item */
buttonProps?: Pick<ButtonStyleProps, 'innerStyles'>;

/** Props forwarded to the `Button.Text` rendered for each item */
textProps?: Pick<ButtonTextProps, 'numberOfLines' | 'style'>;

wrapperStyle?: StyleProp<ViewStyle>;
};

Expand All @@ -40,13 +43,12 @@ function ActionableItemButtons(props: ActionableItemButtonsProps) {
<Button
key={item.key}
onPress={item.onPress}
text={props.shouldUseLocalization ? translate(item.text as TranslationPaths) : item.text}
medium
success={item.isPrimary}
innerStyles={props.styles?.button}
primaryTextNumberOfLines={props.primaryTextNumberOfLines}
textStyles={props.styles?.text}
/>
size={CONST.BUTTON_SIZE.MEDIUM}
variant={item.isPrimary ? CONST.BUTTON_VARIANT.SUCCESS : undefined}
{...props.buttonProps}
>
<Button.Text {...props.textProps}>{item.translationKey ? translate(item.translationKey) : item.text}</Button.Text>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor localization for actionable buttons

When callers still pass translation keys in text and set shouldUseLocalization (for example join requests, fraud alerts, mention whispers, and the track-expense buttons in ChatActionableButtons), this branch no longer translates them because it only calls translate() for item.translationKey. Those existing callers were not migrated, so affected buttons will display raw keys such as actionableMentionTrackExpense.submit or common.yes instead of user-facing labels. Either keep honoring shouldUseLocalization here or update all callers to use translationKey.

Useful? React with 👍 / 👎.

</Button>
))}
</View>
);
Expand Down
17 changes: 10 additions & 7 deletions src/components/ReportActionItem/IssueCardMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Button from '@components/Button';
import Button from '@components/ButtonComposed';
import {useSession} from '@components/OnyxListItemProvider';
import RenderHTML from '@components/RenderHTML';

Expand All @@ -15,6 +15,7 @@ import type {ReportsSplitNavigatorParamList} from '@libs/Navigation/types';
import {isPolicyAdmin} from '@libs/PolicyUtils';
import {getCardIssuedMessage, getOriginalMessage, shouldShowActivateCard, shouldShowAddMissingDetails} from '@libs/ReportActionsUtils';

import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
Expand Down Expand Up @@ -63,10 +64,11 @@ function IssueCardMessage({action, policyID}: IssueCardMessageProps) {
onPress={() => {
Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.MISSING_PERSONAL_DETAILS.getRoute(String(expensifyCard.cardID))));
}}
success
variant={CONST.BUTTON_VARIANT.SUCCESS}
style={[styles.alignSelfStart, styles.mt3]}
text={translate('workspace.expensifyCard.addShippingDetails')}
/>
>
<Button.Text>{translate('workspace.expensifyCard.addShippingDetails')}</Button.Text>
</Button>
)}
{shouldShowActivateButton && (
<Button
Expand All @@ -76,10 +78,11 @@ function IssueCardMessage({action, policyID}: IssueCardMessageProps) {
}
Navigation.navigate(ROUTES.REPORT_CARD_ACTIVATE.getRoute(expensifyCard.cardID, route.params?.reportID, route.params?.reportActionID));
}}
success
variant={CONST.BUTTON_VARIANT.SUCCESS}
style={[styles.alignSelfStart, styles.mt3]}
text={translate('activateCardPage.activateCard')}
/>
>
<Button.Text>{translate('activateCardPage.activateCard')}</Button.Text>
</Button>
)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Button from '@components/Button';
import Button from '@components/ButtonComposed';
import Icon from '@components/Icon';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ReportActionAvatars from '@components/ReportActionAvatars';
Expand Down Expand Up @@ -445,11 +445,12 @@ function TransactionPreviewContent({
)}
{isReviewDuplicateTransactionPage && !isIOUSettled && !isApproved && !isCardTransaction && areThereDuplicates && (
<Button
text={translate('violations.keepThisOne')}
success
variant={CONST.BUTTON_VARIANT.SUCCESS}
style={[styles.ph4, styles.pb4]}
onPress={navigateToReviewFields}
/>
>
<Button.Text>{translate('violations.keepThisOne')}</Button.Text>
</Button>
)}
</View>
</OfflineWithFeedback>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import AmountWithoutCurrencyInput from '@components/AmountWithoutCurrencyInput';
import Button from '@components/Button';
import Button from '@components/ButtonComposed';
import ScrollView from '@components/ScrollView';
import type {SearchAmountFilterKeys, SearchAmountValues} from '@components/Search/types';
import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
Expand Down Expand Up @@ -246,12 +246,13 @@ function AmountFilterContent({baseFilterKey, value, autoFocus, largeButton, styl
</ScrollView>
<Button
style={[styles.ph5, styles.pb5]}
success
large={largeButton}
text={translate('common.confirm')}
pressOnEnter
variant={CONST.BUTTON_VARIANT.SUCCESS}
size={largeButton ? CONST.BUTTON_SIZE.LARGE : undefined}
onPress={updateAmountFilter}
/>
>
<Button.KeyboardShortcut />
<Button.Text>{translate('common.confirm')}</Button.Text>
</Button>
</View>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Button from '@components/Button';
import Button from '@components/ButtonComposed';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import DateFilterBase from '@components/Search/FilterComponents/DateFilterBase';
import type {DateFilterBaseHandle} from '@components/Search/FilterComponents/DateFilterBase';
Expand All @@ -12,22 +12,25 @@
import {getDatePresets} from '@libs/SearchUIUtils';
import type {SearchDateModifier} from '@libs/SearchUIUtils';

import CONST from '@src/CONST';

import type {StyleProp, ViewStyle} from 'react-native';

import React, {useRef} from 'react';
import {ValueOf} from 'type-fest';

Check failure on line 20 in src/components/Search/FilterComponents/AdvancedFilters/DateFilterContent.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

All imports in the declaration are only used as types. Use `import type`

Check failure on line 20 in src/components/Search/FilterComponents/AdvancedFilters/DateFilterContent.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

All imports in the declaration are only used as types. Use `import type`

type DateFilterContentProps = {
baseFilterKey: SearchDateFilterKeys;
value: SearchDateValues;
selectedDateModifier: SearchDateModifier | null;
hasFeed: boolean;
largeButton?: boolean;
size?: Exclude<ValueOf<typeof CONST.BUTTON_SIZE>, typeof CONST.BUTTON_SIZE.SMALL>;
style?: StyleProp<ViewStyle>;
onDateModifierSelected: (modifier: SearchDateModifier | null) => void;
onChange: (values: SearchDateValues) => void;
};

function DateFilterContent({baseFilterKey, value, selectedDateModifier, hasFeed, largeButton, style, onDateModifierSelected, onChange}: DateFilterContentProps) {
function DateFilterContent({baseFilterKey, value, selectedDateModifier, hasFeed, size, style, onDateModifierSelected, onChange}: DateFilterContentProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const dateFilterRef = useRef<DateFilterBaseHandle>(null);
Expand Down Expand Up @@ -61,12 +64,13 @@
{!!selectedDateModifier && (
<Button
style={[styles.ph5, styles.pb5, styles.pt3]}
text={translate('common.apply')}
success
large={largeButton}
pressOnEnter
variant={CONST.BUTTON_VARIANT.SUCCESS}
size={size}
onPress={() => dateFilterRef.current?.save()}
/>
>
<Button.KeyboardShortcut />
<Button.Text>{translate('common.apply')}</Button.Text>
</Button>
)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
import Button from '@components/Button';
import Button from '@components/ButtonComposed';
import ReportFieldBase from '@components/Search/FilterComponents/ReportField';
import type {ReportFieldHandle} from '@components/Search/FilterComponents/ReportField';

import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';

import CONST from '@src/CONST';
import type {SearchAdvancedFiltersForm} from '@src/types/form';
import type {PolicyReportField} from '@src/types/onyx';

import type {StyleProp, ViewStyle} from 'react-native';

import React, {useRef, useState} from 'react';
import {ValueOf} from 'type-fest';

Check failure on line 15 in src/components/Search/FilterComponents/AdvancedFilters/ReportFieldFilterContent.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

All imports in the declaration are only used as types. Use `import type`

Check failure on line 15 in src/components/Search/FilterComponents/AdvancedFilters/ReportFieldFilterContent.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

All imports in the declaration are only used as types. Use `import type`

type ReportFieldFilterContentProps = {
values: Partial<SearchAdvancedFiltersForm> | undefined;
selectedField: PolicyReportField | null;
largeButton?: boolean;
size?: Exclude<ValueOf<typeof CONST.BUTTON_SIZE>, typeof CONST.BUTTON_SIZE.SMALL>;
style?: StyleProp<ViewStyle>;
onFieldSelected: (field: PolicyReportField | null) => void;
onChange: (values: Partial<SearchAdvancedFiltersForm>) => void;
};

function ReportFieldFilterContent({values, selectedField, largeButton, style, onFieldSelected, onChange}: ReportFieldFilterContentProps) {
function ReportFieldFilterContent({values, selectedField, size, style, onFieldSelected, onChange}: ReportFieldFilterContentProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const reportFieldRef = useRef<ReportFieldHandle>(null);
Expand All @@ -42,10 +44,8 @@
{!!selectedField && (
<Button
style={[styles.ph5, styles.pb5, styles.pt3, styles.mtAuto]}
success
large={largeButton}
text={translate('common.apply')}
pressOnEnter
variant={CONST.BUTTON_VARIANT.SUCCESS}
size={size}
onPress={() => {
if (error) {
return;
Expand All @@ -58,7 +58,10 @@

onChange(value);
}}
/>
>
<Button.KeyboardShortcut />
<Button.Text>{translate('common.apply')}</Button.Text>
</Button>
)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Button from '@components/Button';
import Button from '@components/ButtonComposed';
import NegatableFilter from '@components/Search/FilterComponents/NegatableFilter';
import useTextFilterValidation from '@components/Search/hooks/useTextFilterValidation';
import type {ReportFieldTextKey, SearchTextFilterKeys} from '@components/Search/types';
Expand All @@ -17,12 +17,13 @@

import React, {useState} from 'react';
import {View} from 'react-native';
import {ValueOf} from 'type-fest';

Check failure on line 20 in src/components/Search/FilterComponents/AdvancedFilters/TextInputFilterContent.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

All imports in the declaration are only used as types. Use `import type`

Check failure on line 20 in src/components/Search/FilterComponents/AdvancedFilters/TextInputFilterContent.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

All imports in the declaration are only used as types. Use `import type`

type TextInputFilterContentProps = {
baseFilterKey: Exclude<SearchTextFilterKeys, typeof CONST.SEARCH.SYNTAX_ROOT_KEYS.LIMIT | ReportFieldTextKey>;
value: string | undefined;
isNegated: boolean;
largeButton?: boolean;
size?: Exclude<ValueOf<typeof CONST.BUTTON_SIZE>, typeof CONST.BUTTON_SIZE.SMALL>;
autoFocus?: boolean;
style?: StyleProp<ViewStyle>;
onChange: (value: string | undefined, isNegated: boolean) => void;
Expand All @@ -32,7 +33,7 @@
return !!element && 'isFocused' in element;
}

function TextInputFilterContent({baseFilterKey, value: initialValue, isNegated: initialIsNegated, autoFocus, largeButton, style, onChange}: TextInputFilterContentProps) {
function TextInputFilterContent({baseFilterKey, value: initialValue, isNegated: initialIsNegated, autoFocus, size, style, onChange}: TextInputFilterContentProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const [value, setValue] = useState(initialValue);
Expand Down Expand Up @@ -68,17 +69,18 @@
</NegatableFilter>
<Button
style={[styles.ph5, styles.pb5]}
success
large={largeButton}
text={translate('common.confirm')}
pressOnEnter
variant={CONST.BUTTON_VARIANT.SUCCESS}
size={size}
onPress={() => {
if (error) {
return;
}
onChange(value, isNegated);
}}
/>
>
<Button.KeyboardShortcut />
<Button.Text>{translate('common.confirm')}</Button.Text>
</Button>
</View>
);
}
Expand Down
9 changes: 5 additions & 4 deletions src/components/Search/FilterComponents/DateFilterBase.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Button from '@components/Button';
import Button from '@components/ButtonComposed';
import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton';
import FormHelpMessage from '@components/FormHelpMessage';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
Expand Down Expand Up @@ -257,11 +257,12 @@ function DateFilterBase({
<>
{!selectedDateModifier && (
<Button
text={translate('common.reset')}
onPress={reset}
style={[styles.mh4, styles.mt4]}
large
/>
size={CONST.BUTTON_SIZE.LARGE}
>
<Button.Text>{translate('common.reset')}</Button.Text>
</Button>
)}
<FormAlertWithSubmitButton
buttonText={translate('common.save')}
Expand Down
20 changes: 12 additions & 8 deletions src/components/Search/FilterDropdowns/ActionButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import Button from '@components/Button';
import Button from '@components/ButtonComposed';

import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';

import CONST from '@src/CONST';

import React from 'react';
import {View} from 'react-native';

Expand All @@ -22,21 +24,23 @@ function ActionButtons({containerStyle, resetSentryLabel, applySentryLabel, onRe
<View style={containerStyle}>
{!!onReset && (
<Button
medium
size={CONST.BUTTON_SIZE.MEDIUM}
style={[styles.flex1]}
text={translate('common.reset')}
onPress={onReset}
sentryLabel={resetSentryLabel}
/>
>
<Button.Text>{translate('common.reset')}</Button.Text>
</Button>
)}
<Button
success
medium
variant={CONST.BUTTON_VARIANT.SUCCESS}
size={CONST.BUTTON_SIZE.MEDIUM}
style={[styles.flex1]}
text={translate('common.apply')}
onPress={onApply}
sentryLabel={applySentryLabel}
/>
>
<Button.Text>{translate('common.apply')}</Button.Text>
</Button>
</View>
);
}
Expand Down
Loading
Loading