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

Update MoneyRequestView.js to show Violations #32594

Merged
merged 83 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from 70 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
1759325
update package-lock
trevor-coleman Nov 20, 2023
572cad3
feat(Violations): Add transactionViolation onxy connection to MoneyRe…
trevor-coleman Nov 20, 2023
6a853a0
feat(Violations): Add transactionViolations propTypes.
trevor-coleman Nov 20, 2023
f090c0a
feat(Violations): Add violations to fields on MoneyRequestView
trevor-coleman Nov 20, 2023
9ad9678
fix(Violations): Update ViolationUtils.getViolationsForField to retur…
trevor-coleman Nov 20, 2023
4f6863c
feat(Violations): Check `canUseViolations` in getViolationsForField
trevor-coleman Nov 20, 2023
baf551a
feat(Violations): rename getViolationForField to getTranslatedViolati…
trevor-coleman Nov 20, 2023
32c0a6d
feat(Violations): add brick road indicators to fields with navigation
trevor-coleman Nov 20, 2023
b57f82b
feat(Violations): fix default propType for transactionViolations
trevor-coleman Nov 20, 2023
9ca94f1
feat(Violations): fix RBR indicators showing wrong color on Violations
trevor-coleman Nov 20, 2023
047d193
fix(Violations): fix type exports in onyx types
trevor-coleman Nov 27, 2023
29faf0f
fix(Violations): replace `ViolationUtils.getViolationsForField` with …
trevor-coleman Nov 27, 2023
65dc2b4
feat(Violations): add dummy keys to translation file for violation names
trevor-coleman Nov 27, 2023
e973ceb
feat(Violations): use spread operator to ensure changes to the array …
trevor-coleman Nov 27, 2023
5c85c67
Merge branch 'main' into trevor-coleman/violations/money-request-view…
trevor-coleman Nov 27, 2023
f5dd125
feat(Violations): remove boilerplate
trevor-coleman Nov 28, 2023
b77cf26
feat(Violations): bring in new useViolations hook and ViolationUtils …
trevor-coleman Nov 29, 2023
e8e3717
feat(Violations): extract FieldViolationMessages from MoneyRequestVie…
trevor-coleman Nov 29, 2023
a7b2117
feat(Violations): memoize return values for hasViolations
trevor-coleman Nov 29, 2023
cb7a551
feat(Violations): memoize return values for hasViolations
trevor-coleman Nov 29, 2023
ccc88c7
feat(Violations): remove index
trevor-coleman Nov 29, 2023
4b4ed0f
Merge branch 'violation-utils' into trevor-coleman/violations/money-r…
trevor-coleman Dec 1, 2023
f932509
feat(Violations): prettier
trevor-coleman Dec 1, 2023
5e726fe
feat(Violations): declare hasViolations locally
trevor-coleman Dec 4, 2023
f6cdd0a
Merge remote-tracking branch 'upstream/main' into trevor-coleman/viol…
trevor-coleman Dec 4, 2023
34ea213
feat(Violations): prettier
trevor-coleman Dec 5, 2023
1a30bb4
Merge branch 'violation-utils' into trevor-coleman/violations/money-r…
trevor-coleman Dec 5, 2023
9c1d092
feat(Violations): add VIOLATIONS to CONST
trevor-coleman Dec 5, 2023
3bddb2a
feat(Violations): remove unnecessary field prop and import styles
trevor-coleman Dec 5, 2023
af453b6
feat(Violations): refactor Violations types to depend on CONST
trevor-coleman Dec 5, 2023
b2e76dc
Merge pull request #80 from infinitered/trevor-coleman/violations/mon…
trevor-coleman Dec 6, 2023
47f7ea4
Merge remote-tracking branch 'upstream/main' into money-request-fields
trevor-coleman Dec 6, 2023
2532ae9
feat(Violations): Add checks to make sure user has access to the viol…
trevor-coleman Dec 6, 2023
f757a27
feat(Violations): Move ViolationField into useViolations
trevor-coleman Dec 6, 2023
941346a
Merge pull request #83 from infinitered/trevor-coleman/money-request-…
trevor-coleman Dec 6, 2023
405672d
feat(Violations): add missing dependency to array
trevor-coleman Dec 6, 2023
f853ce0
feat(Violations): remove unnecessary guard
trevor-coleman Dec 6, 2023
f649598
feat(Violations): add english violation translations and types.
trevor-coleman Dec 8, 2023
29f8bbd
feat(Violations): add spanish translations
trevor-coleman Dec 8, 2023
ab967fc
feat(Violations): sort types alphabetically
trevor-coleman Dec 8, 2023
d300b98
Merge remote-tracking branch 'upstream/main' into money-request-fields
trevor-coleman Dec 8, 2023
d16e843
feat(Violations): add variables where appropriate and update translat…
trevor-coleman Dec 11, 2023
1493429
Merge remote-tracking branch 'upstream/main' into money-request-fields
trevor-coleman Dec 11, 2023
80f205d
feat(Violations): add variables where appropriate and update translat…
trevor-coleman Dec 11, 2023
4277baf
feat(Violations): move transaction violations
trevor-coleman Dec 12, 2023
4636e08
feat(Violations): rename FieldViolationMessages to ViolationMessages
trevor-coleman Dec 12, 2023
dee57aa
feat(Violations): clean up variable declarations
trevor-coleman Dec 12, 2023
7220f92
feat(Violations): remove documentation
trevor-coleman Dec 12, 2023
0f97e97
feat(Violations): fix inverted conditional in rter, and simplify. fix…
trevor-coleman Dec 12, 2023
b661558
feat(Violations): fix verb conjugation
trevor-coleman Dec 12, 2023
b620aa6
feat(Violations): fix translation
trevor-coleman Dec 12, 2023
f4376a2
feat(Violations): return string not template
trevor-coleman Dec 12, 2023
319c09e
feat(Violations): add example
trevor-coleman Dec 12, 2023
a032ed2
feat(Violations): fix comments, alphabetize cases
trevor-coleman Dec 12, 2023
e91c965
feat(Violations): fix comment
trevor-coleman Dec 12, 2023
7ec9098
feat(Violations): move propTypes into MoneyRequestView
trevor-coleman Dec 12, 2023
84f83fc
feat(Violations): remove unnecessary cast
trevor-coleman Dec 12, 2023
bebb99f
Merge remote-tracking branch 'upstream/main' into money-request-fields
trevor-coleman Dec 12, 2023
d8e9ddc
feat(Violations): move key back
trevor-coleman Dec 12, 2023
d9ef8e2
feat(Violations): remove unnecessary fragment
trevor-coleman Dec 12, 2023
02da9ec
feat(Violations): add period
trevor-coleman Dec 12, 2023
1fe91ef
feat(Violations): remove blank line
trevor-coleman Dec 12, 2023
9b7753c
feat(Violations): remove comment
trevor-coleman Dec 12, 2023
b491946
feat(Violations): add newline
trevor-coleman Dec 13, 2023
ea1828c
feat(Violations): specify shape of data type.
trevor-coleman Dec 14, 2023
b749929
Merge remote-tracking branch 'upstream/main' into money-request-fields
trevor-coleman Dec 15, 2023
fe50d90
prettier
trevor-coleman Dec 15, 2023
44efe42
Fix hook import
lindboe Dec 15, 2023
3e078bc
feat(Violations): change spacing of violations
trevor-coleman Dec 20, 2023
95952b1
feat(Violations): update styles
trevor-coleman Dec 20, 2023
7f118e1
Merge remote-tracking branch 'upstream/main' into money-request-fields
trevor-coleman Dec 20, 2023
e091846
Merge remote-tracking branch 'upstream/main' into money-request-fields
lindboe Dec 22, 2023
b159109
Merge remote-tracking branch 'upstream/main' into money-request-fields
trevor-coleman Jan 2, 2024
fb952fc
Merge remote-tracking branch 'upstream/main' into money-request-fields
trevor-coleman Jan 3, 2024
8ce2f61
feat(Violations): unwrap comment
trevor-coleman Jan 3, 2024
bd7e845
feat(Violations): fix missingComment translation
trevor-coleman Jan 3, 2024
5a9614c
Merge branch 'main' into money-request-fields
trevor-coleman Jan 3, 2024
e251057
Merge remote-tracking branch 'upstream/main' into money-request-fields
trevor-coleman Jan 3, 2024
862ab76
feat(Violations): fix types broken by merge
trevor-coleman Jan 4, 2024
c248cbb
feat(Violations): fix types broken by merge
trevor-coleman Jan 4, 2024
095b228
feat(Violations): fix types broken by merge
trevor-coleman Jan 4, 2024
ac9c564
feat(Violations): wrapping
trevor-coleman Jan 4, 2024
8057dc4
feat(Violations): remove comment
trevor-coleman Jan 4, 2024
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
38 changes: 37 additions & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3022,12 +3022,48 @@ const CONST = {
},

