Skip to content
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
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