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
1 change: 1 addition & 0 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3263,6 +3263,7 @@ const CONST = {
tags: {},
},
} as PolicyTagLists,
DEFAULT_TAG_NAME: 'Tag',
REQUIRE_RECEIPTS_OVER_OPTIONS: {
DEFAULT: 'default',
NEVER: 'never',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ import type {
SubscriptionSettingsSummaryParams,
SubscriptionSizeParams,
SyncStageNameConnectionsParams,
TagSelectionParams,
TaskCreatedActionParams,
TaxAmountParams,
TermsParams,
Expand Down Expand Up @@ -1343,7 +1344,7 @@ const translations: TranslationDeepObject<typeof en> = {
movedFromPersonalSpace: ({workspaceName, reportName}: MovedFromPersonalSpaceParams) =>
`verschobene Ausgabe von persönlichem Bereich zu ${workspaceName ?? `chatten mit ${reportName}`}`,
movedToPersonalSpace: 'Ausgabe in den persönlichen Bereich verschoben',
tagSelection: 'Wählen Sie ein Tag aus, um Ihre Ausgaben besser zu organisieren.',
tagSelection: ({policyTagListName}: TagSelectionParams = {}) => `Wählen Sie ${policyTagListName ?? 'ein Tag'}, um Ihre Ausgaben besser zu organisieren.`,
categorySelection: 'Wählen Sie eine Kategorie, um Ihre Ausgaben besser zu organisieren.',
error: {
invalidCategoryLength: 'Der Kategoriename überschreitet 255 Zeichen. Bitte kürzen Sie ihn oder wählen Sie eine andere Kategorie.',
Expand Down
7 changes: 6 additions & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ import type {
SubscriptionSettingsSummaryParams,
SubscriptionSizeParams,
SyncStageNameConnectionsParams,
TagSelectionParams,
TaskCreatedActionParams,
TaxAmountParams,
TermsParams,
Expand Down Expand Up @@ -1324,7 +1325,11 @@ const translations = {
threadPaySomeoneReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} sent${comment ? ` for ${comment}` : ''}`,
movedFromPersonalSpace: ({workspaceName, reportName}: MovedFromPersonalSpaceParams) => `moved expense from personal space to ${workspaceName ?? `chat with ${reportName}`}`,
movedToPersonalSpace: 'moved expense to personal space',
tagSelection: 'Select a tag to better organize your spend.',
tagSelection: ({policyTagListName}: TagSelectionParams = {}) => {
const article = policyTagListName && StringUtils.startsWithVowel(policyTagListName) ? 'an' : 'a';
const tag = policyTagListName ?? 'tag';
Comment thread
mohammadjafarinejad marked this conversation as resolved.
return `Select ${article} ${tag} to better organize your spend.`;
},
categorySelection: 'Select a category to better organize your spend.',
error: {
invalidCategoryLength: 'The category name exceeds 255 characters. Please shorten it or choose a different category.',
Expand Down
4 changes: 2 additions & 2 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {CONST as COMMON_CONST} from 'expensify-common';
import dedent from '@libs/StringUtils/dedent';
import CONST from '@src/CONST';
import type en from './en';
import type {ViolationsRterParams} from './params';
import type {TagSelectionParams, ViolationsRterParams} from './params';
import type {TranslationDeepObject} from './types';

/* eslint-disable max-len */
Expand Down Expand Up @@ -986,7 +986,7 @@ const translations: TranslationDeepObject<typeof en> = {
threadPaySomeoneReportName: ({formattedAmount, comment}) => `${formattedAmount} enviado${comment ? ` para ${comment}` : ''}`,
movedFromPersonalSpace: ({workspaceName, reportName}) => `movió el gasto desde su espacio personal a ${workspaceName ?? `un chat con ${reportName}`}`,
movedToPersonalSpace: 'movió el gasto a su espacio personal',
tagSelection: 'Selecciona una etiqueta para organizar mejor tus gastos.',
tagSelection: ({policyTagListName}: TagSelectionParams = {}) => `Selecciona ${policyTagListName ?? 'una etiqueta'} para organizar mejor tus gastos.`,
categorySelection: 'Selecciona una categoría para organizar mejor tus gastos.',
error: {
invalidCategoryLength: 'La longitud de la categoría escogida excede el máximo permitido (255). Por favor, escoge otra categoría o acorta la categoría primero.',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ import type {
SubscriptionSettingsSummaryParams,
SubscriptionSizeParams,
SyncStageNameConnectionsParams,
TagSelectionParams,
TaskCreatedActionParams,
TaxAmountParams,
TermsParams,
Expand Down Expand Up @@ -1347,7 +1348,7 @@ const translations: TranslationDeepObject<typeof en> = {
movedFromPersonalSpace: ({workspaceName, reportName}: MovedFromPersonalSpaceParams) =>
`déplacé la dépense de l'espace personnel vers ${workspaceName ?? `discuter avec ${reportName}`}`,
movedToPersonalSpace: "a déplacé la dépense vers l'espace personnel",
tagSelection: 'Sélectionnez une étiquette pour mieux organiser vos dépenses.',
tagSelection: ({policyTagListName}: TagSelectionParams = {}) => `Sélectionnez ${policyTagListName ?? 'une étiquette'} pour mieux organiser vos dépenses.`,
categorySelection: 'Sélectionnez une catégorie pour mieux organiser vos dépenses.',
error: {
invalidCategoryLength: 'Le nom de la catégorie dépasse 255 caractères. Veuillez le raccourcir ou choisir une autre catégorie.',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ import type {
SubscriptionSettingsSummaryParams,
SubscriptionSizeParams,
SyncStageNameConnectionsParams,
TagSelectionParams,
TaskCreatedActionParams,
TaxAmountParams,
TermsParams,
Expand Down Expand Up @@ -1340,7 +1341,7 @@ const translations: TranslationDeepObject<typeof en> = {
threadPaySomeoneReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} inviato${comment ? `per ${comment}` : ''}`,
movedFromPersonalSpace: ({workspaceName, reportName}: MovedFromPersonalSpaceParams) => `spostato la spesa dallo spazio personale a ${workspaceName ?? `chatta con ${reportName}`}`,
movedToPersonalSpace: 'spesa spostata nello spazio personale',
tagSelection: 'Seleziona un tag per organizzare meglio le tue spese.',
tagSelection: ({policyTagListName}: TagSelectionParams = {}) => `Seleziona ${policyTagListName ?? 'un tag'} per organizzare meglio le tue spese.`,
categorySelection: 'Seleziona una categoria per organizzare meglio le tue spese.',
error: {
invalidCategoryLength: 'Il nome della categoria supera i 255 caratteri. Si prega di accorciarlo o scegliere una categoria diversa.',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ import type {
SubscriptionSettingsSummaryParams,
SubscriptionSizeParams,
SyncStageNameConnectionsParams,
TagSelectionParams,
TaskCreatedActionParams,
TaxAmountParams,
TermsParams,
Expand Down Expand Up @@ -1342,7 +1343,7 @@ const translations: TranslationDeepObject<typeof en> = {
threadPaySomeoneReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} 送信済み${comment ? `${comment} のために` : ''}`,
movedFromPersonalSpace: ({workspaceName, reportName}: MovedFromPersonalSpaceParams) => `個人スペースから${workspaceName ?? `${reportName}とチャットする`}に経費を移動しました。`,
movedToPersonalSpace: '経費を個人スペースに移動しました',
tagSelection: '支出をより整理するためにタグを選択してください。',
tagSelection: ({policyTagListName}: TagSelectionParams = {}) => `支出をより適切に整理するために、${policyTagListName ?? 'aタグ'} を選択してください。`,
categorySelection: '支出をより整理するためにカテゴリを選択してください。',
error: {
invalidCategoryLength: 'カテゴリ名が255文字を超えています。短くするか、別のカテゴリを選んでください。',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ import type {
SubscriptionSettingsSummaryParams,
SubscriptionSizeParams,
SyncStageNameConnectionsParams,
TagSelectionParams,
TaskCreatedActionParams,
TaxAmountParams,
TermsParams,
Expand Down Expand Up @@ -1341,7 +1342,7 @@ const translations: TranslationDeepObject<typeof en> = {
movedFromPersonalSpace: ({workspaceName, reportName}: MovedFromPersonalSpaceParams) =>
`verplaatste uitgave van persoonlijke ruimte naar ${workspaceName ?? `chat met ${reportName}`}`,
movedToPersonalSpace: 'verplaatste uitgave naar persoonlijke ruimte',
tagSelection: 'Selecteer een tag om uw uitgaven beter te organiseren.',
tagSelection: ({policyTagListName}: TagSelectionParams = {}) => `Selecteer ${policyTagListName ?? 'een tag'} om je uitgaven beter te organiseren.`,
categorySelection: 'Selecteer een categorie om uw uitgaven beter te organiseren.',
error: {
invalidCategoryLength: 'De categorienaam overschrijdt 255 tekens. Verkort deze of kies een andere categorie.',
Expand Down
5 changes: 5 additions & 0 deletions src/languages/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import type {DelegateRole} from '@src/types/onyx/Account';
import type {AllConnectionName, ConnectionName, PolicyConnectionSyncStage, SageIntacctMappingName} from '@src/types/onyx/Policy';
import type {ViolationDataType} from '@src/types/onyx/TransactionViolation';

type TagSelectionParams = {
policyTagListName?: string;
};

type AddressLineParams = {
lineNumber: number;
};
Expand Down Expand Up @@ -1281,4 +1285,5 @@ export type {
NextStepParams,
ReportFieldParams,
FocusModeUpdateParams,
TagSelectionParams,
};
5 changes: 3 additions & 2 deletions src/languages/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ import type {
SubscriptionSettingsSummaryParams,
SubscriptionSizeParams,
SyncStageNameConnectionsParams,
TagSelectionParams,
TaskCreatedActionParams,
TaxAmountParams,
TermsParams,
Expand Down Expand Up @@ -1339,8 +1340,8 @@ const translations: TranslationDeepObject<typeof en> = {
threadPaySomeoneReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} wysłano${comment ? `dla ${comment}` : ''}`,
movedFromPersonalSpace: ({workspaceName, reportName}: MovedFromPersonalSpaceParams) => `przeniesiono wydatek z przestrzeni osobistej do ${workspaceName ?? `czat z ${reportName}`}`,
movedToPersonalSpace: 'przeniesiono wydatek do przestrzeni osobistej',
tagSelection: 'Wybierz tag, aby lepiej zorganizować swoje wydatki.',
categorySelection: 'Wybierz kategorię, aby lepiej zorganizować swoje wydatki.',
tagSelection: ({policyTagListName}: TagSelectionParams = {}) => `Wybierz ${policyTagListName ?? 'tag'}, aby lepiej uporządkować swoje wydatki.`,
categorySelection: 'Wybierz kategorię, aby lepiej uporządkować swoje wydatki.',
error: {
invalidCategoryLength: 'Nazwa kategorii przekracza 255 znaków. Proszę ją skrócić lub wybrać inną kategorię.',
invalidTagLength: 'Nazwa tagu przekracza 255 znaków. Proszę skrócić ją lub wybrać inny tag.',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/pt-BR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ import type {
SubscriptionSettingsSummaryParams,
SubscriptionSizeParams,
SyncStageNameConnectionsParams,
TagSelectionParams,
TaskCreatedActionParams,
TaxAmountParams,
TermsParams,
Expand Down Expand Up @@ -1338,7 +1339,7 @@ const translations: TranslationDeepObject<typeof en> = {
threadPaySomeoneReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} enviado${comment ? `para ${comment}` : ''}`,
movedFromPersonalSpace: ({workspaceName, reportName}: MovedFromPersonalSpaceParams) => `moveu a despesa do espaço pessoal para ${workspaceName ?? `conversar com ${reportName}`}`,
movedToPersonalSpace: 'movido despesa para o espaço pessoal',
tagSelection: 'Selecione uma tag para organizar melhor seus gastos.',
tagSelection: ({policyTagListName}: TagSelectionParams = {}) => `Selecione ${policyTagListName ?? 'uma etiqueta'} para organizar melhor suas despesas.`,
categorySelection: 'Selecione uma categoria para organizar melhor seus gastos.',
error: {
invalidCategoryLength: 'O nome da categoria excede 255 caracteres. Por favor, reduza-o ou escolha uma categoria diferente.',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/zh-hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ import type {
SubscriptionSettingsSummaryParams,
SubscriptionSizeParams,
SyncStageNameConnectionsParams,
TagSelectionParams,
TaskCreatedActionParams,
TaxAmountParams,
TermsParams,
Expand Down Expand Up @@ -1320,7 +1321,7 @@ const translations: TranslationDeepObject<typeof en> = {
threadPaySomeoneReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} 已发送${comment ? `对于${comment}` : ''}`,
movedFromPersonalSpace: ({workspaceName, reportName}: MovedFromPersonalSpaceParams) => `将费用从个人空间移动到${workspaceName ?? `与${reportName}聊天`}`,
movedToPersonalSpace: '将费用移至个人空间',
tagSelection: '选择一个标签以更好地组织您的支出。',
tagSelection: ({policyTagListName}: TagSelectionParams = {}) => `选择${policyTagListName ?? '一个标签'}以更好地管理您的支出。`,
categorySelection: '选择一个类别以更好地组织您的支出。',
error: {
invalidCategoryLength: '类别名称超过255个字符。请缩短或选择不同的类别。',
Expand Down
11 changes: 11 additions & 0 deletions src/libs/PolicyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@

let allPolicies: OnyxCollection<Policy>;

Onyx.connect({

Check warning on line 58 in src/libs/PolicyUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY,
waitForCollectionCallback: true,
callback: (value) => (allPolicies = value),
Expand Down Expand Up @@ -513,6 +513,16 @@
return tag?.replaceAll(CONST.COLON, '\\:');
}

/**
* Checks if a tag list name is the default 'Tag' name
*/
function isDefaultTagName(tagName: string | undefined): boolean {
if (!tagName) {
return false;
}
return tagName.trim().toLowerCase() === CONST.POLICY.DEFAULT_TAG_NAME.trim().toLowerCase();
}

/**
* Gets a count of enabled tags of a policy
*/
Expand Down Expand Up @@ -1725,6 +1735,7 @@
getPolicyEmployeeAccountIDs,
isMemberPolicyAdmin,
getActivePoliciesWithExpenseChatAndPerDiemEnabled,
isDefaultTagName,
};

export type {MemberEmailsToAccountIDs};
10 changes: 7 additions & 3 deletions src/libs/Violations/ViolationsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as CurrencyUtils from '@libs/CurrencyUtils';
import DateUtils from '@libs/DateUtils';
import {isReceiptError} from '@libs/ErrorUtils';
import Parser from '@libs/Parser';
import {getDistanceRateCustomUnitRate, getPerDiemRateCustomUnitRate, getSortedTagKeys, isTaxTrackingEnabled} from '@libs/PolicyUtils';
import {getDistanceRateCustomUnitRate, getPerDiemRateCustomUnitRate, getSortedTagKeys, isDefaultTagName, isTaxTrackingEnabled} from '@libs/PolicyUtils';
import * as TransactionUtils from '@libs/TransactionUtils';
import {shouldShowViolation} from '@libs/TransactionUtils';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -37,7 +37,9 @@ function getTagViolationsForSingleLevelTags(

// Add 'tagOutOfPolicy' violation if tag is not in policy
if (!hasTagOutOfPolicyViolation && updatedTransaction.tag && !isTagInPolicy) {
newTransactionViolations.push({name: CONST.VIOLATIONS.TAG_OUT_OF_POLICY, type: CONST.VIOLATION_TYPES.VIOLATION});
const tagName = policyTagList[policyTagListName]?.name;
const tagNameToShow = isDefaultTagName(tagName) ? undefined : tagName;
newTransactionViolations.push({name: CONST.VIOLATIONS.TAG_OUT_OF_POLICY, type: CONST.VIOLATION_TYPES.VIOLATION, data: {tagName: tagNameToShow}});
}

// Remove 'tagOutOfPolicy' violation if tag is in policy
Expand All @@ -52,7 +54,9 @@ function getTagViolationsForSingleLevelTags(

// Add 'missingTag violation' if tag is required and not set
if (!hasMissingTagViolation && !updatedTransaction.tag && policyRequiresTags) {
newTransactionViolations.push({name: CONST.VIOLATIONS.MISSING_TAG, type: CONST.VIOLATION_TYPES.VIOLATION});
const tagName = policyTagList[policyTagListName]?.name;
const tagNameToShow = isDefaultTagName(tagName) ? undefined : tagName;
newTransactionViolations.push({name: CONST.VIOLATIONS.MISSING_TAG, type: CONST.VIOLATION_TYPES.VIOLATION, data: {tagName: tagNameToShow}});
}
return newTransactionViolations;
}
Expand Down
5 changes: 3 additions & 2 deletions src/pages/iou/request/step/IOURequestStepTag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import {setDraftSplitTransaction, setMoneyRequestTag, updateMoneyRequestTag} from '@libs/actions/IOU';
import {insertTagIntoTransactionTagsString} from '@libs/IOUUtils';
import Navigation from '@libs/Navigation/Navigation';
import {getTagList, getTagListName, getTagLists, hasDependentTags as hasDependentTagsPolicyUtils, isPolicyAdmin} from '@libs/PolicyUtils';
import {getTagList, getTagListName, getTagLists, hasDependentTags as hasDependentTagsPolicyUtils, isDefaultTagName, isPolicyAdmin} from '@libs/PolicyUtils';
import type {OptionData} from '@libs/ReportUtils';
import {hasEnabledTags} from '@libs/TagsOptionsListUtils';
import {getTag, getTagArrayFromName, isExpenseUnreported} from '@libs/TransactionUtils';
Expand Down Expand Up @@ -59,6 +59,7 @@ function IOURequestStepTag({

const tagListIndex = Number(rawTagIndex);
const policyTagListName = getTagListName(policyTags, tagListIndex);
const tagListNameToShow = useMemo(() => (isDefaultTagName(policyTagListName) ? undefined : policyTagListName), [policyTagListName]);

const isEditing = action === CONST.IOU.ACTION.EDIT;
const isSplitBill = iouType === CONST.IOU.TYPE.SPLIT;
Expand Down Expand Up @@ -175,7 +176,7 @@ function IOURequestStepTag({
)}
{!!shouldShowTag && (
<>
<Text style={[styles.ph5, styles.pv3]}>{translate('iou.tagSelection')}</Text>
<Text style={[styles.ph5, styles.pv3]}>{translate('iou.tagSelection', {policyTagListName: tagListNameToShow})}</Text>
<TagPicker
policyID={policyID}
tagListName={policyTagListName}
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/ViolationUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ describe('getViolationsOnyxData', () => {

const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policy, policyTags, policyCategories, false, false);

expect(result.value).toEqual(expect.arrayContaining([{...missingTagViolation}]));
expect(result.value).toEqual(expect.arrayContaining([{...missingTagViolation, data: {tagName: 'Meals'}}]));
});

it('should add a tagOutOfPolicy violation when policy requires tags and tag is not in the policy', () => {
Expand Down Expand Up @@ -449,7 +449,7 @@ describe('getViolationsOnyxData', () => {

const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policy, policyTags, policyCategories, false, false);

expect(result.value).toEqual(expect.arrayContaining([{...tagOutOfPolicyViolation}, ...transactionViolations]));
expect(result.value).toEqual(expect.arrayContaining([{...tagOutOfPolicyViolation, data: {tagName: 'Meals'}}, ...transactionViolations]));
});

it('should add missingTag violation to existing violations if transaction does not have a tag', () => {
Expand All @@ -458,7 +458,7 @@ describe('getViolationsOnyxData', () => {

const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policy, policyTags, policyCategories, false, false);

expect(result.value).toEqual(expect.arrayContaining([{...missingTagViolation}, ...transactionViolations]));
expect(result.value).toEqual(expect.arrayContaining([{...missingTagViolation, data: {tagName: 'Meals'}}, ...transactionViolations]));
});
});

Expand Down
Loading