/**
* Constants for maxToRenderPerBatch parameter that is used for FlatList or SectionList. This controls the amount of items rendered per batch, which is the next chunk of items rendered on every scroll.
* Constants for maxToRenderPerBatch parameter that is used for FlatList or SectionList. This controls the amount
* of items rendered per batch, which is the next chunk of items rendered on every scroll.
*/
MAX_TO_RENDER_PER_BATCH: {
DEFAULT: 5,
CAROUSEL: 3,
},
VIOLATIONS: {
ALL_TAG_LEVELS_REQUIRED: 'allTagLevelsRequired',
AUTO_REPORTED_REJECTED_EXPENSE: 'autoReportedRejectedExpense',
BILLABLE_EXPENSE: 'billableExpense',
CASH_EXPENSE_WITH_NO_RECEIPT: 'cashExpenseWithNoReceipt',
CATEGORY_OUT_OF_POLICY: 'categoryOutOfPolicy',
CONVERSION_SURCHARGE: 'conversionSurcharge',
CUSTOM_UNIT_OUT_OF_POLICY: 'customUnitOutOfPolicy',
DUPLICATED_TRANSACTION: 'duplicatedTransaction',
FIELD_REQUIRED: 'fieldRequired',
FUTURE_DATE: 'futureDate',
INVOICE_MARKUP: 'invoiceMarkup',
MAX_AGE: 'maxAge',
MISSING_CATEGORY: 'missingCategory',
MISSING_COMMENT: 'missingComment',
MISSING_TAG: 'missingTag',
MODIFIED_AMOUNT: 'modifiedAmount',
MODIFIED_DATE: 'modifiedDate',
NON_EXPENSIWORKS_EXPENSE: 'nonExpensiworksExpense',
OVER_AUTO_APPROVAL_LIMIT: 'overAutoApprovalLimit',
OVER_CATEGORY_LIMIT: 'overCategoryLimit',
OVER_LIMIT: 'overLimit',
OVER_LIMIT_ATTENDEE: 'overLimitAttendee',
PER_DAY_LIMIT: 'perDayLimit',
RECEIPT_NOT_SMART_SCANNED: 'receiptNotSmartScanned',
RECEIPT_REQUIRED: 'receiptRequired',
RTER: 'rter',
SMARTSCAN_FAILED: 'smartscanFailed',
SOME_TAG_LEVELS_REQUIRED: 'someTagLevelsRequired',
TAG_OUT_OF_POLICY: 'tagOutOfPolicy',
TAX_AMOUNT_CHANGED: 'taxAmountChanged',
TAX_OUT_OF_POLICY: 'taxOutOfPolicy',
TAX_RATE_CHANGED: 'taxRateChanged',
TAX_REQUIRED: 'taxRequired',
},
} as const;

