Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Pay button does not change to Review button #55500

Merged
merged 10 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,12 @@ const ROUTES = {
},
SETTINGS_TAGS_ROOT: {
route: 'settings/:policyID/tags',
getRoute: (policyID: string, backTo = '') => getUrlWithBackToParam(`settings/${policyID}/tags`, backTo),
getRoute: (policyID: string | undefined, backTo = '') => {
if (!policyID) {
Log.warn('Invalid policyID while building route SETTINGS_TAGS_ROOT');
}
return getUrlWithBackToParam(`settings/${policyID}/tags`, backTo);
},
},
SETTINGS_TAGS_SETTINGS: {
route: 'settings/:policyID/tags/settings',
Expand Down Expand Up @@ -669,8 +674,11 @@ const ROUTES = {
},
MONEY_REQUEST_STEP_TAG: {
route: ':action/:iouType/tag/:orderWeight/:transactionID/:reportID/:reportActionID?',
getRoute: (action: IOUAction, iouType: IOUType, orderWeight: number, transactionID: string, reportID: string, backTo = '', reportActionID?: string) =>
getUrlWithBackToParam(`${action as string}/${iouType as string}/tag/${orderWeight}/${transactionID}/${reportID}${reportActionID ? `/${reportActionID}` : ''}`, backTo),
getRoute: (action: IOUAction, iouType: IOUType, orderWeight: number, transactionID: string, reportID?: string, backTo = '', reportActionID?: string) =>
getUrlWithBackToParam(
`${action as string}/${iouType as string}/tag/${orderWeight}/${transactionID}${reportID ? `/${reportID}` : ''}${reportActionID ? `/${reportActionID}` : ''}`,
backTo,
),
},
MONEY_REQUEST_STEP_WAYPOINT: {
route: ':action/:iouType/waypoint/:transactionID/:reportID/:pageIndex',
Expand Down
20 changes: 10 additions & 10 deletions src/components/TagPicker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import SelectionList from '@components/SelectionList';
import RadioListItem from '@components/SelectionList/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as OptionsListUtils from '@libs/OptionsListUtils';
import * as PolicyUtils from '@libs/PolicyUtils';
import type * as ReportUtils from '@libs/ReportUtils';
import {getHeaderMessageForNonUserList} from '@libs/OptionsListUtils';
import {getCountOfEnabledTagsOfList, getTagList} from '@libs/PolicyUtils';
import type {OptionData} from '@libs/ReportUtils';
import type {SelectedTagOption} from '@libs/TagsOptionsListUtils';
import * as TagOptionListUtils from '@libs/TagsOptionsListUtils';
import {getTagListSections} from '@libs/TagsOptionsListUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PolicyTag, PolicyTags} from '@src/types/onyx';
Expand All @@ -17,7 +17,7 @@ type TagPickerProps = {
/** The policyID we are getting tags for */
// It's used in withOnyx HOC.
// eslint-disable-next-line react/no-unused-prop-types
policyID: string;
policyID: string | undefined;

/** The selected tag of the expense */
selectedTag: string;
Expand All @@ -26,7 +26,7 @@ type TagPickerProps = {
tagListName: string;

/** Callback to submit the selected tag */
onSubmit: (selectedTag: Partial<ReportUtils.OptionData>) => void;
onSubmit: (selectedTag: Partial<OptionData>) => void;

/** Should show the selected option that is disabled? */
shouldShowDisabledAndSelectedOption?: boolean;
Expand All @@ -46,8 +46,8 @@ function TagPicker({selectedTag, tagListName, policyID, tagListIndex, shouldShow
const [searchValue, setSearchValue] = useState('');

const policyRecentlyUsedTagsList = useMemo(() => policyRecentlyUsedTags?.[tagListName] ?? [], [policyRecentlyUsedTags, tagListName]);
const policyTagList = PolicyUtils.getTagList(policyTags, tagListIndex);
const policyTagsCount = PolicyUtils.getCountOfEnabledTagsOfList(policyTagList.tags);
const policyTagList = getTagList(policyTags, tagListIndex);
const policyTagsCount = getCountOfEnabledTagsOfList(policyTagList.tags);
const isTagsCountBelowThreshold = policyTagsCount < CONST.STANDARD_LIST_ITEM_LIMIT;

const shouldShowTextInput = !isTagsCountBelowThreshold;
Expand Down Expand Up @@ -76,7 +76,7 @@ function TagPicker({selectedTag, tagListName, policyID, tagListIndex, shouldShow
}, [selectedOptions, policyTagList, shouldShowDisabledAndSelectedOption]);

const sections = useMemo(() => {
const tagSections = TagOptionListUtils.getTagListSections({
const tagSections = getTagListSections({
searchValue,
selectedOptions,
tags: enabledTags,
Expand All @@ -90,7 +90,7 @@ function TagPicker({selectedTag, tagListName, policyID, tagListIndex, shouldShow
: tagSections;
}, [searchValue, selectedOptions, enabledTags, policyRecentlyUsedTagsList, shouldOrderListByTagName]);

const headerMessage = OptionsListUtils.getHeaderMessageForNonUserList((sections?.at(0)?.data?.length ?? 0) > 0, searchValue);
const headerMessage = getHeaderMessageForNonUserList((sections?.at(0)?.data?.length ?? 0) > 0, searchValue);

const selectedOptionKey = sections.at(0)?.data?.filter((policyTag) => policyTag.searchText === selectedTag)?.[0]?.keyForList;

Expand Down
46 changes: 34 additions & 12 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3214,6 +3214,7 @@ function getUpdateMoneyRequestParams(
policyTagList: OnyxTypes.OnyxInputOrEntry<OnyxTypes.PolicyTagLists>,
policyCategories: OnyxTypes.OnyxInputOrEntry<OnyxTypes.PolicyCategories>,
violations?: OnyxEntry<OnyxTypes.TransactionViolations>,
hash?: number,
): UpdateMoneyRequestData {
const optimisticData: OnyxUpdate[] = [];
const successData: OnyxUpdate[] = [];
Expand Down Expand Up @@ -3517,21 +3518,40 @@ function getUpdateMoneyRequestParams(

if (policy && isPaidGroupPolicy(policy) && updatedTransaction && (hasModifiedTag || hasModifiedCategory || hasModifiedDistanceRate)) {
const currentTransactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`] ?? [];
optimisticData.push(
ViolationsUtils.getViolationsOnyxData(
updatedTransaction,
currentTransactionViolations,
policy,
policyTagList ?? {},
policyCategories ?? {},
hasDependentTags(policy, policyTagList ?? {}),
),
const violationsOnyxdata = ViolationsUtils.getViolationsOnyxData(
updatedTransaction,
currentTransactionViolations,
policy,
policyTagList ?? {},
policyCategories ?? {},
hasDependentTags(policy, policyTagList ?? {}),
);
optimisticData.push(violationsOnyxdata);
failureData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`,
value: currentTransactionViolations,
});
if (hash) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@nkdengineer as mentioned here, we need to pass the hash in all commands that call getUpdateMoneyRequestParams

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i updated

optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`,
value: {
data: {
[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`]: violationsOnyxdata.value,
},
},
});
failureData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${hash}`,
value: {
data: {
[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`]: currentTransactionViolations,
},
},
});
}
}

// Reset the transaction thread to its original state
Expand Down Expand Up @@ -3805,16 +3825,17 @@ function updateMoneyRequestAttendees(
/** Updates the tag of an expense */
function updateMoneyRequestTag(
transactionID: string,
transactionThreadReportID: string,
transactionThreadReportID: string | undefined,
tag: string,
policy: OnyxEntry<OnyxTypes.Policy>,
policyTagList: OnyxEntry<OnyxTypes.PolicyTagLists>,
policyCategories: OnyxEntry<OnyxTypes.PolicyCategories>,
hash?: number,
) {
const transactionChanges: TransactionChanges = {
tag,
};
const {params, onyxData} = getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, transactionChanges, policy, policyTagList, policyCategories);
const {params, onyxData} = getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, transactionChanges, policy, policyTagList, policyCategories, undefined, hash);
API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_TAG, params, onyxData);
}

