-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Move RBR to workspace chats instead of transaction threads #51893
Conversation
src/libs/ReportUtils.ts
Outdated
// - Belong to the same workspace | ||
// And if any have a violation, then it should have a RBR | ||
const allReports = Object.values(ReportConnection.getAllReports() ?? {}); | ||
const potentialReports = allReports.filter((r: Report) => r?.ownerAccountID === currentUserAccountID && r?.stateNum <= 1 && r?.policyID === report.policyID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error must be for these lines
@@ -693,46 +693,6 @@ describe('DebugUtils', () => { | |||
}); | |||
expect(reason).toBe('debug.reasonVisibleInLHN.pinnedByUser'); | |||
}); | |||
it('returns correct reason when report has IOU violations', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deleted this since it seems to me it's testing the same thing as this other test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the harm in leaving it? That sounds better if it's possible for there to be a case that this catches that the other test doesn't
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why have 2 tests that do the same? It's confusing, useless and a waste of time to have to update it now (and in the future whenever this changes)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cause I got the impression that we think they're identical, but not 100% sure. If that's the case, I think it's better to leave it, but NAB
@ Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Oh I also need to update a regression test: https://expensify.slack.com/archives/C9YU7BX5M/p1730833945360329 |
@iwiznia Should we review or wait? I am a little confused |
Review! What was confusing? |
@iwiznia You mentioned something about regression tests so I wasn't sure if you wanted to add more tests to the PR |
Yes, if you follow the link, we have a plan to update the regression tests when this is merged, but that update is outside of this PR code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking this on! I think one of the most important parts of this PR should be to update the regression tests we have for violations to make sure the steps that used to check for RBRs on the transaction threads are updated to check the workspace chat.
That way we can have Applause run the full suite of violation tests as part of this PR and be confident we're not going to push bugs
@@ -693,46 +693,6 @@ describe('DebugUtils', () => { | |||
}); | |||
expect(reason).toBe('debug.reasonVisibleInLHN.pinnedByUser'); | |||
}); | |||
it('returns correct reason when report has IOU violations', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the harm in leaving it? That sounds better if it's possible for there to be a case that this catches that the other test doesn't
@@ -92,6 +92,9 @@ type TransactionViolation = { | |||
|
|||
/** Additional violation information to provide the user */ | |||
data?: TransactionViolationData; | |||
|
|||
/** Indicates if this violation should be shown in review */ | |||
showInReview?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be optional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because I am not sending it from PHP when it is not true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
showInReview?: boolean; | |
showInReview: boolean | undefined; |
This should be required to be set (and still allow for undefined). This is needed so we create the correct optimistic data. Not doing so led to a regression #54510
However, now we need to know which violations has showInReview=true
. Can you please provide a list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would this need to be set for optimistic actions to work? 😕
However, now we need to know which violations has showInReview=true. Can you please provide a list?
I don't think there's a list, there's a bunch of logic controlling this property's value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would this need to be set for optimistic actions to work?
If we don't then expenses created offline that violate policy rules won't have the red dot set on their previews. This is due to this logic
App/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx
Line 120 in ad99c20
const hasViolations = TransactionUtils.hasViolation(transaction?.transactionID ?? '-1', transactionViolations, true); |
showInReview=true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok, so let's add that property to the optimistic actions (assuming the property will be removed when the data from the server is returned), but no need to mark this prop as required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with not making this required is that the bug could resurface (one could simply forget to add the field). Do you think we shouldn't optimize for this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it actually prevents bugs? Allowing undefined gives the same signal to code authors as allowing it to not be passed, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point. Forcing the field to be set can reduce the occurrence of such bugs as you will get a chance to put in the correct value but it won't 100% prevent the bug.
We will keep the types untouched.
(violation: TransactionViolation) => violation.type === CONST.VIOLATION_TYPES.WARNING, | ||
); | ||
function hasWarningTypeViolation(transactionID: string, transactionViolations: OnyxCollection<TransactionViolation[]>, showInReview?: boolean | null): boolean { | ||
const warningTypeViolations = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB but break this down to make it more readable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like how? I had it formatted more readable but then the styler changed it to this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID]
in a variable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did that, not sure if it makes it any better though 🤷
const warningTypeViolations = transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID]?.filter( | ||
(violation: TransactionViolation) => violation.type === CONST.VIOLATION_TYPES.WARNING, | ||
); | ||
function hasWarningTypeViolation(transactionID: string, transactionViolations: OnyxCollection<TransactionViolation[]>, showInReview?: boolean | null): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make the last param mandatory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
} | ||
|
||
/** | ||
* Checks to see if a report contains a violation of type `warning` | ||
*/ | ||
function hasWarningTypeViolations(reportID: string, transactionViolations: OnyxCollection<TransactionViolation[]>): boolean { | ||
function hasWarningTypeViolations(reportID: string, transactionViolations: OnyxCollection<TransactionViolation[]>, shouldShowInReview?: boolean): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make the last param mandatory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
@@ -809,41 +809,36 @@ function isOnHoldByTransactionID(transactionID: string): boolean { | |||
/** | |||
* Checks if any violations for the provided transaction are of type 'violation' | |||
*/ | |||
function hasViolation(transactionID: string, transactionViolations: OnyxCollection<TransactionViolations>): boolean { | |||
function hasViolation(transactionID: string, transactionViolations: OnyxCollection<TransactionViolations>, showInReview?: boolean): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make the last param mandatory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
); | ||
} | ||
|
||
/** | ||
* Checks if any violations for the provided transaction are of type 'notice' | ||
*/ | ||
function hasNoticeTypeViolation(transactionID: string, transactionViolations: OnyxCollection<TransactionViolation[]>): boolean { | ||
return !!transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID]?.some((violation: TransactionViolation) => violation.type === CONST.VIOLATION_TYPES.NOTICE); | ||
function hasNoticeTypeViolation(transactionID: string, transactionViolations: OnyxCollection<TransactionViolation[]>, showInReview?: boolean): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make the last param mandatory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
} | ||
|
||
/** | ||
* Checks to see if a report contains a violation | ||
*/ | ||
function hasViolations(reportID: string, transactionViolations: OnyxCollection<TransactionViolation[]>): boolean { | ||
function hasViolations(reportID: string, transactionViolations: OnyxCollection<TransactionViolation[]>, shouldShowInReview?: boolean): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make the last param mandatory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the places we are calling this that I did not update, we do not care about the state of this variable, so no.
// - Owned by the same user | ||
// - Are either open or submitted | ||
// - Belong to the same workspace | ||
// And if any have a violation, then it should have a RBR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see this condition was deleted if (isSettled(IOUReportID) || isReportApproved(IOUReportID?.toString())) {
, but should we be checking for settled/approved reports, and only show RBR on workspace chats if there's an expense report on the same policy of the workspace chat that isn't approved or settled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's done with (r.stateNum ?? 0) <= 1
below
I will wait for the ^ comments to be addressed before continuing the review |
Co-authored-by: Carlos Alvarez <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🚀 Verified the following cases as mentioned in the tests:
- In the workspace chat
- In the report preview in the workspace chat
- In the expense preview in the workspace chat for reports with only one expense
- In the expense preview of the report for reports with more than one expense
- In the expense itself
- Check that a receipt with only modified date/amount violation is not shown with a RBR in the LHN, but it does show in the expense page when the report is in open state
- Check that a receipt with only modified date/amount violation is shown with a RBR in in the report/expense page when the report is in submitted state
🎯 @allgandalf, thanks for reviewing and testing this PR! 🎉 An E/App issue has been created to issue payment here: #52341. |
That phrase is not there anymore, I think you were looking at the outdated description? |
i guess my GH's live update didn't work this time 🤣 |
@iwiznia @cead22 We removed the App/src/libs/WorkspacesSettingsUtils.ts Line 70 in 861d7e5
|
🚀 Deployed to staging by https://github.com/cead22 in version: 9.0.61-0 🚀
|
Damn, so someone must've added a usage in the meantime |
Yes |
🚀 Deployed to production by https://github.com/francoisl in version: 9.0.61-3 🚀
|
return !!transactionViolations?.[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS + transactionID]?.some( | ||
(violation: TransactionViolation) => violation.type === CONST.VIOLATION_TYPES.VIOLATION, | ||
(violation: TransactionViolation) => violation.type === CONST.VIOLATION_TYPES.VIOLATION && (showInReview === undefined || showInReview === (violation.showInReview ?? false)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic is confusing. If showInReview
is false
and violation.showInReview
is unset (not sent by BE). Then we will end up showing this in review? (false === false)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Held on https://github.com/Expensify/Web-Expensify/pull/44293Explanation of Change
Fixed Issues
https://github.com/Expensify/Expensify/issues/433103
Tests
Offline tests
No
QA Steps
Same as tests
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
MacOS: Desktop