export default CONST;
92 changes: 78 additions & 14 deletions src/components/ReportActionItem/MoneyRequestView.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import lodashGet from 'lodash/get';
import lodashValues from 'lodash/values';
import PropTypes from 'prop-types';
import React, {useMemo} from 'react';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import categoryPropTypes from '@components/categoryPropTypes';
Expand All @@ -14,12 +14,14 @@ import Switch from '@components/Switch';
import tagPropTypes from '@components/tagPropTypes';
import Text from '@components/Text';
import transactionPropTypes from '@components/transactionPropTypes';
import ViolationMessages from '@components/ViolationMessages';
import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes} from '@components/withCurrentUserPersonalDetails';
import useLocalize from '@hooks/useLocalize';
import usePermissions from '@hooks/usePermissions';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
trevor-coleman marked this conversation as resolved.
Show resolved Hide resolved
import useViolations from '@hooks/useViolations';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as CardUtils from '@libs/CardUtils';
import compose from '@libs/compose';
Expand All @@ -41,6 +43,32 @@ import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import ReportActionItemImage from './ReportActionItemImage';

const violationNames = lodashValues(CONST.VIOLATIONS);

const transactionViolationPropType = PropTypes.shape({
type: PropTypes.string.isRequired,
name: PropTypes.oneOf(violationNames).isRequired,
data: PropTypes.shape({
rejectedBy: PropTypes.string,
rejectReason: PropTypes.string,
amount: PropTypes.string,
surcharge: PropTypes.number,
invoiceMarkup: PropTypes.number,
maxAge: PropTypes.number,
tagName: PropTypes.string,
formattedLimitAmount: PropTypes.string,
categoryLimit: PropTypes.string,
limit: PropTypes.string,
category: PropTypes.string,
brokenBankConnection: PropTypes.bool,
isAdmin: PropTypes.bool,
email: PropTypes.string,
isTransactionOlderThan7Days: PropTypes.bool,
member: PropTypes.string,
taxName: PropTypes.string,
}),
});

