-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Fix: Approved requests shouldn't have a delete option #27952
Changes from all commits
109465e
db2d24e
ce27512
ac8c1ca
90df38f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -755,6 +755,17 @@ function isMoneyRequestReport(reportOrID) { | |
return isIOUReport(report) || isExpenseReport(report); | ||
} | ||
|
||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this a part of this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okey, I think I get it. The added usage cause a lint error. I'm not sure I understand it though, to be honest, I thought that there was no problem with calling functions in the same module, even when there are cycles. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was causing a lint error due to the function being used before it was defined so I needed to rearrange its order. |
||
* Get the report given a reportID | ||
* | ||
* @param {String} reportID | ||
* @returns {Object} | ||
*/ | ||
function getReport(reportID) { | ||
// Deleted reports are set to null and lodashGet will still return null in that case, so we need to add an extra check | ||
return lodashGet(allReports, `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {}) || {}; | ||
} | ||
|
||
/** | ||
* Can only delete if the author is this user and the action is an ADDCOMMENT action or an IOU action in an unsettled report, or if the user is a | ||
* policy admin | ||
|
@@ -764,29 +775,36 @@ function isMoneyRequestReport(reportOrID) { | |
* @returns {Boolean} | ||
*/ | ||
function canDeleteReportAction(reportAction, reportID) { | ||
// For now, users cannot delete split actions | ||
if (ReportActionsUtils.isMoneyRequestAction(reportAction) && lodashGet(reportAction, 'originalMessage.type') === CONST.IOU.REPORT_ACTION_TYPE.SPLIT) { | ||
return false; | ||
} | ||
const report = getReport(reportID); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function becomes a mess... Do I understand correctly that it's equivalent to... const report = getReport(reportID);
const isMoneyRequestActionProtectedFromBeingUserDeleted = () => {
if (ReportActionsUtils.isMoneyRequestAction(reportAction)) {
// For now, users cannot delete split actions
const isSplitAction = lodashGet(reportAction, 'originalMessage.type') === CONST.IOU.REPORT_ACTION_TYPE.SPLIT;
return isSplitAction || isSettled(reportAction.originalMessage.IOUReportID) || isReportApproved(report);
} else {
return false;
}
}
const isActionProtectedFromBeingUserDeleted = () => reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT ||
reportAction.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE ||
ReportActionsUtils.isCreatedTaskReportAction(reportAction) ||
reportAction.actorAccountID === CONST.ACCOUNT_ID.CONCIERGE ||
isMoneyRequestActionProtectedFromBeingUserDeleted();
const isAdmin = () => {
const policy = lodashGet(allPolicies, `${ONYXKEYS.COLLECTION.POLICY}${report.policyID}`) || {};
return policy.role === CONST.POLICY.ROLE.ADMIN && !isDM(report);
}
return (isActionOwner && !isActionProtectedFromBeingUserDeleted()) || isAdmin(); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think below 2 points look incorrect to me
reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT ||
reportAction.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE ||
ReportActionsUtils.isCreatedTaskReportAction(reportAction) ||
reportAction.actorAccountID === CONST.ACCOUNT_ID.CONCIERGE ||
isMoneyRequestActionProtectedFromBeingUserDeleted();
So I think combining all parts here won't work as expected. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right, early returns matter a lot here. Still, we introduce code duplication and add extra complexity to already complex function. How about this? function canDeleteReportAction(reportAction, reportID) {
const report = getReport(reportID);
const isActionOwner = reportAction.actorAccountID === currentUserAccountID;
if (ReportActionsUtils.isMoneyRequestAction(reportAction)) {
// For now, users cannot delete split actions
const isSplitAction = lodashGet(reportAction, 'originalMessage.type') === CONST.IOU.REPORT_ACTION_TYPE.SPLIT;
if (isSplitAction || isSettled(reportAction.originalMessage.IOUReportID) || isReportApproved(report)) {
return false;
}
if (isActionOwner) {
return true;
}
}
if (
reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT ||
reportAction.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE ||
ReportActionsUtils.isCreatedTaskReportAction(reportAction) ||
reportAction.actorAccountID === CONST.ACCOUNT_ID.CONCIERGE
) {
return false;
}
const policy = lodashGet(allPolicies, `${ONYXKEYS.COLLECTION.POLICY}${report.policyID}`) || {};
const isAdmin = policy.role === CONST.POLICY.ROLE.ADMIN && !isDM(report);
return isActionOwner || isAdmin;
} I proved that these two functions have equivalent truth tables: function canDeleteAction1(args) {
if (args.isMoneyRequestAction && args.isSplitAction) {
return false;
}
if (args.isActionOwner && args.isMoneyRequestAction && !args.isActionSettled && !args.isApproved) {
return true;
}
if (
args.isNotAddComment ||
args.isPendingDelete ||
args.isCreatedTask ||
(args.isMoneyRequestAction && (args.isActionSettled || args.isApproved)) ||
args.isConcierge
) {
return false;
}
if (args.isActionOwner) {
return true;
}
return args.isAdmin;
}
function canDeleteAction2(args) {
if (args.isMoneyRequestAction) {
if (args.isSplitAction || args.isActionSettled || args.isApproved) {
return false;
} else if (args.isActionOwner) {
return true;
}
}
if (
args.isNotAddComment ||
args.isPendingDelete ||
args.isCreatedTask ||
args.isConcierge
) {
return false;
}
return args.isActionOwner || args.isAdmin;
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks much cleaner to me @cubuspl42 🚀 |
||
|
||
const isActionOwner = reportAction.actorAccountID === currentUserAccountID; | ||
if (isActionOwner && ReportActionsUtils.isMoneyRequestAction(reportAction) && !isSettled(reportAction.originalMessage.IOUReportID)) { | ||
return true; | ||
|
||
if (ReportActionsUtils.isMoneyRequestAction(reportAction)) { | ||
// For now, users cannot delete split actions | ||
const isSplitAction = lodashGet(reportAction, 'originalMessage.type') === CONST.IOU.REPORT_ACTION_TYPE.SPLIT; | ||
|
||
if (isSplitAction || isSettled(reportAction.originalMessage.IOUReportID) || isReportApproved(report)) { | ||
return false; | ||
} | ||
|
||
if (isActionOwner) { | ||
return true; | ||
} | ||
} | ||
|
||
if ( | ||
reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT || | ||
reportAction.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || | ||
ReportActionsUtils.isCreatedTaskReportAction(reportAction) || | ||
(ReportActionsUtils.isMoneyRequestAction(reportAction) && isSettled(reportAction.originalMessage.IOUReportID)) || | ||
reportAction.actorAccountID === CONST.ACCOUNT_ID.CONCIERGE | ||
) { | ||
return false; | ||
} | ||
if (isActionOwner) { | ||
return true; | ||
} | ||
const report = lodashGet(allReports, `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {}); | ||
|
||
const policy = lodashGet(allPolicies, `${ONYXKEYS.COLLECTION.POLICY}${report.policyID}`) || {}; | ||
return policy.role === CONST.POLICY.ROLE.ADMIN && !isDM(report); | ||
const isAdmin = policy.role === CONST.POLICY.ROLE.ADMIN && !isDM(report); | ||
|
||
return isActionOwner || isAdmin; | ||
} | ||
|
||
/** | ||
|
@@ -1194,17 +1212,6 @@ function getDisplayNamesWithTooltips(personalDetailsList, isMultipleParticipantR | |
}); | ||
} | ||
|
||
/** | ||
* Get the report given a reportID | ||
* | ||
* @param {String} reportID | ||
* @returns {Object} | ||
*/ | ||
function getReport(reportID) { | ||
// Deleted reports are set to null and lodashGet will still return null in that case, so we need to add an extra check | ||
return lodashGet(allReports, `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {}) || {}; | ||
} | ||
|
||
/** | ||
* Determines if a report has an IOU that is waiting for an action from the current user (either Pay or Add a credit bank account) | ||
* | ||
|
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.
We forgot to factor in the deleted requests here. This later on caused #26019