Expand Down Expand Up @@ -3941,12 +3962,13 @@ function updateMoneyRequestCategory(
policy: OnyxEntry<OnyxTypes.Policy>,
policyTagList: OnyxEntry<OnyxTypes.PolicyTagLists>,
policyCategories: OnyxEntry<OnyxTypes.PolicyCategories>,
hash?: number,
) {
const transactionChanges: TransactionChanges = {
category,
};

const {params, onyxData} = getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, transactionChanges, policy, policyTagList, policyCategories);
const {params, onyxData} = getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, transactionChanges, policy, policyTagList, policyCategories, undefined, hash);
API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_CATEGORY, params, onyxData);
}

Expand Down
48 changes: 25 additions & 23 deletions src/pages/iou/request/step/IOURequestStepCategory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@ import Button from '@components/Button';
import CategoryPicker from '@components/CategoryPicker';
import FixedFooter from '@components/FixedFooter';
import * as Illustrations from '@components/Icon/Illustrations';
import {useSearchContext} from '@components/Search/SearchContext';
import type {ListItem} from '@components/SelectionList/types';
import Text from '@components/Text';
import WorkspaceEmptyStateSection from '@components/WorkspaceEmptyStateSection';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {getIOURequestPolicyID, setDraftSplitTransaction, setMoneyRequestCategory, updateMoneyRequestCategory} from '@libs/actions/IOU';
import {enablePolicyCategories, getPolicyCategories} from '@libs/actions/Policy/Category';
import Navigation from '@libs/Navigation/Navigation';
import * as OptionsListUtils from '@libs/OptionsListUtils';
import * as PolicyUtils from '@libs/PolicyUtils';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import * as TransactionUtils from '@libs/TransactionUtils';
import * as IOU from '@userActions/IOU';
import * as Category from '@userActions/Policy/Category';
import {hasEnabledOptions} from '@libs/OptionsListUtils';
import {isPolicyAdmin} from '@libs/PolicyUtils';
import {isMoneyRequestAction} from '@libs/ReportActionsUtils';
import {canEditMoneyRequest, getTransactionDetails, isGroupPolicy, isReportInGroupPolicy} from '@libs/ReportUtils';
import {areRequiredFieldsEmpty} from '@libs/TransactionUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
Expand All @@ -43,12 +44,12 @@ function IOURequestStepCategory({
},
transaction,
}: IOURequestStepCategoryProps) {
const [policyReal] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${getIOURequestPolicyID(transaction, reportReal)}`);
const [policyDraft] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${getIOURequestPolicyID(transaction, reportDraft)}`);
const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`);
const [policyReal] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${IOU.getIOURequestPolicyID(transaction, reportReal)}`);
const [policyDraft] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${IOU.getIOURequestPolicyID(transaction, reportDraft)}`);
const [policyCategoriesReal] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${IOU.getIOURequestPolicyID(transaction, reportReal)}`);
const [policyCategoriesDraft] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES_DRAFT}${IOU.getIOURequestPolicyID(transaction, reportDraft)}`);
const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${IOU.getIOURequestPolicyID(transaction, reportReal)}`);
const [policyCategoriesReal] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${getIOURequestPolicyID(transaction, reportReal)}`);
const [policyCategoriesDraft] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES_DRAFT}${getIOURequestPolicyID(transaction, reportDraft)}`);
const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${getIOURequestPolicyID(transaction, reportReal)}`);
let reportID = '-1';
if (action === CONST.IOU.ACTION.EDIT && reportReal) {
if (iouType === CONST.IOU.TYPE.SPLIT) {
Expand All @@ -63,34 +64,35 @@ function IOURequestStepCategory({
const report = reportReal ?? reportDraft;
const policy = policyReal ?? policyDraft;
const policyCategories = policyCategoriesReal ?? policyCategoriesDraft;
const {currentSearchHash} = useSearchContext();
const styles = useThemeStyles();
const theme = useTheme();
const {translate} = useLocalize();
const isEditing = action === CONST.IOU.ACTION.EDIT;
const isEditingSplitBill = isEditing && iouType === CONST.IOU.TYPE.SPLIT;
const currentTransaction = isEditingSplitBill && !lodashIsEmpty(splitDraftTransaction) ? splitDraftTransaction : transaction;
const transactionCategory = ReportUtils.getTransactionDetails(currentTransaction)?.category;
const transactionCategory = getTransactionDetails(currentTransaction)?.category;

// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const reportAction = reportActions?.[report?.parentReportActionID || reportActionID] ?? null;

const shouldShowCategory =
(ReportUtils.isReportInGroupPolicy(report) || ReportUtils.isGroupPolicy(policy?.type ?? '')) &&
(isReportInGroupPolicy(report) || isGroupPolicy(policy?.type ?? '')) &&
// The transactionCategory can be an empty string, so to maintain the logic we'd like to keep it in this shape until utils refactor
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
(!!transactionCategory || OptionsListUtils.hasEnabledOptions(Object.values(policyCategories ?? {})));
(!!transactionCategory || hasEnabledOptions(Object.values(policyCategories ?? {})));

const isSplitBill = iouType === CONST.IOU.TYPE.SPLIT;
const canEditSplitBill = isSplitBill && reportAction && session?.accountID === reportAction.actorAccountID && TransactionUtils.areRequiredFieldsEmpty(transaction);
const canEditSplitBill = isSplitBill && reportAction && session?.accountID === reportAction.actorAccountID && areRequiredFieldsEmpty(transaction);
// eslint-disable-next-line rulesdir/no-negated-variables
const shouldShowNotFoundPage = isEditing && (isSplitBill ? !canEditSplitBill : !ReportActionsUtils.isMoneyRequestAction(reportAction) || !ReportUtils.canEditMoneyRequest(reportAction));
const shouldShowNotFoundPage = isEditing && (isSplitBill ? !canEditSplitBill : !isMoneyRequestAction(reportAction) || !canEditMoneyRequest(reportAction));

const fetchData = () => {
if ((!!policy && !!policyCategories) || !report?.policyID) {
return;
}

Category.getPolicyCategories(report?.policyID);
getPolicyCategories(report?.policyID);
};
const {isOffline} = useNetwork({onReconnect: fetchData});
const isLoading = !isOffline && policyCategories === undefined;
Expand All @@ -114,19 +116,19 @@ function IOURequestStepCategory({
if (transaction) {
// In the split flow, when editing we use SPLIT_TRANSACTION_DRAFT to save draft value
if (isEditingSplitBill) {
IOU.setDraftSplitTransaction(transaction.transactionID, {category: updatedCategory}, policy);
setDraftSplitTransaction(transaction.transactionID, {category: updatedCategory}, policy);
navigateBack();
return;
}

if (isEditing && report) {
IOU.updateMoneyRequestCategory(transaction.transactionID, report.reportID, updatedCategory, policy, policyTags, policyCategories);
updateMoneyRequestCategory(transaction.transactionID, report.reportID, updatedCategory, policy, policyTags, policyCategories, currentSearchHash);
navigateBack();
return;
}
}

IOU.setMoneyRequestCategory(transactionID, updatedCategory, policy?.id);
setMoneyRequestCategory(transactionID, updatedCategory, policy?.id);

if (action === CONST.IOU.ACTION.CATEGORIZE) {
if (report?.reportID) {
Expand Down Expand Up @@ -164,7 +166,7 @@ function IOURequestStepCategory({
subtitle={translate('workspace.categories.emptyCategories.subtitle')}
containerStyle={[styles.flex1, styles.justifyContentCenter]}
/>
{PolicyUtils.isPolicyAdmin(policy) && (
{isPolicyAdmin(policy) && (
<FixedFooter style={[styles.mtAuto, styles.pt5]}>
<Button
large
Expand All @@ -176,7 +178,7 @@ function IOURequestStepCategory({
}

if (!policy.areCategoriesEnabled) {
Category.enablePolicyCategories(policy.id, true, false);
enablePolicyCategories(policy.id, true, false);
}
InteractionManager.runAfterInteractions(() => {
Navigation.navigate(
Expand Down
Loading
Loading