const propTypes = {
/** The report currently being looked at */
report: reportPropTypes.isRequired,
Expand All @@ -61,6 +89,9 @@ const propTypes = {
/** The transaction associated with the transactionThread */
transaction: transactionPropTypes,

/** Violations detected in this transaction */
transactionViolations: PropTypes.arrayOf(transactionViolationPropType),

/** Collection of tags attached to a policy */
policyTags: tagPropTypes,

Expand All @@ -76,10 +107,11 @@ const defaultProps = {
currency: CONST.CURRENCY.USD,
comment: {comment: ''},
},
transactionViolations: [],
policyTags: {},
};

function MoneyRequestView({report, parentReport, parentReportActions, policyCategories, shouldShowHorizontalRule, transaction, policyTags, policy}) {
function MoneyRequestView({report, parentReport, parentReportActions, policyCategories, shouldShowHorizontalRule, transaction, policyTags, policy, transactionViolations}) {
const theme = useTheme();
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
Expand Down Expand Up @@ -131,6 +163,9 @@ function MoneyRequestView({report, parentReport, parentReportActions, policyCate
const shouldShowTag = isPolicyExpenseChat && (transactionTag || OptionsListUtils.hasEnabledOptions(lodashValues(policyTagsList)));
const shouldShowBillable = isPolicyExpenseChat && (transactionBillable || !lodashGet(policy, 'disabledFields.defaultBillable', true));

const {getViolationsForField} = useViolations(transactionViolations);
const hasViolations = useCallback((field) => canUseViolations && getViolationsForField(field).length > 0, [canUseViolations, getViolationsForField]);

let amountDescription = `${translate('iou.amount')}`;

if (isCardTransaction) {
Expand Down Expand Up @@ -192,12 +227,13 @@ function MoneyRequestView({report, parentReport, parentReportActions, policyCate
</View>
</OfflineWithFeedback>
)}
{!hasReceipt && canEdit && !isSettled && canUseViolations && (
{!hasReceipt && canEdit && !isSettled && (
<ReceiptEmptyState
hasError={hasErrors}
onPress={() => Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.RECEIPT))}
/>
)}
{canUseViolations && <ViolationMessages violations={getViolationsForField('receipt')} />}
<OfflineWithFeedback pendingAction={getPendingFieldAction('pendingFields.amount')}>
<MenuItemWithTopDescription
title={formattedTransactionAmount ? formattedTransactionAmount.toString() : ''}
Expand All @@ -208,9 +244,10 @@ function MoneyRequestView({report, parentReport, parentReportActions, policyCate
interactive={canEditAmount}
shouldShowRightIcon={canEditAmount}
onPress={() => Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.AMOUNT))}
brickRoadIndicator={hasErrors && transactionAmount === 0 ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''}
brickRoadIndicator={hasViolations('amount') || (hasErrors && transactionAmount === 0) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''}
error={hasErrors && transactionAmount === 0 ? translate('common.error.enterAmount') : ''}
/>
{canUseViolations && <ViolationMessages violations={getViolationsForField('amount')} />}
</OfflineWithFeedback>
<OfflineWithFeedback pendingAction={getPendingFieldAction('pendingFields.comment')}>
<MenuItemWithTopDescription
Expand All @@ -222,8 +259,10 @@ function MoneyRequestView({report, parentReport, parentReportActions, policyCate
titleStyle={styles.flex1}
onPress={() => Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.DESCRIPTION))}
wrapperStyle={[styles.pv2, styles.taskDescriptionMenuItem]}
brickRoadIndicator={hasViolations('comment') ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''}
numberOfLinesTitle={0}
/>
{canUseViolations && <ViolationMessages violations={getViolationsForField('comment')} />}
</OfflineWithFeedback>
{isDistanceRequest ? (
<OfflineWithFeedback pendingAction={lodashGet(transaction, 'pendingFields.waypoints') || lodashGet(transaction, 'pendingAction')}>
Expand All @@ -245,9 +284,10 @@ function MoneyRequestView({report, parentReport, parentReportActions, policyCate
shouldShowRightIcon={canEdit}
titleStyle={styles.flex1}
onPress={() => Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.MERCHANT))}
brickRoadIndicator={hasErrors && isEmptyMerchant ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''}
brickRoadIndicator={hasViolations('merchant') || (hasErrors && isEmptyMerchant) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''}
error={hasErrors && isEmptyMerchant ? translate('common.error.enterMerchant') : ''}
/>
{canUseViolations && <ViolationMessages violations={getViolationsForField('merchant')} />}
</OfflineWithFeedback>
)}
<OfflineWithFeedback pendingAction={getPendingFieldAction('pendingFields.created')}>
Expand All @@ -258,9 +298,10 @@ function MoneyRequestView({report, parentReport, parentReportActions, policyCate
shouldShowRightIcon={canEdit && !isSettled}
titleStyle={styles.flex1}
onPress={() => Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.DATE))}
brickRoadIndicator={hasErrors && transactionDate === '' ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''}
brickRoadIndicator={hasViolations('date') || (hasErrors && transactionDate === '') ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''}
error={hasErrors && transactionDate === '' ? translate('common.error.enterDate') : ''}
/>
{canUseViolations && <ViolationMessages violations={getViolationsForField('date')} />}
</OfflineWithFeedback>
{shouldShowCategory && (
<OfflineWithFeedback pendingAction={lodashGet(transaction, 'pendingFields.category') || lodashGet(transaction, 'pendingAction')}>
Expand All @@ -271,7 +312,9 @@ function MoneyRequestView({report, parentReport, parentReportActions, policyCate
shouldShowRightIcon={canEdit}
titleStyle={styles.flex1}
onPress={() => Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.CATEGORY))}
brickRoadIndicator={hasViolations('category') ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''}
/>
{canUseViolations && <ViolationMessages violations={getViolationsForField('category')} />}
</OfflineWithFeedback>
)}
{shouldShowTag && (
Expand All @@ -283,7 +326,9 @@ function MoneyRequestView({report, parentReport, parentReportActions, policyCate
shouldShowRightIcon={canEdit}
titleStyle={styles.flex1}
onPress={() => Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.TAG))}
brickRoadIndicator={hasViolations('tag') ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''}
/>
{canUseViolations && <ViolationMessages violations={getViolationsForField('tag')} />}
</OfflineWithFeedback>
)}
{isCardTransaction && (
Expand All @@ -295,15 +340,24 @@ function MoneyRequestView({report, parentReport, parentReportActions, policyCate
/>
</OfflineWithFeedback>
)}

{shouldShowBillable && (
<View style={[styles.flexRow, styles.optionRow, styles.justifyContentBetween, styles.alignItemsCenter, styles.ml5, styles.mr8]}>
<Text color={!transactionBillable ? theme.textSupporting : undefined}>{translate('common.billable')}</Text>
<Switch
accessibilityLabel={translate('common.billable')}
isOn={transactionBillable}
onToggle={(value) => IOU.editMoneyRequest(transaction, report.reportID, {billable: value})}
/>
</View>
<>
<View style={[styles.flexRow, styles.optionRow, styles.justifyContentBetween, styles.alignItemsCenter, styles.ml5, styles.mr8]}>
<Text color={!transactionBillable ? theme.textSupporting : undefined}>{translate('common.billable')}</Text>
<Switch
accessibilityLabel={translate('common.billable')}
isOn={transactionBillable}
onToggle={(value) => IOU.editMoneyRequest(transaction, report.reportID, {billable: value})}
/>
</View>
{hasViolations('billable') && (
<ViolationMessages
violations={getViolationsForField('billable')}
isLast
/>
)}
</>
)}
</View>
<SpacerView
Expand Down Expand Up @@ -349,5 +403,15 @@ export default compose(
return `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`;
},
},
transactionViolation: {
Copy link
Contributor

Choose a reason for hiding this comment

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

there's a typo here which I'm fixing here if you can review please @trevor-coleman . I was able to see the violations once I fixed it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good catch! Let me review

key: ({report}) => {
const parentReportAction = ReportActionsUtils.getParentReportAction(report);
Copy link
Contributor

Choose a reason for hiding this comment

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

@trevor-coleman ReportActionsUtils.getParentReportAction is a deprecated method. I'm trying to remove these in #27262. Can you please create a PR to clean this up and remove the usage of the deprecated method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, I was a paid contractor and I'm no longer on this project.

Copy link
Contributor

Choose a reason for hiding this comment

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

@tgolen can you do this as part of one of your PRs removing the method?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'll add it to the list.

Thanks for responding @trevor-coleman and I hope you come back at some point! 👋

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks!

const transactionID = lodashGet(parentReportAction, ['originalMessage', 'IOUTransactionID'], 0);
return `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`;
},
},
policyTags: {
key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${report.policyID}`,
},
}),
)(MoneyRequestView);
26 changes: 26 additions & 0 deletions src/components/ViolationMessages.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, {useMemo} from 'react';
hayata-suenaga marked this conversation as resolved.
Show resolved Hide resolved
import {View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import ViolationsUtils from '@libs/ViolationsUtils';
import {TransactionViolation} from '@src/types/onyx';
import Text from './Text';

export default function ViolationMessages({violations, isLast}: {violations: TransactionViolation[]; isLast?: boolean}) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const violationMessages = useMemo(() => violations.map((violation) => [violation.name, ViolationsUtils.getViolationTranslation(violation, translate)]), [translate, violations]);

return (
trevor-coleman marked this conversation as resolved.
Show resolved Hide resolved
<View style={[styles.mtn2, isLast ? styles.mb2 : styles.mb1]}>
{violationMessages.map(([name, message]) => (
<Text
key={`violationMessages.${name}`}
style={[styles.ph5, styles.textLabelError]}
>
{message}
</Text>
))}
</View>
);
}
7 changes: 3 additions & 4 deletions src/hooks/useViolations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import {useCallback, useMemo} from 'react';
import {TransactionViolation, ViolationName} from '@src/types/onyx';

/**
* Names of Fields where violations can occur
* Names of Fields where violations can occur.
*/
type ViolationField = 'amount' | 'billable' | 'category' | 'comment' | 'date' | 'merchant' | 'receipt' | 'tag' | 'tax';

/**
* Map from Violation Names to the field where that violation can occur
* Map from Violation Names to the field where that violation can occur.
*/
const violationFields: Record<ViolationName, ViolationField> = {
allTagLevelsRequired: 'tag',
Expand Down Expand Up @@ -60,13 +60,12 @@ function useViolations(violations: TransactionViolation[]) {
return violationGroups ?? new Map();
}, [violations]);

const hasViolations = useCallback((field: ViolationField) => Boolean(violationsByField.get(field)?.length), [violationsByField]);
const getViolationsForField = useCallback((field: ViolationField) => violationsByField.get(field) ?? [], [violationsByField]);

return {
hasViolations,
getViolationsForField,
};
}

export default useViolations;
export type {ViolationField};
Loading
Loading