Skip to content

Commit

Permalink
Merge pull request #36978 from Expensify/yuwen-splitTags
Browse files Browse the repository at this point in the history
Implement same tag splitting logic we have in the API

(cherry picked from commit 4a885f5)
  • Loading branch information
yuwenmemon authored and OSBotify committed Feb 23, 2024
1 parent 366032f commit 821a44b
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
<MenuItemWithTopDescription
key={name}
shouldShowRightIcon={!isReadOnly}
title={TransactionUtils.getTag(transaction, index)}
title={TransactionUtils.getTagForDisplay(transaction, index)}
description={name}
numberOfLinesTitle={2}
onPress={() =>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ function MoneyRequestView({
>
<MenuItemWithTopDescription
description={name ?? translate('common.tag')}
title={TransactionUtils.getTag(transaction, index)}
title={TransactionUtils.getTagForDisplay(transaction, index)}
interactive={canEdit}
shouldShowRightIcon={canEdit}
titleStyle={styles.flex1}
Expand Down
16 changes: 8 additions & 8 deletions src/libs/IOUUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,18 @@ function isValidMoneyRequestType(iouType: string): boolean {
}

/**
* Inserts a newly selected tag into the already existed report tags like a string
* Inserts a newly selected tag into the already existing tags like a string
*
* @param reportTags - currently selected tags for a report
* @param tag - a newly selected tag, that should be added to the reportTags
* @param transactionTags - currently selected tags for a report
* @param tag - a newly selected tag, that should be added to the transactionTags
* @param tagIndex - the index of a tag list
* @returns
*/
function insertTagIntoReportTagsString(reportTags: string, tag: string, tagIndex: number): string {
const splittedReportTags = reportTags.split(CONST.COLON);
splittedReportTags[tagIndex] = tag;
function insertTagIntoTransactionTagsString(transactionTags: string, tag: string, tagIndex: number): string {
const tagArray = TransactionUtils.getTagArrayFromName(transactionTags);
tagArray[tagIndex] = tag;

return splittedReportTags.join(CONST.COLON).replace(/:*$/, '');
return tagArray.join(CONST.COLON).replace(/:*$/, '');
}

export {calculateAmount, updateIOUOwnerAndTotal, isIOUReportPendingCurrencyConversion, isValidMoneyRequestType, navigateToStartMoneyRequestStep, insertTagIntoReportTagsString};
export {calculateAmount, updateIOUOwnerAndTotal, isIOUReportPendingCurrencyConversion, isValidMoneyRequestType, navigateToStartMoneyRequestStep, insertTagIntoTransactionTagsString};
5 changes: 3 additions & 2 deletions src/libs/ModifiedExpenseMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as Localize from './Localize';
import * as PolicyUtils from './PolicyUtils';
import * as ReportUtils from './ReportUtils';
import type {ExpenseOriginalMessage} from './ReportUtils';
import * as TransactionUtils from './TransactionUtils';

let allPolicyTags: OnyxCollection<PolicyTagList> = {};
Onyx.connect({
Expand Down Expand Up @@ -189,8 +190,8 @@ function getForReportAction(reportID: string | undefined, reportAction: OnyxEntr
const policyTags = allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {};
const transactionTag = reportActionOriginalMessage?.tag ?? '';
const oldTransactionTag = reportActionOriginalMessage?.oldTag ?? '';
const splittedTag = transactionTag.split(CONST.COLON);
const splittedOldTag = oldTransactionTag.split(CONST.COLON);
const splittedTag = TransactionUtils.getTagArrayFromName(transactionTag);
const splittedOldTag = TransactionUtils.getTagArrayFromName(oldTransactionTag);
const localizedTagListName = Localize.translateLocal('common.tag');

Object.keys(policyTags).forEach((policyTagKey, index) => {
Expand Down
36 changes: 35 additions & 1 deletion src/libs/TransactionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,18 +364,50 @@ function getBillable(transaction: OnyxEntry<Transaction>): boolean {
return transaction?.billable ?? false;
}

/**
* Return a colon-delimited tag string as an array, considering escaped colons and double backslashes.
*/
function getTagArrayFromName(tagName: string): string[] {
// WAIT!!!!!!!!!!!!!!!!!!
// You need to keep this in sync with TransactionUtils.php

// We need to be able to preserve double backslashes in the original string
// and not have it interfere with splitting on a colon (:).
// So, let's replace it with something absurd to begin with, do our split, and
// then replace the double backslashes in the end.
const tagWithoutDoubleSlashes = tagName.replace(/\\\\/g, '☠');
const tagWithoutEscapedColons = tagWithoutDoubleSlashes.replace(/\\:/g, '☢');

// Do our split
const matches = tagWithoutEscapedColons.split(':');
const newMatches: string[] = [];

for (const item of matches) {
const tagWithEscapedColons = item.replace(//g, '\\:');
const tagWithDoubleSlashes = tagWithEscapedColons.replace(//g, '\\\\');
newMatches.push(tagWithDoubleSlashes);
}

return newMatches;
}

/**
* Return the tag from the transaction. When the tagIndex is passed, return the tag based on the index.
* This "tag" field has no "modified" complement.
*/
function getTag(transaction: OnyxEntry<Transaction>, tagIndex?: number): string {
if (tagIndex !== undefined) {
return transaction?.tag?.split(CONST.COLON)[tagIndex] ?? '';
const tagsArray = getTagArrayFromName(transaction?.tag ?? '');
return tagsArray[tagIndex] ?? '';
}

return transaction?.tag ?? '';
}

function getTagForDisplay(transaction: OnyxEntry<Transaction>, tagIndex?: number): string {
return getTag(transaction, tagIndex).replace(/[\\\\]:/g, ':');
}

/**
* Return the created field from the transaction, return the modifiedCreated if present.
*/
Expand Down Expand Up @@ -605,6 +637,8 @@ export {
getCategory,
getBillable,
getTag,
getTagArrayFromName,
getTagForDisplay,
getTransactionViolations,
getLinkedTransaction,
getAllReportTransactions,
Expand Down
3 changes: 2 additions & 1 deletion src/libs/Violations/ViolationsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import reject from 'lodash/reject';
import Onyx from 'react-native-onyx';
import type {OnyxUpdate} from 'react-native-onyx';
import type {Phrase, PhraseParameters} from '@libs/Localize';
import * as TransactionUtils from '@libs/TransactionUtils';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -50,7 +51,7 @@ const ViolationsUtils = {
}

if (policyRequiresTags) {
const selectedTags = updatedTransaction.tag?.split(CONST.COLON) ?? [];
const selectedTags = TransactionUtils.getTagArrayFromName(updatedTransaction.tag ?? '') ?? [];
const policyTagKeys = Object.keys(policyTagList);

if (policyTagKeys.length === 0) {
Expand Down
6 changes: 3 additions & 3 deletions src/libs/actions/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1633,8 +1633,8 @@ function buildOptimisticPolicyRecentlyUsedCategories(policyID?: string, category
return lodashUnion([category], policyRecentlyUsedCategories);
}

function buildOptimisticPolicyRecentlyUsedTags(policyID?: string, reportTags?: string): RecentlyUsedTags {
if (!policyID || !reportTags) {
function buildOptimisticPolicyRecentlyUsedTags(policyID?: string, transactionTags?: string): RecentlyUsedTags {
if (!policyID || !transactionTags) {
return {};
}

Expand All @@ -1643,7 +1643,7 @@ function buildOptimisticPolicyRecentlyUsedTags(policyID?: string, reportTags?: s
const policyRecentlyUsedTags = allRecentlyUsedTags?.[`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`] ?? {};
const newOptimisticPolicyRecentlyUsedTags: RecentlyUsedTags = {};

reportTags.split(CONST.COLON).forEach((tag, index) => {
TransactionUtils.getTagArrayFromName(transactionTags).forEach((tag, index) => {
if (!tag) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/EditRequestPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function EditRequestPage({report, route, policy, policyCategories, policyTags, p
IOU.updateMoneyRequestTag(
transaction.transactionID,
report.reportID,
IOUUtils.insertTagIntoReportTagsString(transactionTag, updatedTag, tagIndex),
IOUUtils.insertTagIntoTransactionTagsString(transactionTag, updatedTag, tagIndex),
policy,
policyTags,
policyCategories,
Expand Down
2 changes: 1 addition & 1 deletion src/pages/iou/request/step/IOURequestStepTag.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ function IOURequestStepTag({
*/
const updateTag = (selectedTag) => {
const isSelectedTag = selectedTag.searchText === tag;
const updatedTag = IOUUtils.insertTagIntoReportTagsString(transactionTag, isSelectedTag ? '' : selectedTag.searchText, tagIndex);
const updatedTag = IOUUtils.insertTagIntoTransactionTagsString(transactionTag, isSelectedTag ? '' : selectedTag.searchText, tagIndex);
if (isSplitBill && isEditing) {
IOU.setDraftSplitTransaction(transactionID, {tag: updatedTag});
navigateBack();
Expand Down

0 comments on commit 821a44b

Please sign in to comment.